• Uncategorized

About c++ : CC-How-to-generate-executable-file-that-can-run-on-both-Windows-and-Linux

Question Detail

I’m new in programming. From what i know, a program that is compiled in Linux should not be able to run in Windows. So, if we want to run the same program in both platform, we need to compile the source code under both platform, and create 2 different executable files.

Recently I am studying the source code of an open source, cross-platform Java GUI application. I’m surprised to find that the backend engine of that GUI application is a small executable file generated from C++ codes. No matter users use that application in Windows or Linux, the Java GUI will call the same executable file in the bin folder.

I just want to know, how can that executable file run on both Windows and Linux?

I’m also interested to create a cross-platform Java GUI application using a C++ program as the engine. That C++ program is only available for Linux only. I’ve been googling for a while and i found that I need to use Cygwin to port it to Windows. However, if i use Cygwin, i will end up having 2 different executable files.

How can i combine the Windows executable file with the Linux executable file? Is it possible to generate a single executable file that can run on both platform?

Thanks.

Question Answer

The simple answer is, is that you can’t.

The PE (Windows) and ELF (Linux) binary executable formats are totally different.

Not to mention that a C/C++ Program requires linking to libraries that won’t be available on either platform simultaneously.

However, you could use Wine on Linux to run the Windows executable providing it doesn’t attempt exotic Windows specific calls.

Or you could choose to use a more “common” cross-platform language such as a CLI language (C#/IronPython/Java etc.) that .NET for Windows and Mono for linux/others supports.

Ok, kids.

Yes, you CAN write a multi-platform binary, but it’s difficult. It’s called a Fat Binary, and it used to common enough in the 1980’s although I haven’t seen it done in decades. https://en.wikipedia.org/wiki/Fat_binary

Basically, you compile the machine code for each platform you want to run on and then hand-link the code with different entry points. While the Wikipedia article merely describes packing different architectures into the same binary, its actually possible to make one binary that runs on different operating systems so long as the entry points for the operating systems don’t collide.

Some executable formats were intentionally designed to allow this. For example, MZ, NE, LX and PE can be overlaid. Old OS/2 programs sometimes did this… they rarely contained an entire program for both operating systems, but when run on DOS would print a message telling you that you were using the wrong operating system for the program.

As far as Linux and Windows in one binary: While you can’t do an ELF and PE, I believe it might be doable with a PIE or a COFF and a PE or COM. Older Linux will run COFF binaries, which PE is descended from, so it seems you might be able to create a universal binary if newer versions of Linux will still run these. I can’t say for sure this would work, but it seems plausible.

Another caveat: Usually you need to put a jump in the code right at the beginning to skip past the other operating system’s entry point, headers, etc. because you can’t locate your code there (obviously).

The problem with this in modern computing is that most anti-virus software will incorrectly identify this as a virus. It used to be common that viruses would attack binaries by inserting such a jump at the beginning of an executable that jumped to the end of the binary, tacking their own code onto the end of the binary, then inserting another jump back to the main executable code. Since you need to do something more-or-less similar to support multiple platforms in one binary, most AV software will heuristically identify this as a virus and quarantine your executable.

So in short: YES it can be done for (some) combinations of platforms. It is not impossible, but you would have to be insane to do it.

There is no way to have a single native executable compiled from C++ source that works on different platforms. I don’t believe you that the same executable file is run on Windows and Linux, as you state in your second paragraph.

Simply put, it is not possible to run the same executable on different platforms. It is true for Windows, Linux, or any other UNIX platform.

The idea of having a single executable is nothing new and is the idea behind Java Runtime and Windows .Net (Mono for Linux). These themselves rely on different executables compiled on the specific machines.

No matter users use that application in Windows or Linux, the Java GUI
will call the same executable file in the bin folder.

They might simply be using relavant paths to these executables, and these executables are probably compiled separately on different platforms. Hard to tell without looking at the code.

Cygwin is a command line interface on windows that provides UNIX look and feel.

One option to try would be Wine which is a program for Linux to run windows programs on Linux.

It may be possible, if the OSes are on the same platform.

However, Linux can run on a variety of platforms with different processors: VAX, MAC, PC, Sun, etc.

One problem is that an executable contains assembly (machine code) instructions specific to a processor. The machine code for adding a register using ARM processor may be different than a Motorola, Intel or Sun processor. So with this context, one executable may not be guaranteed to run on different platforms.

Another issue is that the Run-Time library may also make calls to specific OS functions (like file open, displaying text, etc.) Some operating systems may not supply the same functionality; while others have a different method to execute the same functionality. An OS on an embedded platform may not support a file system. Windows Vista may block calls from unsecure MSDOS requests.

Other languages become platform independent by generating code which is executed by a “virtual machine”. The code is not directly executed by a processor.

The traditional method for porting C and C++ methods is to provide the source and let the customers build the software on their platform. Other delivery processes is to create an executable for every supported platform; this becomes a maintenance nightmare.

You can’t do that….i.e. you can’t run the same executable on both Unix as well as Windows.

Windows uses executable files, while Unix used elf file format. They are basically different. Unlike the counterpart Java where you can run the same executable( bytecode) on both machines, which in turn uses an interpreter(the JVM) to execute.

Now, said that you have two options…

  1. Either you can actually install C compilers on both windows and linux(unix) and then compile your code on both of them.
  2. Or you can install ‘Wine’, a porting software on linux which will be able to actually run windows executable file on linux by windows emulation.

Probably, option no 2 would be better suited…Its your call…

Regards,

Can’t you make a C++ program load it’s respective existing libraries using #ifdef?
I think that’s the C++ solution to cross platform binaries. However the code needs to be adjusted to work with both or all chosen libraries.

However without a java front end or a 2 different binaries or a bat and a sh or a program like wine you won’t be able to run the respective binary.

If you create a well behaved MS Windows application, it can run unmodified on Linux x86 platforms using the wine utility.

Wine is a compatibility layer which provides Win32 and associated runtime library calls so that the program thinks it is running on MS Windows, but the wine layer translates those into Linuxisms with really good performance.

More detail at http://www.winehq.org/

You may also like...

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.