machine type (C++ librairies) : i386 vs x86_64

2020-07-13 08:46发布

问题:

I have little understanding about the different machine architectures (32bits , 64bits,...). And because of that, I often have hard time when using C++ libraries on different machines, being stuck with the annoying "undefined symbols for architecture...".

I would be really happy if someone can explain to me why I get such confusing answers when I use the following commands on the same machine (a 2 years old mac with mountain Lion OS) . the man uname indicates

-m print the machine hardware name.

-p print the machine processor architecture name.

  • At a first look, I would say that -p is more relevant. So I run uname -p and I get:

i386 (which means 32bits If I am not wrong).

  • However for a library that I compiled on the same machine, running lipo -info lib_test.a returns:

input file lib_test.a is not a fat file

Non-fat file: lib_test.a is architecture: x86_64 (which means 64bits If I am not wrong)

  • The Latter is however more coherent with the return of uname -m which is

x86_64

回答1:

It's a Mac OS X oddity. All hardware that OS X for Intel has shipped on has been 64-bit and so has the operating system - however, it can be force run in 32-bit-only mode. It's capable of executing 64-bit and 32-bit binaries, unless run in 32-bit mode.

Most binaries (.dylib and executables) delivered on this platform are "fat" binaries, means they contain both a 32-bit Intel binary and a 64-bit Intel binary, and sometimes binaries for other architectures (Power PC) combined into one file. The system will automatically load the most suitable part of the binary.

Because the underlying compiler usually needs to run with different flags to generate binaries for different architectures, and even the platform #defines are different, making the compiler see different source code after pre-processing, the binary needs to be compiled once per platform separately and then combined using lipo utility. XCode can automate this process on your behalf.

While the system is capable of running different binaries, both 32-bit and 64-bit, their execution model is different and they cannot be combined in the same process address space. So if you have one library as 64-bit only and other as 32-bit only, you cannot use them together.