Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Pass ICU to libtool in package script #7773

Merged
merged 1 commit into from
Feb 16, 2017
Merged

Conversation

boundsj
Copy link
Contributor

@boundsj boundsj commented Jan 18, 2017

In #6984 we started using ICU in core. This causes linker errors in an iOS application that uses a static build of the Mapbox iOS SDK.

This passes ICU (via Mason) to libtool when the iOS static build is created so that the dependency is available when the Mapbox iOS SDK is used in a host iOS application.

The ICU lib actually replaces libgeojson. On our build machines libgeojson was not actually getting passed to libtool since the path used was provided by {IOS_SDK_VERSION} (created with xcrun --sdk iphonesimulator|iphoneos --show-sdk-version was greater than the 8.0 value that is currently hard coded in the mason.sh script. I'm still unclear about why libgeojson was added but it does seem safe to remove it.

To attempt to start to sync up with the mason.sh file, this also adds a MASON_PLATFORM_VERSION variable to the iOS package.sh script that is now hardcoded to 8.0 just like the mason.sh script. This is required to get things to link but is fragile and I'm unclear about how this dependency should actually be handled in the various scripts. I'm not sure that hard coding this value in mason itself is a good idea.

** edit **

As noted below, we ended up using the cmake cache to find the ICU archive and to avoid having the package script know about the mason and ICU versions that are already specified in the cmake config.

cc @1ec5 @ChrisLoer @jfirebaugh

@boundsj boundsj added build iOS Mapbox Maps SDK for iOS labels Jan 18, 2017
@boundsj boundsj added this to the ios-v3.5.0 milestone Jan 18, 2017
@boundsj boundsj self-assigned this Jan 18, 2017
@boundsj boundsj requested a review from 1ec5 January 18, 2017 20:24
@mention-bot
Copy link

@boundsj, thanks for your PR! By analyzing this pull request, we identified @yhahn, @1ec5 and @incanus to be potential reviewers.

@1ec5
Copy link
Contributor

1ec5 commented Jan 18, 2017

A minimum deployment target of 8.0 is also defined in CMake configuration for mbgl.xcodeproj. For its part, ios.xcodeproj specifies a minimum deployment target of 7.0 that applies to the static target. (The dynamic target overrides the minimum deployment target to 8.0 because iOS 7.0 doesn’t support dynamic frameworks.) This all makes me wonder whether the SDK really does support deploying back to iOS 7.0 anymore. Unfortunately, I don’t have a good way to check.

Also related: mapbox/mason#290.

/cc @kkaefer

@kkaefer
Copy link
Member

kkaefer commented Jan 19, 2017

Background on libgeojson is that it used to have a compiled component, but that changed in #6494

@kkaefer
Copy link
Member

kkaefer commented Jan 19, 2017

How is mapbox/mason#290 related to this?

@boundsj can we add a CI task that checks the static library for linking errors?

@1ec5
Copy link
Contributor

1ec5 commented Jan 19, 2017

How is mapbox/mason#290 related to this?

Not strictly related. I just figured it was worth mentioning in the context of the binaries we’re getting from Mason.

can we add a CI task that checks the static library for linking errors?

We used to build the dynamic+static scheme on CI, but it got trimmed down as part of a push to speed up CI builds. I’d appreciate building dynamic+static again, in order to catch issues like #6194 sooner.

Copy link
Member

@kkaefer kkaefer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should move the framework bundle creation to the Xcode stage. http://stackoverflow.com/a/16492468 has a guide as to how to do it.

@@ -117,7 +119,7 @@ if [[ ${BUILD_FOR_DEVICE} == true ]]; then
-o ${OUTPUT}/static/${NAME}.framework/${NAME} \
${LIBS[@]/#/${PRODUCTS}/${BUILDTYPE}-iphoneos/lib} \
${LIBS[@]/#/${PRODUCTS}/${BUILDTYPE}-iphonesimulator/lib} \
`find mason_packages/ios-${IOS_SDK_VERSION} -type f -name libgeojson.a`
`find mason_packages/ios-${MASON_PLATFORM_VERSION} -type f -name libicuuc.a`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This breaks badly if you have multiple versions of ICU in your mason_packages folder, e.g. when we upgrade ICU at some point.

@@ -13,6 +13,8 @@ BUILDTYPE=${BUILDTYPE:-Debug}
BUILD_FOR_DEVICE=${BUILD_DEVICE:-true}
SYMBOLS=${SYMBOLS:-YES}

MASON_PLATFORM_VERSION="8.0" # Deployment target version
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should duplicate the version here. Can we find another way of getting that number into here (if we need it at all)

@boundsj boundsj added the release blocker Blocks the next final release label Jan 24, 2017
@boundsj boundsj force-pushed the boundsj-icu-in-static-build branch from 0a9d243 to e9d1138 Compare February 14, 2017 07:43
@boundsj
Copy link
Contributor Author

boundsj commented Feb 14, 2017

I think we should move the framework bundle creation to the Xcode stage. http://stackoverflow.com/a/16492468 has a guide as to how to do it.

@kkaefer thanks for the suggestion. That SO post walks through creating a Bundle configured as a relocatable object file. Although this seems to allow for more flexibility with regards to symbol hiding, I'd prefer to defer that change for now and stick to something along the lines of our existing solution.

In e9d1138, I cleaned the up package.sh so that libtool is no longer tasked with combining the SDK and libicuuc. Instead, I configured the static target to link with libicuuc with a LIBRARY_SEARCH_PATHS that points to the mason location. The next step could be to update iOS's config.cmake to make these changes. I think this would be more future proof since the cmake system is aware of the exact path to libicuuc and the version in use. For example, it writes something like mbgl_core_LINK_LIBRARIES = "/Users/boundsj/mapbox-gl-native/mason_packages/ios-8.0/icu/58.1/lib/libicuuc.a" "-lz" to the generated config.xcconfig file.

@boundsj
Copy link
Contributor Author

boundsj commented Feb 14, 2017

Actually, @kkaefer @1ec5 what do you think of 1c72fc2? It reverts e9d1138 and uses libtool again to combine libicuuc in the fat binary. However, it uses cmake's cache to get the correct version of ICU.

This fixes the problem and seems pretty reliable. Maybe we can use something like this approach for now so we can close this release blocker? We can ticket additional static build system changes (if required) and a future upgrade to CI to catch this sort of issue.

@@ -616,6 +616,7 @@
40CFA6501D787579008103BD /* MGLShapeSourceTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLShapeSourceTests.mm; path = ../../darwin/test/MGLShapeSourceTests.mm; sourceTree = "<group>"; };
40EDA1BD1CFE0D4A00D9EA68 /* MGLAnnotationContainerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationContainerView.h; sourceTree = "<group>"; };
40EDA1BE1CFE0D4A00D9EA68 /* MGLAnnotationContainerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLAnnotationContainerView.m; sourceTree = "<group>"; };
40F066C41E52E89D002B1DB5 /* libicuuc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libicuuc.a; path = "../../mason_packages/ios-8.0/icu/58.1/lib/libicuuc.a"; sourceTree = "<group>"; };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this reference still needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I squashed all the previous commits into 2c9bcb78f8f7c1e1786ee641c4ff2703b8d05453 that only has the path change for libtool.

@boundsj boundsj force-pushed the boundsj-icu-in-static-build branch from 1c72fc2 to 2c9bcb7 Compare February 15, 2017 19:59
@boundsj boundsj force-pushed the boundsj-icu-in-static-build branch from 2c9bcb7 to bcc2f4b Compare February 15, 2017 21:12
@@ -117,7 +117,7 @@ if [[ ${BUILD_FOR_DEVICE} == true ]]; then
-o ${OUTPUT}/static/${NAME}.framework/${NAME} \
${LIBS[@]/#/${PRODUCTS}/${BUILDTYPE}-iphoneos/lib} \
${LIBS[@]/#/${PRODUCTS}/${BUILDTYPE}-iphonesimulator/lib} \
`find mason_packages/ios-${IOS_SDK_VERSION} -type f -name libgeojson.a`
`cmake -LA -N ${DERIVED_DATA} | grep MASON_PACKAGE_icu_LIBRARIES | cut -d= -f2`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of using this, we could also use MASON_PLATFORM=ios MASON_PLATFORM_VERSION=8.0 ./scripts/mason.sh LIBRARIES icu VERSION 58.1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like looking up the value in the cmake cache because it automatically gets the correct path that (I think) is a result of mason_use(icu VERSION 58.1) and target_add_mason_package(mbgl-core PUBLIC icu) in the config.cmake file in the iOS platform directory. This way, this package.sh script does not need to know anything about the platform (although that would not be bad), the mason platform version, or the version of ICU. That can all come from the result of cmake and its config.cmake.

@boundsj boundsj merged commit 655b7c0 into master Feb 16, 2017
@boundsj boundsj deleted the boundsj-icu-in-static-build branch February 16, 2017 18:59
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
build iOS Mapbox Maps SDK for iOS release blocker Blocks the next final release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants