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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/478298/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 11:53:26  来源:igfitidea点击:

How do I write a C++ program that will easily compile in Linux and Windows?

c++cwindowslinuxplatform

提问by Unknown

I am making a C++ program.

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

One of my biggest annoyances with C++ is its supposed platform independence.

我对 C++ 的最大烦恼之一是它所谓的平台独立性。

You all probably know that it is pretty much impossible to compile a Linux C++ program in Windows and a Windows one to Linux without a deluge of cryptic errors and platform specific include files.

你们可能都知道,在 Windows 中编译 Linux C++ 程序并将 Windows 编译到 Linux 中几乎不可能没有大量的神秘错误和特定于平台的包含文件。

Of course you can always switch to some emulation like Cygwin and wine, but I ask you, is there really no other way?

当然你可以随时切换到Cygwin和wine之类的模拟,但我问你,真的没有其他办法吗?

回答by

The language itself is cross-platform but most libraries are not, but there are three things that you should keep in mind if you want to go completely cross-platform when programming in C++.

该语言本身是跨平台的,但大多数库不是,但是如果您想在使用 C++ 编程时完全跨平台,则应牢记三件事。

Firstly, you need to start using some kind of cross-platform build system, like SCons. Secondly, you need to make sure that all of the libraries that you are using are built to be cross-platform. And a minor third point, I would recommend using a compiler that exists on all of your target platforms, gcccomes in mind here (C++ is a rather complex beast and all compilers have their own specific quirks).

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

I have some further suggestions regarding graphical user interfaces for you. There are several of these available to use, the three most notable are:

我有一些关于图形用户界面的进一步建议。有几种可用的,最显着的三个是:

GTK+and QTare two API's that come with their own widget sets (buttons, lists, etc.), whilst wxWidgetsis more of a wrapper API to the currently running platforms native widget set. This means that the two former might look a bit differently compared to the rest of the system whilst the latter one will look just like a native program.

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

And if you're into games programming there are equally many API's to choose from, all of them cross-platform as well. The two most fully featured that I know of are:

如果您从事游戏编程,则有同样多的 API 可供选择,而且它们都是跨平台的。我所知道的两个功能最齐全的是:

Both of which contains everything from graphics to input and audio routines, either through plugins or built-in.

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

Also, if you feel that the standard library in C++ is a bit lacking, check out Boostfor some general purpose cross-platform sweetness.

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

Good Luck.

祝你好运。

回答by Klathzazt

C++ is cross platform. The problem you seem to have is that you are using platform dependent libraries.

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

I assume you are really talking about UI componenets- in which case I suggest using something like GTK+, Qt, or wxWindows- each of which have UI components that can be compiled for different systems.

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

The only solution is for you to find and use platform independent libraries.

唯一的解决方案是让您查找和使用平台无关的库。

And, on a side note, neither cygwin or Wine are emulation- they are 100% native implementations of the same functionality found their respective systems.

而且,附带说明一下,cygwin 或 Wine 都不是模拟——它们是在各自系统中找到的相同功能的 100% 本机实现。

回答by Marc Bernier

Once you're aware of the gotchas, it's actually not that hard. All of the code I am currently working on compiles on 32 and 64-bit Windows, all flavors of Linux, as well as Unix (Sun, HP and IBM). Obviously, these are not GUI products. Also, we don't use third-party libraries, unless we're compiling them ourselves.

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

I have one .h file that contains all of the compiler-specific code. For example, Microsoft and gcc disagree on how to specify an 8-bit integer. So in the .h, I have

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

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

There's also quite a bit of code that uniformizes certain lower-level function calls, for example:

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

#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

Now in this case, I believe I had to write a UnixSplitPath() function - there will be times when you need to. But most of the time, you just have to find the correct replacement function. In my code, I'll call SplitPath(), even though it's not a native function on either platform; the #defines will sort it out for me. It takes a while to train yourself.

现在在这种情况下,我相信我必须编写一个 UnixSplitPath() 函数 - 有时您需要这样做。但大多数时候,您只需要找到正确的替换函数即可。在我的代码中,我将调用 SplitPath(),即使它在任一平台上都不是本机函数;#defines 会帮我解决这个问题。需要一段时间来训练自己。

Believe it or not, my .h file is only 240 lines long. There's really not much to it. And that includes handling endian issues.

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

Some of the lower-level stuff will need conditional compilation. For example, in Windows, I use Critical Sections, but in Linux I need to use pthread_mutex's. CriticalSection's were encapsulated in a class, and this class has a good deal of conditional compilation. However, the upper-level program is totally unaware, the class functions exactly the same regardless of the platform.

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

The other secret I can give you is: build your project on all platforms often (particularly at the beginning). It is a lot easier when you nip the compiler problems in the bud. Don't wait until you're done development before you attempt to go cross-platform.

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

回答by duffymo

Stick to ANSI C++ and libraries that are cross-platform and you should be fine.

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

回答by Igor Oks

Create some low-level layer that will contain all the platform-specific code in your project. Implement 2 versions of this layer - one for Windows, and one for Linux - with the same interface, and build them to 2 libraries. Access all platform-specific functionality in your project through that interface.

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

This layer can contain general classes for file access, printing, GUI, etc.

该层可以包含用于文件访问、打印、GUI 等的通用类。

All the (now non-platform-specific) code that uses that layer can now be compiled once on Windows and once on Linux.

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

回答by geowa4

Compile it in Window and again in Linux. Unless you used platform specific libraries, it should work. It's not like Java, where you compile it once and it works everywhere. No one has made a virtual machine for C++, and probably never will. The code you write in C++ will work in any platform. You just have to compile it in every platform first.

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

回答by Mr.Ree

Suggestions:

建议:

  • Use typedef's for ints. Or #include <stdint.h>. Some machines think int is 8 bytes, some 4. (It used to be 2 and 4. How the times have changed.)

  • Use encapsulation wherever possible. My last window's compiler thought %lld was %I64d", gave screwy return values for vsnprintf(), similar issues with close() and sockets, etc.

  • Watch out for stack size / buffer size limits. I've run into an 8k UDP buffer limit under Windows, amongst other problems.

  • For some reason, my Window's C++ compiler wouldn't accept dynamicly-sized allocations off the stack. E.g.: void foo(int a) { int b[a]; } Be aware of those sort of things. Plan how you will recode.

  • #ifdef can be your best friend. And your worst enemy! (At the same time!)

  • 对整数使用 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 可以成为您最好的朋友。还有你最大的敌人!(同时!)

It can certainly be done. But compile and test early and often!

这当然可以做到。但是要尽早并经常编译和测试!

回答by Mr.Ree

Also Linux and Windows have diffrent data model. See article: The forgotten problems of 64-bit programs development

Linux 和 Windows 也有不同的数据模型。参见文章:64位程序开发中被遗忘的问题

回答by Pratik Deoghare

Standard C++is code compiles without errors on any platform. Try using Bloodshed Dev C++on windows (instead of VC++ / Borland C++).

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

As Bloodshed Dev C++ confirms C++ standards, so programs compiled using it will be compiled on linux without errors in most of the cases.

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