Cross Win32 and Win64 applications - c++

I always had these questions in my mind before I start learning C++:
1- Could an application that is compiled on a x86 computer run on a x64 computer?
2- Could an application that is compiled on a x64 computer run on a x86 computer?
3- Is there any difference?
4- If 1 and 2 are yes, Then why some applications have different downloads for each os bits, and why some libs I got like lua52 has a x64 and x86 version which work on the specified os only and errors on different os?
EDIT:
5- Can I compile my applications in x86 if my os is x64?

Ok, let's try and address those points in turn
Yes, an x86 computer could cross compile to x64 code (this is a common practice). Also the x64 based operating system may have an emulation layer for running x86 code (This is what Windows does for backwards compatibility)
Yes, a x64 computer could cross compile to x86 code (also a common practice). In theory, a x86 based operating system could have an emulation layer for running x64 code (though I don't believe this is done in practice)
In the case of cross compilation, there'll be no difference between a x64 code compiled on an x64 computer vs the same code cross compiled on a x86 computer. If the x64 is running an emulation layer to run x86 code, then it'll be less efficient than running native x64 code. If you want to support x86 systems, then you'll have to provide an x86 version.
See (3) - It's generally better better to provide 'native' versions.
Yes. - see (1) and (2)

Related

How can we distribute compiled source code if it is specific to the hardware it was compiled on?

Suppose we take a compiled language, for example, C++. Now let's take an example Framework, suppose Qt. Qt has it's source code publically available and has the options for users to download the binary files and let users use their API. My question is however, when they compiled their code, it was compiled to their specific HardWare, Operating System, all that stuff. I understand how many Software Require recompilation for different types of Operating Systems (Including 32 vs 64bit) and offer multiple downloads on their website, however how does it not go even further to suggest it is also Hardware Specific and eventually result in the redistribution of compiled executes extremely frustrating to produce?
Code gets compiled to a target base CPU (e.g. 32-bit x86, x86_64, or ARM), but not necessarily a specific processor like the Core i9-10900K. By default, the compiler typically generates the code to run on the widest range of processors. And Intel and AMD guarantee forward compatibility for running that code on newer processors. Compilers often offer switches for optimizing to run on newer processors with new instruction sets, but you rarely do that since not all your customers have that config. Or perhaps you build your code twice (once for older processors, and an optimized build for newer processors).
There's also a concept called cross-compiling. That's where the compiler generates code for a completely different processor than it runs on. Such is the case when you build your iOS app on a Mac. The compiler itself is an x86_64 program, but it's generating ARM CPU instruction set to run on the iPhone.
Code gets compiled and linked with a certain set of OS APIs and external runtime libraries (including the C/C++ runtime). If you want your code to run on Windows 7 or Mac OSX Maverics, you wouldn't statically link to an API that only exists on Windows 10 or Mac OS Big Sur. The code would compile, but it wouldn't run on the older operating systems. Instead, you'd do a workaround or conditionally load the API if it is available. Microsoft and Apple provides the forward compatibility of providing those same runtime library APIs to be available on later OS releases.
Additionally Windows supports running 32-bit processes on 64-bit chips and OS. Mac can even emulate x86_64 on their new ARM based devices coming out later this year. But I digress.
As for Qt, they actually offer several pre-built configurations for their reference binary downloads. Because, at least on Windows, the MSVCRT (C-runtime APIs from Visual Studio) are closely tied to different compiler versions of Visual Studio. So they offer various downloads to match the configuration you want to build your your code for (32-bit, 64-bit, VS2017, VS2019, etc...). So when you put together a complete application with 3rd party dependencies, some of these build, linkage, and CPU/OS configs have to be accounted for.

Compiled dll not working on intel Atom 32bit

I am compiling a dll in visual studio 2017 c++.
SDK: 10.0.17134.0
this project uses a template, that automatically creates 2 dll, one for 32 bit and one for 64 bit. I do have two machines that run the same software but have different hardware and OS.
First machine has a intel i7 and runs windows embedded standard 64 bit
the second machine has a intel atom and runs windows embedded standard 32 bit
On the 64 bit machine, both dll work. (32 bit and 64 bit), on the atom the 32 bit does not work tough. I do not have any error messages, the only thing i get from the software is that it is not compatible without any additional clues. The software is the same on both systems so I assume that the problem is related to the OS or the processor.
the software I am developing for is a vision system by omron so it is nothing that is available online or that can be shared here.
What could be the cause for this? If you need additional information just ask.
Generally, in order for an executable file (either an .EXE program or a .DLL support module) built using the MSVC C/C++ compiler in Visual Studio 2015 or later, to work on a target PC, you need to have the latest VC++ Redistributable run-time libraries installed on that PC.
See also this discussion on Stack Overflow.

What makes a C++ program be 64-bit only or machine-restricted?

How do I know if the program I am writing in C++ will run properly in a 32-bit OS or not?
(without manually testing in one)
I am using Visual Studio and compiling in a 64-bit machine. Will that stop the program from working in other machines?
And what about the processor and Windows version? Will the binary be compatible with most Windows versions and processors, if the program just does a few simple things such as web requests and calculations, with a simple user interface?
My program doesn't have to be 64-bit. I would just like to create one binary that runs in most computers, like those I download every day on the Internet. How could I do that?
If you are building your code specifically for 64-bit Windows, you can't expect the binary to work on 32-bit Windows. That will require a separate build.
An executable compiled and linked for 64-bit will typically also require 64-bit libraries.
Use tools like the Dependency Walker to find out, if a given executable is refering to 32- or 64-bit libraries.
In Visual Studio, the "target platform" decides which CPU architecture you are targeting. It is perfectly feasible to create 64-bit executables on a 32-bit system, but you can't actually run them on such a machine.
You can do what's called cross-compiling i.e compiling on one machine for another. How to compile a 32-bit binary on a 64-bit linux machine with gcc/cmake This is what you're after if I read you correctly. There should be a Windows equivalent.

MS Visual Studio Professional 2013 - C++ Compile single executable for 32bit and 64bit operating systems?

Google gave me a clue that it is possible to compile code into a single executable that will run as 32bit on a 32bit OS and as 64bit on a 64bit OS. Is it really possible for the executable to determine its bitness at runtime?
In my case the target systems would be Windows 7 Professional x64 and Windows XP SP3 x86.
So what I read on various articles (I think there was even answers to similiar topics on SO) is that one has to go to the Soltuion's Configuration Manager (RMB onto Solution -> Configuration Manager) and set the Platform to Any CPU.
Now all of these articles described a setup for older MSVS or MSVC++ versions, but I think there are no major changes to the Configuration Manager in the 2013 RC version (which I have just recently installed).
In the Active Solution dropdown I do not have the option Any CPU, so I followed this recipe that I found on SO. Following this little guide fails in my case, I still do not have the option to select Any CPU when following step 5:
5) Make sure "Any CPU" is selected under New Platform. If there was
no Any CPU solution platform in step 3, then make sure the "Create
new solutions platform" checkbox is checked. Then click OK.
The dropdown items that are available to me are x64 and ARM (Win32 too but that is already added by default), I can not chose Any CPU.
Adding target platform x64 and compiling the executable works fine, the program is ran as 64bit on Windows 7 x64 but ofcourse it can not be run on the 32bit Windows XP machine.
How do I set the target platform to Any CPU in Microsoft Visual Studio Professional 2013 RC?
No it is absolutely not. You need to define separate executables.
The "Any CPU" dropdown is there to allow you to set compiler settings for more than one platform (e.g. a _DEBUG processor for x64 and Win32) You cannot actually build to that target.
AnyCPU refers to .Net programs, not C++. C++ must compile down to native, either x86 or x64. You could build 64 bit program and bundle it into your 32 program, extracting it at runtime. This technique is used by ProcessExplorer.
Perhaps not a true answer, but for MOST things, running 32-bit code on a 64-bit system works absolutely fine. Of course, it may run a little slower, but compared to having to deal with (and thoroughly test) two different binaries, unless it's significant performance benefits in 64-bit mode (or your application uses more than around 2GB of memory space), I'd be very tempted to use 32-bit mode.
MacOS supports something called "fat binaries", where the program is compiled twice and both versions are packed into a single file. The OS decides which version to actually launch.
Windows doesn't have anything like it.
You can compile the .NET wrapper (Any CPU) and the rest of program as yourprogram86.dll and yourprogram64.dll
[DllImport("yourprogram32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "open")]
public static extern void open32();
[DllImport("yourprogram64.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "open")]
public static extern void open64();
static bool Is64()
{
//.Net 4.0
//Environment.Is64BitOperatingSystem
//.Net 2.0
return IntPtr.Size == 8;
}
static void open()
{
if (Is64())
open64();
else
open32();
}

What must two computers have in common to run the same executable?

I am developing a cross-platform application and I need to determine whether machine B will be able to run the application that is compiled on machine A.
I am using Qt and I already understand that I need to either package the Qt libraries with the application or statically link against Qt itself.
I also understand that something compiled on Windows can't run on Linux.
However, there are still some other vectors that I'm not sure to what extent they matter. Here is the summary of my current understanding:
Affects Portability
Operating System (Windows, Mac, Linux)
Availability of third party libraries (Qt, static vs dynamic linking, etc)
May Affect Portability
Flavor of Linux (Ubuntu, Red Hat, Fedora)
Architecture (32 or 64-bit)
Version of Operating System (Windows 7 vs Windows XP, Rhel5 vs Rhel6)
Instruction type (i386, x64)
Of the May Affect Portability items, which ones actually do? Are there any that I am missing?
All. At least potentially.
If two different machines have no binary compatibility (e.g.
they run on different architectures, or interface to
incompatible systems), then it will be impossible to create
a single binary that will run on both. (Or... does running
a Windows program under Wine on Linux count?)
Otherwise, it depends. You mention third party libraries: if
they're dynamically loaded, they have to be there, but there's
always static linking, and there may be ways of deploying with
the dynamic library, so that it will be there.
The 32 bit vs. 64 bit is a difference in architectures: a 32 bit
program will not run in a 64 bit environment and vice versa.
But most modern systems will make both environments available
if they are on a 64 bit machine.
Issues like the flavor and version of the OS are more complex.
If you use any functions recently added to the OS, of course,
you won't be able to run on machines with an OS from before they
were added. Otherwise: the main reason why the low level system
libraries are dynamically loaded is to support forwards and
backwards compatibility; I've heard that it doesn't always work,
but I suspect that any problems involve some of the rarer
functions. (There are limits to this. Modern Windows programs
will not run under Windows95, and vice versa.)
There is also an issue as to whether various optional
packages are installed. Qt requires X Windows under Linux or
Solaris; I've worked on a lot of Linux and Solaris boxes where
it wasn't installed (and where there wasn't even a display
device).
And there is the issue whether it will run acceptably. It may
run on a smaller, older machine than the one on which you tested
it, but it could end up paging like crazy, to the point where it
becomes unusable.
If you compile an application on a 64-bit processor, it wouldn't by default run on a 32-bit processor. However, you can pass options to the compiler to have it compile code to run on a 32-bit processor. For example, if you're using GCC on a 64-bit machine, if you pass -m32, it will compile 32-bit code. 32-bit code by default can run on a 64-bit machine.
Sources
https://stackoverflow.com/a/3501880/193973
Different flavors of Linux or versions of operating systems may have different system libraries. For example, the GetModuleFileNameEx function is only available in Windows XP and up. As long as you watch what functions you use though, it shouldn't be too much of a problem.
The x64 architecture is backwards compatible with x86 ("32-bit"), so programs compiled for the x86 will run on x64 machines, but not vice versa. Note that there are other, less common architectures too, such as the ARM and PowerPC.
I can immediately think of three things that interfere with portability. But if your code is in a file format understood by both systems, an instruction set understood by both systems, and only makes system calls understood by both systems, then your code should probably run on both systems.
Executable File format
Windows understands PE, COFF, COM, PEF, .NET, and others
Linux by default ELF, OUT, and others
MaxOSX uses Mach-O
Linux has extensions to run the Windows/Mac formats too (Wine, Mono...)
Instruction set
Each processor is a little different, but
There is usually a "lowest common denominator" which can be targetted
Sometimes compilers will write code to do a function twice
one with the LCD set, one with a "faster" instruction set
and the code will pick the right one at runtime.
x64 can run 64bit and 32bit, but not 16bit.
x86 can run 32bit and 16bit, but no 64bit.
Operating System calls
Each OS usually has different calls
This can be avoided by using a dynamic library, instead of direct OS calls
Such as... the C runtime library.
Or the CLR for .Net.