如何生成 CMakeLists.txt?

我需要一些关于如何为 CMake 自动生成 CMakeLists.txt 文件的指针/建议。有人知道现有的发电机吗?我已经检查了在 CMake Wiki中列出的那些,但不幸的是,他们不适合我。

我已经有了一个基本的 Python 脚本,它可以遍历我的项目的目录结构并生成所需的文件,但是现在它真的很“笨”。我想对它进行扩展,以考虑到我正在构建的不同平台、我正在使用的编译器交叉编译器或者我可能拥有的库依赖的不同版本。我在 CMake 方面没有太多的专业经验,举个例子来说明我的工作或者一个已经工作的生成器可能会有很大的帮助。

109910 次浏览

我在 Cmake 也没有多少经验,但是要执行一个跨平台的任务,需要编写和修改很多文件,包括 CMakeLists.txt 文件,我建议你使用这个叫做 ProjectGenerator 工具的新工具,它非常酷,它可以完成所有额外的工作,并且很容易为第三方源生成这样的文件。 只要在使用前仔细阅读 README 即可。

连结: Http://www.ogre3d.org/forums/viewtopic.php?f=1&t=54842

我觉得你这样做是颠倒的。

在使用 CMake 时,您应该自己编写 CMakeLists.txt。通常,您不需要处理不同的编译器,因为 CMake 对它们有所了解。但是,如果必须这样做,则可以在 CMakeFiles 中添加代码,以根据所使用的工具执行不同的操作。

我认为您不需要使用自动化脚本来生成 CMakeList。因为它是一个非常简单的任务写一个,在你了解了基本的程序。是的,我同意理解 CMake Wiki 中给出的编写过程也很困难,因为它太详细了。

一个展示如何编写 CMakeLists.txt的非常基本的示例显示为 给你,我认为它对每个人都有用,甚至是第一次编写 CMakeLists.txt 的人。

CLion 是一个完全基于 CMake 项目文件的集成开发环境。

当使用 从源头导入项目时,它能够自己生成 CMakeLists.txt 文件

但是,随着项目的增长和添加外部依赖项,很可能需要手动编辑此文件。

不确定这是否是原始海报面临的问题,但是正如我在上面看到的大量“只写 CMakefile.txt”的答案,让我简短地解释为什么生成 CMakefile 可能是有意义的:

A)我有另外一个我相当满意的构建系统

(其中包括大型多平台的大型集合构建 相互连接的共享和静态库、程序、脚本 语言扩展,以及各种内部和外部工具 依赖性、怪癖和变体)

B)即使我换了它,我也不会考虑 cmake。

我看了一下 CMakefile,对其语法并不满意 而且不喜欢这种语义。

C) CLion 使用 Cmakefile,并且只使用 Cmakefile (似乎有点意思)

所以,为了给 CLion 一个机会(我喜欢 PyCharm,所以它很诱人) ,但是为了继续使用我的构建系统,我很乐意使用一些工具,它们可以让我 执行 使生成 _ cmake 并根据电流动态生成所有必要的 CMakefile 从我的构建系统中提取的信息。我可以很高兴地向工具/脚本提供信息,我的应用程序包含哪些源和头,它期望构建哪些库和程序,期望为哪个组件设置-I,-L,-D 等等。

当然,如果 JetBrains 允许提供一些直接的协议来向 IDE 提供它所需要的信息,我会更高兴 (例如,允许我提供自己的命令来编译、运行和 发出他们真正需要的任何元数据——我认为他们主要需要在动态代码分析中实现的 inc夹和定义,以及为调试器设置 LD _ LIBRARY _ PATH 的库路径) ,而不需要引用 cmake。作为协议的 CMakefile 有些复杂。

也许这个会有帮助:

Https://conan.io/

作者就 cmake 以及如何在 CPPCon 中使用 cmake 创建模块化项目做了一些介绍。据我所知,这个工具需要 cmake,因此我认为它是在集成新包或创建新包时生成的。最近我读了一些关于如何使用 YAML 文件编写 C/C + + 项目的更高级描述的文章,但是不确定它是否是柯南的一部分(我读的是柯南的作者)。我从来没有使用过,它是一些悬而未决的东西,所以,请如果你使用它,并适合你的需要,评论你的意见,以及它如何适合你的情况。

