cmake: 在CMakeLists.txt中选择生成器

55

我想在CMakeLists.txt中强制使用"Unix Makefiles" 生成器

这是我现在使用的命令。

cmake -G "Unix Makefiles" .

我希望它是这样的。

cmake .

在Windows上安装了VC和自定义工具链时,我期望能够在CMakeLists.txt文件中设置生成器。

也许可以像这样。

set(CMAKE_GENERATOR "Unix Makefiles")
5个回答

34

以下是我成功尝试过的方法- 在您的项目目录中创建一个名为 PreLoad.cmake 的文件,其内容如下:

set (CMAKE_GENERATOR "Unix Makefiles" CACHE INTERNAL "" FORCE)


4
看起来“Preload.cmake”行为在“官方”的CMake文档中没有记录;请参考票号17231 - 但是知道这点很好! - Michael Kopp
3
2020年或CMake 3.17版本后是否有更好的方法?这种方式似乎无法像-GNinja那样工作。 - Jay

19

在我的看法中,如果在CMakeLists.txt中设置变量CMAKE_GENERATOR,那么它似乎设置得太晚了。即使你在CMakeLists.txt的开头使用它。

set(CMAKE_GENERATOR "Ninja")
message("generator is set to ${CMAKE_GENERATOR}")

您可以在输出中看到类似以下的内容

% cmake ../source
-- The C compiler identification is GNU 4.9.2
...
-- Detecting CXX compile features - done
generator is set to Ninja
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/build

因此,变量仅在生成过程的最后设置。如果您使用类似于

set(CMAKE_GENERATOR "Ninja" CACHE INTERNAL "" FORCE)

CMakeLists.txt 中,运行 cmake ../source 的第一次运行(不带 -G 选项)将使用默认生成器。然而,变量CMAKE_GENERATOR被存储在缓存中。因此,如果之后重新运行cmake ../source,它将使用缓存中指定的CMAKE_GENERATOR变量中的生成器。

尽管如此,这肯定不是最优雅的解决方案;-)也许可以使用批处理文件来实际执行用户所需的cmake -G generator...


2
我希望他们能让用户在CMakeLists.txt中设置所有配置。如果你还需要一个.bat文件,那这有什么意义呢? - Royi
2
看起来Ivan的答案非常接近这个问题 -- 变量在一个cmake配置文件中被配置,在实际的CMakeLists.txt加载之前被引用。 - Michael Kopp

3
当我运行相同的命令时,cmake会寻找gcc编译器/ make实用程序,但我得到的结果与此不同。如果PATH设置不正确,则会出现以下类似错误:
D:\Development\build>cmake -G "Unix Makefiles" ..\source CMake Error: CMake was unable to find a build program corresponding to "Unix Makefiles". CMAKE_MAKE_PROGRAM is not set. You probably need to select a different build tool. CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly. Missing variable is: CMAKE_C_COMPILER_ENV_VAR CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly. Missing variable is: CMAKE_C_COMPILER CMake Error: Could not find cmake module file:D:/Development/build/CMakeFiles/CMakeCCompiler.cmake CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly. Missing variable is: CMAKE_CXX_COMPILER_ENV_VAR CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly. Missing variable is: CMAKE_CXX_COMPILER CMake Error: Could not find cmake module file:D:/Development/build/CMakeFiles/CMakeCXXCompiler.cmake CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage CMake Error: CMAKE_CXX_COMPILER not set, after EnableLanguage -- Configuring incomplete, errors occurred!
当gcc / mingw在路径中时,一切正常。因此,请提供更多关于您的PATH变量或CMAKE版本的信息。

1
因为我正在使用自定义工具链,并且已经安装了VC++,所以我不能依赖于CMake选择生成器。我也不想在命令行上指定一个生成器,这样用户就可以轻松地克隆和构建项目。 - Ted
1
好的...抱歉我误解了你的问题。在这种情况下,我建议将一个CMakeCache.txt放置到目录中,该目录大多为空,但有CMAKE_GENERATOR变量。或者您可以在源代码库中拥有该缓存文件,并使用-C cmake选项传递它。 - Frank

1
你需要在生成阶段设置生成器,以便将其写入缓存中。对于第一次配置,只需运行一次此命令。
cmake .. -DCMAKE_GENERATOR:INTERNAL=Ninja
这将配置Ninja作为默认生成器。
稍后,你只需运行
cmake ..
它会使用Ninja生成器作为默认值。
你可以在从命令行运行CMake中了解更多信息。
在从命令行运行cmake时,可以指定命令行选项以设置缓存中的值。这是通过在命令行上使用-DVARIABLE:TYPE=VALUE语法来完成的。这对于非交互式夜间测试构建非常有用。

1

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