在Windows和Linux上构建C++代码

10
我参与了一个针对Windows和Linux(RHEL)平台的C++项目。目前,开发工作纯粹在Visual Studio 2008上完成。为了在Linux上编译,我们使用了第三方Visual Studio插件,该插件读取VS解决方案/项目文件,并在Linux机器上进行远程编译。
最近决定放弃第三方插件。
现在我最大的关注点是构建系统。我正在寻找跨平台构建工具。这样,我就不需要维护两组构建文件(例如Windows的vcproj / solution和Linux的makefile)。
我发现了以下候选人: a. Scons b. cmake 您对于用于跨平台开发的工具有何看法?
还有一个问题让我感到困扰,即没有vcproj文件,Visual Studio(+ Visual Assist)将失去很多功能——您如何处理这个问题?
谢谢, Dima
PS 1:Scons有一个我喜欢的特点,它使用Python,因此非常灵活,而cmake使用专有语言(我理解这不是构建系统的优胜特性);Scons是自包含的(无需像cmake一样在Linux上生成makefiles)。
那么为什么不选择Scons?为什么您的项目决定使用cmake?

我们的系统旨在最多支持两个平台,所以问题是如果使用cmake是否“过度杀伤”?我还担心的另一点是构建必须是可重复的(从头开始构建两次将完全相同)。当然,使用本地构建系统我已经接近目标了。但是,使用cmake会不会破坏它,并根据编译人员的设置创建不同的vcproj/makefiles(例如,对于Windows,每个开发人员都在自己的机器上进行编译)? - dimba
关于Visual Assist的一点说明。它有一个选项,在使用空解决方案时从目录加载文件。 - sean e
6个回答

10

CMake可以让你仍然使用Visual Studio的解决方案和项目文件。CMake本身并不构建源代码,而是为你生成构建文件。对于Linux来说,这可以是Code::Blocks,KDevelop或纯makefile,还有其他更奇特的选择。对于Windows来说,可以使用Visual Studio项目文件等,而对于MacOS等操作系统也有其他选项。

因此,Visual Studio的解决方案和项目是从你的CMakeLists.txt创建的。对于大型项目来说,这样做非常好用。例如,当前的Ogre3d在所有平台(Windows,Linux,MacOS和IPhone)都使用CMake,并且效果非常好。

我对Scons在这方面了解不多,我只在Linux上构建了一个库。因此,我无法在公平的基础上比较这两个工具。但对于我们的跨平台项目,CMake已经足够强大了。


CMake相当不错 - 它可以重新生成VS项目文件,因此说“允许您仍然使用...项目文件”是有一定误导性的。如果你需要在许多包括Windows在内的操作系统之间实现兼容性,并且还想使用Visual Studio,我强烈推荐它用于C++项目,因为这是唯一的解决方案。 - Arafangion
我希望我的回答能够澄清这个问题。 :) 你当然是正确的。你现在拥有的解决方案文件将被生成的文件所替代。CMake会自动添加一些项目到你的解决方案中(ALL_PROJECTS,INSTALL,ZERO_CHECK),这些可能一开始会让人感到尴尬,但一旦你了解它们的用途,就会发现它们非常方便,特别是INSTALL。它将构建解决方案的所有部分,并将创建的DLL、EXE和其他文件按照CMakeFiles.txt中指定的目标目录进行复制,以便你只需运行NSIS或其他打包工具即可创建安装包。 - haffax
值得注意的是,SCons 可以 生成VS项目文件。 - Diaa Sami

3
我以前没有使用过Scons,所以无法说它是如何工作的,但CMake表现得相当不错。
它通过生成目标平台所需的构建文件来工作。
当用于VC++时,它会生成解决方案和项目文件,因此从VS中,它看起来就像本地VS项目。唯一的区别是,当你直接通过VS编辑项目或解决方案时,下次运行CMake时,更改将被覆盖,因为它会重写你的项目/解决方案文件。
因此,任何更改都必须在CMake文件中进行。

