如何根据 cmake 中的配置类型更改库加载*路径*?

发布于 2024-12-27 08:25:26 字数 2156 浏览 1 评论 0原文

我有一个 CMake 项目,我想在其中链接正确的库(调试构建获取调试库;发布构建获取发布库),而无需手动覆盖。 (例如,一旦 CMake 构建了 msbuild 位,我希望 CMake 生成的所有四个目标(调试、发布等)能够在不再次运行 CMake 的情况下进行构建)

CMake 文档(以及 我发现的关于此的其他内容)大致如下:

SET(LINK_LIBRARY optimized Foo debug Foo_d)
target_link_libraries(MyEXE ${LINK_LIBRARY})

但是,这改变了库基于链接关于文件名。举例来说,我正在使用 CMake 中包含的 Google Test 位(FindGTest.cmake 等),并且 Google Test 发行版如下所示:

 Directory of C:\Foo\gtest-1.6.0\lib

12/30/2011  03:08 PM    <DIR>          Debug
12/30/2011  03:08 PM    <DIR>          Release

 Directory of C:\Foo\gtest-1.6.0\lib\Debug

12/30/2011  03:08 PM         3,388,036 gtest.lib
12/30/2011  03:08 PM           602,112 gtest.pdb
12/30/2011  03:08 PM           131,528 gtest_main.lib
12/30/2011  03:08 PM           389,120 gtest_main.pdb

 Directory of C:\Foo\gtest-1.6.0\lib\Release

12/30/2011  03:08 PM         2,701,324 gtest.lib
12/30/2011  03:08 PM           552,960 gtest.pdb
12/30/2011  03:08 PM           126,364 gtest_main.lib
12/30/2011  03:08 PM           372,736 gtest_main.pdb

CMake 文档中提供的示例不再有效;该库的调试版本和发布版本具有相同的名称。因此,CMake 文档中提供的示例不起作用——名称没有不同,这就是在那里指定库的方式。我不想在依赖库的构建树(Google Test)中重命名它们,因为这会添加额外的步骤来获得工作构建。我希望有人能够下载 Google Test,构建它,下载我的位,将环境变量 CMAKE_LIBRARY_PATH 设置为指向 Google Test,并成功构建我的库。

作为参考,我当前的 CMakeLists.txt 看起来类似于:

project( Utilities )
cmake_minimum_required( VERSION 2.8.0 )
file( GLOB Utilities_SourceFiles  "src/*.cpp"  "src/*.rc" "include/utilities/*.h" )
file( GLOB Utilities_TestFiles   "test/*.cpp" "test/*.rc" )

find_package( GTest       REQUIRED )

include_directories( "include/" ${GTEST_INCLUDE_DIRS}))

cxx_library    ( utilities  ${Utilities_SourceFiles} )
cxx_executable ( test       ${Utilities_TestFiles} )
target_link_libraries( test ${GTEST_BOTH_LIBRARIES} )

enable_testing()
GTEST_ADD_TESTS(Test.exe "" ${Utilities_TestFiles})

我如何完成这样的事情?

I've got a CMake project where I'd like to link the correct libraries (debug builds get debug libraries; release builds get release libraries) in without having to manually override things. (E.g. once the msbuild bits are constructed by CMake, I want all four targets (Debug, Release, etc.) CMake generates to be able to build without running CMake again)