我正在维护一个 C + + 软件环境,该环境有1000多个模块(共享的、静态的库、程序) ,并使用了20多个第三方(ost、 openCV、 Qt、 Qwt...)。这个软件环境托管了许多程序(大约50个) ,每个程序接收一些库、程序和第三方。我使用 CMake 来生成 makefile,这真的很棒。

但是,如果按照建议的方式编写 CMakeLists.txt(将模块声明为库/程序,导入源文件,添加依赖项...)。我同意 Celavek 的观点: 维护那些 CMakeLists.txt文件是一件非常痛苦的事情:

  • 向模块添加新文件时,需要更新其 CMakeLists.txt
  • 当您升级第三方时,您需要更新使用它的所有模块的 CMakeLists.txt
  • 当您添加一个新的依赖项(库 A现在需要库 B)时,您可能需要使用 A更新所有程序的 CMakeLists.txt
  • 当您希望更改新的全局设置(编译器设置、预定义变量、使用 C + + 标准)时,您需要更新所有的 CMakeLists.txt

然后,我看到了两个解决这些问题的策略,可能就是 OP 提到的那个。

1-让 CMakeLists.txt写得很好,并且足够聪明,不要让自己的行为冻结,以便随时更新自己。这就是我们的软件环境。每个模块都有一个标准化的文件组织(源文件在 src文件夹中,包括在 inc文件夹中...) ,并且有简单的文本文件来指定它们的依赖关系(使用我们定义的关键字,如 QT表示模块需要与 Qt链接)。然后,我们的 CMakeLists.txt是一个两行文件,只需调用我们编写的用于自动设置模块的 cmake 宏。作为一个 MCVE,它应该是:

CMakeLists.txt:

include( utl.cmake )
add_module( "mylib", lib )

返回文章页面

macro( add_module name what )
file(GLOB_RECURSE source_files "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)
if ( what STREQUEL "lib" )
add_library( ${name} SHARED ${source_files} )
elseif ( what STREQUEL "prg" )
add_executable( ${name} ${source_files} )
endif()
# TODO: Parse the simple texts files to add target_link_libraries accordingly
endmacro()

然后,对于上面暴露的所有情况,您只需更新 utl.cmake,而不需要更新所有的 CMakeLists.txt..。

老实说,我们对这种方法非常满意,系统变得非常容易维护,我们可以很容易地添加新的依赖项,升级第三方,改变一些构建/依赖项策略..。

然而,仍然有许多 CMake脚本需要编写。而且 CMake脚本语言糟透了... ... 这个工具非常强大,对吧,但是脚本的变量作用域、缓存、痛苦的且没有很好文档说明的语法(只是为了检查一个列表是否为空,你必须询问它的大小并将其存储在一个变量中事实上它不是面向对象的,这使得维护它非常痛苦。

因此,我现在确信,真正好的方法可能是:

2-完全从更强大的语言(如 Python)生成 CMakeLists.txt 。Python 脚本将执行与 utl.CMake 类似的操作,相反,它将生成一个 CMakeLists.txt,准备传递给 CMake 工具(使用 HelloWorld 中提出的格式,没有变量,没有函数... ... 它将只调用标准 CMake 函数)。

我怀疑这样的通用工具的存在,因为它很难产生的 CMakeLists.txt文件将使每个人都高兴,你将不得不自己编写它。请注意,Gen-cmake可以做到这一点(生成 CMakeLists.txt) ,但是是以一种非常原始的方式,而且显然它只支持 Linux,但是它可能是一个很好的起点。

这很可能是我们的软件环境的 v2... 有一天。

注意: 此外,如果您希望同时支持 qmake 和 cmake,那么编写良好的 Python 脚本可以根据需要生成 CMakeList 和 pro 文件!

我一直在寻找这样一个生成器,但最后我决定编写自己的(部分原因是我想了解 CMake 是如何工作的) :

Https://github.com/aenteas/cmake-generator

它还有一些额外的特性,比如创建 Python 包装器(SWIG)。

编写一个适合每个人的生成器是不可能的,但我希望它能给你一个想法,如果你想制作你的定制版本。