3
我们有许多基于核心库和应用程序的代码。我们在Linux上维护一个基于Makefile的构建系统,而在Windows上则使用每个项目或库的Visual Studio解决方案。
我们发现这对我们的需求很有效,每个库或应用程序都是在Linux或Windows上开发的,并考虑到交叉编译(例如,不使用特定于平台的API)。我们使用boost处理文件路径、线程等内容。在特定情况下,我们使用模板/#define来选择特定于平台的解决方案(例如事件)。当准备好后,我们转移到另一个系统(Linux或Windows),重新编译,修复警告/错误并进行测试。 与其花时间找出可以在两个平台上进行交叉编译的工具,我们更喜欢使用最适合每个平台的系统,并花时间解决特定问题,使软件变得更好。 目前,我们仅在Windows上拥有GUI应用程序,因此没有GUI进行交叉编译。我们在Windows和Linux之间共享的大部分开发都是服务器端网络(套接字、TCP/IP、UDP等)以及Linux上的客户端工具和Windows上的GUI应用程序。
使用Perforce进行源代码版本管理时,我们发现Linux的Makefile系统比Windows的VS更加灵活,特别是对于使用多个工作区(源代码版本的视图),我们需要指向公共目录等情况。在Linux上,可以通过运行脚本自动完成此操作,而在Visual Studio中引用环境变量非常不灵活,因为很难在视图/分支之间自动更新。
重新同步问题:
我假设您想知道如何确保Linux和Windows之间的两个构建系统同步。我们实际上在Linux上使用Hudson,在Windows上使用CruiseControl(我们先有了Windows版的CruiseControl,当我去设置Linux版本时,我发现Hudson更好,所以现在我们有了混合环境)。我们的系统一直在运行。当有更新时,它会进行测试并发布(无论是Windows还是Linux版本),因此如果不起作用,您将立即知道。在测试期间,我们确保所有最新功能都存在且完全可用。我想就这样,没有黑魔法涉及其中。
哦,你指的是构建脚本...每个应用程序都有自己的解决方案,在解决方案中设置依赖项。在Linux端,我为每个项目都有一个makefile,以及在项目目录中的一个构建脚本,负责处理所有依赖项,这通常意味着构建核心库和给定应用程序所需的几个特定框架。正如您所看到的,这对于每个平台都是不同的,可以轻松添加一行以构建所需的项目。
在Windows上,您打开项目并添加依赖项项目。再次强调,没有黑魔法涉及其中。我认为这些任务属于开发相关,例如您向项目添加了新功能并需要链接框架和标头。因此,从我的角度来看,没有理由自动化这些内容-因为它们是开发人员实现功能时要做的一部分。

如果你能说出如何确保各种构建脚本不会失步,我会点赞的。(持续集成服务器可能是一种方式) - Arafangion

3

另一个选择是premake。它类似于cmake,可以从定义文件生成解决方案。它是开源的,最新版本使用Lua脚本非常高度可定制。我们能够轻松添加自定义平台支持。对于您的情况,它支持Visual Studio和GNU makefiles标准。

请参见Premake 4.0主页

CruiseControl是持续集成的好选择。我们在Linux上使用Mono成功地运行它。


1
我不建议使用Premake,因为与CMake和SCons相比,它缺乏流行度、社区和支持,而这两者被许多重要项目所使用。 - Diaa Sami

1

这里有一篇文章,关于KDE开发者选择CMake而非SCons的决定。然而我必须指出,这篇文章已经近三年了,所以SCons应该得到了改进。

这里是SCons与其他构建工具的比较。


请注意,SCons更通用,而CMake偏向于特定的语言。 - Arafangion

0

过去经常需要这样做。我们使用GNU Make来处理几乎所有事情,包括在Windows上。

如果您愿意,可以在Windows下使用项目文件,并在Linux下使用GNU Make。

编写跨平台Makefile没有什么好的方法,因为目标文件等内容会有所不同(以及路径名问题,\ vs /等)。通常,您可能需要在各个平台上微调代码以考虑细微差异,因此必须对Makefile进行微调并在其他平台上进行检查。

许多操作系统项目为不同平台维护Makefile,例如zlib,它们的名称类似于Makefile.win、Makefile.linux等。您可以效仿他们的做法。


使用您的方法相比于使用CMake有什么优势?使用CMake,您只需要管理一个构建文件集,并仍然可以充分利用您喜欢的IDE。 - haffax
一个优点是,使用每个系统的标准脚本可能比想出一个单一的跨平台脚本更容易,该脚本只需在所有操作系统中以某种方式解决任何怪癖。尽管如此,仍需要大量重复的努力... - Arafangion

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