As we know java is a platform independent language due to JVM it's program can run at any OS.
What about C/C++? could C/C++ exe run at any OS ? Could we have done something about this(Like write once run anywhere)? please clear my doubt about this.
Thanks
No - an executable is built for a specific operating system and hardware (CPU) architecture.
If you are carefull not to use any OS specific functions, or any assumptions about word size etc, then c++ source can be recompiled to run anywhere.
C and C++ are traditionally transformed into machine code for a particular CPU type/family, and packed within a format that a particular operating system can start.
There's nothing stopping anyone from making a C or C++ compiler that compiles code to run on a virtual machine in the same sense that java source code is compiled to byte code intended to run on the jvm. Someone
(The usefulness of doing so is another matter though, and e.g. while it's quite far from standard C++, C++/.CLI compiles a C++ like language to run on .NET)
Theorically, C programs only need a compiler that produce executable binaries for the target platform. That's why C is used in almost any embedded platform.
Practically, that require a separate compilation for each target platform.
C++ is another beast, clearly more complex and rich of features. Depending on the platform, you might or not have a compiler for C++, and if you have, embedded platform often require (for often non-obvious and sometimes critiquables reasons) that some C++ features are deactivated.
So with C++ you still "can" compile for any target platform, because it is a system programming language, like C (meaning that you're "close to the metal" with those languages).
However, there are still some problems you have to solve if you want to target some platforms :
some platform constructors will not allow you to run binaries on their platforms, only to sue their "secured" virtual-machine based language (whatever it is);
some platform constructors will provide compilers for their platforms, but with limited features, making them too poor to use for industrial developpement;
So theorically, C and C++ can run anywhere, if you compile for the target and that you use only cross-platform code/library.
In practice, it depends on the context.
Executable programs are platform and OS dependent. There are emulators in some OS that allows to run executables of other platforms (such as wine, dosbox etc. and of course VMWare) but this is an emulation/virtualization only.
Each operating system has it's own executable format, so you have to compile your C(++) program separately for each OS. If you use cross platform libraries, you can easily recompile your program without having to change your code a lot.
Related
I want to detect which operating system my .exe is being run on, so that I could perform specific operations depending on the underlying operating system. I want it to be just for windows and mac.
I want to detect which operating system my .exe is being run on
(notice that on MacOSX executable files are traditionally not suffixed with .exe; that convention is specific to Windows)
You cannot detect that in pure standard C++11 at runtime (so your question makes technically no sense), because the C++11 standard n3337 does not know about operating systems (some C++ source code may be compiled for the bare metal). I would recommend conditional compilation (e.g. #if) and using operating system specific headers (and configuring your build automation to detect them). Some C++ frameworks (boost, poco, Qt....) could be helpful, but you need to decide to choose one (they might try to provide some common abstractions above several OSes, but the evil is still in the details, e.g. file paths are still different on Windows and on MacOSX).
MicroSoft Windows has its own API, called WinAPI (which is only, in practice, used by Windows. Perhaps some day ReactOS would implement most of that API), documented here. MacOSX is more or less conforming to POSIX, which is a standard API about a family of OSes (but Windows don't care much about that standard).
If you want to learn more about OSes in general (a sensible thing to do), read for example Operating Systems: Three Easy Pieces (freely downloadable textbook).
In practice, an executable file compiled from C++ source code is specific to the operating system it is designed to run on, and its file format is also specific to some OS (e.g. PE on Windows, ELF on Linux, Mach-O on MacOSX...). So a Windows executable won't run on MacOSX and vice versa (the fat binary idea is out of fashion in 2018). You probably would adjust your build procedure (e.g. your Makefile, or with cmake, ninja, etc...) for your OS. That build procedure might (and often does) pass extra compilation flags (e.g. some -DBUILD_FOR_MACOSX compiler flag for your preprocessor, if building for MacOSX; then you might -in few places- use some preprocessor directive like #if BUILD_FOR_MACOSX in your C++ source code) specific to the target operating system. You could even customize your build so that on MacOSX some for-macosx.cc C++ file is compiled (and its object file linked into) your software, but on Windows you'll use some other for_windows.cc C++ file. Sometimes, the build procedure is flexible enough to auto-detect at build time what is the operating system (but how to do that is a different question. The GNU autoconf could be inspirational).
Once your build procedure has been configured for (or has auto-detected) your operating system, you could use preprocessor conditional facilities to #include appropriate system-specific headers and to compile calls to OS specific functions (such as POSIX uname) querying further at runtime about the OS.
Some compilers predefine a set of preprocessor symbols, and that set depends upon the target operating system and processor and of your compiler. If you use GCC, you might create some empty file empty.cc and compile it with g++ -c -C -E -dM (perhaps also with other relevant flags, e.g. -std=c++11) to find out which set of preprocessor symbols are predefined in your case.
Consider studying the source code (including the build procedure!) of some cross-platform free software projects (e.g. on github or somewhere else) for inspiration. You can also find many resources about multi-platform C++ builds (e.g. this one and many others).
There are various ways you could do it, like testing for the presence of a C:\Windows directory to detect Windows (edit: if the OS accepts a path like that at all then it's at least part of the DOS family), but none of them are foolproof. Here's one way (although it's cheating):
#include<boost/predef.h>
enum class OperatingSystem {
// ...
Windows
// ...
};
OperatingSystem DetectOperatingSystem()
{
#ifdef BOOST_OS_WINDOWS
return OperatingSystem::Windows;
#endif
}
Also, if you just want a name to show the user, then on POSIX systems you can use uname(2).
To solve this kind of problem you would need to check both at compile time and at run time. You are going to need different code for different both systems. You are going to need Windoze code to check the Windoze version and Mac code to check the Mac version.
You are going to have to use
#if defined ()
at compile time to check which of the two you are on. Then have separate code for each to get the version.
Okay so I know that there are multiple c++ versions. And I dont really know much about the differences between them but my question is:
Lets say i made a c++ application in c++ 11 and sent it off to another computer would it come up with errors from other versions of c++ or will it automatically detect it and run with that version? Or am I getting this wrong and is it defined at compile time? Someone please tell me because I am yet to find a single answer to my question on google.
It depends if you copy the source code to the other machine, and compile it there, or if you compile it on your machine and send the resulting binary to the other computer.
C++ is translated by the compiler to machine code, which runs directly on the processor. Any computer with a compatible processor will understand the machine code, but there is more than that. The program needs to interface with a filesystem, graphic adapters, and so on. This part is typically handled by the operating system, in different ways of course. Even if some of this is abstracted by C++ libraries, the calls to the operating system are different, and specific to it.
A compiled binary for ubuntu will not run on windows, for example, even if both computers have the same processor and hardware.
If you copy the source code to the other machine, and compile it there (or use a cross-compiler), your program should compile and run fine, if you don't use OS-specific features.
The C++ version does matter for compilation, you need a C++11 capable compiler of course if you have C++11 source code, but once the program is compiled, it does not matter any more.
C++ is compiled to machine code, which is then runnable on any computer having that architecture e.g. i386 or x64 (putting processor features like SSE etc. aside).
For Java, to bring a counterexample, it is different. There the code is compiled to a bytecode format, that is machine independent. This bytecodeformat is read/understood by the Java Virtual Machine (JVM). The JVM then has to be available for your architecture and the correct version has to be installed.
Or am I getting this wrong and is it defined at compile time?
This is precisely the idea: The code is compiled, and after that the language version is almost irrelevant. The only possible pitfall would be if a newer C++ version would include a breaking change to the standard C++ library (the library, not the language itself!). However, since the vast majority of that library is template code, it's compiled along with your own code anyway. It's basically baked into your .exe file along with your own code, so it's just as portable as yours. Also, both the C and C++ designers take great care not to break old code; so you can expect even those parts that are provided by the system itself (the standard C library) not to break anything.
So, even though there are things that could break in theory, pure C++ code should run fine on all machines that understand the same .exe format as the machine it was compiled on.
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.
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.
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.
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...
Either you can actually install C compilers on both windows and linux(unix) and then compile your code on both of them.
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/
Can I create a Python program, send it to a remote computer, and run it there without that computer having Python installed? I've heard that you cannot, as Python needs to be interpreted. If this is true, then it seems very odd as it would be hard to distribute your program unless everyone decides to install Python.
Also, what about C and C++? Can they be run on a remote computer without having the language installed? (I think you can, as it is a compiled language).
I'm not exactly sure and would like clarification.
EDIT:
I'm getting some mixed answers on this and am not sure where to go. I see that I can include the Python library in the program and I can use py2exe.
However, I'm confused on C and C++. Do I have to include their libraries in the program? Can they only be run on certain machines? Does the compiler allow it to run on all machines?
Look at py2exe and py2app for Windows and Mac. Macs running OSX and most modern Linuces have Python installed, however.
C/C++ apps are normally compiled to executables which work on one machine/OS architecture (e.g. 32-bit Windows, or 64-bit OSX); such an executable can run on some but not all machines. For example, 64-bit Windows or OSX can run programs built either for the 32-bit or 64-bit flavor of their respective OSes.
python is interpreted, so it won't run without python. However, that doesn't mean that python has to be installed, you can include a copy in your program directory or even bundle your program and the python runtime into a single file.
C and C++ compilers toolchains generate machine code (in most cases, C interpreters do exist, as do C and C++ -> p-code and bytecode compilers). But most C and C++ programs use shared libraries, and will not run unless the shared library is present (again, doesn't have to be installed, can be placed in the program directory). There's also usually a build option (static linking) to include all necessary libraries in the main program file.
But the result is still limited to a particular combination of OS and CPU architecture. Getting a program to run on more than a single platform always requires platform-specific runtime support.
You can use py2exe for distributing Python programs to Windows.
http://www.py2exe.org/
If a you have written a program in any language, and that program is not compiled to machine code, something on the user's computer must convert it to machine code before it can be run.
In the case of JavaScript, that "something" is often a web browser. In the case of Python, that is often a stand-alone interpreter, though it is possible to compile it:
Is it feasible to compile Python to machine code?
However, to be clear: just because your program is not compiled to imachine code does not mean that it will be interpreted. Programs written in C# are usually compiled to MSIL, which is compiled to machine code the first time the program is run. Java programs are also compiled when they are first run.
I will give a practical application of sending code to a remote machine to run. This is typically done in the BOINC project, a community GRID computing initiative which has produced gems such as SETI#Home. The applications typically are compiled C++ versions with multi-platform binaries for x86-linux, AMD64-linux, win32, win64 and Mac OS Universal Binaries (with ppc,x86 and 64-bit). This is a lot of variety for distribution, but a modern make system can easily automate all that (e.g. CMake).
A lot of people prefer the WORA method (write once run anywhere) and stick with VM based language like Java or Python. In this case the boinc projects distribute a version of the VM as well as the code to run on it. Java VM's being encumbered with licensing issues, Python VM is much nicer. Boinc is attempting to embed the Python VM in various BOINC clients to make the distribution of Python based GRID applications easier.
I hope this gives you an idea about application distribution and helps you make an informed decision.
There is a py2exe that can produce an executable that will run on another computer without that user installing the normal Python package.
Yes, C and C++ are (at least normally) implemented as compilers that can produce standalone executables.
Edit: In a typical case, a C or C++ implementation will link the functions from the standard library that are used in the program into the executable. This can (and often does) include quite a bit that's not used directly, but still doesn't normally include (anywhere close to) the entire standard library.
In most cases you can also produce an executable that depends on an implementation of the standard library already being present on the target machine in the form of a shared library, DLL, etc. (different OSes use different names). This reduces the size of the executable, but increases the headaches involved in distribution; I use it for code I'm compiling on my own machine, but generally avoid it when/if I'm distributing an executable to anybody else. Given current hard drive prices, the savings in disk space is rarely worth the headache.
Look into Pyinstaller for standalone executables with no python integration needed. Well, apart from the crucial libraries so it can run!
It's recently updated, well maintained and even supports cython integration though that can get complex. You can compress the files to be smaller or if you have multiple executables, you can link them to one file to reduce size.
You can also of course create a single executable with python installed. Don't use anaconda though (use default python 3.6) to ensure your program is very small in size.
Hope this helps.
What's the difference between a program developed in C++ under Windows and Linux?
Why can't a program developed under Windows in C++ be used under Linux?
Windows and Linux use different container formats to hold the executable code (PE vs ELF).
Windows and Linux have completely different APIs (except for trivial programs that only use the CRT and STL)
Windows and Linux have a completely different directory structure
You could write a program that can use either set of APIs (for example, using Qt), and that can handle either directory structure, but you still won't be able to run the same file on both operating systems because of the differing container formats.
This can be solved by using Wine.
Native programs are not compatible because Windows has a completely different set of API's than Linux, for one. As others have mentioned, each platform uses a different executable format as well. Also both platforms have their own set of libraries that programs will be linked against and/or share. For example, a Windows program will typically be developed in Visual Studio using windows-specific libraries such as MFC, Win32 API, etc. These libraries are not available in linux, so the program will not even compile unless care is taken to make sure cross-platform libraries (such as QT) are used.
If you are careful, however, you can use cross-platform libraries in your code and you can get the same program to compile under both platforms. For such a program you would need to carefully put any platform-specific details (file system locations, etc) in their own files. Then, you would need to setup the proper #define statements and/or makefile directives to ensure the proper files are included in the build for each platform.
Of course, if you use a "cross-platform" language such as Java or Python, and do not use any platform-specific code in your implementation, then your program can run under both environments.
Note Although the executable formats are different, some programs developed on Windows can be executed under Linux using an emulator called WINE.
In a nutshell,
Windows runs PE format executables
Linux runs ELF format executables
Furthermore, even if there were a tool to convert between PE and ELF, the program instructions necessary to interface with the operating system are completely different between Windows and Linux. Only the most restricted computation-only code (that only does calculations and doesn't interact with the operating system at all) could be ported between systems without special action. However, this is rarely done.
I believe some versions of Linux allow you to directly load device drivers designed for Windows without recompiling. However, this is an extremely special purpose application and the technique is not generally used.
Each operating system defines an API. If you code to call the Win32 API, it won't be there on Linux. If you code to the POSIX API, it won't jump right out at you in Windows.
To learn more about this, download a significant open source program (for example, Perl or Python) and see how its 'configure' script makes arrangements to compile in either place.
When a C++ program is compiled on a platform, it ultimately changes into a form that machine can understand (i.e. Machine code). Under the hood, the program uses system calls to perform privileged action. These system calls are implemented via methods or APIs. These methods differ from platform to platform. Hence on every platform, the compiled code is different. There are many cross-compilers available if you want to compile your code for a different platform.
Not to be overly pedantic, but developing a program is different than building it and executing it. In many cases, a program written on one operating system can be built and compiled to execute on another. Other programs, as others have pointed out, rely on certain functionality provided only by a particular OS or libraries resident only on that OS. As a result, it must be built and run on that OS.
C++ is itself portable. But some C++ libraries are not. If a C++ program uses some libraries, which are not portable, then this program is not portable.
For example, a C++ program uses MFC to draw the GUI stuff, because MFC is supported only in Windows, so this C++ program cannot be compiled or run on Linux directly.
There are two major reasons.
Theoretically, the same program (source code) for some languages like C, can run on both Windows and Linux. But the compilation only differs; this means you have to compile the same source code file for each platform.
But actually, each operating system has a different set of APIs. And different techniques to get job done faster... Which usually attract developers to use them. And they don't stick to standards, so they lose portability.
This was for native programs... Anyway, there are the Java and Python languages... They are truly cross-platform, but you have to sacrifice speed for sake of portability.
This is a large topic.
First, Windows and Linux aren't binary comparable. This means that even the simplest of programs will not be recognized from one machine to the other. This is why interpreted languages like PHP, Perl, Python and Java are becoming so popular, but even these don't all support the same set of features on each platform.
Library dependence / OS support: Any significantly complicated program will need to access the system is some way, and many of the features available on one system are not available on the other. There are a million examples; just look on so for the Linux equivalent of blank or Windows equivalent of blank. Moving beyond OS support applications are built mostly on top of libraries of functions and some of those are just not available on both systems.