首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在CMake中作为外部项目下载、编译和链接库?

如何在CMake中作为外部项目下载、编译和链接库?
EN

Stack Overflow用户
提问于 2020-11-25 06:31:25
回答 1查看 720关注 0票数 1

我正在尝试使用ExternalProject_Add框架在CMake中自动下载、编译和链接一个静态库。您可以找到库这里,但是这个问题可以应用于任何外部CMake项目。

以下是我问题的边界条件:

  1. 外部项目是与CMake兼容的
  2. 外部项目提供要链接到主项目目标的静态或动态库。
  3. 将使用ExternalProject_Add框架
  4. UNIX (Linux和MacOS)的可移植性就足够了。
  5. 现代CMake是可用的(CMake 3.14+)

我能够通过硬编码来让它工作,但是我非常肯定我的解决方案不是优雅的,也不是可移植的。

这是我的项目结构

代码语言:javascript
运行
复制
root
|---> CMakeList.txt
|
|---> external ---> CMakeList.txt
|              |--> CMakeList.txt.inih.in     
|
|--->   src    ---> CMakeList.txt

root/CMakeList.txt

代码语言:javascript
运行
复制
add_subdirectory(external)
set(INIH_LIB_DIR ${CMAKE_CURRENT_BINARY_DIR}/external/inih-install/lib)
set(INIH_INC_DIR ${CMAKE_CURRENT_BINARY_DIR}/external/inih-install/include/inih)
set(INIH_LIBRARIES inih inihcpp)
message(STATUS "inih includes directory : ${INIH_LIB_DIR}")
message(STATUS "inih libraries directory : ${INIH_INC_DIR}")
add_subdirectory(src)

root/external/CMakeList.txt

代码语言:javascript
运行
复制
configure_file(${PROJECT_SOURCE_DIR}/external/CMakeLists.txt.inih.in inih-download/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
        RESULT_VARIABLE result
        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/inih-download)
if (result)
    message(FATAL_ERROR "CMake step for inih failed: ${result}")
endif ()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
        RESULT_VARIABLE result
        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/inih-download)
if (result)
    message(FATAL_ERROR "Build step for inih failed: ${result}")
endif ()

root/external/CMakeList.txt.inih.in

代码语言:javascript
运行
复制
include(ExternalProject)
ExternalProject_Add(inih
        GIT_REPOSITORY    https://github.com/OSSystems/inih.git
        GIT_TAG           master
        SOURCE_DIR        "${CMAKE_CURRENT_BINARY_DIR}/inih-src"
        BINARY_DIR        "${CMAKE_CURRENT_BINARY_DIR}/inih-build"
        INSTALL_DIR       "${CMAKE_CURRENT_BINARY_DIR}/inih-install"
        CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}/inih-install ${CMAKE_CURRENT_BINARY_DIR}/inih-src
        BUILD_COMMAND     ${MAKE}
        INSTALL_COMMAND   make install
        TEST_COMMAND      ""
        )

root/src/CMakeList.txt

代码语言:javascript
运行
复制
add_executable(test test.cpp)
target_include_directories(test PRIVATE ${INIH_INC_DIR})
target_link_directories(test PRIVATE ${INIH_LIB_DIR})
target_link_libraries(WagasciRecon ${INIH_LIBRARIES})

我的问题是:是否有一种更优雅、更便携的方法来实现这一点?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-29 07:53:49

感谢Tsyvarev的评论,我能够用一个更干净、更健壮的代码来实现同样的目标:

  • root/CMakeList.txt
代码语言:javascript
运行
复制
set(INIH_PROJECT inih_project)
set(INIH_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/external/inih-install)
set(INIH_LIB_DIR ${INIH_INSTALL_DIR}/lib)
set(INIH_INC_DIR ${INIH_INSTALL_DIR}/include/inih)

add_library (inih STATIC IMPORTED)
set_target_properties (inih PROPERTIES IMPORTED_LOCATION ${INIH_LIB_DIR}/libinih.a)
target_include_directories(inih INTERFACE ${INIH_INC_DIR})

add_library (inihcpp STATIC IMPORTED)
set_target_properties(inihcpp PROPERTIES IMPORTED_LOCATION ${INIH_LIB_DIR}/libinihcpp.a)
target_include_directories(inihcpp INTERFACE ${INIH_INC_DIR})

set(INIH_LIBRARIES inih inihcpp)
message(STATUS "inih includes directory : ${INIH_INC_DIR}")
message(STATUS "inih libraries directory : ${INIH_LIB_DIR}")

...

add_subdirectory(external)
add_subdirectory(src)
  • root/external/CMakeList.txt
代码语言:javascript
运行
复制
include(CMakeLists.txt.inih.in)
  • root/external/CMakeList.txt.inih.in
代码语言:javascript
运行
复制
include(ExternalProject)
ExternalProject_Add(${INIH_PROJECT}
        GIT_REPOSITORY    https://github.com/OSSystems/inih.git
        GIT_TAG           master
        PREFIX            "${CMAKE_CURRENT_BINARY_DIR}/inih-prefix"
        INSTALL_DIR       "${INIH_INSTALL_DIR}"
        CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
        BUILD_COMMAND     ${MAKE}
        INSTALL_COMMAND   make install
        TEST_COMMAND      ""
        )
  • root/src/CMakeList.txt
代码语言:javascript
运行
复制
add_executable(test test.cpp)
target_link_libraries(test ${INIH_LIBRARIES})

更新

如果将上面的解决方案应用到一个新的构建目录中,就会遇到像Imported target "inih" includes non-existent path这样的错误,这个错误可以像这里那样处理。

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

https://stackoverflow.com/questions/64999518

复制
相关文章

相似问题

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