mapbox / mapbox-gl-native

Interactive, thoroughly customizable maps in native Android, iOS, macOS, Node.js, and Qt applications, powered by vector tiles and OpenGL
https://mapbox.com/mobile
Other
4.38k stars 1.32k forks source link

build broken on Xcode 6.0b5 / iOS 8 #409

Closed incanus closed 10 years ago

incanus commented 10 years ago
Undefined symbols for architecture x86_64:
  "_alphasort$INODE64", referenced from:
      _uv__fs_work in libuv.a(libuv_la-fs.o)
  "_scandir$INODE64", referenced from:
      _uv__fs_work in libuv.a(libuv_la-fs.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Seems restricted to libuv.

/cc @springmeyer

incanus commented 10 years ago

Using:

$ xcode-select -p
/Applications/Xcode6-Beta5.app/Contents/Developer

Did a make clean; make distclean; make setup. This yields success for an OS X build & run, but doesn't work on any iOS version.

springmeyer commented 10 years ago

We don't yet build for the 64 bit simulator - perhaps that is the problem? Or is this linking error for the device? Can you workaround by using a 32 bit sim?

whilethis commented 10 years ago

The above error is with building for the 64-bit simulator. I don't have an iPad Air, so I can't test if it is the same issue on a device.

This isn't holding up development at the moment, but may hold me up once I need to start testing on multiple devices.

whilethis commented 10 years ago

I forgot to add that I'm building and linking against the provided static library. I'm not building from source.

incanus commented 10 years ago

Yep, changing the build architectures for both of the generated Xcode projects (mapboxgl-ios and mapboxgl-app) to just armv7 armv7s i386 and dropping arm64 seems to build fine.

incanus commented 10 years ago

Strange that going back and building with arm64 under Xcode 5 works fine again, though.

incanus commented 10 years ago

Trying this on 10.10 with Xcode 6.0b5, too.

I should note that above, I didn't do a clean command-line build, just opened Xcode and did a clean & build there. So that would mean the mapnik-packaging stuff like libuv didn't change between the two Xcode versions.

incanus commented 10 years ago

Trying to build on 10.10 leads to other issues:

**** building libpng ****

checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for arm-apple-darwin-strip... no
checking for strip... strip
checking for a thread-safe mkdir -p... ./install-sh -c -d
checking for gawk... no
checking for mawk... no
checking for nawk... no
checking for awk... awk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking whether to enable maintainer-specific portions of Makefiles... no
checking for arm-apple-darwin-gcc... /Applications/Xcode6-Beta5.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
checking whether the C compiler works... no
configure: error: in `/Users/incanus/Desktop/gl/mapnik-packaging/osx/out/packages/libpng-1.6.12':
configure: error: C compiler cannot create executables
See `config.log' for more details
make: *** [config.gypi] Error 77

config.log here: https://gist.github.com/anonymous/f4103839e4140aee66ea

incanus commented 10 years ago

I am realizing now that building the mapboxgl-ios target works fine in all variations; it's just the actual app that's a problem. Seems like a linking issue.

springmeyer commented 10 years ago

I am realizing now that building the mapboxgl-ios target works fine in all variations; it's just the actual app that's a problem.

That makes sense. The core lib does not link to libpng/libuv, only the app. And it makes sense that linking would fail because we are not yet building for the 64 bit simulator.

WRT to the png error of cannot create executables: sorry, that was a temp breakage in the last hour, fixed by: https://github.com/mapnik/mapnik-packaging/commit/600c2853606a0a48cc1d2ee2f78c9b48b2c8e2f7#diff-d41d8cd98f00b204e9800998ecf8427e. To avoid breakages like this in the future I'm going to start versioning/tagging the build scripts once they are ported over to https://github.com/mapbox/mason.

incanus commented 10 years ago

sorry, that was a temp breakage in the last hour

Little off topic here, but I'm still seeing this problem even with that commit.

incanus commented 10 years ago

This bubbles up when trying to integrate Mapbox GL into a Swift project, too.

Undefined symbols for architecture x86_64:
  "_alphasort$INODE64", referenced from:
      _uv__fs_work in libMapboxGL.a(libuv_la-fs.o)
  "_scandir$INODE64", referenced from:
      _uv__fs_work in libMapboxGL.a(libuv_la-fs.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
incanus commented 10 years ago

We don't yet build for the 64 bit simulator

@springmeyer How involved is doing this? This would be good not just for 64-bit simulator testing but also for Swift playground use of Mapbox GL. I've got a dynamic library variant building that works in apps (in 32-bit anyway) simply via @import MapboxGL.

springmeyer commented 10 years ago

@incanus would require:

incanus commented 10 years ago

Cool, I will check on this. Still happens with Xcode 6.0b6, naturally.

incanus commented 10 years ago

Pretty well into this; almost ready for a PR. Going the route of two different lipo output folders, one (traditional naming; build-cpp11-libcpp-universal) for native host (Linux/OS X; normal make setup) and another (build-cpp11-libcpp-universal-ios) for iOS in particular (make isetup). Ideally both can co-exist and I'm exporting the right paths near the bottom of setup-libraries.sh.

incanus commented 10 years ago

I also realize that in our current setup, we don't really need to lipo the OS X-only build since it's single-arch (x86_64). Any thoughts on that @springmeyer?

springmeyer commented 10 years ago

Correct, no need for universal/lipo at all for OS X since we don't care about 32 bit or PPC. So just referring to the original lib directory would be fine for OS X.

incanus commented 10 years ago

I spent a while going down the path of separate universal output folders for OS X and iOS, including different Makefile targets, but then something occurred to me: Why do we need to treat OS X 64-bit and iPhone Simulator 64-bit differently? They are the same thing. We're having lipo problems because they are the same platform; why build twice?

I ended up tearing a bunch of stuff out and just going the route of:

  1. Changing references to iPhoneSimulator.sh to MacOSX32.sh.
  2. Changing references to MacOSX.sh to MacOSX64.sh.
  3. Removing references to iPhoneSimulator64.sh.
  4. Some other slight cleanups in setup-libraries.sh to refer to a common build-cpp11-libcpp-universal for conciseness.

Between https://github.com/mapbox/mapbox-gl-native/commit/4637accafad4638fe17015113a4c1f328f431c95 and https://github.com/mapnik/mapnik-packaging/commit/c2852703bf6d7bb7177dfd32e054fd6513f5a00d, these things are done.

One other thing I noticed is a failure to even pull in armv7s builds on iOS, let alone the Mac stuff. So I made this fix in make_universal.sh, which also catches the new 64-bit stuff:

-    ARCHS="x86_64-macosx arm64-iphoneos armv7s-iphoneos armv7-iphoneos i386-iphonesimulator x86_64-iphonesimulator"
+    ARCHS="x86_64-macosx arm64-iphoneos64 armv7s-iphoneoss armv7-iphoneos i386-iphonesimulator"

The variables referenced here are used as search folders when finding *.a to combine into fat binaries with lipo. However these names didn't match up to what each platform script was setting as $MASON_PLATFORM (and by extension, $XCODE_PLATFORM). Fixing this results in five-way libraries for the OS X & iOS common libraries (libpng & libuv) and just 64-bit for the Mac build for all the rest (plus the Boost headers still get copied as part of OS X 64-bit):

*making universal libcrypto.a*
Architectures in the fat file: ...universal/lib/libcrypto.a are: x86_64 
*making universal libcurl.a*
Architectures in the fat file: ...universal/lib/libcurl.a are: x86_64 
*making universal libglfw3.a*
Architectures in the fat file: ...universal/lib/libglfw3.a are: x86_64 
*making universal libpng.a*
Architectures in the fat file: ...universal/lib/libpng.a are: armv7s armv7 i386 x86_64 arm64 
*making universal libpng16.a*
Architectures in the fat file: ...universal/lib/libpng16.a are: armv7s armv7 i386 x86_64 arm64 
*making universal libssl.a*
Architectures in the fat file: ...universal/lib/libssl.a are: x86_64 
*making universal libuv.a*
Architectures in the fat file: ...universal/lib/libuv.a are: armv7s armv7 i386 x86_64 arm64 

Also, each of the simulator & device combos all build now for GL on iOS and OS X, plus the fat binaries check out on iOS:

...Debug-iphoneos/Mapbox GL.app)--($ lipo -info Mapbox\ GL 
Architectures in the fat file: Mapbox GL are: armv7 armv7s arm64 

...Debug-iphonesimulator/Mapbox GL.app)--($ lipo -info Mapbox\ GL 
Architectures in the fat file: Mapbox GL are: i386 x86_64 

Remaining tasks:

Really glad I understand this whole thing now! Ready to help with Mason! 🔥

incanus commented 10 years ago

LOL of course now I'm still getting the original build error on Xcode6b6:

Undefined symbols for architecture x86_64:
  "_alphasort$INODE64", referenced from:
      _uv__fs_work in libuv.a(libuv_la-fs.o)
  "_scandir$INODE64", referenced from:
      _uv__fs_work in libuv.a(libuv_la-fs.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
incanus commented 10 years ago

Likely related:

springmeyer commented 10 years ago

Awesome work and improvements. Sanity check / fixes look good, other than this question/concern: https://github.com/mapnik/mapnik-packaging/commit/c2852703bf6d7bb7177dfd32e054fd6513f5a00d#commitcomment-7497850.

Not worried if libmapnik.a process is broken atm, can fix that up later on.

WRT to the linking error, well crap :)

incanus commented 10 years ago

The odd thing is that everything builds fine on all platforms in Xcode 5 but fails in 6.

I think I need to at least experiment around your comment in mapnik-packaging before calling this a solution.

incanus commented 10 years ago

One thing I ran into when removing MacOSX.sh @springmeyer was that the Boost headers wouldn't get copied over properly to the universal folder. Could quite get to the bottom of why. Any ideas?

springmeyer commented 10 years ago

@incanus perhaps that is because cross-compiling broke, which it looks like it may have because the HOST_PLATFORM needs adapted to the change in names. The way cross-compiling works is that it uses the HOST_PLATFORM to re-source the right environment.

incanus commented 10 years ago

Ok @springmeyer, I got a chance to get back to this and I think we're a go here pending some sanity checks! Just got everything to build for iOS (armv7 armv7s arm64 i386 x86_64) & OS X (x86_64), including in Xcode 6.0b7 (out today) without incident.

baxvzwhiuaatdt0 jpg-large

Summary

Branches across repos named ios-64-bit.

Todo

incanus commented 10 years ago

I have gotten Mapbox GL built as a dynamic framework as well, which is a prerequisite for Playground use. Then, I got basic Playground operation working, at least as well as an Apple map:

screen shot 2014-09-02 at 6 07 38 pm

Async render views like these don't seem to work yet in Playgrounds. Note the Apple "legal" link and Mapbox "info" buttons.

Next steps would be just doing this in a regular app project, meaning Mapbox GL could be brought into apps via Swift. Should be trivial compared to Playgrounds.

incanus commented 10 years ago

Xcode 6.0 GM out last week and iOS 8 out tomorrow. Going to clean this up & merge as a good solution.

incanus commented 10 years ago

Just getting Travis happy (with pre-bundled hash tarballs etc.) and this is good to go.

incanus commented 10 years ago
incanus commented 10 years ago

Just merged into master. Headless tests are still failing for some reason, but we can fix that in master.

Going to close in favor of https://github.com/mapbox/mapbox-gl-cocoa/issues/52, after which we can pick up Swift and/or playground use.