在CMake中,如何解决Visual Studio 2010尝试添加的Debug和Release目录?

39

我正尝试使用Visual Studio 2010构建我的一个基于CMake的项目,但是在项目输出目录方面出现了问题。Visual Studio一直非常喜欢在输出二进制文件时添加Debug/和Release/子目录,而由于各种原因,我一直非常喜欢将它们删除 - 现在我正在使用一个新版本的CMake和Visual Studio,旧版CMake中的解决方法似乎不再起作用,因此我正在寻找“新”的方法。

在以前的CMake(2.6)和Visual Studio(2008)版本中,我使用了以下方法:

IF(MSVC_IDE)
    # A hack to get around the "Debug" and "Release" directories Visual Studio tries to add
    SET_TARGET_PROPERTIES(${targetname} PROPERTIES PREFIX "../")
    SET_TARGET_PROPERTIES(${targetname} PROPERTIES IMPORT_PREFIX "../")
ENDIF(MSVC_IDE)

这之前工作得很好,但现在似乎不再起作用了。请问是否有类似的但更为更新的解决方法,可以与CMake 2.8.6和Visual Studio 2010兼容?

4个回答

71

这有点取决于你具体想要什么, 但我建议看看可用的目标属性,类似于这个问题

这有点取决于你确切的需求。对于每个目标,你可以手动设置library_output_directoryruntime_output_directory属性。

if ( MSVC )
    set_target_properties( ${targetname} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${youroutputdirectory} )
    set_target_properties( ${targetname} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_DEBUG ${youroutputdirectory} )
    set_target_properties( ${targetname} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELEASE ${youroutputdirectory} )
    # etc for the other available configuration types (MinSizeRel, RelWithDebInfo)
endif ( MSVC )

您也可以对所有子项目全局执行此操作,使用类似以下代码:

# First for the generic no-config case (e.g. with mingw)
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${youroutputdirectory} )
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${youroutputdirectory} )
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${youroutputdirectory} )
# Second, for multi-config builds (e.g. msvc)
foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )
    string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG )
    set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${youroutputdirectory} )
    set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${youroutputdirectory} )
    set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${youroutputdirectory} )
endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES )

5
太棒了,谢谢!结果发现我在目标上寻找的是ARCHIVE_OUTPUT_DIRECTORY_{config}属性。干杯! :) - Stuart Golodetz
我做了完全相同的事情,直到调用get_target_property(test_EXE test LOCATION)时,例如add_executable(test test.cpp)。它仍然具有D:/Codebase/test/bin/$(Configuration)/test.exe。有什么解决这个问题的想法吗? - choosyg
1
哪个变量将保存当前项目的输出文件夹(不涉及不同配置)?也就是说,如果我在发布模式下工作,它将指向 x64\Release\,如果我在调试模式下运行,它将指向 x64\Debug\ 文件夹?换句话说,我不想改变它,我只想访问它。 - Royi

13

https://cmake.org/cmake/help/latest/prop_tgt/LIBRARY_OUTPUT_DIRECTORY.html解释说:

多配置生成器(VS,Xcode)会将每个配置的子目录附加到指定的目录中,除非使用生成器表达式。

因此,唯一的解决方法是使用生成器表达式。一种很酷的方法是在路径末尾使用$<0:>。因此,如果您的路径是/what/ever/,则需要将其替换为/what/ever/$<0:>。

示例中的目标是Nuua,路径为C:/Nuua/bin/。

set_target_properties(nuua PROPERTIES RUNTIME_OUTPUT_DIRECTORY C:/Nuua/bin/$<0:>)

$<0:>代表什么?只是一个生成器表达式,它的值为nil吗? - legends2k
它的计算结果为空字符串。如果没有表达式,生成器可以自由地将RUNTIME_OUTPUT_DIRECTORY设置为每个配置子目录。而有了表达式,生成器就会强制评估并将此属性设置为预期目录! - legends2k

7

在当前的CMake版本中,您可以使用生成器表达式来避免配置特定后缀的LIBRARY_OUTPUT_DIRECTORY

我只是在我的代码中添加了$<$<CONFIG:Debug>:>,它总是扩展为空,虽然看起来有点奇怪,但它确实有效,并且不会那么奇怪,您可以用简短的注释来解释它:

# Use a generator expression so that the specified folder is used directly, without any
# configuration-dependent suffix.
#
# See https://cmake.org/cmake/help/v3.8/prop_tgt/LIBRARY_OUTPUT_DIRECTORY.html
set_target_properties(library PROPERTIES
                      LIBRARY_OUTPUT_DIRECTORY my/folder/$<$<CONFIG:Debug>:>)

4
我希望有一个SO功能,让第三方能够随着时间的推移审查CMake问题,并将6年后提出的答案标记为“忘掉之前提到的一切,这就是2019年如何完成X”。 - Artalus
我对建议中的“Debug”一词有些困惑,可能可以简化为“$<$CONFIG::>”吗? - Pavel K.
1
@PavelK。我认为$<CONFIG:>测试需要配置名称。也许你可以使用$<0:>或其他类似的东西代替。 - Tom Seddon
Erik的回答引用了CMake文档,解释了为什么这样可以工作。 - legends2k

2

感谢Erik的提示,建议使用$<0:>。

如果您有多个目标需要这种解决方案,则可以尝试以下操作:

# Get Targets in ${CMAKE_CURRENT_SOURCE_DIR}
get_property(current_targets DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY BUILDSYSTEM_TARGETS)
foreach(TARGET ${current_targets})
    set_target_properties(${TARGET} PROPERTIES
                        RUNTIME_OUTPUT_DIRECTORY  ${CMAKE_BINARY_DIR}/$<0:> 
                        LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/$<0:>
                        ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/$<0:>)
endforeach()

要在${CMAKE_CURRENT_SOURCE_DIR}中为所有目标执行它,而不必为每个可执行文件/库单独添加它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接