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

mbgl-test-runner fails to link in mapbox-gl-native-ios workspace #16259

Open
1ec5 opened this issue Mar 2, 2020 · 9 comments
Open

mbgl-test-runner fails to link in mapbox-gl-native-ios workspace #16259

1ec5 opened this issue Mar 2, 2020 · 9 comments
Labels
build iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS

Comments

@1ec5
Copy link
Contributor

1ec5 commented Mar 2, 2020

The mapbox/mapbox-gl-native-ios repository’s make xproj command generates a macos.xcworkspace that includes various gl-native targets, including mbgl-test-runner. mbgl-test-runner fails to build with the following linker errors:

Showing All Messages
Ld /path/to/mapbox-gl-native-ios/build/macos/Debug/mbgl-test-runner normal x86_64 (in target 'mbgl-test-runner' from project 'Mapbox GL Native')
    cd /path/to/mapbox-gl-native-ios/vendor/mapbox-gl-native
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -target x86_64-apple-macos10.15 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -L/path/to/mapbox-gl-native-ios/build/macos/Debug -F/path/to/mapbox-gl-native-ios/build/macos/Debug -filelist /path/to/mapbox-gl-native-ios/build/macos/Mapbox\ GL\ Native.build/Debug/mbgl-test-runner.build/Objects-normal/x86_64/mbgl-test-runner.LinkFileList -Xlinker -object_path_lto -Xlinker /path/to/mapbox-gl-native-ios/build/macos/Mapbox\ GL\ Native.build/Debug/mbgl-test-runner.build/Objects-normal/x86_64/mbgl-test-runner_lto.o -Xlinker -no_deduplicate -Wl,-headerpad_max_install_names -Wl,-force_load /path/to/mapbox-gl-native-ios/build/macos/test/Debug/libmbgl-test.a /path/to/mapbox-gl-native-ios/build/macos/Debug/libmbgl-core.a /path/to/mapbox-gl-native-ios/build/macos/Debug/libmbgl-vendor-csscolorparser.a /path/to/mapbox-gl-native-ios/build/macos/Debug/libmbgl-vendor-parsedate.a /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/OpenGL.framework/OpenGL.tbd -framework AppKit -framework CoreGraphics -framework CoreLocation -framework SystemConfiguration /path/to/mapbox-gl-native-ios/build/macos/Debug/libmbgl-vendor-icu.a -lsqlite3 -lz /path/to/mapbox-gl-native-ios/build/macos/test/Debug/libmbgl-vendor-googletest.a -Xlinker -dependency_info -Xlinker /path/to/mapbox-gl-native-ios/build/macos/Mapbox\ GL\ Native.build/Debug/mbgl-test-runner.build/Objects-normal/x86_64/mbgl-test-runner_dependency_info.dat -o /path/to/mapbox-gl-native-ios/build/macos/Debug/mbgl-test-runner

clang: error: no such file or directory: '/path/to/mapbox-gl-native-ios/build/macos/test/Debug/libmbgl-test.a'
clang: error: no such file or directory: '/path/to/mapbox-gl-native-ios/build/macos/test/Debug/libmbgl-vendor-googletest.a'
Command Ld failed with a nonzero exit code

This is the Debug configuration, but the same errors occur in the other configurations.

To work around this issue, I modified the mbgl-test-runner target’s OTHER_LDFLAGS build setting to remove test/ from the paths of libmbgl-test.a and libmbgl-vendor-googletest.a. The other paths are already correct. This is a trivial change inside Xcode, but it doesn’t persist because mbgl relies on CMake to generate Xcode projects on the fly. I’m not sure what CMake magic is required to fix these paths.

I think this issue would also affect any future iOS test runner that becomes buildable within Xcode. It’s very useful to be able to run these test runners as part of the overall map SDK workspace, so that we can more confidently make changes across repositories such as mapbox/mapbox-gl-native-ios#189 / #16253.

/ref #16253 (comment)
/cc @mapbox/gl-native @mapbox/maps-ios

@1ec5 1ec5 added iOS Mapbox Maps SDK for iOS build macOS Mapbox Maps SDK for macOS labels Mar 2, 2020
@1ec5
Copy link
Contributor Author

1ec5 commented Mar 5, 2020

UnitTestAppTests also fails to link unless I unset FRAMEWORK_SEARCH_PATHS, which CMake hardcodes as /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Frameworks.

To reproduce, change this line to also pass in -DCMAKE_OSX_SYSROOT=iphoneos -DMBGL_IOS_UNIT_TEST=ON.

The tests don’t run on a device, probably due to this warning:

