CMAKE: сборка библиотеки и ссылка на нее

Я пытаюсь использовать cmake (на Linux с GNU make и g++) для создания проекта с двумя подкаталогами: MyLib и MyApp. MyLib содержит источник для статической библиотеки; MyApp необходимо связать с этой библиотекой. Я пытаюсь создать Linux с сгенерированными make файлами, используя следующий CMakeLists.txt:

cmake_minimum_required (VERSION 2.6)
project (MyProj)
include_directories (MyLib)
file(GLOB MyLibSrc MyLib/*.cpp)
add_library(MyLibrary STATIC ${MyLibSrc})
file(GLOB MyAppSrc MyApp/*.cpp)
add_executable(MyApplication ${MyAppSrc})
target_link_libraries(MyApplication MyLibrary)

Это "почти" работает. Он не работает во время связи, потому что пока он генерирует libMyLibrary.a - он находится в корне. Когда я добавляю:

link_directories(${MyProj_BINARY_DIR})

это не имеет значения.

У меня есть несколько (взаимосвязанных) вопросов:

  • Какой лучший способ принудить cmake к созданию моей библиотеки и исполняемого файла в "промежуточном каталоге" — скажите MyStage — сохранить цели отдельно от источника?
  • Как убедить cmake связать приложение с библиотекой?
  • Если бы я хотел создать отладочную версию и версию выпуска, то какой лучший способ расширить мои сценарии cmake, чтобы сделать это & ​​mdash; убедиться, что приложение отладки ссылается на библиотеку отладки и приложение выпуска на библиотеку выпусков?

Я относительный новичок в cmake. Я читал, что могу найти в Интернете, но обнаружил, что изо всех сил пытаюсь связать мою библиотеку с моим исполняемым файлом. На мой взгляд, такая конфигурация должна быть довольно распространенной. Пример, из которого на кроватку был бы очень полезен, но я его не нашел.

Ответ 1

  • Используйте "вне сборки источника". Создайте каталог, используемый только для сборки и в нем, вызовите

    cmake <path to the sources, it may be relative>
  • Используйте либо

    link_directories(${MyProj_BINARY_DIR}/MyLib)

    или make CMakeLists.txt в каждом подкаталоге - это будет лучше для проекта, большего, чем очень маленький.

  • Это немного сложно, проверьте CMAKE_BUILD_TYPE в документах (вы можете установить его и/или "если" им). Вы также можете установить его из командной строки:

    cmake -DCMAKE_BUILD_TYPE=Debug

Ответ 2

Что ж, лучше прочитать этот пример и сделать именно так, как предложено.

cmake_minimum_required (VERSION 2.6)
project (MyProj CXX)
add_subdirectory(MyLib)
add_subdirectory(MyApp)

Затем для каждого указанного подкаталога создаются файлы CMakeLists.txt.

MyLib\CMakeLists.txt

file(GLOB SRC_FILES *.cpp)
add_library(MyLib ${SRC_FILES})

MyApp\CMakeLists.txt

file(GLOB SRC_FILES *.cpp)
add_executable(MyApp ${SRC_FILES})
target_link_libraries(MyApp MyLib) 

Ответ 3

Я нашел "оптимальное" решение для (1)... так что подумал, что я должен опубликовать его здесь:

SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY MyStage)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY MyStage)

То, что меня смутило ранее, состоит в том, что статические библиотеки не считаются LIBRARY by Cmake - они считаются ARCHIVE.

Ответ 4

Не добавляйте библиотеки и исполняемые файлы в корневой каталог Cmakelists.txt. Добавьте эти библиотеки и исполняемые файлы в Cmakelists.txt подкаталогов.