【发布时间】:2021-07-17 13:02:58
【问题描述】:
我一直在开发一个 Visual Studio 2019 项目,目的是将应用程序移植到 Centos 8。我在 VS2019 中使用 CMake 项目,并在我的 Centos 机器上进行远程构建。基本上,所有文件都被传输到远程机器上,项目就建好了。我的项目目录看起来像
Child
| CMakeLists.txt
| source
|__public
| headers
| libs
Parent
| CMakeLists.txt
| source
Child 生成一个共享库 (.so) 和一些要在 Parent 中链接的公共头文件。 so 文件和公共头文件存在于 Child 的公共目录中。两个文件的CMake文件如下
Child/CMakeLists.txt
set(PROJECT_NAME "Child")
set(Header_Files
#set of public headers and source headers
)
set(Source_Files
#set of source files
)
set(ALL_FILES
${Header_Files}
${Source_Files}
)
if (UNIX)
#Target is an SO
add_library(${PROJECT_NAME} SHARED ${ALL_FILES})
set(BOOST_INCLUDEDIR "${CMAKE_HOME_DIRECTORY}/Boost")
set(BOOST_LIBRARYDIR "${CMAKE_HOME_DIRECTORY}/Boost/libs/linux64-clang-9.0.0/static/release")
find_package(Boost REQUIRED)
if (Boost_FOUND)
target_include_directories(${PROJECT_NAME} PRIVATE ${Boost_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES})
endif()
set(XercesC_INCLUDE_DIR "${CMAKE_HOME_DIRECTORY}/Xercesc/Linux-Clang-Release/include")
set(XercesC_LIBRARY "${CMAKE_HOME_DIRECTORY}/Xercesc/Linux-Clang-Release/lib64")
find_package(XercesC REQUIRED)
if (XercesC_FOUND)
target_include_directories(${PROJECT_NAME} PRIVATE ${XercesC_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} "${CMAKE_HOME_DIRECTORY}/Xercesc/Linux-Clang-Release/lib64/libxerces-c.so")
endif()
endif()
父/CMakeLists.txt
set(PROJECT_NAME "Parent")
set(Header_Files
#set of headers
)
set(Source_Files
#set of source files
)
set(ALL_FILES
${Header_Files}
${Source_Files}
)
if (UNIX)
set(CHILD_HEADERS "${CMAKE_HOME_DIRECTORY}/Child/public/headers")
set(CHILD_LIB_DIR "${CMAKE_BINARY_DIR}/Child/libs")
link_directories(${CHILD_LIB_DIR})
add_executable(${PROJECT_NAME} ${ALL_FILES})
target_include_directories(${PROJECT_NAME} PRIVATE ${CHILD_HEADERS})
target_link_libraries(${PROJECT_NAME} PRIVATE Child)
#Copy libChild.so to Parent executable directory
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND
cp "${CHILD_LIB_DIR}/libChild.so"
"${CMAKE_CURRENT_BINARY_DIR}/libChild.so"
)
endif()
问题
我的目标是为我的客户构建一个版本。因此,我需要将所有可执行文件和库打包在一个 zip 文件夹下。但是,这样做后,我发现链接器路径采用了绝对路径值的排序
$ldd Parent
libChild.so => /root/.vs/Project/829a6827-2641-4552-a2fb-abec91ed47a2/out/build/Linux-Clang-Release/Child/libChild.so (0x00007f6934908000)
但是,关于我的最终构建文件夹将是这样的
Parent (executable)
libChild.so
libboost_regex...
libxerces... etc. etc.
我有点想要一个指向同一目录的相对路径链接
libChild.so => ./libChild.so
因此,当我以 zip 格式导出到另一台机器时,它无法找到共享库。我已经尝试了几件事(使用其他 CMake 函数)以及首先将库复制到可执行目录然后链接。但是,它仍然将其链接为绝对路径,这可能会再次导致相同的问题。我浏览了 CMake 文档并仔细阅读了 cmake-packages 和 relocatable packages 但无法解决问题。
【问题讨论】:
-
"我需要将所有可执行文件和库打包到一个 zip 文件夹下。" - 不要从 构建树 打包文件。而是打包安装树。对于已安装的库,CMake 为您提供了调整 RPATH 的全部功能,请参阅CMake RPATH Handling wiki。此外,CMake 具有 CPack 组件,可用于为 CMake 包创建不同类型的存档。
标签: visual-studio cmake