首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CMake:生成或提取共享库所需的报头

CMake:生成或提取共享库所需的报头
EN

Stack Overflow用户
提问于 2017-07-13 11:32:41
回答 1查看 848关注 0票数 3

我目前正在做一个没有维护的更大的项目。

解释它尝试使用CMake,但不是很直观。与其从每个子模块中包含共享库和头,还可以在顶级CMakeList中设置一个标志,该标志会触发一个add_subdirectory,然后偷偷地将顶级CMAKE_BUILD_DIR安装到其中。这些CMakeLists只使用glob重新调用来查找所有源,而且大多数操作不是基于目标的,而是全局的。为此,主目标正确地编译。下面是主CMakeList的一个小片段

代码语言:javascript
复制
set(MY_BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(MY_SOURCE_BASE_DIR "${MY_BASE_DIR}/myproject")

# includes
include(build/global.cmake)
#include(externalLibs/mz-cmaketools-master/global.cmake)


# configuration options
option(MOD1 "" ON)
option(MOD2 "" ON)
option(MOD3 "" OFF)
option(MOD4 "" OFF)
option(MOD5 "" ON)
option(MOD6 "" OFF)
option(MOD7 "" ON)

message("-- Building myproject unit-tests - ${ENABLE_MYPROJECT_TEST}")
set(CMAKE_ECLIPSE_MAKE_ARGUMENTS "-j4")

if(MOD1)
    message(STATUS "Building viral_core + viral_recon")
    add_subdirectory(${MY_BASE_DIR}/externalLibs/viral/trunk/linux)


include_directories(${MY_BASE_DIR}/externalLibs/viral/trunk/source/)
    else(MOD1)
        if(MOD3)
            message(WARNING "Building viral_core + viral_recon")
            add_subdirectory(${MY_BASE_DIR}/externalLibs/viral/trunk/linux)
            include_directories(${MY_BASE_DIR}/externalLibs/viral/trunk/source/)
        endif(MOD3)
    endif(MOD1)

# external libraries
include(${MY_BASE_DIR}/externalLibs.cmake)


include_directories(
  ${MY_BASE_DIR}
  ${MY_SOURCE_BASE_DIR}
  ${MY_BASE_DIR}/externalLibs/viral/trunk/source/
)


# depending on the supported robots we have different dependencies
if( MOD1 ) 
        set(OPT1 TRUE)
endif()

...

# collect binaries
set(LIBRARY_OUTPUT_PATH ${MY_BASE_DIR} CACHE PATH "Library output path")
set(EXECUTABLE_OUTPUT_PATH ${MY_BASE_DIR} CACHE PATH "Executable output path")
message("-- Setting executable output path: ${EXECUTABLE_OUTPUT_PATH}")
message("-- Setting library output path   : ${LIBRARY_OUTPUT_PATH}")


# collect sources

file(GLOB MY 
    "${MY_SOURCE_BASE_DIR}/*.h"
    "${MY_SOURCE_BASE_DIR}/*.cpp"
)
source_group(base FILES ${MY_BASE})#

file(GLOB MY_UTIL 
    "${MY_SOURCE_BASE_DIR}/util/*.h"
    "${MY_SOURCE_BASE_DIR}/util/*.cpp"
)
source_group(util FILES ${MY_UTIL})

file(GLOB_RECURSE MY_KINEMATICS 
    "${MY_SOURCE_BASE_DIR}/kinematics/*.h"
    "${MY_SOURCE_BASE_DIR}/kinematics/*.cpp"
) 
source_group(kinematics FILES ${MY_KINEMATICS})

file(GLOB MY_COLLISION
    "${MY_SOURCE_BASE_DIR}/collision/pqp/*.cpp"
    "${MY_SOURCE_BASE_DIR}/collision/PQP*.cpp"
)
source_group(collision FILES ${MY_COLLISION})
...
add_library(MY SHARED
    ${MY_COLLISION}
    ${MY_UTIL}
    ${MY_KINEMATICS}
    ...}
)
....

最后,该项目构建了几个库,但没有发布使用它们所需的标头。这些库放在构建目录的顶层。(没有安装步骤)

问题

是否有可能使CMake导出库(目标)所包含的标头。更准确地说,这些标头应该只位于源文件夹和下面;不应该被考虑。此外,如果将头合并到一个标头中,则是可以接受的。但从~1700头只有~40是相关的,所以一个简单的发现递归似乎不够。

我确实看过GENERATE_EXPORT_HEADER,但不认为这是我想要的。而且我没有修改项目的权限,所以我想给SVN存储库做一个补丁,不想再做一个存储库的副本,因为大约有10个不同的版本在使用中。

如果有任何解决方案或策略的提示,我将不胜感激。

这是我关于堆栈溢出的第一个问题,所以请谅解:)

EN

回答 1

Stack Overflow用户

发布于 2018-07-26 09:29:22

我希望我正确理解了你的问题。

我通常使用CMakePackageConfigHelpers为库生成cmake配置文件,如果正确的话,很好的一点是,当您使用包配置链接到库时,CMake会自动设置传递依赖项并包含目录。

然后,可以使用install命令将目标、目录、包括文件复制到CMAKE_INSTALL_PREFIX dir,或者通过CPack复制到存档中。

在声明我的目标之后,我通常会得到如下内容:

代码语言:javascript
复制
install(TARGETS MyLibrary
    LIBRARY DESTINATION lib
)

include(CMakePackageConfigHelpers)

write_basic_package_version_file(
    "${GENERATED_DIR}/MyLibraryConfigVersion.cmake" COMPATIBILITY SameMajorVersion
)

configure_package_config_file(
    "cmake/Config.cmake.in" 
    "${GENERATED_DIR}/MyLibraryConfig.cmake"
    INSTALL_DESTINATION "cmake"
)

install(FILES 
    inc/someHeader.h
    inc/someHeaderB.h
    DESTINATION include/MyLibrary
)

install(FILES 
    "${GENERATED_DIR}/MyLibraryConfig.cmake" 
    "${GENERATED_DIR}/MyLibraryConfigVersion.cmake" 
    DESTINATION "cmake"
)

然后可以将CMAKE_INSTALL_PREFIX设置为您选择的目录并运行make install,创建以下结构:

代码语言:javascript
复制
InstallationDir
├── cmake
│   ├── MyLibraryConfig.cmake
│   └── MyLibraryConfigVersion.cmake
├── include
│   └── MyLibrary
│       ├── someHeaderB.h
│       └── someHeader.h
└── lib
    └── MyLibrary.so

然后,您可以使用find_packageCONFIG模式下,自动设置包含目录,编译选项等当链接到MyLibrary.so。

只是一个提示:target_include_directories函数比include_directories更好。如果您不使用配置文件生成,我不确定它的工作效果如何。还请查看目标上的更高级控件的下列函数:set_target_propertiestarget_link_librariestarget_compile_definitions

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45079389

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档