Hatred's Log Place

DON'T PANIC!

Jun 11, 2019 - 1 minute read - programming

CMake: Object Library и target_link_libraries()

В современном мире рекомендуется не использовать include_directories() и target_include_directories(), а экспортировать таргет в стиле пространства имён: Target::Target, например так:

add_library(avcpp avcpp.cpp ...)
...
add_library(AvCpp::AvCpp ALIAS avcpp)

и задавать интерфейсные опции для таргета, например так:

target_include_directories(avcpp
  INTERFACE
    $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>
    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

После чего задавать параметры как линковки, так и компиляции одной командой:

add_executable(foo main.cpp)
...
target_link_libraries(foo PUBLIC AvCpp::AvCpp)

Так вот, если вы используете CMake версии до 3.12, то такой подход не сработает для OBJECT_LIBRARY.

Иными словами, если вы решите пробросить параметры компиляции (не линковки) таким образом:

add_library(foo_common OBJECT foo.cpp)
target_link_libraries(foo_common PUBLIC AvCpp::AvCpp)

То получите сообщение об ошибке, примерно такого вида:

CMake Error at tests/CMakeLists.txt:10 (target_link_libraries):
  Object library target "foo_common" may not link to anything.

В общем, читаем:

Решения:

  • Обновляем CMake, к сожалению, на travis.org для OSX пока это сделать трудно, там через brew ставится, на момент написания статьи, 3.11.4;
  • Используем target_include_directories();
  • Используем как и раньше include_directories(), но лучше не надо;
  • Не используем Object Library, что не всегда удобно.

Вопрос, а как можно из командной строки, установить DMG или tar.gz пакет CMake с cmake.org? Второй это просто тарбол, с определённой структурой, можно ли просто распаковать и установить PATH, указывающий на bin директорию внутри?