2013-05-04 219 views
1

我對Cmake非常陌生,我試圖用它作爲approach的替代方案,但這種方法無法正常工作。在Cmake中包含庫和目錄包含的共享對象

我的結構其實很簡單,我有:

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

而且在每個App/src/soN文件夾中,我有一個.cpp文件時,將被編譯成一個共享對象。 我知道我必須在上面列出的每個文件夾中添加一個CMakeLists.txt文件,但我真的迷失在圖書館鏈接和包含。

例如,假設有App/src/so1下的以下文件:

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

和共享對象so1.so需要-I /some/dir/include,並且也需要被鏈接到-L /some/other/dir/lib -l otherdirlibCMake有什麼合適的指令?

回答

2

編輯:

使用文件和GLOB_RECURSE:

GLOB_RECURSE會產生類似規則GLOB名單,除了 它會遍歷匹配的目錄下的所有子目錄和 匹配文件。

我建議你rearrenge文件是這樣的:

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

中的CMakeLists.txt在app文件夾:

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) 

中的CMakeLists.txt每個lib文件夾中會是這樣的(相應地更改每個文件中的LIB_OUTPUT_NAME):

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}) 

然後在主要的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) 

更多信息:

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

+0

+1非常感謝您爲您的幫助,但我還沒有能夠產生makefile文件。我有一些特別的問題:在你的文章中,什麼說我正在製作共享對象?與動態庫('-L/path/to/mylib -l mylib')的鏈接在哪裏?包含似乎工作正常,我想這兩個是現在唯一的左側依賴關係。我可以用link_directories(「path/to/mylib」)添加路徑,但是我不知道在'target_link_libraries(??? mylib)'中使用哪個名稱。根據我的想法,'???'應該替換爲每個產生的'.so'。 – Rubens 2013-05-04 14:12:03

+0

我可能不清楚,但實際上我必須將每個'soN/soN.cpp,soN/soN.hpp'編譯到一個共享庫中,所以首先是'soN.o',然後,一個'soN.so'。我的意思是,我不會擁有一個獨特的可執行文件,我只會擁有'N'共享對象'.so'。 – Rubens 2013-05-04 14:32:41

+0

哦,這些都是動態庫,那麼你需要在每個文件夾CMakeLists,讓我更新帖子。 – AngelCastillo 2013-05-04 15:30:43