macdeploy help

1742
9
Jump to solution
03-20-2020 08:49 AM
JeremyRoberts2
New Contributor III

So I am reading...

Deploy your app—ArcGIS Runtime SDK for Qt | ArcGIS for Developers 

It talks about creating symbolic links and suggests...

ln -s $HOME/ArcGIS/<version>/sdk/OSX/x64/lib/libEsriRuntimeQt.dylib /usr/lib/libEsriRuntimeQt.dylib

A couple of things I noticed...

1) The SDK is not installed on my machine under $HOME/ArcGIS.  I am running 100.5 and am pretty sure I just accepted the defaults during installation.  Should this documentation be updated or is it just something specific on my machine?  Or do I need to find specific documentation for 100.5?

2) I have the following path...$HOME/ArcGIS_SDKs/Qt100.5/sdk/macOS/x64/lib but do not see libEsriRuntimeQt.dylib as suggested by the above documentation.  What I do have in that folder is: libArcGISRuntimeToolkitCppApi.dylib, libEsriCommonQt.dylib, and libruntimecore.dylib.  Should I make symbolic links to any of these instead?

3) Whenever I try to create the symbolic link, I get "Operation not permitted".  Any suggestions on how to get around this?

I'm running macOS Mojave 10.14.6 and runtime 100.5.  Appreciate the help.

I must need to get the above figured out I guess because whenever I navigate to my *.app content and run manually I get...

qrc:/qml/main.qml:2:1: module "Esri.ArcGISRuntime" is not installed
qrc:/qml/main.qml:1:1: module "Esri.ArcGISExtras" is not installed

Thanks!

Jeremy

0 Kudos
1 Solution

Accepted Solutions
LucasDanzinger
Esri Frequent Contributor

Hey Jeremy-

We need to update that doc. I'll put a ticket in our backlog. At one point there were some issues with the current version (at the time) of macOS and Qt, which required these strange symbolic links to be set up. I don't seem to need to do that anymore.

macdeployqt should take care of most of the hard work, but there are a few manual steps. This is because our 'plugin' library is called libArcGISRuntimePlugin.dylib. That library dynamically links to libEsriCommonQt.dylib, which dynamically links to libruntimecore.dylib. The tool isn't sophisticated enough at this point to find all of the library's dependencies, so after you run the tool, you'll need to copy them in manually and swap around some of the references.

To do this, you can use "install_name_tool -change" command which will come with your Xcode command line tools. I also like to run "otool -L pathToLib", and this will show you all of the library's dependencies. When you create your output app bundle, the goal should be that the various libraries that get copied in are now all looking in relative locations to load the dependencies, and not hardcoded to anything on your system.

Here is an example series of commands that I used on my system.

# run macdeployqt with options
./macdeployqt ~/Desktop/TestMacBuild.app -qmlimport=/Users/username/ArcGIS_SDKs/Qt100.6/sdk/macOS/x64/qml -executable=/Users/username/Desktop/TestMacBuild.app/Contents/MacOS/TestMacBuild -qmldir=/Users/username/qml/TestMacBuild/qml 

# copy in dependent library libEsriCommonQt.dylib
cp /Users/username/ArcGIS_SDKs/Qt100.6/sdk/macOS/x64/lib/libEsriCommonQt.dylib /Users/username/Desktop/TestMacBuild.app/Contents/Frameworks 

# copy in dependent library libruntimecore.dylib
cp /Users/username/ArcGIS_SDKs/Qt100.6/sdk/macOS/x64/lib/libruntimecore.dylib /Users/username/Desktop/TestMacBuild.app/Contents/Frameworks 

# run install_name_tool on the ArcGISRuntime plugin dylib to find EsriCommonQt.dylib
cd /Users/username/Desktop/TestMacBuild.app/Contents/Plugins/quick

install_name_tool -change /Users/username/ArcGIS_SDKs/Qt100.6/sdk/macOS/x64/lib/libEsriCommonQt.dylib @executable_path/../Frameworks/libEsriCommonQt.dylib libArcGISRuntimePlugin.dylib

