使用C ++创建跨平台程序

时间:2012-11-14 12:01:13

标签: c++ compilation cross-platform

假设我在MSVC ++ 2010中有一个简单的项目。 所有内容都是main.cpp,它的代码很简单:

    // include macros
    #define WIN32
    #include <FL/Fl.H>
    #include <FL/Fl_Window.H>
    #include <FL/fl_ask.H>
    // main function
    int main()
    {
        // init window
        Fl_Window *window = new Fl_Window(250, 250, "Derp Window"); 
        // show window, run window
        window->show();
        int result = Fl::run();
        fl_message("Goodbye...");
        // release pointers
        delete window;
        // return
        return result;
    }

制作Windows兼容版本很容易,我所要做的就是将模式设置为发布并构建它。但是,正如我最近发现的那样,生成的.exe文件无法在Mac或Linux操作系统上运行。这让我感到惊讶,因为我所使用的只是普通的旧c ++和FLTK,它是跨平台的。

所以,我的问题是,我如何使用这个代码并以一种可以在Linux操作系统和Mac OS上运行的方式编译它?或者,是否可以保留相同的代码并以不同的方式编译它,以便它可以在另一个操作系统上运行?如果不可能,我还需要改变什么?

PS。代码很简单,但是如果你想知道#define WIN32就在那里,因为没有它,编译器会对丢失的头文件感到不满,比如“X / X11.h”

4 个答案:

答案 0 :(得分:4)

代码是兼容的,但这并不意味着生成的二进制文件将是。总的来说,这是永远不会的情况。

编译器会将您的代码转换为您的特定架构和平台可以理解的低级代码,而Windows与Mac不同。这个较低级别的代码基本上与C ++,FLTK或其中任何一个的兼容性承诺无关。

这里的类比是驾驶道路左侧的汽车在机械上与在道路右侧驾驶汽车相同(所以让我们忽略导航差异等事实和你的事实“可能在不同的方向转向”,所以你对驾驶汽车的知识完全符合这两种情况......但这并不意味着你可以简单地将你的汽车放在法国或美国的道路左侧。你会引发一场非常严重的事故。当您将驾驶汽车的知识应用于特定环境时,您必须遵守当地的道路规则。

您可以在目标环境下重新编译相同的代码,或使用交叉编译器。

答案 1 :(得分:3)

如果您无法访问Linux或Mac OSX计算机,则必须对其进行交叉编译。要做到这一点,你必须找到一个现有的交叉编译器,你可以将源代码下载到例如GCC并建立自己的自我。从“交叉编译器”(或类似的)做一些搜索,你会发现一些易于学习的教程。

如果您可以访问Linux或Mac,那么只需复制代码并在该环境中构建它。小心Linux,因为不同的发行版有一些库的不同版本。

最后,有Wine等环境允许Windows程序在其他平台上运行。

答案 2 :(得分:0)

如果您使用FLTK,则需要在编译程序的每个平台上包含其标题,而不仅仅是WIN32。

您找不到X11/X.h的错误消息是由于缺少编译器标志(请参阅 1 ),需要先包含的先决条件(参见 2 )或缺少标题(参见 3 )。

  1. 使用fltk-config --cflags获取所需的编译器标志,fltk-config --libs以获取需要传递给链接器的标志。
  2. 似乎不适用于此处,但您可能会遇到需要它的库。
  3. 如果您使用Ubuntu或Debian,请通过执行apt-get install x11proto-core-dev安装X标头,但如果您已经安装了libfltk1.3-dev(或其他一些版本),则不应该这样做,因为它应该引入所有必需的依赖项。如果您使用其他发行版,请确保已安装X标头包。

答案 3 :(得分:0)

问题可能是#define WIN32。根据您的描述,我猜想FLTK库正在使用它来有条件地为Windows或Unix(X)编译其头文件。因此,在编译Windows时需要定义它,在编译Unix时需要定义。处理此类问题的常用方法是在编译Windows时为编译器调用添加/DWIN32选项。您可能还需要做一些事来获得正确的库。

FWIW:完全可以设计库,以便头文件适用于两个系统,无需任何条件编译。如果你想要条件编译,你应该使用系统的预定义符号(例如_WIN32)。