Build Mapnik 'Fat' (universal/64bit on mac osx) #160

Closed
artemp opened this Issue Oct 11, 2011 · 8 comments

Projects

None yet

2 participants

@artemp
Mapnik member

Patching Sconscript to do this would be great.

I've yet to rebuild my boost and other lib dependencies universal, so I can't link mapnik properly yet.

But the below snippet is a start to adding some of the needed compiler flags:

{{{
UNIVERSAL = True

def DarwinDevSdk():
import platform

devpath = { "4" : "/Developer/SDKs/MacOSX10.4u.sdk", "5" : "/Developer/SDKs/MacOSX10.5.sdk" }
version = platform.mac_ver()[0].split(".")
if version[0] != '10' or int(version[1]) < 4:
print "Only Mac OS X >= 10.4 is supported"
env.Exit(1)
return devpath[version[1]]

Mac OSX (Darwin) special settings

if env['PLATFORM'] == 'Darwin':
pthread = ''
# Getting the macintosh version number, sticking as a compiler macro
# for Leopard -- needed because different workarounds are needed than
# for Tiger.
if platform.mac_ver()[0].startswith('10.5'):
common_cxx_flags += '-DOSX_LEOPARD '
if UNIVERSAL:
flags = []
uniarch = ["ppc", "i386","ppc64", "x86_64"]
for i in uniarch:
flags += ['-arch', i]
ppflags = flags + ['-isysroot' , DarwinDevSdk() ]
linkflags = flags + ['-Wl,-syslibroot,%s' % DarwinDevSdk()]
env.Append(CXXFLAGS=ppflags)
env.AppendUnique(FORTRANFLAGS=ppflags)
env.AppendUnique(SHFORTRANFLAGS=ppflags)
env.Append(SHLINKFLAGS=linkflags)
env.Append(LINKFLAGS=linkflags)

else:
pthread = '-pthread'
}}}

I may not get to a patch any time soon, so consider this ticket just a stub unless someone is keen on working on it.

Below is where scons bails during linking and hints at all my libraries that are not universal:

{{{
g++ -o src/libmapnik.dylib -Wl,-install_name,libmapnik.dylib -dynamiclib -arch ppc -arch i386 -arch ppc64 -arch x86_64 -Wl,-syslibroot,/Developer/SDKs/MacOSX10.5.sdk src/agg_renderer.os src/datasource_cache.os src/envelope.os src/filter_factory.os src/font_engine_freetype.os src/font_set.os src/graphics.os src/image_reader.os src/image_util.os src/layer.os src/line_pattern_symbolizer.os src/map.os src/load_map.os src/memory.os src/params.os src/placement_finder.os src/plugin.os src/png_reader.os src/point_symbolizer.os src/polygon_pattern_symbolizer.os src/save_map.os src/shield_symbolizer.os src/text_symbolizer.os src/tiff_reader.os src/wkb.os src/projection.os src/proj_transform.os src/distance.os src/scale_denominator.os src/memory_datasource.os src/stroke.os src/symbolizer.os src/arrow.os src/unicode.os src/libxml2_loader.os -Lagg -Lsrc -L/usr/lib -L/usr/local/pgsql/lib -L/usr/local/lib -L/opt/local/lib -lagg -lfreetype -lxml2 -lz -lpthread -liconv -lm -lm -lltdl -lpng -ltiff -lz -ljpeg -lproj -lpq -licuuc -licudata -lgdal -lboost_system-mt -lboost_filesystem-mt -lboost_regex-mt -lboost_iostreams-mt -lboost_program_options-mt -lboost_thread-mt -liconv
ld: warning in agg/libagg.a, file is not of required architecture
ld: warning in /opt/local/lib/libfreetype.dylib, file is not of required architecture
ld: warning in /opt/local/lib/libpng.dylib, file is not of required architecture
ld: warning in /opt/local/lib/libtiff.dylib, file is not of required architecture
ld: warning in /opt/local/lib/libjpeg.dylib, file is not of required architecture
ld: warning in /Developer/SDKs/MacOSX10.5.sdk/usr/local/lib/libproj.dylib, file is not of required architecture
ld: warning in /opt/local/lib/libicuuc.dylib, file is not of required architecture
ld: warning in /opt/local/lib/libicudata.dylib, file is not of required architecture
ld: warning in /Developer/SDKs/MacOSX10.5.sdk/usr/local/lib/libgdal.dylib, file is not of required architecture
ld: warning in /opt/local/lib/libboost_system-mt.dylib, file is not of required architecture
ld: warning in /opt/local/lib/libboost_filesystem-mt.dylib, file is not of required architecture
ld: warning in /opt/local/lib/libboost_regex-mt.dylib, file is not of required architecture
ld: warning in /opt/local/lib/libboost_iostreams-mt.dylib, file is not of required architecture
ld: warning in /opt/local/lib/libboost_program_options-mt.dylib, file is not of required architecture
ld: warning in /opt/local/lib/libboost_thread-mt.dylib, file is not of required architecture
Undefined symbols:
"_jpeg_destroy_compress", referenced from:
}}}
[..snip pages of boost errors...]

