Can programs which are written in c++ run anywhere? - c++

I know that for running c++ on Windows you need to compile specifically for Windows and the same goes for linux and on...
But for example, if I'm compiling program for Windows written in native c++ I can run it on a freshly installed windows pc? I mean, without downloading visual c++ runtime libraries, etc, I can just compile it, let's say, reinstall windows on my computer, and run it without installing anything else?
(The question above using Windows as an example but the same thing can be done on freshly installed linux distro? e.g Ubuntu)
Thanks in advance.

The only answer is "it depends".
There are many ways that an OS can "run" a program, many ways a program can be build, and many way code can be assembled.
A program that uses only "standard libraries" and that links all libraries statically, does not need any other dependency (in the sense that all the code it need is in the binary itself or into OS libraries that -being part of the system itself- are already on the system).
But:
statically link the standard libraries (which are most likely present in all programs) will bloat the memory usage of many copy of the same code. That's the reason library are often linked dynamically, but this requires "installation" of those libraries as well
Programs that use only standard libraries can do only the things that are somehow "common" (or can be commonly represented) into all systems, thus loosing all the peculiarity that makes an OS different from another.
There are "platforms" that - by the nature of their peripherals - are not represented one into the other: a coffee machine has 12 keys and a textual 2 row x 20 col display. A PC has a mouse, a keyboard, and a display that can reach even 10'000 pixel of width, of millions of color each. A tablet has a touch surface that can seize multiple points at the same time.
Can you imagine a program running the same on all those three platform?

No. Often the libraries are different on different systems. If your program involves any GUI then you will definatly have OS specific code that won't run on other OSs.
If you write a C++ program targeting the g++ compiler without GUI code there may still be some OS specific code. But you should be able to port it with minimal effort.
If your program only uses stl and stdio, then it will probably be portable. For example, MS STL's ::c_str() function works a little different than the linux one.

For what it's worth, when using MinGW with static linkage to libc and libc++, It's very likely that your C++ application will work on any Windows system '95 and later, unless you specifically enabled functionality in the Windows API that isn't available, like NT features. All of my SDL applications compiled for Windows 7 (compiled in 32 bit of course) work fine on my '95 machine.
When deploying a Linux application, it's best to just supply the source plus a configure script or makefile. This will ensure that the user has valid dependencies for your application. You could deploy binaries to specific package managers if you wanted to though.

Yes, the standard libraries are everywhere. Just think about it, most of your programs that you get are writen in C/C++. Only dependencies come when you use some specified libraries like winsock etc, therefore some windows applications are unlikely to work on linux and vice versa.

Related

Using software libraries written for windows (using dlls) in linux

This is a possible duplicate to this question but the answer is not solving my problem...
I want to use third party software delivered by c++ headers, libraries (.lib) and dlls for a project. Because it will run on a BeagleBone, I am writing this project for Linux. Is there any proper way to link dlls for Linux applications?
Highly unlikely to ever work:
Windows uses a different file-format for executable files (and DLL's are essentially executable files - same for shared libraries in Linux). This means that relocation information and symbol linkage is different.
Even if you manage to load and relocate the DLL, you most likely will need many other DLL's (such as the compiler runtime and system runtime [kernel32.dll for example]) to actually run the application. And of course, those dependent files need to have a correct interface to work on Linux (see #3)
There's nothing stopping a Windows DLL from making system calls directly in the shared library - these won't work in Linux.
Your best choices are:
Request Linux versions from the supplier of those libraries. Depending on what the functionality is, it may or may not be an easy task for the supplier to produce alternatives for different architectures.
Run the application inside the WINE (WINdows Emulator) package.
Run a Windows virtual machine, and run the application inside that.
Write your own replacement libraries, or find others already available out there.

Is it possible to use same DLL for clients using both Windows and Linux

I am looking to create a C++ library that can be used by both Linux and Windows clients. The OS specific functionality will be hooked up by the client by implementing the interfaces provided by the library.
Is this possible to achieve? Do I need to recompile the C++ project again in linux.
P.S: I am using CodeBlocks IDE
The short answer is no, you still need to compile your library for each targetted platform -- however, assuming your code is written such that it is cross-platform, you can set up your build to target both Windows and Linux environments with little fuss. I do this now using CMake to generate both Visual Studio projects for Windows environments and Makefiles for Linux environments.
I'm pretty confident that Linux will not accept a .dll :) And yes, you will need to recompile. Unless you run windows as a virtual machine under linux which sort of preempts the question.
It certainly cannot be the same binary file: shared objects ELF format on Linux, DLL "PE" format on Windows. And dynamic loading has different semantics on both systems. See Levine's linker and loader book for details.
You could, if done carefully, have the same source code giving the two different files (the DLL on Windows, the dynamic shared object on Linux).
But you probably would need some conditional compilation tricks like #ifdef WINDOWS etc...
You might use libraries providing you a common abstraction for such things. For instance, both GTK/Glib and Qt have some mechanism giving a common abstraction of dynamically linked (or dynamically loaded - ie dlopen-ed) libraries.
You probably want to read the Program Library Howto (at least for Linux).

(C/C++) How to generate executable file that can run on both Windows and Linux?

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 a python program be run on a computer without Python? What about C/C++?

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.

The difference between a program in C++ developed under Windows and Linux

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.