CMake one build directory for multiple projects

Jestem początkującym użytkownikiem CMake. Moje środowisko ma kilka projektów takich jak:

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

Chciałbym użyć jednego katalogu budowania dla każdego projektu, jak pokazano powyżej. Preferencyjnie, że można go podzielić na wiele podprojektów, jak build/projectA, build/ProjectB tak, że jeśli muszę przebudować pojedynczy projekt mogę usunąć cały build/Project plik i wszystko zniknęło i Nowy Cmake zbuduje go ponownie.

Mam problemy z konfiguracją CMAKE.

Mój oryginalny CMakeList.txt na folder projektu:

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)

Moje pytania to:

A) co się stanie, jeśli uruchomię cmake w jednym katalogu build-czy jest to możliwe i jaka byłaby prawidłowa konfiguracja CMAKE ?

B) moja Kompilacja dla ProjectA musi zawierać pliki z ProjectB - Jak mogę to ustawić w CMakeLists.txt dla każdego projektu ?

C) na koniec potrzebuję jednego pliku makefile do zbudowania wszystkich, a także opcji budowania każdego projektu indywidualnie. Czy będzie to możliwe z jednym katalog budowy ?

Dzięki za pomoc.
Author: Mendes, 2015-12-23

2 answers

Po pierwsze, nie wygląda na to, że kod CMake, który napisałeś, należy do top CMakeList.plik txt, ponieważ bezpośrednio odwołuje się do niego .plików cpp oraz "projectA". Jest też kilka rzeczy, które nie są idiomatyczne: {]}

cmake_minimum_required(VERSION 3.2.2.)

Skąd ta kropka ? Nie wiem, czy cmake będzie narzekał, ale i tak jest bezużyteczny.

set(CMAKE_BUILD_TYPE Debug)
Nie rób tego. Zamiast tego wywołaj cmake używając znacznika linii poleceń -DCMAKE_BUILD_TYPE=Debug lub użyj ccmake, lub GUI, lub edytuj CMakeCache.txt plik.
file(GLOB SOURCES "*.cpp")
Tego też nie rób. Dobrą praktyką jest jednoznaczne wyświetlanie plików źródłowych w CMake, ponieważ globbing nie spowoduje, że cmake automatycznie wykryje nowo dodane lub usunięte pliki. Niektórzy ludzie mogą się jednak nie zgodzić.

A teraz sedno tematu, oto jak zwykle rzeczy są zrobione:

Top CMakeLists.plik txt:

cmake_minimum_required(VERSION 3.2.2)
project(globalProject)

add_subdirectory(projectA)
add_subdirectory(projectB)

ProjectA CMakeLists.plik txt (zakładając, że projectA jest wykonywalny):

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.plik txt (zakładając, że projectB jest biblioteką):

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

install(TARGETS projectB
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib)

Należy pamiętać, że ta konfiguracja wymaga kroku make install, aby utworzyć bin i lib w wybranym miejscu, jak podano w wywołaniu linii poleceń cmake -DCMAKE_INSTALL_PREFIX=.. (zakładając, że make jest uruchamiany z katalogu build).

Ta konfiguracja pozwala również wybrać, czy chcesz budować biblioteki statyczne, czy dzielone, używając: -DBUILD_SHARED_LIBS=ON. Aby zbudować oba, musisz mieć dwa add_library wywołania o dwóch różnych nazwach, jedno statyczne, drugie wspólne.

Podsumowując kroki wymagane do wykonania tej pracy:

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

Możesz umieścić te polecenia w skrypcie dla ponownego użycia.

Teraz możesz odpowiedzieć na twoje pytania:

A) jest to możliwe i zalecane, patrz kod powyżej, potrzebny jest tylko jeden katalog budowania.

B) Patrz kod projectA / CMakeLists.txt, musisz zadzwonić include_directories()

C) tak, to możliwe. Każdy cel w projekcie może być zbudowany indywidualnie z katalogu budowania za pomocą make i cel nazwa: make projectB i make projectA

 24
Author: SirDarius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-23 20:41:48

A) możesz zrobić 1 Cmakelisty.txt dla N projektów. Kiedy definiujesz bibliotekę, możesz jej użyć w pliku wykonywalnym zdefiniowanym w cmake (add_executable i target_link_libraries, aby zobaczyć).

B) patrz target_include_directories

C) wydaje się, że możesz wywołać cmake --target target, aby wygenerować plik Makefile tylko dla jednego z celów Twoich cmakelist.plik txt.

 1
Author: Pierre Emmanuel Lallemant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-23 15:14:30