Omnis Technical Note TNEX0008 Dec 2019

Loading external frameworks in macOS Mojave and later

For Omnis Studio 10.x
By Andrei Augustin, Tech Support

With macOS Catalina, Apple has introduced notarization and an overall much more secure operating system.

As a consequence, the rules on loading external frameworks at runtime are stricter. This means that you will need to make some changes if you want your dylib to be loaded by Omnis.

An example of dylib that you may be loading at runtime is the Oracle dylibs which are required to integrate Omnis with the InstantClient, or the dylibs from the SQL Anywhere client.

Previously, you would have created a symbolic link to those dylib and placed them in a specific folder where macOS would look for them when asked by Omnis.

Now, that approach won't load those dylib. However, there are two ways to load dylibs at runtime now which are described below.

More secure approach

The more secure approach is to add your dylib directly into the Omnis.app/Contents/Frameworks folder, then codesign and notarize the application. This is the most secure approach as you would be loading the dylibs from within your application bundle rather than from an arbitrary folder.

Furthermore, with this approach your customers won't have to spend time setting up the required dylib themselves, as you would be supplying them with your application.

However, this also means that if there is an update or a patch to one of the frameworks/dylib, you will need to codesign and notarize again and supply a new application bundle to the customer. In order to overcome this issue, there's a less secure approach.

Less secure approach

In the less secure approach, the dylib can be loaded at runtime from an arbitrary folder. This means that you will be able to replace the dylib in the folder with a newer version without having to go through the process of codesigning and notarizing your application bundle again.

The first step is to make sure your application bundle's standard entitlements include the following com.apple.security.cs.allow-dyld-environment-variables key

<key>com.apple.security.cs.allow-dyld-environment-variables</key>
  <true/>

This entitlement will allow you to use an environment variable to specify a folder which contains the dylibs you wish to load at runtime. The environment library which you need to specify is DYLD_LIBRARY_PATH.

This can be done on the fly by doing "export DYLD_LIBRARY_PATH=/Path/to/folder/containing/dylibs" from the terminal application on macOS (terminal can be found in /Applications/Utilities/Terminal.app).

However, this won't persist when you restart your Mac. In order to make this persistent, you will need to create a LaunchAgent. To do this, you will need to execute the following in your termina app (terminal can be found in /Applications/Utilities/Terminal.app):

  cat << EOF | sudo tee /Library/LaunchAgents/setenv.DYLD_LIBRARY_PATH.plist
  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
    <dict>
    <key>Label</key>
    <string>setenv.DYLD_LIBRARY_PATH</string>
    <key>ProgramArguments</key>
    <array>
      <string>/bin/launchctl</string>
      <string>setenv</string>
      <string>DYLD_LIBRARY_PATH</string>
      <string>/Path/to/folder/containing/dylibs</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
  </dict>
  </plist>
  EOF

Please note that you may be asked for your Mac user password.

This will create the LaunchAgent which will set the DYLD_LIBRARY_PATH environment variable whenever the Mac is started.

The LaunchAgent will obviously not take effect until you restart your Mac, therefore you may want to load it straight away by executing the following in your terminal (terminal can be found in /Applications/Utilities/Terminal.app):

launchctl load -w /Library/LaunchAgents/setenv.DYLD_LIBRARY_PATH.plist

And now, as long as your dylibs are in the folder you specified in your setenv.DYLD_LIBARY_PATH.plist, they will be loaded by Omnis.

This also means that if a newer version of the dylibs is released, you can simply replace it in the folder specified in your setenv.DYLD_LIBARY_PATH.plist, without having to codesign and notarize your application bundle again.

   

Search Omnis Developer Resources

 

Hit enter to search

X