Clang: Output a 32 AND 64 bit combination .dylib - macos

I've seen dylibs that are both 32 and 64 bit when performed the file command on. How do I go about building one in Clang?
The -m32 flag creates 32 bit dylib, -m64 makes 64 bit, but using both of them doesn't work.
Edit: For instance, here's the output of file on the type of dylib I'm trying to build
file /Library/Frameworks/SDL.framework/Versions/A/SDL
/Library/Frameworks/SDL.framework/Versions/A/SDL: Mach-O universal binary with 2 architectures
/Library/Frameworks/SDL.framework/Versions/A/SDL (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
/Library/Frameworks/SDL.framework/Versions/A/SDL (for architecture i386): Mach-O dynamically linked shared library i386

You can either use the -arch argument multiple times for each architecture you want, e.g.
cc -arch i386 -arch x86_64 ...
or create multiple binaries, then glue them together with lipo:
lipo -create -arch i386 my32bitbinary -arch x86_64 my64bitbinary -output myfatbinary

Related

Creating a universal binary using Intel compiler

In MacOSX, gcc command line accepts multiarchitecture options:
gcc -arch i386 -arch x86_64 etc.
... and creates a universal binary by compiling and linking for both archs and running lipo for gluing them together.
However using this command line with Intel, produces a compiler warning:
command line warning #10121: overriding '-arch i386' with '-arch x86_64'
Am I doing something wrong or is this a compiler limitation?
I couldn't find anything about it in the Intel developer zone.

Error when making dynamic lib from .o

I'm trying to make dynamic lib from set of .o files, but when i do
gcc -dynamiclib -current_version 1.0 mymod.o -o mylib.dylib
or
ld *.o -o mylib.dylib
i get a lot of errors like:
"_objc_msgSend", referenced from:
-[NSObject(NSObject_SBJSON) JSONFragment] in NSObject+SBJSON.o
"operator new(unsigned long)", referenced from:
MStatistic::instance() in MStatistic.o
StatisticProfileLoggingObserver::instance() in StatisticObserver.o
ld: symbol(s) not found for architecture x86_64
Can you please help me, how to solve it and get my .dylib?
You can pass -undefined dynamic_lookup as an option to ld, or:
-Wl,-undefined -Wl,dynamic_lookup to gcc or clang (which passes it to the linker).
From this line:
ld: symbol(s) not found for architecture x86_64
it sounds like you are building some libraries that have make files that only build for 32-bit architectures.
You need to modify the makefiles for all the libraries / frameworks you're building to build both 32-bit and 64-bit; and in a practical sense, all shipping MacOS machines are 64-bit capable so it may just be safe to build only for 64-bit.
In your compile / linking lines, add something like this: "-arch x86_64" and that should compile things for the 64-bit side. To do both 32 & 64-bit, you'll basically need to duplicate the compile & link lines with their own "-arch i386" and "-arch x86_64" lines.

How do I suppress '-arch', 'x86_64' flags when compiling an OpenGL/SDL application with Waf on OSX?

I need to suppress "-arch x86_64 -arch i386" flags Waf is passing to GCC.
I am building an SDL/Opengl application. If I link against 32 bit SDL runtime I get error
Undefined symbols for architecture i386:
"_SDL_Quit", referenced from:
__del_video in SDL_functions.c.2.o
__init_video in SDL_functions.c.2.o
If I link against 64 bit SDL runtime, I get error "Undefined symbols for architecture x86_64"
The compiler is apparently using flags
-arch x86_64 -arch i386
I understand that this causes GCC on OSX to try to compile for both architectures. I want to either compile for 64 bit, or compile for 32 bit. How do I suppress the flags for one architecture?
I found out in my case that the double arch flags were originating here, specifically from distutils.sysconfig.get_config_var('LDFLAGS'). This returns the LDFLAGS that Python thinks you should link Python modules with. In my case, file $(which python) is a "Mach-O universal binary with 2 architectures", so Python thinks you should link with -arch x86_64 -arch i386 -Wl,F.
My problem was that I was building a Python native module that needed to link against Python and another library which was not built with both arches. When building my module with both arches, linking failed with "symbols not found", because both arches were not available in the third-party library.
Since waf unfortunately doesn't allow you to override its computed flags with your own flags, as Automake does, I could only fix this by messing directly with my ctx() object in my wscript:
for var in ['CFLAGS_PYEMBED', 'CFLAGS_PYEXT', 'CXXFLAGS_PYEMBED',
'CXXFLAGS_PYEXT', 'LINKFLAGS_PYEMBED', 'LINKFLAGS_PYEXT']:
newvar = []
for ix, arg in enumerate(ctx.env[var]):
if '-arch' not in (arg, ctx.env[var][ix - 1]):
newvar.append(arg)
ctx.env[var] = newvar
(This removes all -arch flags and their arguments from the relevant variables. Since I was also passing my own -arch flag in my CFLAGS, it now does not get overridden.)
I don't know of a way to issue a command/flag to suppress other flags. However, to compile for only 64 or 32 bits, you can use -m64 or -m32, respectively. Since you're compiling for both architectures, -m32 might be your only option because -m64 won't work for i386.

Building gcc 4.5.2 on snow leopard fails linking with unsupported file format

I'm working on OS X 10.6.6 to build a gcc cross-compiler and gnu java for an embedded system. gcc native and cross need to be the same version, so I want to get everything up to the latest gcc version. After building gmp, mpfr, mpc, and binutils with no problem, building native gcc is failing with what I think is the first link step. The specific step that fails is:
fixincludes$ gcc -g -O2 -o fixincl fixincl.o fixtests.o fixfixes.o server.o procopen.o fixlib.o fixopts.o ../libiberty/libiberty.a
ld: warning: in ../libiberty/libiberty.a, file was built for unsupported file format which is not the architecture being linked (x86_64)
Lots of undefined symbol errors follow this warning. libiberty.a and the .o files appear to be the same architecture:
fixincludes$ lipo -info ../libiberty/libiberty.a input file ../libiberty/libiberty.a is not a fat file
Non-fat file: ../libiberty/libiberty.a is architecture: x86_64
fixincludes$ lipo -info *.o
Non-fat file: fixfixes.o is architecture: x86_64
Non-fat file: fixincl.o is architecture: x86_64
Non-fat file: fixlib.o is architecture: x86_64
Non-fat file: fixopts.o is architecture: x86_64
Non-fat file: fixtests.o is architecture: x86_64
Non-fat file: procopen.o is architecture: x86_64
Non-fat file: server.o is architecture: x86_64
I suspect this has to do with 32-bit vs 64-bit, but I don't know what else to check and can't find a specific solution anywhere. Can anyone tell me what's going on here or just nudge me in the right direction?

g++ on MacOSX doesn't work with -arch ppc64

I am trying to build a Universal binary on MacOSX with g++. However, it doesn't really work. I have tried with this simple dummy code:
#include <iostream>
using namespace std;
int main() {
cout << "Hello" << endl;
}
This works fine:
% g++ test.cpp -arch i386 -arch ppc -arch x86_64 -o test
% file test
test: Mach-O universal binary with 3 architectures
test (for architecture i386): Mach-O executable i386
test (for architecture ppc7400): Mach-O executable ppc
test (for architecture x86_64): Mach-O 64-bit executable x86_64
However, this does not:
% g++ test.cpp -arch i386 -arch ppc -arch x86_64 -arch ppc64 -o test
In file included from test.cpp:1:
/usr/include/c++/4.2.1/iostream:44:28: error: bits/c++config.h: No such file or directory
In file included from /usr/include/c++/4.2.1/ios:43,
from /usr/include/c++/4.2.1/ostream:45,
from /usr/include/c++/4.2.1/iostream:45,
from test.cpp:1:
/usr/include/c++/4.2.1/iosfwd:45:29: error: bits/c++locale.h: No such file or directory
/usr/include/c++/4.2.1/iosfwd:46:25: error: bits/c++io.h: No such file or directory
In file included from /usr/include/c++/4.2.1/bits/ios_base.h:45,
from /usr/include/c++/4.2.1/ios:48,
from /usr/include/c++/4.2.1/ostream:45,
from /usr/include/c++/4.2.1/iostream:45,
from test.cpp:1:
/usr/include/c++/4.2.1/ext/atomicity.h:39:23: error: bits/gthr.h: No such file or directory
/usr/include/c++/4.2.1/ext/atomicity.h:40:30: error: bits/atomic_word.h: No such file or directory
...
Any idea why that is?
I am on MacOSX 10.6. I have installed Xcode 3.2.2 with all SDKs it comes with. GCC 4.2 is the default. GCC 4.0 produces some different errors, though behaves similar.
ppc64 support was dropped in Snow Leopard. You can still use ppc64 if you build and link against the Mac OS X 10.5 SDK.
Try the following command at the command line:
g++ test.cpp -arch i386 -arch ppc -arch x86_64 -arch ppc64 -mmacosx-version-min=10.5 -isysroot/Developer/SDKs/MacOSX10.5.sdk -DMACOSX_DEPLOYMENT_TARGET=10.5 -o test
Or for the 10.4 SDK use:
g++-4.0 test.cpp -arch i386 -arch ppc -arch x86_64 -arch ppc64 -mmacosx-version-min=10.4 -isysroot/Developer/SDKs/MacOSX10.4u.sdk -DMACOSX_DEPLOYMENT_TARGET=10.4 -o test
Note, if you want to use the 10.4 SDK, you will have to use gcc 4.0 (or g++4.0 ). Apple's GCC 4.2 doesn't support the 10.4 SDK.

Resources