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

时间:2013-11-08 18:23:33

标签: visual-studio-2012 cmake

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

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

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

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

2 个答案:

答案 0 :(得分:10)

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

  

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

别。始终使用CMake进行out-of-source build。我知道,当你第一次这样做时感觉很奇怪,但请相信我:一旦你习惯了它,你就永远不想回去了。

当代码和构建文件被正确分离时,使用源代码控制变得更加方便的一个事实使得它成为CMake的杀手级功能。

  

是否还有一种方法可以指定必须在哪里创建Visual Studio解决方案文件?

你真的不应该在意。

我明白为什么你觉得你需要完全控制如何创建解决方案和项目文件,但实际上并非如此。只需将解决方案的目标指定为源外构建的原点,并忘记生成的所有其他文件。您不必担心,而且您不必担心 - 这正是CMake应该为您处理的那种东西

问问自己:如果你可以手工挑选每个项目文件的位置,你会得到什么?没什么,因为机会是,你永远不会碰他们。 CMake现在是你唯一的主人......

  

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

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

结论:CMake在几个方面与手工制作的VS解决方案不同。这需要一些人习惯,但最终会比人们担心的痛苦少得多。

答案 1 :(得分:1)

您并不总是可以选择环境所需的内容。 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有办法运行后期生成脚本,那会有所帮助,但我找不到。

其他没有成功的想法:

  1. 将cmake包装在执行相同操作的脚本中,但是:
    • 告诉用户运行一个单独的脚本并不比说两次运行cmake简单。特别是因为需要两次运行cmake并不是一个外国概念。
  2. 把它放在预制步骤中,但是
    • 建筑是常见的,改变构建很少
    • 从IDE内部的构建中更改解决方案使其成为......事物
  3. 使用add_subdirectory,因为假设首先完成
    • 它似乎立即制作了vcxproj,但是直到稍后才开始制作,但我并没有那么努力,因为这增加了一堆我不想要的杂乱 - 所以也许这可以让它起作用