2015-12-23 2 views
9

Я начинающий пользователь CMake. В моей среде есть несколько проектов, таких как:CMake one build directory для нескольких проектов

project 
    |------ CMakeLists.txt (The main Cmake) 
    |------ ProjectA 
    |   |----- .cpp files 
    |   |----- .hpp files 
    |   |----- CMakeList.txt 
    |------ ProjectB 
    |   |----- .cpp files 
    |   |----- .hpp files 
    |   |----- CMakeList.txt 
    | 
    |------ build 
    |   |----- CMakeStuff 
    |------ bin 
    |  |---- executables 
    |------ lib 
    |  |---- libwhatever.a 
    |------ db 
      |---- Database stuff 

Я хотел бы использовать один каталог компоновки для каждого проекта, как показано выше. Предпочтительно, чтобы его можно было разделить на несколько подпроектов, таких как build/projectA, build/ProjectB, так что, если мне нужно перестроить один проект, я могу удалить весь файл build/Project, и все исчезнет, ​​и новый Cmake снова построит его.

У меня возникли трудности с настройкой CMAKE.

Мой оригинальный CMakeList.txt папку проекта:

cmake_minimum_required(VERSION 3.2.2.) 
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../lib) 
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../lib) 
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../bin) 

project(projectA) 
set(CMAKE_BUILD_TYPE Debug) 

file(GLOB SOURCES "*.cpp") 

add_library(commonmessage SHARED ${SOURCES}) 

install(TARGETS commonmessage DESTINATION ../lib) 

Мои вопросы:

A) Что произойдет, если я бегу CMake на одной директории сборки - это то, что возможно и что бы быть правильной конфигурацией CMAKE?

B) Моя компиляция для ProjectA должна содержать файлы от ProjectB - как я могу установить это в CMakeLists.txt для каждого отдельного проекта?

C) В конце мне нужен один make-файл для создания всех, а также возможность индивидуального создания каждого проекта. Будет ли это возможно с помощью одного каталога сборки?

Спасибо за помощь.

ответ

16

Прежде всего, это не похоже, что код CMake, который вы опубликовали, принадлежит к верхнему файлу CMakeList.txt, так как он напрямую ссылается на файлы .cpp и «projectA». Есть также несколько вещей, которые не идиоматическое:

cmake_minimum_required(VERSION 3.2.2.) 

почему завершающая точка здесь? Не уверен, пожалуется ли cmake, но это бесполезно в любом случае.

set(CMAKE_BUILD_TYPE Debug) 

Не делайте этого. Вместо этого вызовите cmake, используя флаг командной строки -DCMAKE_BUILD_TYPE=Debug, или используйте ccmake или графический интерфейс пользователя или отредактируйте файл CMakeCache.txt.

file(GLOB SOURCES "*.cpp") 

Не делайте этого. Хорошей практикой является прямое перечисление исходных файлов в CMake, потому что globbing не будет автоматически определять cmake автоматически или автоматически удаленные файлы. Однако некоторые люди могут не согласиться.

Теперь для сердца тему, вот как вещи обычно делается:

Лучшие CMakeLists.TXT файл:

cmake_minimum_required(VERSION 3.2.2) 
project(globalProject) 

add_subdirectory(projectA) 
add_subdirectory(projectB) 

ProjectA CMakeLists.txt файл (предполагается, что Projecta является исполняемым):

add_executable(projectA file1.cpp file2.cpp ...) 
include_directories(${CMAKE_SOURCE_DIR}/projectB) # include files from ProjectB 
target_link_libraries(projectA projectB) 

install(TARGETS projectA RUNTIME DESTINATION bin) 

ProjectB CMakeLists.txt файл (предполагается, что projectB библиотека):

add_library(projectB file1.cpp file2.cpp ...) 

install(TARGETS projectB 
    LIBRARY DESTINATION lib 
    ARCHIVE DESTINATION lib) 

Обратите внимание, что для этой установки необходим шаг make install для создания bin и lib в выбранном вами месте, как указано в вызове командной строки cmake -DCMAKE_INSTALL_PREFIX=.. (предположим make make запускается из файла сборки).

Кроме того, эта настройка позволяет вам выбрать, хотите ли вы создавать статические или разделяемые библиотеки, используя: -DBUILD_SHARED_LIBS=ON. Для создания обоих вам необходимо иметь два вызова add_library с двумя разными именами, один STATIC, другой SHARED.

Суммируя шаги, необходимые, чтобы сделать эту работу:

$ mkdir build && cd build 
$ cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=.. -DBUILD_SHARED_LIBS=ON 
$ make 
$ make install 

Вы можете поместить эти команды в сценарий для многократного использования.

Теперь можно ответить на ваши вопросы:

A) можно и рекомендуется, см код выше, только один каталог для сборки необходимо.

B) Смотрите код для Projecta/CMakeLists.txt, вы должны вызвать include_directories()

C) Да, это возможно. Каждая цель в вашем проекте может быть построена индивидуально из каталога сборки с использованием make и целевого имени: make projectB и make projectA

+0

Сэр, спасибо за помощь ... что делать, если мне нужно сгенерировать файлы lib и bin в целевой папке без необходимости «make install»? – Mendes

+0

Хотя это возможно с помощью переменных 'CMAKE _ * _ OUTPUT_DIRECTORY', я бы не рекомендовал этого, потому что у вас может быть несколько каталогов сборки с несколькими конфигурациями (Debug vs. Release, другой компилятор и т. Д.), И всегда хорошо иметь возможность тестировать их параллельно, не перезаписывая файлы при компиляции. Зачем вам нужен bin/lib в корне вашего проекта? – SirDarius

+0

Хорошая точка. 'bin' - это место, где будут установлены все исполняемые файлы. 'lib 'будет содержать все библиотеки. – Mendes

1

A) Вы можете сделать 1 CMakeLists.txt для N проектов. Когда вы определяете библиотеку, вы можете использовать ее в исполняемом файле, определенном в cmake (см. Add_executable и target_link_libraries).

В) см target_include_directories

C), кажется, можно назвать cmake --target target для создания Makefile только для одной мишени из файла CMakeLists.txt.

Смежные вопросы