cutting-room-floor / mapbox-gl-cocoa

OBSOLETE
74 stars 12 forks source link

move LLMR from dependent target to statically linked library #9

Closed incanus closed 10 years ago

incanus commented 10 years ago

Steps:

incanus commented 10 years ago

The actual move here is going to happen pretty late in the game since introducing the static library early is a workflow pain for LLMR development.

kkaefer commented 10 years ago

FWIF, I wouldn't remove/hide C++ files as that'll make it harder to debug for iOS developers if they choose to dive into the lib.

incanus commented 10 years ago

Hide LLMR C++ files from view

What I mean by this is how it's done for Proj4 here:

https://github.com/mapbox/mapbox-ios-sdk/tree/release/Proj4

Note that all the files, as well as the Xcode project needed to build them, are in the source tree.

However, the SDK Xcode project itself merely links in the libProj4.a as a result of https://github.com/Alpstein/route-me/issues/85#issuecomment-8466818. This speeds up compile time for the SDK as well as keeps it simple.

We could always provide an Xcode workspace (a way of combining 2+ Xcode projects) that includes the normal toolset project as well as the project used to build the static libs of LLMR for people who want to hack it. I think we can consider them largely exclusive audiences a lot of the time, though.

incanus commented 10 years ago

Related: https://github.com/mapbox/llmr-native/issues/243#issuecomment-44217022

incanus commented 10 years ago

Taking a crack at this now.

incanus commented 10 years ago

This is what iOS devs will have to install to get up and running:

screen shot 2014-05-29 at 5 41 05 pm

incanus commented 10 years ago

Happening in https://github.com/mapbox/MVKMapKit/tree/easy-install.

Just need to test inclusion in a fresh Xcode project, then will merge.

incanus commented 10 years ago

Yeah, hitting some walls here. Would appreciate an eyeball, @springmeyer.

Here's my current build process, ideally, encapsulated in ./pkg/package.sh:

  1. Use ./pkg/MVKMapKit.gyp to generate ./pkg/MVKMapKit.xcodeproj.
  2. Use xcodebuild to build sim/device versions of MVKMapKit.
  3. Use xcodebuild to build sim/device versions of libllmr-ios.a.
  4. Use lipo to combine all into a fat static library.
  5. Misc. other stuff like grabbing headers and the resource bundle (non-code).

My problem however is that MVKMapKit can't build as it relies on llmr.hpp. Adding that to the MVKMapKit.gyp gets me a bit further along until:

error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: can't locate file for: -lz
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: -lz is not an object file (not allowed in a library)
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: can't locate file for: -lpthread
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: -lpthread is not an object file (not allowed in a library)
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: can't locate file for: -ldl
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: -ldl is not an object file (not allowed in a library)

My problem is that MVKMapKit relies on linking against llmr-ios, really.

I tried also making MVKMapKit.gyp and its target a dependency of the top-level llmr.gyp but then that has problems with the Cocoa runtime, since these Cocoa files aren't meant to be part of the C++ library.

Am I screwed here? Should I just be putting MVKMapKit into LLMR proper?

My thinking here was to contain the Cocoa code as well as meet the easy clone/install vision described by the screenshot above.

Any ideas?

springmeyer commented 10 years ago

Can you share the exact command that failed? I'll take a closer look when I can get back online.

On May 29, 2014, at 8:14 PM, "Justin R. Miller" notifications@github.com wrote:

Yeah, hitting some walls here. Would appreciate an eyeball, @springmeyer.

Here's my current build process, ideally, encapsulated in ./pkg/package.sh:

Use ./pkg/MVKMapKit.gyp to generate ./pkg/MVKMapKit.xcodeproj.

Use xcodebuild to build sim/device versions of MVKMapKit.

Use xcodebuild to build sim/device versions of libllmr-ios.a. Use lipo to combine all into a fat static library. Misc. other stuff like grabbing headers and the resource bundle (non-code). My problem however is that MVKMapKit can't build as it relies on llmr.hpp. Adding that to the MVKMapKit.gyp gets me a bit further along until:

error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: can't locate file for: -lz error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: -lz is not an object file (not allowed in a library) error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: can't locate file for: -lpthread error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: -lpthread is not an object file (not allowed in a library) error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: can't locate file for: -ldl error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: -ldl is not an object file (not allowed in a library) My problem is that MVKMapKit relies on linking against llmr-ios, really.

I tried also making MVKMapKit.gyp and its target a dependency of the top-level llmr.gyp but then that has problems with the Cocoa runtime, since these Cocoa files aren't meant to be part of the C++ library.

Am I screwed here? Should I just be putting MVKMapKit into LLMR proper?

My thinking here was to contain the Cocoa code as well as meet the easy clone/install vision described by the screenshot above.

Any ideas?

— Reply to this email directly or view it on GitHub.

springmeyer commented 10 years ago

error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: can't locate file for: -lz

Replicated this. Its happening because we want to dynamically link zlib but -lz is ending up in the linker args for libMVKMapKit.a. But this won't work because libMVKMapKit.a needs a libz.a around. So, the solution is to not have -lz in the linker args for the creation of libMVKMapKit.a. Rather the final app that links libMVKMapKit.a will need -lz.

Thinking through a fix now.

incanus commented 10 years ago

