Bug 19602 - Linker adds a reference to the JavascriptCore private framework library if deployment target is set to iOS 6.x and linker is set to "Dont link"
Summary: Linker adds a reference to the JavascriptCore private framework library if de...
Status: VERIFIED NOT_ON_ROADMAP
Alias: None
Product: iOS
Classification: Xamarin
Component: Tools ()
Version: 7.2.3
Hardware: PC Mac OS
: Normal normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2014-05-07 16:55 UTC by bilal.durrani
Modified: 2014-05-26 09:43 UTC (History)
4 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
VERIFIED NOT_ON_ROADMAP

Description bilal.durrani 2014-05-07 16:55:40 UTC
I noticed a few people ran into this problem on the forums just like I did.

I have an iPad app built for iOS 6.x and higher. I had the linker option set to "Dont Link" because of the following bug

https://bugzilla.xamarin.com/show_bug.cgi?id=14456

bug 14456 has been fixed, btw.

The app got rejected from the app store on submission because of the following:
----------------
Non-public API usage: 

The app links to non-public libraries in <app name: /System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore 
-----------------

Sure enough, when I ran otool -L on the app, I see the following:

---------------------------------
*list snipped for brevity*

	/System/Library/Frameworks/ExternalAccessory.framework/ExternalAccessory (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/AdSupport.framework/AdSupport (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/QuickLook.framework/QuickLook (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/SpriteKit.framework/SpriteKit (compatibility version 1.0.0, current version 2.0.0)

**** heavens to megatron! ***

	/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore (compatibility version 1.0.0, current version 537.51.2)

**** end of heavens to megatron ***


	/System/Library/Frameworks/MultipeerConnectivity.framework/MultipeerConnectivity (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/GameController.framework/GameController (compatibility version 1.0.0, current version 1.0.0)

--------------------------

Notice the private framework included there even though I was not using it.

I realize that JavascriptCore has been made into a public lib in iOS 7, but there really should be a warning or something indicating that this will cause a problem when submitting to the app store. Perhaps the list of libs should vary based on the app target version.

Again, this only happens with building for iOS 6 and higher with the "Dont link" option specified, so it's a very specific corner case, but I still wasted time trying to figure out the problem. 

I was able to resolve this by switching linker options to "Link all SDK assemblies"
Comment 1 Sebastien Pouliot 2014-05-07 17:19:49 UTC
If you disable the (managed) linker then you include all the code from monotouch.dll [1] inside your application. 

That will, in turn, that requires the (native) linker to reference every (public) iOS frameworks - since they are all referenced by monotouch.dll.


Q: what version of the iOS SDK are you using ? for 7.0+ it should be (natively) linking against the public (not the private framework).


[1] ... and of every referenced BCL assemblies. That will generate huge application size (and long build times, since everything needs to be AOT'ed). It also prevent the linker from optimizing the bindings (more performance and even less code).

It will also affect application startup time since every ObjC type (not just the one you need) will be registered (it's also bigger/slower to load into memory).

I strongly advice against shipping apps without linking (see my Evolve 2013 video for more details).
Comment 2 bilal.durrani 2014-05-08 09:03:48 UTC
The SDK version is set to the "Default" option. The Deployment target  for the ios app is set to 6.1. 

I agree, disabling the linker is bad. I had it turned on to work around the bug I mentioned and had forgotten to turn it off. Once I realized what was happening, I figured the linker option was probably to blame.
Comment 3 Sebastien Pouliot 2014-05-08 10:15:03 UTC
Interesting. With a deployment target of 4.2 I get:

pollux:monotouch sebastienpouliot$ otool -L tests/dontlink/bin/iPhone/Release/dontlink.app/dontlink | grep Java
	/System/Library/Frameworks/JavaScriptCore.framework/JavaScriptCore (compatibility version 1.0.0, current version 537.51.2)

-> likely because the private framework did not exist back then

with 6.1 I get:

pollux:monotouch sebastienpouliot$ otool -L tests/dontlink/bin/iPhone/Release/dontlink.app/dontlink | grep Java
	/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore (compatibility version 1.0.0, current version 537.51.2)

-> which is bad.

and with 7.0 I get

pollux:monotouch sebastienpouliot$ otool -L tests/dontlink/bin/iPhone/Release/dontlink.app/dontlink | grep Java
	/System/Library/Frameworks/JavaScriptCore.framework/JavaScriptCore (compatibility version 1.0.0, current version 537.51.2)

-> correct, as expected.


So yes there's a conflict if you're both not using the (managed) linker and targetting an iOS version where only the private framework existed.
Comment 4 Sebastien Pouliot 2014-05-08 11:10:19 UTC
4.2 ok
4.3 bad
5.0 bad
5.1 bad
6.1 bad
7.0 ok
7.1 ok

The only build difference is the `-miphoneos-version-min=4.2` (just re-linking is enough).

Somehow Apple tool chain knows which framework to use when supplied with `-weak_framework JavaScriptCore`, i.e. I only have the iphone 7.1 SDK (and the simulator SDK do not go lower than 6.0) and yet it links to different frameworks for 5.x and 4.x.

Trying to hack around this (e.g. using -weak_library with a full path) does not change the result.

I'll have a look at how Xcode handle this...
Comment 5 Sebastien Pouliot 2014-05-14 11:00:00 UTC
Xcode does not handle this, i.e. it will link with 

	/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore (compatibility version 1.0.0, current version 537.51.2)

if you include a reference (even an optional one) to JavaScriptCode and target iOS 6.1. It looks like this is a restriction from Apple [1] - I wish I had found this earlier :-)

The solution is to run the linker (at least on monotouch.dll) on every app that is published to the AppStore.

[1] http://stackoverflow.com/a/23514580
Comment 6 bilal.durrani 2014-05-14 12:43:09 UTC
This makes sense. I figured it was going to turn out to be something like this.

I wish I had found that post earlier too :)

Thanks for looking into this.
Comment 7 Saurabh 2014-05-26 09:43:56 UTC
As per comment 5 and comment 6, this issue is resolved now.

Hence closing this issue. Marking it as verified