2013-05-04 1 views
1

Je suis très nouveau à Cmake, et j'essaye de l'employer comme une alternative à ceci approach, qui ne fonctionnait pas bien.Les objets partagés avec des bibliothèques et des inclusions de répertoire dans Cmake

Ma structure est en fait simple, je:

App/src/ 
App/src/so1 
App/src/so2 
App/src/so3 

Et dans chaque dossier App/src/soN, j'ai un fichier .cpp, qui doit être compilé dans un objet partagé. Je sais que je dois ajouter un fichier CMakeLists.txt dans chaque dossier ci-dessus, mais je suis vraiment perdu avec le lien et l'inclusion de la bibliothèque.

Par exemple, supposons que il y a les fichiers suivants sous App/src/so1:

App/src/so1/so1.hpp 
App/src/so1/so1.cpp 

Et l'objet partagé so1.so nécessite -I /some/dir/include, et doit également être lié à -L /some/other/dir/lib -l otherdirlib. Quelles sont les directives appropriées pour faire cela en utilisant CMake?

Répondre

2

EDIT:

Utiliser le fichier et GLOB_RECURSE:

GLOB_RECURSE va générer une liste similaire à la MONDIALISA régulière, sauf il traversera tous les sous-répertoires du répertoire adapté et match de la des dossiers.

conseils que je vous rearrenge vos fichiers comme ceci:

app/ 
|_ src/ 
|_ include/ 
|_ CMakeLists.txt 
so1/ 
|_ src/ 
|_ include/ 
|_ CMakeLists.txt 
so2/ 
|_ src/ 
|_ include/ 
|_ CMakeLists.txt 
so3/ 
|_ src/ 
|_ include/ 
|_ CMakeLists.txt 
CMakeLists.txt 

Le CMakeLists.txt dans le dossier application:

SET (APP_NAME app) 

# Print variables to stdout 
MESSAGE (STATUS) 
MESSAGE (STATUS "Configuring ${APP_NAME}:") 
MESSAGE (STATUS) 

