У меня есть следующий сценарий:
- Я импортирую две готовые библиотеки в свой проект (
libA
, libB
) libB
зависит от libA
- Исполняемый файл зависит как от
libA
, так и от libB
Однако относительный порядок ссылок в моем файле link.txt неверен
/usr/bin/c++ CMakeFiles/bin.dir/main.cpp.o -o bin ../libA.a ../libB.a
Я ожидаю, что libA.a
будет указан после libB.a
.CMakeLists.txt выглядит примерно так: 1024 *
cmake_minimum_required(VERSION 3.13)
project(cmake_test)
set(lib_dir ${CMAKE_CURRENT_SOURCE_DIR})
add_library(MY::libA IMPORTED INTERFACE)
set_target_properties(MY::libA PROPERTIES INTERFACE_LINK_LIBRARIES "${lib_dir}/libA.a")
add_library(MY::libB IMPORTED INTERFACE)
set_target_properties(MY::libB PROPERTIES INTERFACE_LINK_LIBRARIES "MY::libA;${lib_dir}/libB.a")
add_executable(bin ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
target_link_libraries(bin PUBLIC MY::libB MY::libA)
Ниже приведено описание моих попыток решить проблему.Некоторые безуспешно, некоторые с успехом, но используют модификации, которые делают код бесполезным для производственной среды.
Успешные попытки:
- Устранить зависимость
bin
от libA
(т.е. замените последнюю строку на target_link_libraries(bin PUBLIC MY::libB)
. Это работает, но я не могу удалить зависимость в реальном коде. - Замените целевой тип
IMPORTED INTERFACE
на IMPORTED STATIC
. Используйте IMPORTED_LOCATION
вместо INTERFACE_LINK_LIBRARIES
ииспользуйте target_link_libraries
для выражения зависимости libB
от libA
. В этом случае link.txt
дает: [...] -o bin ../libA.a ../libB.a ../libA.a
. Как только я возвращаю целевой тип для libB
, порядок ссылок снова нарушается.однако в производственной среде conan создает одну из целей как IMPORTED INTERFACE
.
Попытки безуспешны (как описано выше):
- Создайте отдельную
IMPORTED
target (используйте IMPORTED_LOCATION
) для каждой библиотеки и сгруппируйте их в INTERFACE
target - Посыпьте код с помощью
ADD_DEPENDENCIES
- Удалите
libA
из INTERFACE_LINK_LIBRARIES
в строке 9 используйте вместо него target_link_libraries(MY::libB INTERFACE MY::libA)
. Тот же результат.
Пример кода, который показывает ту же ошибку, используя INTERFACES
в качестве строительного блока
cmake_minimum_required(VERSION 3.13)
project(cmake_test)
set(lib_dir ${CMAKE_CURRENT_SOURCE_DIR})
# libA
add_library(MY::libA_file1 IMPORTED STATIC)
set_target_properties(MY::libA_file1 PROPERTIES IMPORTED_LOCATION "${lib_dir}/libA.a")
add_library(libA INTERFACE)
target_link_libraries(libA INTERFACE MY::libA_file1)
# libB
add_library(MY::libB_file1 IMPORTED STATIC)
set_target_properties(MY::libB_file1 PROPERTIES IMPORTED_LOCATION "${lib_dir}/libB.a")
add_library(libB INTERFACE)
target_link_libraries(libB INTERFACE MY::libB_file1 libA)
add_executable(bin ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
target_link_libraries(bin PUBLIC libA libB)