Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Linking problem, Mac 10.5.8 SFML 1.6  (Read 3821 times)

0 Members and 1 Guest are viewing this topic.

Keybounce

  • Newbie
  • *
  • Posts: 3
    • View Profile
Linking problem, Mac 10.5.8 SFML 1.6
« on: June 22, 2010, 08:58:07 pm »
I am having trouble getting an SMFL program to link when compiled from source.

The program is Vba-M. It is the first Cmake based program I've worked with.

The final linking stage has this command:

/usr/bin/c++   -O3 -Wall -Wl,-search_paths_first -headerpad_max_install_names  CMakeFiles/vbam.dir/src/sdl/debugger.o CMakeFiles/vbam.dir/src/sdl/SDL.o CMakeFiles/vbam.dir/src/sdl/dummy.o CMakeFiles/vbam.dir/src/sdl/filters.o CMakeFiles/vbam.dir/src/sdl/text.o CMakeFiles/vbam.dir/src/sdl/inputSDL.o CMakeFiles/vbam.dir/src/common/SoundSDL.o CMakeFiles/vbam.dir/src/sdl/expr.o CMakeFiles/vbam.dir/src/sdl/exprNode.o CMakeFiles/vbam.dir/src/sdl/expr-lex.o CMakeFiles/vbam.dir/src/filters/hq/c/hq_implementation.o  -o vbam  -L/opt/local/lib -F/opt/local/Library/Frameworks libvbamcore.a -lSDLmain /opt/local/lib/libSDL.dylib -framework Cocoa /usr/lib/libz.dylib /opt/local/lib/libpng.dylib -framework AGL -framework OpenGL -framework sfml-system -framework sfml-audio -framework sfml-graphics -framework sfml-network -framework sfml-window libfex.a -framework SFML



That has an "-F/opt/local/Library/Frameworks". That's where the SFML libraries are located.

Running it gives this error:

Kleiman-ibook:trunk michael$ ./vbam
dyld: Library not loaded: @executable_path/../Frameworks/sfml-system.framework/Versions/A/sfml-system
  Referenced from: /Volumes/Michael/Documents/Development/vbam/trunk/./vbam
  Reason: image not found
Trace/BPT trap

What do I need to do to link an SFML application on the Mac?

10.5.8, PPC. Universal 32 bit binary image downloaded.

(See also: http://vba-m.com/forum/compiling-on-mac-os-x-t-436.html#pid3712 )
placeholder

Ceylo

  • Hero Member
  • *****
  • Posts: 2325
    • View Profile
    • http://sfemovie.yalir.org/
    • Email
Linking problem, Mac 10.5.8 SFML 1.6
« Reply #1 on: June 23, 2010, 01:39:04 am »
Even if linking succeeds, when launching your app, Mac OS X cannot automatically find the SFML frameworks in the directory you're using.

You only have two possibilities, and both are explained in the tutorial : put the frameworks in the default system directory (/Library/Frameworks), or put them into the application.

See the tutorial (Distribute your application) for more details.


Edit: as for your work-around, it'll only work for you (until you expect every user to type the command you wrote).

And as for the path of the rom file, when using SFML, paths are relative to the Resources folder (<your app>.app/Contents/Resources) as soon as you build a bundle application; and relative to the executable itself when you build a bare executable program (though I admit there hasn't been a lot of testing done on this last possiblity...).
Want to play movies in your SFML application? Check out sfeMovie!

Keybounce

  • Newbie
  • *
  • Posts: 3
    • View Profile
Linking problem, Mac 10.5.8 SFML 1.6
« Reply #2 on: June 23, 2010, 06:08:21 pm »
Quote from: "Ceylo"
Even if linking succeeds, when launching your app, Mac OS X cannot automatically find the SFML frameworks in the directory you're using.


That's odd. otool -L reports some absolute pathnames for frameworks.

... Hmm, it seems to have absolutes for system frameworks and any dynamic library, but not for user frameworks.

Alright, why did Apple make that sort of limitation in the framework linking? Never mind.

(Expecting that everyone will ship the frameworks that they use, to prevent versioning issues? Well, fine, but that doesn't explain why the dynamic libraries can be hardcoded.)
placeholder

Ceylo

  • Hero Member
  • *****
  • Posts: 2325
    • View Profile
    • http://sfemovie.yalir.org/
    • Email
Linking problem, Mac 10.5.8 SFML 1.6
« Reply #3 on: June 23, 2010, 07:19:15 pm »
Well, what I wrote was partly wrong, Mac OS X is not the only one responsible here.

I mean... there is a path saved in every framework. This path defines where the OS will have to look for the framework when a program linked to this framework is launched. This path is called the install name.

For example : most of the OS framework have an absolute install name, which is /System/Library/Frameworks/framework_name.framework/Versions/Current/framework_name. Thus when you build a program and link against this framework, this path will be saved in the executable, and that's where Mac OS X will try to find the framework.

If the framework is not found, the OS will look for some other default directories. Some of these are : /System/Library/Frameworks, /Library/Frameworks and /System/Library/PrivateFrameworks.

Now consider that you want your framework to be bundled in your application (let's say the SFML framework). You can't define an absolute path, because as soon as you move your app, the OS will no more be able to find the frameworks in it (as the frameworks moved with the app). The solution is to use a path relative to the program. This can be done with the following path : @executable_path/../Frameworks/...

In a bundle application, you may know files are structured as follow :
Code: [Select]
app_name.app
 + Contents
     + MacOS
     + Resources
     + Frameworks


The executable is contained in the MacOS directory, and the frameworks you want to provide with you app, in the Frameworks directory (the "Frameworks" name is a convention rather than an obligation).

Thus with the path I wrote, when the executable is loaded by the OS, the OS will be able to find the frameworks in the "Frameworks" directory of the app.



Now... your problem... you cannot install the framework in a specific directory until you change the install name of this framework and redo the linking step of the executable. When doing so, the OS will check for your framework in the directory you set. To do so, there is the "install_name_tool" command line utility. Thus in your case, you would have to redefine the SFML frameworks install names and it would give something like that :
Code: [Select]
install_name_tool -id /opt/local/Library/Frameworks/sfml-system.framework/Versions/Current/sfml-system /path/to/your/framework/sfml-system.framework/Versions/Current/sfml-system
With this line, the install name of the sfml-system framework will be modified and, after having linked a program against this framework, Mac OS X will first look in the /opt/local/Library/Frameworks directory (and then in the default framework OS directories).



So the issue you're having is because the current install name of the SFML framework is relative to the executable (and targets the Frameworks directory in the app). This has been done to allow the SFML users to provide the frameworks directly in the app.
Want to play movies in your SFML application? Check out sfeMovie!

Keybounce

  • Newbie
  • *
  • Posts: 3
    • View Profile
Linking problem, Mac 10.5.8 SFML 1.6
« Reply #4 on: June 23, 2010, 10:25:27 pm »
Ahh. Thank you.

That is a tool (install_name_tool) that I had never seen mentioned before, nor the idea that a library/framework includes a "Where to find me" separate from its actual location.

As for the "Frameworks" section of a bundle, I thought that magic was done by the dynamic linker, and not by hardcoding a "relative" pathname in anything.

====

There is a option to ld that actually does what I want:
Code: [Select]

   -dylib_file install_name:file_name
                 Specifies that a dynamic shared library is in a different
                 location than its standard location. Use this option when you
                 link with a library that is dependent on a dynamic library,
                 and the dynamic library is in a location other than its
                 default location. install_name specifies the path where the
                 library normally resides. file_name specifies the path of the
                 library you want to use instead. For example, if you link to
                 a library that depends upon the dynamic library libsys and
                 you have libsys installed in a nondefault location, you would
                 use this option: -dylib_file /lib/lib-
                 sys_s.A.dylib:/me/lib/libsys_s.A.dylib.

This is what I thought was default behavior, but has to be specified.
I would not have found this without your hint about install_name_tool

---
So I think my final solution will be to put it into /Library, and leave /opt to MacPorts.
placeholder