Having the final app link is ok, btw. Just needs put in the install instructions but it's not a hurdle.

springmeyer commented 10 years ago

Other potential gocha / way this is different than libProj4.a is that libMapboxGL.a / libMVKMapKit.a also depends on C++ and libuv.a and libpng.a

incanus commented 10 years ago

C++ issue should likely be solved by providing a starter project with the right settings for c++/libc++/-stdc++11

I was hoping to avoid the need to build for C++, which (I think) may be unavoidable? Basically, does that mean a user has to make their project an Objective-C++ project? Or can this be per-file?

springmeyer commented 10 years ago

We should be able to pretend C++ is not involved at compile (so .m rather than .mm files can be used I think). But at link time C++ will need to be involved. Because we need to link a static lib (libMapboxGL.a) the dynamic symbols that static lib depends on also need to be linked at the same time. So, -lz is one (as per above) but also the c++ lib. The shorthand for this is -stdlib=libc++ but it is basically -lc++.

In summary:

I was hoping to avoid the need to build for C++, which (I think) may be unavoidable?

Yes, unavoidable.

Basically, does that mean a user has to make their project an Objective-C++ project?

I don't think so.

incanus commented 10 years ago

Ok, that's helpful. Linker flags in the install docs are also OK™.

springmeyer commented 10 years ago

Okay, progress:


    MVKMapView *mapView = [[MVKMapView alloc] initWithFrame:CGRectMake(100, 100, 500, 500)];
    [self.view addSubview:mapView];

Now I'm hitting this at runtime:

Assertion failure in +[MVKMapView resourceImageNamed:], /Users/dane/projects/llmr-native/ios/MVKMapKit/MVKMapKit/MVKMapView.mm:548
2014-05-29 23:41:11.097 tttttest[2281:60b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Resource image not found in application.'
incanus commented 10 years ago

Cool, that's a bundle-related issue, but we're out of the woods on linking, so that's what I really needed.

##     ## ####  ######   ##     ##    ######## 
##     ##  ##  ##    ##  ##     ##    ##       
##     ##  ##  ##        ##     ##    ##       
#########  ##  ##   #### #########    #######  
##     ##  ##  ##    ##  ##     ##          ## 
##     ##  ##  ##    ##  ##     ##    ##    ## 
##     ## ####  ######   ##     ##     ######  

Can you elaborate on:

Marked one (could have made a dummy) of the .m files as "Objective-C++ Source". This seems like the only way to trick XCode into linking with clang++ instead of clang.

springmeyer commented 10 years ago

regarding making one .m objective c++:

screenshot 2014-05-29 23 52 53

springmeyer commented 10 years ago

It should be possible to avoid this by instead adding -lc++ and a few other flags to the other linker flags, but it would be more error prone.

incanus commented 10 years ago

Oh, interesting. That's weird. So basically because we aren't compiling in MVKMapKit.mm, there's no hint to use Objective-C++. I will see if I can work around that.

springmeyer commented 10 years ago

yeah, and I see no way to gently tell xcode to link as a C++ app. silly, but at least the workaround is easy, if odd.

incanus commented 10 years ago

Back on this and close.

incanus commented 10 years ago

@springmeyer I could possibly use a hand again on a new and wonderfully different task now.

So linking is good and I'm trying to solve the resource bundle issue. What needs to happen is that I need the output of the llmr-ios dependent target build_stylesheet, which is a style.min.js. I need to make that available to this copy phase so that it ends up alongside the image resources.

The build_stylesheet target is already running via llmr-ios, so adding it to mapbox-gl-cocoa.gyp as a dependency doesn't do anything useful. It's more a matter of figuring out how to get at the target result.

springmeyer commented 10 years ago

What about just:

cp $PARENT/build/DerivedSources/Release/bin/style.min.js $OUTPUT/
incanus commented 10 years ago

I did see the file there, but thought that brittle. Works great, though! :+1:

incanus commented 10 years ago

Ok, as of de9e0d0 we have a shippable static library, resource bundle, and header collection. The last thing I'd like to hit is the wonky Objective-C++ file designation above in https://github.com/mapbox/mapbox-gl-cocoa/issues/9#issuecomment-44620460, do some quick QA, and tag it.

incanus commented 10 years ago

First time I've seen an explicit mention of the .m -> .mm trick being necessary:

http://answers.oreilly.com/topic/631-how-to-get-c-and-objective-c-to-play-nicely-in-xcode/

That's looking to be the way. I may just include a dummy as you suggested @springmeyer -- like maybe a MapboxGL.mm with just comments in it.

incanus commented 10 years ago

This is done and the entire download-to-live-view install process is encapsulated here:

https://github.com/mapbox/mapbox-gl-cocoa#installation

It's very simple and builds in no time to get up & running with Cocoa - easily a few seconds.

springmeyer commented 10 years ago

\o/

springmeyer commented 10 years ago

one other idea on the triggering c++ issue. It would also likely work to provide an xconfig file with GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp in it. But I think the dummy mm is likely the easiest.

incanus commented 10 years ago

Interesting. I may explore that if there's feedback on the stub file. But right now it fits nicely alongside the other resources:

https://github.com/mapbox/mapbox-gl-cocoa/tree/master/dist

Thanks a ton for the help & research @springmeyer.