【问题标题】:Shared objects with libraries and directory inclusions in Cmake与 Cmake 中的库和目录包含的共享对象
【发布时间】:2013-05-04 04:31:35
【问题描述】:

我对@9​​87654322@ 很陌生,我正在尝试将它用作approach 的替代品,但效果不佳。

我的结构其实很简单,我有:

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 otherdirlib。使用CMake 进行此操作的适当指令是什么?

【问题讨论】:

    标签: c++ makefile cmake shared-objects mpic++


    【解决方案1】:

    编辑:

    使用文件和 GLOB_RECURSE:

    GLOB_RECURSE 将生成一个类似于常规 GLOB 的列表,除了 它将遍历匹配目录的所有子目录和 匹配文件。

    我建议您像这样重新排列您的文件:

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

    app文件夹中的CMakeLists.txt:

    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)
    

    每个 lib 文件夹中的 CMakeLists.txt 应该是这样的(相应地更改每个文件中的 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

    【讨论】:

    • +1 非常感谢您的帮助,但我还不能生成 makefile。我有一些特别的问题:在您的帖子中,我正在生产共享对象的哪些内容?与动态库 (-L /path/to/mylib -l mylib) 的链接在哪里?包含似乎工作正常,我想这两个是现在唯一剩下的依赖项。我可以使用link_directories ("path/to/mylib") 添加路径,但我不知道在target_link_libraries (??? mylib) 中使用哪个名称。从我的想法来看,??? 应该为每个产生的.so 替换。
    • 我可能还不清楚,但我确实必须将每个soN/soN.cpp, soN/soN.hpp 编译到一个共享库中,所以首先会有一个soN.o,然后是一个soN.so。我的意思是,我不会有唯一的可执行文件,我只会有 N 共享对象 .so
    • 哦,那些是动态库,那么你需要在每个文件夹中都有一个 CMakeLists,让我更新帖子。
    • 我想没关系;你实际上让我发疯了,试图让它运行,但现在我想我已经学到了一些cMake——至少足以在我需要的每个文件夹中构建一个正确的CMakeLists.txt。我会尝试在这里完成事情,如果我在任何步骤中遇到困难,我会寻求帮助。我刚刚注意到您的编辑;谢谢你的回答!
    猜你喜欢
    • 1970-01-01
    • 2018-11-09
    • 1970-01-01
    • 2020-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多