dyld: warning: could not load inserted library '/private/var/containers/Bundle/Application/12C5DCAD-DEDD-4D5C-B816-A63E4F213C21/UnitTestsApp.app/Frameworks/libXCTestBundleInject.dylib' into hardened process because image not found

@zmiao
Copy link
Contributor

zmiao commented Mar 19, 2020

I think it is not an issue related to gl-native.

If I run from mapbox-gl-native-ios project with the following script:

mkdir -p build/ios && cd build/ios && CMAKE -G Xcode ../../vendor/mapbox-gl-native \
-DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos -DMBGL_IOS_UNIT_TEST=ON

xed Mapbox\ GL\ Native.xcodeproj 

Then try to build the TestAPP with Xcode, there were no linking errors. As by default the linker flag is configured to linking to

mapbox-gl-native-ios/build/ios/test/Debug${EFFECTIVE_PLATFORM_NAME}/libmbgl-test.a

and the actual build products will be inside test/Debug${EFFECTIVE_PLATFORM_NAME}/

However, if I run make iproj, which will copy the WorkspaceSettings.xcsettings, I checked inside

<key>CustomBuildIntermediatesPath</key>
<string>../../build/ios</string>
<key>CustomBuildLocationType</key>
<string>RelativeToWorkspace</string>
<key>CustomBuildProductsPath</key>
<string>../../build/ios</string>
<key>DerivedDataCustomLocation</key>
<string>../../build/ios</string>

I am not sure which one causes it, but I assume with above configuration, It reconfigured the build product path, which will cause the build lib relocating to mapbox-gl-native-ios/build/ios/Debug${EFFECTIVE_PLATFORM_NAME}/libmbgl-test.a

@1ec5
Copy link
Contributor Author

1ec5 commented Mar 23, 2020

When Mapbox GL Native.xcodeproj is run inside another workspace, these paths need to be modified to point to the same build products directory that other workspace products are put into. It normally works, but I’m not sure what’s causing the test/ to persist in the paths for test targets.

@1ec5
Copy link
Contributor Author

1ec5 commented Apr 23, 2020

It normally works, but I’m not sure what’s causing the test/ to persist in the paths for test targets.

This seems to be a limitation of CMake’s add_subdirectory command. CMake expects each subdirectory to represent a separate, self-contained executable target. This breaks Xcode’s expectation that the build products would commingle under a centralized build products folder.

add_subdirectory(${PROJECT_SOURCE_DIR}/test)
add_subdirectory(${PROJECT_SOURCE_DIR}/benchmark)
add_subdirectory(${PROJECT_SOURCE_DIR}/render-test)

The mbgl build system currently relies on SYMROOT to be set on each target, but inside a workspace, Xcode ignores the per-target SYMROOT in favor of a per-project SYMROOT or even a per-user setting: flutter/flutter#32494 (comment). It’ll put the build products somewhere else, causing the CMake-generated OTHER_LDFLAGS to become inaccurate.

Of all the antipatterns in how CMake configures Xcode, its reliance on an inaccurate SYMROOT isn’t especially severe, since there is a workaround: I can manually fix up the build settings every time I rerun CMake or perhaps override the paths using an .xcconfig file.

@1ec5
Copy link
Contributor Author

1ec5 commented Apr 23, 2020

The tests don’t run on a device, probably due to this warning:

dyld: warning: could not load inserted library '/private/var/containers/Bundle/Application/12C5DCAD-DEDD-4D5C-B816-A63E4F213C21/UnitTestsApp.app/Frameworks/libXCTestBundleInject.dylib' into hardened process because image not found

Might be related to this build-time warning:

warning: skipping copy phase strip, binary is code signed: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/lib/libXCTestBundleInject.dylib

@tmpsantos
Copy link
Contributor

@1ec5 I think setting CMAKE_RUNTIME_OUTPUT_DIRECTORY to CMAKE_BINARY_DIR will solve the problem

@tmpsantos
Copy link
Contributor

@1ec5 I think setting CMAKE_RUNTIME_OUTPUT_DIRECTORY to CMAKE_BINARY_DIR will solve the problem

Making a PR here for you to test

@tmpsantos
Copy link
Contributor

Making a PR here for you to test

Can you give this a try?

#16431

@stale stale bot added the archived Archived because of inactivity label Oct 23, 2020
@1ec5
Copy link
Contributor Author

1ec5 commented Oct 27, 2020

/cc @ChrisLoer

@stale stale bot removed the archived Archived because of inactivity label Oct 27, 2020
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 macOS Mapbox Maps SDK for macOS
Projects
None yet
Development

No branches or pull requests

3 participants