首页 > 解决方案 > CMake:不同变体满足的库依赖关系

问题描述

在我们的项目中,我们有一个依赖于库 B 的库 A,它依赖于库 C1。但是,出于测试目的,我们希望将库 C1 替换为一些伪造的库 C2。

工作 CMakeLists.txt:

# works, but not CMake-style
add_library(libC1 c1.cpp)
add_library(libC2 c2.cpp)
add_library(libB b.cpp)
add_library(libA a.cpp)
add_executable(e1 e.cpp)
target_link_libraries(e1 libA libB libC1)
add_executable(e2 e.cpp)
target_link_libraries(e2 libA libB libC2)

代码:

// a.cpp
void b();
void a() { b(); }

// b.cpp
void c();
void b() { c(); }

// c1.cpp
#include <iostream>
void c() { std::cout << 1 << std::endl; }

// c2.cpp
#include <iostream>
void c() { std::cout << 2 << std::endl; }

// e.cpp
void a();
int main() { a(); }

现在,最好不要在我们使用 libA 的任何地方明确提及 libB,例如:

# doesn't work
add_library(libC1 c1.cpp)
add_library(libC2 c2.cpp)
add_library(libB b.cpp)
add_library(libA a.cpp)
target_link_libraries(libA libB)
add_executable(e1 e.cpp)
target_link_libraries(e1 libA libC1)
add_executable(e2 e.cpp)
target_link_libraries(e2 libA libC2)

但是,这不起作用,因为现在库按 libA libCx libB 的顺序传递给链接器,导致“未定义引用”错误。有解决这个问题的好方法吗?

我知道的一种方法是保留每个库的两个变体,例如

# works, but clumsy
add_library(libC1 c1.cpp)
add_library(libC2 c2.cpp)
add_library(libB b.cpp)
add_library(libB1 dummy.cpp)
target_link_libraries(libB1 libB libC1)
add_library(libB2 dummy.cpp)
target_link_libraries(libB2 libB libC2)
add_library(libA a.cpp)
add_library(libA1 dummy.cpp)
target_link_libraries(libA1 libA libB1)
add_library(libA2 dummy.cpp)
target_link_libraries(libA2 libA libB2)
add_executable(e1 e.cpp)
target_link_libraries(e1 libA1)
add_executable(e2 e.cpp)
target_link_libraries(e2 libA2)

这要么过于侵入(如果在每个库定义本地完成),要么需要在其他地方完整复制依赖层次结构(如果在定义假库的地方完成)。

标签: cmake

解决方案


推荐阅读