The CMake documentation (and other things I've found about this) have something along the lines of:

SET(LINK_LIBRARY optimized Foo debug Foo_d)
target_link_libraries(MyEXE ${LINK_LIBRARY})

However, this changes the library that gets linked based on the file name. Let's say, for the sake of example, that I'm using the Google Test bits included with CMake (FindGTest.cmake, etc), and the Google Test distribution looks like this:

 Directory of C:\Foo\gtest-1.6.0\lib

12/30/2011  03:08 PM    <DIR>          Debug
12/30/2011  03:08 PM    <DIR>          Release

 Directory of C:\Foo\gtest-1.6.0\lib\Debug

12/30/2011  03:08 PM         3,388,036 gtest.lib
12/30/2011  03:08 PM           602,112 gtest.pdb
12/30/2011  03:08 PM           131,528 gtest_main.lib
12/30/2011  03:08 PM           389,120 gtest_main.pdb

 Directory of C:\Foo\gtest-1.6.0\lib\Release

12/30/2011  03:08 PM         2,701,324 gtest.lib
12/30/2011  03:08 PM           552,960 gtest.pdb
12/30/2011  03:08 PM           126,364 gtest_main.lib
12/30/2011  03:08 PM           372,736 gtest_main.pdb

The example provided in the CMake docs no longer works; the debug and release versions of the library have the same name. Therefore, the example provided in the CMake docs doesn't work -- the names don't differ and that's how the libraries are being specified there. I don't want to have to rename these in the dependent library's build tree (Google Test), because that would add additional steps to get a working build. I want someone to just be able to download Google Test, build it, download my bits, set the environment variable CMAKE_LIBRARY_PATH to point at Google Test, and have my library build successfully.

For reference, my current CMakeLists.txt looks something like:

project( Utilities )
cmake_minimum_required( VERSION 2.8.0 )
file( GLOB Utilities_SourceFiles  "src/*.cpp"  "src/*.rc" "include/utilities/*.h" )
file( GLOB Utilities_TestFiles   "test/*.cpp" "test/*.rc" )

find_package( GTest       REQUIRED )

include_directories( "include/" ${GTEST_INCLUDE_DIRS}))

cxx_library    ( utilities  ${Utilities_SourceFiles} )
cxx_executable ( test       ${Utilities_TestFiles} )
target_link_libraries( test ${GTEST_BOTH_LIBRARIES} )

enable_testing()
GTEST_ADD_TESTS(Test.exe "" ${Utilities_TestFiles})

How might I accomplish something like this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

转身以后 2025-01-03 08:25:26

对于 VisualStudio,请考虑一次设置多个配置并使用不同的每个配置 目标属性。另请看看我对 的回答这个问题演示了如何根据当前使用的配置设置输出名称。

另外:为 Googletest 设置一个新的/好的 find-package 脚本,并使用 add_library。有了它,您可以定义单个库目标 Foo 并且可以为每个配置设置其属性(位置、文件名等):

# Assuming the Foo-root dir is defined in FOO_DIR
add_library( Foo IMPORTED )
# You can define two import-locations: one for debug and one for release.
set_target_properties( Foo PROPERTIES IMPORTED_LOCATION_DEBUG ${FOO_DIR}/Debug/Foo_d.lib
set_target_properties( Foo PROPERTIES IMPORTED_LOCATION_RELEASE ${FOO_DIR}/Release/Foo.lib

所以,总而言之:

  1. 当构建您自己的库时在项目内部,使用输出属性 OUTPUT_NAME 和各种 ARCHIVE_ ,<一href="http://cmake.org/cmake/help/cmake-2-8-docs.html#prop_tgt:RUNTIME_OUTPUT_DIRECTORY" rel="nofollow noreferrer">RUNTIME_, LIBRARY_,输出属性都具有每个配置的变体。

  2. 链接到 3rdparty 库时,请使用导入属性,其中 IMPORTED_LOCATION 及其每个配置的变体尤其重要。

For VisualStudio consider setting up multiple configurations at once and make use of different per-configuration target properties. Also take a look at my answer to this question which demonstrates how to setup an output-name based on the currently used configuration.

In addition: setup a new/good find-package script for Googletest and use the IMPORTED option for add_library. With it, you can define a single library target Foo and you can set its properties (location, filename, etc.) for each configuration:

# Assuming the Foo-root dir is defined in FOO_DIR
add_library( Foo IMPORTED )
# You can define two import-locations: one for debug and one for release.
set_target_properties( Foo PROPERTIES IMPORTED_LOCATION_DEBUG ${FOO_DIR}/Debug/Foo_d.lib
set_target_properties( Foo PROPERTIES IMPORTED_LOCATION_RELEASE ${FOO_DIR}/Release/Foo.lib

So, all in all:

  1. When building you own libraries, internal to your project, make use of the output properties OUTPUT_NAME and the various ARCHIVE_, RUNTIME_, LIBRARY_, output properties which all have per-configuration variants.

  2. When linking to 3rdparty libraries, make use of the import properties where IMPORTED_LOCATION is especially important and its per-configuration variants.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文