# Source code files 
FILE (GLOB_RECURSE SOURCE_FILES src/*.cpp include/*.h include/*.inl) 

# Compiler options 
IF (CMAKE_COMPILER_IS_GNUCXX) 
    ADD_DEFINITIONS (-ansi -Wall -Wextra -Werror -pthread) 
ENDIF() 

# Build application 
ADD_EXECUTABLE (${APP_NAME} ${SOURCE_FILES}) 

TARGET_LINK_LIBRARIES (${APP_NAME} 
    ${SO1_LIB} 
    ${SO2_LIB} 
    ${SO3_LIB} 
) 

INSTALL (TARGETS ${APP_NAME} RUNTIME DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) 

Le CMakeLists.txt dans chaque dossier lib serait quelque chose comme ceci (changer le LIB_OUTPUT_NAME dans chaque fichier en conséquence):

SET (LIB_OUTPUT_NAME so1) 

# Print variables to stdout 
MESSAGE (STATUS) 
MESSAGE (STATUS "Configuring ${LIB_OUTPUT_NAME}:") 
MESSAGE (STATUS) 

# Source code, headers and test files 
FILE (GLOB_RECURSE HEADER_FILES include/*.h include/*.inl) 
FILE (GLOB_RECURSE SOURCE_FILES src/*.cpp include/*.h include/*.inl) 
FILE (GLOB_RECURSE TEST_SRC_FILES tests/*.cpp tests/*.h tests/*.inl) 

# Compiler options 
IF (CMAKE_COMPILER_IS_GNUCXX) 
    ADD_DEFINITIONS (-ansi -Wall -Wextra -Werror -pthread) 
ENDIF() 

# Build library 
ADD_LIBRARY (${LIB_OUTPUT_NAME} SHARED ${SOURCE_FILES}) 

Puis, dans la principale CMakeLists.txt:

CMAKE_MINIMUM_REQUIRED (VERSION 2.6) 
PROJECT (App CXX) 

# Set common variables 
IF ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") 
    SET (BUILD_DIR build/release) 
ELSE() 
    SET (BUILD_DIR build/debug) 
ENDIF() 

# Print variables to stdout 
MESSAGE (STATUS) 
MESSAGE (STATUS "Building App:") 
MESSAGE (STATUS "change a configuration variable with: cmake -D<Variable>=<Value>") 
MESSAGE (STATUS "CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}") 
MESSAGE (STATUS "CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}") 
MESSAGE (STATUS "CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}") 
MESSAGE (STATUS) 

# Remove build directory on clean target 
SET_DIRECTORY_PROPERTIES (PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${BUILD_DIR}) 

# Include directories 
INCLUDE_DIRECTORIES (
    "app/include" 
    "so1/include" 
    "so2/include" 
    "so3/include" 
) 

# Add common compiler flags 
IF (CMAKE_COMPILER_IS_GNUCXX) 
    SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CPP_FLAGS_RELEASE} -O2") 
    SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g) 
ENDIF() 

# Build all dynamic Libraries 
ADD_SUBDIRECTORY (smartmatic ${BUILD_DIR}/so1) 
SET (SO1_LIB ${CMAKE_CURRENT_SOURCE_DIR}/${BUILD_DIR}/so1/so1.so) 

ADD_SUBDIRECTORY (saes-runtime ${BUILD_DIR}/so2) 
SET (SO2_LIB ${CMAKE_CURRENT_SOURCE_DIR}/${BUILD_DIR}/so2/so2.so) 

ADD_SUBDIRECTORY (saes-devices ${BUILD_DIR}/so3) 
SET (SO3_LIB ${CMAKE_CURRENT_SOURCE_DIR}/${BUILD_DIR}/so3/so3.so) 

# Add dynamic lib to app build for linking. 
ADD_SUBDIRECTORY (so1 ${BUILD_DIR}/so1) 
SET (SO1_LIB ${CMAKE_CURRENT_SOURCE_DIR}/${BUILD_DIR}/so1/so1.so) 

ADD_SUBDIRECTORY (so2 ${BUILD_DIR}/so2) 
SET (SO2_LIB ${CMAKE_CURRENT_SOURCE_DIR}/${BUILD_DIR}/so2/so2.so) 

ADD_SUBDIRECTORY (so3 ${BUILD_DIR}/so3) 
SET (SO3_LIB ${CMAKE_CURRENT_SOURCE_DIR}/${BUILD_DIR}/so3/so3.so) 

# Build Application 
ADD_SUBDIRECTORY (app ${CMAKE_CURRENT_SOURCE_DIR}/${BUILD_DIR}/app) 

Plus d'informations sur:

http://www.cmake.org/cmake/help/cmake2.6docs.html

+0

+1 Merci beaucoup pour votre aide, mais je n'ai pas encore été en mesure de produire le makefiles. J'ai quelques questions particulières: qu'est-ce que, dans votre message, déclare que je produis des objets partagés? où est le lien avec les bibliothèques dynamiques ('-L/chemin/vers/mylib -l mylib')? L'inclusion semble fonctionner correctement, je suppose que ces deux sont les seules dépendances à gauche maintenant. Je suis capable d'ajouter le chemin avec 'link_directories (" chemin/vers/mylib ")', mais je ne sais pas quel nom utiliser dans 'target_link_libraries (??? mylib)'. D'après ce que je pense, "???" devrait être remplacé pour chaque ".so" produit. – Rubens

+0

Je n'ai peut-être pas été clair, mais je dois effectivement compiler chaque 'soN/soN.cpp, soN/soN.hpp' dans une bibliothèque partagée, donc il y aurait d'abord un' soN.o', et ensuite, un 'soN.so'. Je suis méchant, je ne vais pas avoir un exécutable unique, je vais juste avoir 'N' des objets partagés' .so'. – Rubens

+0

Oh, ce sont des bibliothèques dynamiques, alors vous avez besoin d'un CMakeLists dans chaque dossier, laissez-moi mettre à jour le poste. – AngelCastillo

Questions connexes