# check that all references now are relative and not hardcoded to install path
otool -L libArcGISRuntimePlugin.dylib

# run install_name_tool on the EsriCommonQt dylib to find runtimecore.dylib
cd /Users/username/Desktop/TestMacBuild.app/Contents/Frameworks

install_name_tool -change /Users/username/ArcGIS_SDKs/Qt100.6/sdk/macOS/x64/lib/libruntimecore.dylib @executable_path/../Frameworks/libruntimecore.dylib libEsriCommonQt.dylib

# check that all references now are relative and not hardcoded to install path
otool -L libArcGISRuntimePlugin.dylib

View solution in original post

0 Kudos
9 Replies
LucasDanzinger
Esri Frequent Contributor

Hey Jeremy-

We need to update that doc. I'll put a ticket in our backlog. At one point there were some issues with the current version (at the time) of macOS and Qt, which required these strange symbolic links to be set up. I don't seem to need to do that anymore.

macdeployqt should take care of most of the hard work, but there are a few manual steps. This is because our 'plugin' library is called libArcGISRuntimePlugin.dylib. That library dynamically links to libEsriCommonQt.dylib, which dynamically links to libruntimecore.dylib. The tool isn't sophisticated enough at this point to find all of the library's dependencies, so after you run the tool, you'll need to copy them in manually and swap around some of the references.

To do this, you can use "install_name_tool -change" command which will come with your Xcode command line tools. I also like to run "otool -L pathToLib", and this will show you all of the library's dependencies. When you create your output app bundle, the goal should be that the various libraries that get copied in are now all looking in relative locations to load the dependencies, and not hardcoded to anything on your system.

Here is an example series of commands that I used on my system.

# run macdeployqt with options
./macdeployqt ~/Desktop/TestMacBuild.app -qmlimport=/Users/username/ArcGIS_SDKs/Qt100.6/sdk/macOS/x64/qml -executable=/Users/username/Desktop/TestMacBuild.app/Contents/MacOS/TestMacBuild -qmldir=/Users/username/qml/TestMacBuild/qml 

# copy in dependent library libEsriCommonQt.dylib
cp /Users/username/ArcGIS_SDKs/Qt100.6/sdk/macOS/x64/lib/libEsriCommonQt.dylib /Users/username/Desktop/TestMacBuild.app/Contents/Frameworks 

# copy in dependent library libruntimecore.dylib
cp /Users/username/ArcGIS_SDKs/Qt100.6/sdk/macOS/x64/lib/libruntimecore.dylib /Users/username/Desktop/TestMacBuild.app/Contents/Frameworks 

# run install_name_tool on the ArcGISRuntime plugin dylib to find EsriCommonQt.dylib
cd /Users/username/Desktop/TestMacBuild.app/Contents/Plugins/quick

install_name_tool -change /Users/username/ArcGIS_SDKs/Qt100.6/sdk/macOS/x64/lib/libEsriCommonQt.dylib @executable_path/../Frameworks/libEsriCommonQt.dylib libArcGISRuntimePlugin.dylib

# check that all references now are relative and not hardcoded to install path
otool -L libArcGISRuntimePlugin.dylib

# run install_name_tool on the EsriCommonQt dylib to find runtimecore.dylib
cd /Users/username/Desktop/TestMacBuild.app/Contents/Frameworks

install_name_tool -change /Users/username/ArcGIS_SDKs/Qt100.6/sdk/macOS/x64/lib/libruntimecore.dylib @executable_path/../Frameworks/libruntimecore.dylib libEsriCommonQt.dylib

# check that all references now are relative and not hardcoded to install path
otool -L libArcGISRuntimePlugin.dylib
0 Kudos
JeremyRoberts2
New Contributor III

This worked perfectly.  Thanks.

0 Kudos
JeremyRoberts2
New Contributor III

Hi Lucas!  Do we need to run the same install_name_tool against libArcGISExtrasPlugin.dylib?  After getting our app notarized I am getting the following error...

