CMake 和 Visual Studio - 指定解决方案文件目录

Posted

技术标签:

【中文标题】CMake 和 Visual Studio - 指定解决方案文件目录【英文标题】:CMake and Visual Studio - Specify solution file directory 【发布时间】:2013-11-08 18:23:32 【问题描述】:

我为我的项目定义了一个CMakeLists.txt 文件,它可以正常工作。

我使用 CMake GUI 生成 Visual Studio 项目,并要求在文件夹 Build 中构建二进制文件(CMAke 缓存和其他内容),该文件夹与 CMakeLists.txt 所在的文件夹相同。

我能够指定必须在何处创建可执行文件和库。 有没有办法指定必须在哪里创建 Visual Studio 解决方案文件?我想将它放在根目录中,但同时我不想在 Build 目录中拥有 CMake 创建的所有其他文件。

CMake 创建了我在CMakeLists.txt 中定义的项目,还创建了另外两个项目:ALL_BUILDZERO_CHECK。它们的用途是什么? 通过使用命令set_property(GLOBAL PROPERTY USE_FOLDERS On),我能够避免创建ZERO_CHECK。 有没有办法避免创建ALL_BUILD

【问题讨论】:

【参考方案1】:

您似乎最近才切换到 CMake,因为当我第一次开始使用 CMake 时,这些问题也突然出现在我的脑海中。让我们按照您发布它们的顺序来解决它们:

我使用 CMake GUI 来生成 Visual Studio 项目,我问 在文件夹中构建二进制文件(CMMake 缓存和其他东西) 构建在 CMakeLists.txt 所在的同一文件夹中。

不要。始终使用 CMake 执行 out-of-source build。我知道,第一次做的时候感觉很奇怪,但相信我:一旦你习惯了,你就再也不想回去了。

当代码和构建文件正确分离时,使用源代码管理变得非常方便,这使得它成为 CMake 的杀手级功能。

有没有办法指定 Visual Studio 解决方案文件的创建位置?

你真的不应该在乎。

我明白为什么您确实觉得您需要完全控制解决方案和项目文件的创建方式,但您确实不需要。只需将解决方案的目标指定为源外构建的来源,然后忘记生成的所有其他文件。您无需担心,也无需担心 - 这正是 CMake 应该为您处理的事情

问问自己:如果您可以手动选择每个项目文件的位置,您会得到什么?没什么,因为很有可能,你无论如何都不会碰它们。 CMake 现在是你唯一的主人...

CMake 创建我在 CMakeLists.txt 中定义的项目,但也创建了两个 其他项目:ALL_BUILD 和 ZERO_CHECK。它们的用途是什么?我曾是 能够通过使用命令避免创建 ZERO_CHECK set_property(全局属性 USE_FOLDERS 开启)。有没有办法 还要避免创建 ALL_BUILD?

再说一次,你真的不应该在意。 CMake 定义了几个虚拟项目,它们对于您不想担心的某些内部巫术非常有用。一开始它们看起来很奇怪,但你会比你想象的更快地适应它们的视线。只是不要试图把它们扔掉,因为它不能正常工作。 如果他们的视线真的让您很烦恼,请考虑moving them to a folder inside the solution,这样您就不必一直看着他们。

底线:CMake 在几个方面与手工制作的 VS 解决方案不同。这需要一些时间来适应,但最终的痛苦比人们可能担心的要少得多。

【讨论】:

感谢您的完整回答。我得到了你的大部分观点,我必须同意他们。外源构建的想法是强大的。对于项目文件(对于 *.vcxproj 和 *.vcxproj.filter 类型的每种类型为 3),我希望将解决方案文件放在不同的文件夹中的唯一原因是在一天,您必须打开解决方案才能使用它。将这个文件与项目文件和 CMake 的东西分开会更好......但可能一个软链接可以解决这个问题。 +1,只是想补充一点,将解决方案文件保存在临时文件夹中会再次提醒您生成cmake -> *.sln 是一种方式处理,所有*.sln 修改将重生后消失【参考方案2】:

您并不总是可以选择您的环境需要什么。 Visual Studio 的 GitHub 集成要求解决方案文件存在于源代码管理中并且位于源代码树的根目录中。这是一个记录在案的限制。

我能想到的最好的方法就是将此位添加到 CMakeList.txt:

# The solution file isn't generated until after this script finishes, 
# which means that:
#   - it might not exist (if this is the first run)
#   - you need to run cmake twice to ensure any new solution was copied
set(sln_binpath $CMAKE_CURRENT_BINARY_DIR/$PROJECT_NAME.sln)
if(EXISTS $sln_binpath)
    # Load solution file from bin-dir and change the relative references to 
    # project files so that the in memory copy is as if it had been built in 
    # the source dir.
    file(RELATIVE_PATH prefix 
        $CMAKE_CURRENT_SOURCE_DIR 
        $CMAKE_CURRENT_BINARY_DIR)
    file(READ $sln_binpath sln_content)
    string(REGEX REPLACE 
        "\"([^\"]+).vcxproj\""
        "\"$prefix/\\1.vcxproj\"" 
        sln_content
        "$sln_content")

    # Compare the updated contents with the existing source path sln, if it
    # exists and is the same we don't want to disturb VS by touching it.
    set(sln_srcpath $CMAKE_CURRENT_SOURCE_DIR/$PROJECT_NAME.sln)
    set(old_content "")
    if(EXISTS $sln_srcpath)
        file(READ $sln_srcpath old_content)
    endif()
    if(NOT old_content STREQUAL sln_content)
        file(WRITE $sln_srcpath $sln_content)
    endif()
endif()

如果 cmake 有一种方法来运行后期生成脚本,那将有帮助,但我找不到。

其他没有成功的想法:

    将 cmake 包装在一个执行相同操作的脚本中,但是: 告诉用户运行一个单独的脚本并不比运行 cmake 两次简单。尤其是因为需要运行两次 cmake 并不是一个陌生的概念。 将其放在预构建步骤中,但是 构建很常见,很少更改构建 从 IDE 内部的构建中更改解决方案使其能够做到……事情 使用 add_subdirectory 因为这应该先完成 它似乎立即制作了 vcxproj,但直到后来才制作了 sln,但我没有那么努力,因为这增加了一堆我不想要的额外混乱 - 所以也许可以让它工作李>

【讨论】:

这段代码很棒,完全符合我的要求,谢谢!

以上是关于CMake 和 Visual Studio - 指定解决方案文件目录的主要内容,如果未能解决你的问题,请参考以下文章

与 CMake 和 Visual Studio 2010 的链接错误

CMake 和 Visual Studio - 指定解决方案文件目录

使用 CMake 和 Visual Studio 2019 编译 GLEW?

从 CMake 创建 Visual Studio 项目,Visual Studio 找不到可执行文件

Visual Studio 2017 - 为依赖项禁用 CMake

CMake Project in Visual Studio 2019