@artemp
Mapnik member

[springmeyer] Looks like boost can now do universal on osx: https://svn.boost.org/trac/boost/changeset/41592

@artemp
Mapnik member

[springmeyer] looks like this may do it for boost:

{{{
bjam --toolset=darwin \
--with-thread --with-filesystem --with-iostreams \
--with-regex --with-program_options --with-python \
--with-system stage \
--architecture=x86 --address-model=64
}}}

{{{
springmeyer:boost_1_37_0 spring$ file stage/lib/libboost_system-xgcc40-mt.dylibstage/lib/libboost_system-xgcc40-mt.dylib: Mach-O 64-bit dynamically linked shared library x86_64
}}}

@artemp
Mapnik member

[springmeyer] bjam --toolset=darwin \
--with-thread --with-filesystem --with-iostreams \
--with-regex --with-program_options --with-python \
--architecture=x86 --address-model=64 \
--with-system stage

sudo bjam --toolset=darwin \
--with-thread --with-filesystem --with-iostreams \
--with-regex --with-program_options --with-python \
--architecture=x86 --address-model=64 \
--with-system install

@artemp
Mapnik member

[springmeyer] BTW, for anyone interested... once all mapnik dependencies can be built universal, lipo is the tool to use to build a 32bit and 64bit version of mapnik and then you combine them into a fat binary.

However, for the time being I've halted working on this since one motivation on mac os towards being able to run 64bit is to be able to run mapnik within a mod_wsgi or mod_python apache process (since the leopard provided apache runs 64bit on intel machines).

If you try this you'll get an error such as:
{{{
#!sh
[error] [client ::1] File "/Library/Python/2.5/site-packages/mapnik/init.py", line 31, in \n from _mapnik import *
[error] [client ::1] ImportError: dlopen(/Library/Python/2.5/site-packages/mapnik/_mapnik.so, 10): no suitable image found. Did find:\n\t/Library/Python/2.5/site-packages/mapnik/_mapnik.so: mach-o, but wrong architecture
[info] removed PID file /private/var/run/httpd.pid (pid=50678)
}}}

But the easiest solution (rather than actually building mapnik 64bit on os x) is to kick apache into 32bit mode:

{{{
#!sh
sudo apachectl stop
sudo mv /usr/sbin/httpd /usr/sbin/httpd.bkp
sudo lipo -thin i386 /usr/sbin/httpd.bkp -output /usr/sbin/httpd.i386
sudo ln -s /usr/sbin/httpd.i386 /usr/sbin/httpd
sudo apachectl start
}}}

@artemp
Mapnik member

[springmeyer] if anyone is following along, if your dependencies are also built multi-arch, then this alone will work for compiling Mapnik both 32/64 bit on intel:

{{{
python scons/scons.py CXX='g++ -arch i386 -arch x86_64'
}}}

  • Note: add '-arch ppc' or ='arch ppc64' if you want powerpc arch's
@artemp
Mapnik member

[springmeyer] and for multi-arch boost do:

{{{
bjam address-model=32_64 architecture=x86 ....
}}}

  • note: 'architecture=combined' will give you ppc arch's
@springmeyer
Mapnik member

only 64 matters now, closing.

@springmeyer springmeyer closed this Sep 6, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment