2

So the GStreamer documentation for 1.0+ seems to be...lacking to say the least. The GStreamer SDK has some helpul tips, but unforutnately they fall short.

So, here's what I've done. I've built an application that calls upon GStreamer in /Library/GStreamer.Framework/

I build using command-line tools. This is the only way I can build this application. I can't use the XCode GUI.

I want to submit this app to the store, but to do so I can't submit it as a package (so I can bundle the GStreamer package installer) which means I'll have to bundle GStreamer.framework with my application.

In the GStreamer SDK docs above, you will notice a tool called osxrelocator.py. This is great, because it changes all refrences of /Library/GStreamer.Framework to @executable_path/../Frameworks/GStreamer.framework/

BUT

Unfortunately all of the GStreamer .dylibs have an issue... You need to use install_name_tool -id to change their paths because install_name_tool -change doesn't change the paths to themselves!

So, for example using otool:

$ otool -L Application.app/Contents/Frameworks/GStreamer.framework/Versions/1.0/lib/libgstreamer-1.0.0.dylib
Application.app/Contents/Frameworks/GStreamer.framework/Versions/1.0/lib/libgstreamer-1.0.0.dylib:
    Library/Frameworks/GStreamer.framework/Versions/1.0/lib/libgstreamer-1.0.0.dylib (compatibility version 402.0.0, current version 402.0.0)
    Library/Frameworks/Frameworks/GStreamer.framework/Versions/1.0/lib/libgobject-2.0.0.dylib (compatibility version 4001.0.0, current version 4001.0.0)
    Library/Frameworks/GStreamer.framework/Versions/1.0/lib/libffi.6.dylib (compatibility version 7.0.0, current version 7.1.0)
    Library/Frameworks/GStreamer.framework/Versions/1.0/lib/libgmodule-2.0.0.dylib (compatibility version 4001.0.0, current version 4001.0.0)
    Library/Frameworks/Frameworks/GStreamer.framework/Versions/1.0/lib/libglib-2.0.0.dylib (compatibility version 4001.0.0, current version 4001.0.0)
    Library/Frameworks/Frameworks/GStreamer.framework/Versions/1.0/lib/libintl.8.dylib (compatibility version 10.0.0, current version 10.2.0)
    Library/Frameworks/Frameworks/GStreamer.framework/Versions/1.0/lib/libiconv.2.dylib (compatibility version 8.0.0, current version 8.1.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 855.14.0)

Then using osxrelocator.py (which invokes install_name_tool -change):

./osxrelocator.py Application.app/Contents/MacOS /Library/Frameworks/GStreamer.framework/Versions/Current/lib @executable_path/../Frameworks/GStreamer.framework/Versions/Current/lib -r

Gives:

$ otool -L Application.app/Contents/Frameworks/GStreamer.framework/Versions/1.0/lib/libgstreamer-1.0.0.dylib
Application.app/Contents/Frameworks/GStreamer.framework/Versions/1.0/lib/libgstreamer-1.0.0.dylib:
    /Library/Frameworks/GStreamer.framework/Versions/1.0/lib/libgstreamer-1.0.0.dylib (compatibility version 402.0.0, current version 402.0.0)
    @executable_path/../Frameworks/GStreamer.framework/Versions/1.0/lib/libgobject-2.0.0.dylib (compatibility version 4001.0.0, current version 4001.0.0)
    @executable_path/../Frameworks/GStreamer.framework/Versions/1.0/lib/libffi.6.dylib (compatibility version 7.0.0, current version 7.1.0)
    @executable_path/../Frameworks/GStreamer.framework/Versions/1.0/lib/libgmodule-2.0.0.dylib (compatibility version 4001.0.0, current version 4001.0.0)
    @executable_path/../Frameworks/GStreamer.framework/Versions/1.0/lib/libglib-2.0.0.dylib (compatibility version 4001.0.0, current version 4001.0.0)
    @executable_path/../Frameworks/GStreamer.framework/Versions/1.0/lib/libintl.8.dylib (compatibility version 10.0.0, current version 10.2.0)
    @executable_path/../Frameworks/GStreamer.framework/Versions/1.0/lib/libiconv.2.dylib (compatibility version 8.0.0, current version 8.1.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 855.14.0)

Notice that first line where the .dylib references itself? That's doesn't change to @executable_path/../Frameworks/GStreamer.framework/ unless you invoke install_name_tool -id. And this happens with EVERY .dylib in the GStreamer framework! There are hundreds of them and I'm sure doing this manually is definitely going to cause errors.

Hopefully I've made my issue clear. Does anyone have any suggestions as to what to do?

Thanks!

SRG3006
  • 447
  • 8
  • 21
  • I was thinking of possibly statically linking the file? This poses a problem though of the following: I use ldflags to link using: -F/Library/Frameworks -framework GStreamer and it doesn't seem there's a way to statically link a framework? – SRG3006 Sep 18 '14 at 12:51

1 Answers1

2

I created a simple Xcode project to show you how to bundle the framework: https://github.com/corrosion/gstreamer-osx-bundle.git


For library relocation use: https://github.com/tito/osxrelocator


Setup to build a project with XCode:

  • Install gstreamer-1.0-1.5.2-x86_64.pkg
  • Install gstreamer-1.0-devel-1.5.2-x86_64.pkg
  • Move /Library/Frameworks/GStreamer.framework to $(PROJECT_DIR)/GStreamer-devel.framework
  • Go to the $(PROJECT_DIR) and run the following commands:
  • osxrelocator ./GStreamer-devel.framework/Versions/Current /Library/Frameworks/GStreamer.framework/pwd/GStreamer-devel.framework/
  • install_name_tool -id @executable_path/../Frameworks/GStreamer.framework/GStreamer ./GStreamer-devel.framework/Versions/Current/GStreamer
  • Add "$(PROJECT_DIR)/GStreamer-devel.framework/Headers" to Header Search Paths
  • Add "GStreamer-devel.framework/GStreamer" file to the Xcode project

Prepare the runtime framework:

  • Install gstreamer-1.0-1.5.2-x86_64.pkg
  • Move /Library/Frameworks/GStreamer.framework to $(PROJECT_DIR)/GStreamer.framework
  • Do some clean up of the framework:
  • rm ./GStreamer.framework/Headers ./GStreamer.framework/Commands
  • rm ./GStreamer.framework/Versions/Current/Commands
  • rm -r ./GStreamer.framework/Versions/Current/bin/
  • rm -r ./GStreamer.framework/Versions/Current/etc/
  • rm -r ./GStreamer.framework/Versions/Current/share/
  • Relocate the framework's .dylibs:
  • osxrelocator -r ./GStreamer.framework/Versions/Current /Library/Frameworks/GStreamer.framework/ @executable_path/../Frameworks/GStreamer.framework/
  • Since gst-plugin-scanner is executed during gst_init it also has to be able to find all libraries. So create link to "Frameworks" in the libexec directory to resolve @executable_path/../Frameworks/GStreamer.framework/
  • ln -sf ../../../../ GStreamer.framework/Versions/Current/libexec/Frameworks
  • In the project's Build Phases settings create new Copy Files Phase and copy the GStreamer.framework to Fameworks

Set GST_PLUGIN_SCANNER and GST_PLUGIN_SYSTEM_PATH environment variables in code before calling gst_init():

// Setup GSTreamer environment
NSString *frameworksPath = [[NSBundle mainBundle] privateFrameworksPath];
NSString *scannerPath = [NSString stringWithFormat:@"%@/%s", frameworksPath,
                         "GStreamer.framework/Versions/1.0/libexec/gstreamer-1.0/gst-plugin-scanner"];
NSString *pluginsPath = [NSString stringWithFormat:@"%@/%s", frameworksPath,
                         "GStreamer.framework/Versions/1.0/lib"];
setenv("GST_PLUGIN_SCANNER", [scannerPath UTF8String], 1);
setenv("GST_PLUGIN_SYSTEM_PATH", [pluginsPath UTF8String], 1);

// Initialize GStreamer
gst_init(&argc, (char ***) &argv);
corro
  • 343
  • 3
  • 15