c++ - example - CMake un directorio de compilación para múltiples proyectos
cmake tutorial (2)
A) Puedes hacer 1 CMakeLists.txt para N proyectos. Cuando define una biblioteca, puede usarla en un archivo ejecutable definido en cmake (add_executable y target_link_libraries para ver).
B) ver target_include_directories
C) parece que se puede llamar cmake --target target
para generar el Makefile para solo uno del objetivo de su archivo cmakelists.txt.
Soy un usuario principiante de CMake. Mi entorno tiene varios proyectos como:
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
Me gustaría utilizar un único directorio de compilación para cada proyecto, como se muestra arriba. Preferiblemente, se puede dividir en múltiples subproyectos, como build/projectA
, build/ProjectB
modo que si necesito reconstruir un solo proyecto, puedo eliminar toda la build/Project
archivo de build/Project
y todo se va y un nuevo Cmake
lo construirá nuevamente.
Tengo dificultades para configurar CMAKE.
Mi CMakeList.txt original en la carpeta del proyecto:
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)
Mis preguntas son:
A) ¿Qué pasará si ejecuto cmake en un solo directorio de compilación? ¿Es posible y cuál sería la configuración correcta de CMAKE?
B) Mi compilación para ProjectA
necesita incluir archivos de ProjectB
. ¿Cómo puedo configurar eso en CMakeLists.txt
para cada proyecto individual?
C) Al final, necesito un único archivo MAKE para construir todo, así como también la opción de construir cada proyecto individualmente. ¿Será posible con un único directorio de compilación?
Gracias por ayudar.
En primer lugar, no parece que el código CMake que publicó pertenezca al archivo CMakeList.txt superior, ya que hace referencia directamente a los archivos .cpp y a "projectA". También hay algunas cosas que no son idiomáticas:
cmake_minimum_required(VERSION 3.2.2.)
¿Por qué el punto final aquí? No estoy seguro de si cmake se quejará, pero es inútil de cualquier manera.
set(CMAKE_BUILD_TYPE Debug)
No hagas eso. En su lugar, invoque cmake utilizando el -DCMAKE_BUILD_TYPE=Debug
línea de comando -DCMAKE_BUILD_TYPE=Debug
, o use ccmake, o una GUI, o edite el archivo CMakeCache.txt.
file(GLOB SOURCES "*.cpp")
No hagas eso tampoco. Es una buena práctica incluir explícitamente los archivos de origen en CMake, porque globbing no hará que cmake detecte archivos recién agregados o eliminados automáticamente. Algunas personas pueden estar en desacuerdo sin embargo.
Ahora, para el meollo del tema, así es cómo se hacen las cosas habitualmente:
Archivo CMakeLists.txt superior:
cmake_minimum_required(VERSION 3.2.2)
project(globalProject)
add_subdirectory(projectA)
add_subdirectory(projectB)
Archivo ProjectA CMakeLists.txt (suponiendo que projectA es un ejecutable):
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)
Archivo ProjectB CMakeLists.txt (suponiendo que projectB es una biblioteca):
add_library(projectB file1.cpp file2.cpp ... )
install(TARGETS projectB
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
Tenga en cuenta que esta configuración necesita el paso make install
para crear bin y lib en la ubicación de su elección como figura en la invocación de cmake -DCMAKE_INSTALL_PREFIX=..
línea de comandos (suponiendo que make se ejecute desde el directorio de compilación).
Además, esta configuración le permite elegir si desea compilar bibliotecas estáticas o compartidas, utilizando: -DBUILD_SHARED_LIBS=ON
. Para compilar ambos, necesita tener dos llamadas add_library
con dos nombres diferentes, uno STATIC y el otro SHARED.
Para resumir los pasos necesarios para hacer que esto funcione:
$ mkdir build && cd build
$ cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=.. -DBUILD_SHARED_LIBS=ON
$ make
$ make install
Podría poner estos comandos en una secuencia de comandos para su reutilización.
Ahora, sus preguntas pueden ser respondidas:
A) es posible y recomendado, vea el código anterior, solo se necesita un directorio de compilación.
B) Vea el código para el proyecto A / CMakeLists.txt, debe llamar a include_directories()
C) Sí, es posible. Cada objetivo en su proyecto se puede construir individualmente desde el directorio de compilación utilizando make y el nombre de destino: make projectB
y make projectA