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

时间:2017-07-13 11:32:41

标签: c++ svn cmake export

我目前正在开展一个没有维护的大型项目。

解释 它试图使用CMake但不是很直观。可以在顶级CMakeList中设置一个标志,而不是包含来自每个子模块的共享库和标头,该标志触发add_subdirectory,潜入顶层CMAKE_BUILD_DIR并安装到其中。这些CMakeLists仅使用glob RECUSE来查找所有源,并且大多数操作不是基于目标的,而是全局的。因此主要目标正确编译。这是主CMakeList的一小部分

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导出lib(目标)的包含头。更准确地说,这些标题应该只位于源文件夹及其下方;来自/ usr / ...的标题不应该被考虑。此外,如果标题合并为一个标题,则可以接受。但是从~1700标题只有~40是相关的,所以一个简单的发现RECURSE对我来说似乎不够。

我确实看过GENERATE_EXPORT_HEADER,但不认为这就是我想要的。我没有更改项目的权限,因此我想对SVN存储库进行修补,并且不想制作存储库的另一个副本,因为有大约10种不同的使用。

我很感激任何解决方案或策略的提示

这是我关于stackoverflow的第一个问题,所以请恭喜:)

1 个答案:

答案 0 :(得分:0)

希望我能正确理解您的问题。

我通常使用CMakePackageConfigHelpers来为lib生成cmake配置文件,如果正确完成,那就好了,当您使用程序包配置链接到库时,CMake会设置传递依赖关系并自动包含目录。 / p>

然后install命令可用于将目标,目录,包含文件复制到CMAKE_INSTALL_PREFIX目录,或通过CPack复制到存档中。

声明目标之后,通常会有以下内容:

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,创建以下结构:

InstallationDir
├── cmake
│   ├── MyLibraryConfig.cmake
│   └── MyLibraryConfigVersion.cmake
├── include
│   └── MyLibrary
│       ├── someHeaderB.h
│       └── someHeader.h
└── lib
    └── MyLibrary.so

然后,当与MyLibrary.so链接时,您可以在find_package模式下使用CONFIG来自动设置包含目录,编译选项等。

只是一个提示:target_include_directories函数优于include_directories。如果您不使用配置文件,我不确定配置文件的生成效果如何。还请查看以下功能,以对目标进行更高级的控制:set_target_propertiestarget_link_librariestarget_compile_definitions