В нашем проекте у нас есть библиотека A, которая зависит от библиотеки B, которая зависит от библиотеки 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(); }
Теперь было бы неплохо не иметь явных упоминаний о libB везде, где мы используем libA, например:
# 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)
Это либо слишком навязчиво (если это делается локально при каждом определении библиотеки) или требует полной копии иерархии зависимостей где-то еще (если это сделано, когда определена библиотека подделок).