如何编写可在Linux和Windows中轻松编译的C ++程序?

时间:2009-01-25 21:11:22

标签: c++ c windows linux platform

我正在制作一个C ++程序。

我对C ++最大的烦恼之一就是它假定的平台独立性。

你们都可能知道,在Windows中编译Linux C ++程序,在Linux中编译Linux C ++程序几乎是不可能的,而不会产生大量的神秘错误和平台特定的包含文件。

当然你可以随时切换到像Cygwin和wine这样的仿真,但我问你,有没有别的办法呢?

9 个答案:

答案 0 :(得分:37)

语言本身是跨平台的,但大多数库都不是,但如果你想在C ++编程时想要完全跨平台,你应该记住三件事。

首先,您需要开始使用某种跨平台构建系统,例如SCons。其次,您需要确保所使用的所有库都是跨平台构建的。 第三点,我建议使用存在于所有目标平台上的编译器,gcc在这里考虑(C ++是一个相当复杂的野兽,所有编译器都有自己特定的怪癖)。

我有一些关于图形用户界面的进一步建议。有几个可供使用,最值得注意的三个是:

GTK+QT是两个API,它们带有自己的小部件集(按钮,列表等),而wxWidgets更像是当前运行平台的包装API本机小部件集。这意味着两个前者与系统的其他部分相比可能看起来有点不同,而后者看起来就像本机程序。

如果你正在进行游戏编程,那么有很多API可供选择,所有这些都是跨平台的。我所知道的最全面的两个是:

两者都包含从图形到输入和音频例程的所有内容,无论是通过插件还是内置。

另外,如果您觉得C ++中的标准库有点缺乏,请查看Boost以获得一些通用的跨平台甜蜜。

祝你好运。

答案 1 :(得分:13)

C ++是跨平台的。您似乎遇到的问题是您正在使用平台相关库。

我假设你真的在谈论UI组件 - 在这种情况下我建议使用像GTK +,Qt或wxWindows这样的东西 - 每个都有可以为不同系统编译的UI组件。

唯一的解决方案是让您找到并使用独立于平台的库。

并且,在旁注中,cygwin或Wine都不是仿真 - 它们是100%本机实现的相同功能的发现它们各自的系统。

答案 2 :(得分:9)

一旦你意识到了问题,它实际上并不那么难。我目前正在处理的所有代码都编译在32位和64位Windows上,所有类型的 Linux ,以及Unix(Sun,HP和IBM)。显然,这些不是GUI产品。此外,我们不使用第三方库,除非我们自己编译它们。

我有一个.h文件,其中包含所有特定于编译器的代码。例如,Microsoft和gcc在如何指定8位整数方面存在分歧。所以在.h中,我有

#if defined(_MSC_VER)
   typedef __int8 int8_t;
 #elif defined(__unix)
   typedef char int8_t;
 #endif

还有相当多的代码可以统一某些低级函数调用,例如:

#if defined(_MSC_VER)
  #define SplitPath(Path__,Drive__,Name__,Ext__) _splitpath(Path__,Drive__,Dir__,Name__,Ext__)
#elif defined(__unix)
  #define SplitPath(Path__,Drive__,Name__,Ext__) UnixSplitPath(Path__,Drive__,Name__,Ext__)
#endif

现在在这种情况下,我相信我必须编写一个UnixSplitPath()函数 - 有时您需要。但大多数时候,你只需要找到正确的替换功能。在我的代码中,我将调用SplitPath(),即使它不是任何平台上的本机函数; #defines将为我排序。培训自己需要一段时间。

信不信由你,我的.h文件只有240行。这真的不多。这包括处理endian问题。

一些较低级别的东西需要条件编译。例如,在Windows中,我使用Critical Sections,但在Linux中我需要使用pthread_mutex。 CriticalSection被封装在一个类中,这个类有很多条件编译。但是,上层程序完全没有意识到,无论平台如何,类的功能都完全相同。

我能给你的另一个秘诀是:经常在所有平台上构建你的项目(特别是在开始时)。当您将编译器问题扼杀在萌芽状态时,这会容易得多。在你尝试跨平台之前,不要等到你完成开发。

答案 3 :(得分:2)

坚持使用ANSI C ++和跨平台的库,你应该没问题。

答案 4 :(得分:1)

创建一个低级图层,其中包含项目中所有特定于平台的代码。实现此层的2个版本 - 一个用于Windows,一个用于Linux - 具有相同的接口,并将它们构建到2个库。通过该界面访问项目中所有特定于平台的功能。

此图层可以包含文件访问,打印,GUI等的常规类。

使用该层的所有(现在非特定于平台的)代码现在可以在Windows上编译一次,在Linux上编译一次。

答案 5 :(得分:0)

在Window中再编译,在Linux中再次编译。除非您使用特定于平台的库,否则它应该可行。它不像Java,你可以编译一次,它可以在任何地方使用。没有人为C ++制作虚拟机,也许永远不会。用C ++编写的代码可以在任何平台上运行。你只需要先在每个平台上编译它。

答案 6 :(得分:0)

建议:

  • 使用typedef进行整数。或#include< stdint.h>。有些机器认为int是8个字节,有些是4个。(以前是2和4个。时间如何变化。)

  • 尽可能使用封装。我的最后一个窗口的编译器认为%lld是%I64d“,为vsnprintf()提供了棘手的返回值,与close()和套接字等类似的问题。

  • 注意堆栈大小/缓冲区大小限制。我在Windows下遇到了8k UDP缓冲区限制,以及其他问题。

  • 出于某种原因,我的Window的C ++编译器不接受堆栈的动态大小分配。例如:void foo(int a){int b [a];要注意那些事情。计划如何重新编码。

  • #ifdef可以成为你最好的朋友。而你最大的敌人! (同时!)

当然可以做到。但是要经常进行编译和测试!

答案 7 :(得分:0)

Linux和Windows也有不同的数据模型。 请参阅文章:The forgotten problems of 64-bit programs development

答案 8 :(得分:-1)

标准C ++ 是代码在任何平台上编译都没有错误。 尝试在Windows上使用 Bloodshed Dev C ++ (而不是VC ++ / Borland C ++)。

由于Bloodshed Dev C ++确认了C ++标准,因此在大多数情况下,使用它编译的程序将在linux上编译而没有错误。

相关问题