11/30/2018 更新

另外推荐两个C++ package manager。 Conan之前有所耳闻,然后cppCon 2018上看了他们的demo, 觉得还不错。 就是觉得python && C++&& CMake 用起来略臃肿。

Conan for all platforms.C/C++ Open Source Package Manager​conan.io10f84f9404efbe2d7c9346406dbb1510.png

Spack工作用的多,主要针对对象是HPC machine,但是设计理念很先进,Linux+macOS上用的很顺手, 熟悉他们的流程之后觉得比Conan好用。

Spack for supercomputers, macOS and Linux.Spack​spack.io

/***********************************************************************************/

首先必须肯定CMake。它简化了cross platform, OS, compiler的开发成本,同时支持多个IDE(VS, QtCreator, Eclipse, CLion...etc.),并且有一个成熟开源社区。 当你挣扎于将based on autotools的项目迁移至OSX或者Windows的时候,你就会感谢CMake的美好。 网络上有各种资源可供你使用学习,运气好可以直接照用别人的CMakeLists.txt。

支持多种Generator。make, Eclipse, Ninja, MSVC... 个人强推Ninja。 至少我司所有CMake Developer都偏爱它。 突出一个字 - 快。 极大提升了开发效率。

下面来说说问题。

赞同@Xi Yang和@pilot的说法。 首先CMake的learning curve真的不是一般的高。 build system本来就难,configuration + generation + compile time 任何一个环节都可能出错。上手需要踩过无数的坑,你才能初步入门。

第二,CMake没有好的paradigm, 就连我司的官方教程都是上古旧书 - CMake 3.1。 上周同事刚发布CMake 3.11.3,距离3.1已经过去4年多了。虽然官方的documentation很详细,但特么都是描述性的。也就是说CMake告诉你他能做什么,我有多屌,但是他不告诉你该怎么做,以及为什么要这么做。从而开发过程就变成了一个试错过程。 加这个link path解决问题了,慢着不对,为什么windows上又炸了;我该link那个python environment,那我hard code一个path吧。 若干个月后,你可能会恨自己做了这件事。。。 CMake当然有正确的paradigm,但往往它是"口口相传",局限于某几个圈子里。 往往做完了几个大feature要求同事作code review的时候,我才能系统的从他们一大堆comments和change requests下学习正确的方式。

第三,CMake的本身属性一定程度上限制了它的发展。 开源意味着有更大的用户群体和一种让世界更美好的愿景,但是也随之带来了funding和customer service的问题。CMake的发展进步有赖于社区的维护,但是随着开发人员的新老交替,无可避免的会慢慢产生冗余代码(参见FindBoost.cmake)。 我有问过同事们为什么我们不每隔1,2年更新Mastering CMake这本官方教程,同事的回答让我觉得很有道理:“我们也想啊! 但是问题是funding从哪里来? 虽然我们负责维护,开发和发布CMake新版本,但这不是我们的主业。 编写教程需要大量的时间,除非客户愿意资助我们,我们也爱莫能助。我们也要养家糊口啊。。。”

CMake的推动有赖于他的用户群体。 i.e. 客户A要我们帮他们开发一个新软件。 开发的过程中,我们需要拓展CMake去支持一系列新功能。我们说服客户这些新功能是必要的,并希望他们能支持把这些代码回馈给CMake master, 于是CMake得到了拓展。如果没有这些客户,以及其他community CMake的开发者们,也不会有CMake的今天。 使用过程自然而然会遇到问题,但是人们往往只能求助stackOverFlow 或者CMake mailing list. 由于没有人会赞助CMake的customer service所以一切都是out of courtesy。帮你是好心,没人有义务帮你。遇上一些暴脾气的在mailing list里骂人的,我们一般都当午休时候的笑料- -

最后,针对提到的一些问题,我要为CMake辩护下:

Modern CMake在target based的开发理念下,其实已经有了相当强的模块化能力。`include` keyword已经淡出了历史舞台,成为legacy。以下两篇blog我觉得针对这个理念写的不错:

自动解决依赖问题早就不是什么问题了: Package developers应该生成package files给upstream users使用。如果你创建了一个library foo, 理论上别人应当只需要find_package(foo)便足以。

Windows上微软出了一个叫vcpkg的管理工具,据说挺好用的,可以了解下。

"它虽然是过程式语言,但函数TMD没有返回值!"好问题。。。我午休去问问同事

“作为一个string based language, 很少有利用CMake来处理functional programming的cases. 加上CMake诞生之初要兼容fortran, 所以这一功能也不了了之。 虽然community有几个人提过这个feature request,但是没有一个令人信服的使用场景 ”by Brad King。就这样。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