QQmlApplicationEngine failed to load component
qrc:/qml/main.qml:1:1: plugin cannot be loaded for module "Esri.ArcGISExtras": Cannot load library /Users/jr9128/ArcGIS_SDKs/Qt100.7/sdk/macOS/x64/qml/Esri/ArcGISExtras/libArcGISExtrasPlugin.dylib: (dlopen(/Users/jr9128/ArcGIS_SDKs/Qt100.7/sdk/macOS/x64/qml/Esri/ArcGISExtras/libArcGISExtrasPlugin.dylib, 133): no suitable image found.  Did find:
    /Users/jr9128/ArcGIS_SDKs/Qt100.7/sdk/macOS/x64/qml/Esri/ArcGISExtras/libArcGISExtrasPlugin.dylib: code signature in (/Users/jr9128/ArcGIS_SDKs/Qt100.7/sdk/macOS/x64/qml/Esri/ArcGISExtras/libArcGISExtrasPlugin.dylib) not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.)
int main(int, char **) QObject(0x0)
Error: Your root item has to be a Window.

I don't know why it is even trying to access the Extras library there, which made me believe maybe I need to include that in the install_name_tool command?  If I uninstall 100.7 from my machine our app runs fine.  So for some reason when runtime is installed, our app tries accessing the Extras library at the runtime installation path.

Thanks!

0 Kudos
LucasDanzinger
Esri Frequent Contributor

If I understand you correctly, you're saying your app does not use Extras, but there are some references to it somewhere that are causing notarization to fail?

0 Kudos
JeremyRoberts2
New Contributor III

It does use Extras.  Notarization states it succeeds.  But....

1) App crashes upon startup if i have 100.7 installed on my machine

2) If I go into the app folder/content/macos and start from there, I see the error spit back in my terminal referencing libArcGISExtrasPlugin.dylib at a location on my machine (outside of the app folder).  Not sure why it is even referencing that file located somewhere entirely outside of the app.

3) Uninstall 100.7 from my machine, app starts up fine.

Does that make sense?  Well, does my description make sense?  

0 Kudos
LucasDanzinger
Esri Frequent Contributor

I think what you said makes sense. I'm not exactly sure what the problem is - these are tricky problems to fix... Have you tried running install_name_tool on this lib as well?

0 Kudos
JeremyRoberts2
New Contributor III

I have not tried that.  But this begs the question, do I need to manually copy libArcGISExtrasPlugin.dylib into the Frameworks folder of the app?

0 Kudos
LucasDanzinger
Esri Frequent Contributor

not to Frameworks - you should see it under <app_bundle>/Contents/Resources/qml/Esri/ArcGISExtras

If you do not see that, I'd first check the  files inside the directory specified for the qmldir argument (-qmldir=/Users/username/qml/TestMacBuild/qml). Do any of those import ArcGISExtras? My understanding of the macdeployqt tool is it scans all QML files in that location to build up a list of all dependent libraries.

0 Kudos
JeremyRoberts2
New Contributor III

Ah, yeah I do see it under <app_bundle>/Contents/Resources/qml/Esri/ArcGISExtras.  Thanks.  So then it seems as though on my machine if runtime is installed, it is trying to use that location rather than the one in the app.  Do you think there is some link that needs to be changed during the build process?  Do I need to run install_name_tool on something to get it to point to the file in the app_bundle?  I'm not sure what library is calling it.  We have its import inside main.qml and in various JS files.  Seems like to run install_name_tool I'd need to know what runtime file is referencing Extras.

P.S. - I ran the following to make sure all dylibs within my app bundle have no reference to my runtime installation...

#!/bin/bash
for i in $(find . -name "*.dylib"); do
    otool -L $i
done

Then examined the output searching for "jr9128".  Nothing was found.

Could the runtime installer be setting some path that causes the app to try to access the file outside the bundle?  This is only an issue on my machine because it does find the file at the runtime path (which has a foldername specific to me) and of course that particular copy of libArcGISExtrasPlugin.dylib is not notarized.  If we don't attempt to notarize our app at all with Apple it runs too presumably because it doesn't have the extra checks on everything.

0 Kudos