OSX GCC how to specify sfml library source?

2019-03-22 02:32发布

问题:

I'm trying to compile a project that uses sfml I installed sfml 2.1 through homebrew like below

unknown542696d2a12b:keeperrl kevzettler$ brew list sfml
    /usr/local/Cellar/sfml/2.1/Frameworks/freetype.framework/ (3 files)
    /usr/local/Cellar/sfml/2.1/Frameworks/sndfile.framework/ (3 files)
    /usr/local/Cellar/sfml/2.1/include/SFML/ (87 files)
    /usr/local/Cellar/sfml/2.1/lib/libsfml-audio.2.1.dylib
    /usr/local/Cellar/sfml/2.1/lib/libsfml-graphics.2.1.dylib
    /usr/local/Cellar/sfml/2.1/lib/libsfml-network.2.1.dylib
    /usr/local/Cellar/sfml/2.1/lib/libsfml-system.2.1.dylib
    /usr/local/Cellar/sfml/2.1/lib/libsfml-window.2.1.dylib
    /usr/local/Cellar/sfml/2.1/lib/ (10 other files)
    /usr/local/Cellar/sfml/2.1/share/SFML/ (3 files)

The project compiles ok however when I try to run it I get an error:

unknown542696d2a12b:keeperrl kevzettler$ ./keeper
dyld: Library not loaded: @executable_path/../Frameworks/freetype.framework/Versions/A/freetype
  Referenced from: /usr/local/lib/libsfml-graphics.2.dylib
  Reason: image not found
Trace/BPT trap: 5

It looks like dyld is trying to load a different version of sfml. Than the one installed from homebrew I suspect this is some system default from OSX.

The compile command looks like:

 /usr/local/Cellar/gcc49/4.9.0/bin/gcc-4.9 -Wall -std=c++0x -lstdc++ -ftemplate-depth=1024 -Wno-sign-compare -Wno-unused-variable \
-I. -I./extern -I/usr/local/Cellar/boost/1.55.0/include/boost/ -I/usr/local/Cellar/boost/1.55.0/lib -I/usr/local/Cellar/sfml/2.1/include/SFML/ -I/usr/local/Cellar/sfml/2.1/lib/ -static-libstdc++ -g -O3 -o keeper \
obj-opt/time_queue.o obj-opt/level.o obj-opt/model.o obj-opt/square.o obj-opt/util.o obj-opt/monster.o obj-opt/square_factory.o obj-opt/view.o obj-opt/creature.o obj-opt/message_buffer.o obj-opt/item_factory.o obj-opt/item.o obj-opt/inventory.o obj-opt/debug.o obj-opt/player.o obj-opt/window_view.o obj-opt/field_of_view.o obj-opt/view_object.o obj-opt/creature_factory.o obj-opt/quest.o obj-opt/shortest_path.o obj-opt/effect.o obj-opt/equipment.o obj-opt/level_maker.o obj-opt/monster_ai.o obj-opt/attack.o obj-opt/tribe.o obj-opt/name_generator.o obj-opt/event.o obj-opt/location.o obj-opt/skill.o obj-opt/fire.o obj-opt/ranged_weapon.o obj-opt/map_layout.o obj-opt/trigger.o obj-opt/map_memory.o obj-opt/view_index.o obj-opt/pantheon.o obj-opt/enemy_check.o obj-opt/collective.o obj-opt/task.o obj-opt/markov_chain.o obj-opt/controller.o obj-opt/village_control.o obj-opt/poison_gas.o obj-opt/minion_equipment.o obj-opt/statistics.o obj-opt/options.o obj-opt/renderer.o obj-opt/tile.o obj-opt/map_gui.o obj-opt/gui_elem.o obj-opt/item_attributes.o obj-opt/creature_attributes.o obj-opt/serialization.o obj-opt/unique_entity.o obj-opt/entity_set.o obj-opt/gender.o obj-opt/main.o obj-opt/gzstream.o obj-opt/singleton.o obj-opt/technology.o obj-opt/encyclopedia.o obj-opt/creature_view.o obj-opt/input_queue.o obj-opt/user_input.o obj-opt/window_renderer.o obj-opt/texture_renderer.o obj-opt/minimap_gui.o obj-opt/music.o obj-opt/test.o obj-opt/sectors.o obj-opt/vision.o \
-lsfml-graphics -lsfml-audio -lsfml-window -lsfml-system -lboost_serialization -lz -L/usr/local/Cellar

I've tried specifying -I and -L flags to point at the 2.1 library

-I/usr/local/Cellar/sfml/2.1/include/SFML/ -I/usr/local/Cellar/sfml/2.1/lib/ -L/usr/local/Cellar

回答1:

Why doesn't SFML formula work out of the box?

SFML was built to use freetype and libsndfile frameworks from /Library/Frameworks or from the Frameworks folder in your application bundle.

You can find more technical details here and there.

How can I use SFML on Mac easily?

It's really easy: follow 1:1 the official guide: SFML and Xcode (Mac OS X) (And yes, you can use SFML outside Xcode!)

I really want to use brew formula. How can I fix it?

First, take a good look at this issue. That would give you an overview of the problems with the current naïve formula.

Specifically to you current issue, you will need to use install_name_tool to fix your binaries.

Here is how you can do it for freetype. It's similar for libsndfile.

install_name_tool -change @executable_path/../Frameworks/freetype.framework/Versions/A/freetype /usr/local/lib/libfreetype.dylib /usr/local/Cellar/sfml/2.1/lib/libsfml-graphics.2.1.dylib

However, this means your app will look for freetype in /usr/local/lib. Hence, you would have to install freetype there on your clients' computers too. This is not the case if you use the official installation procedure and use Xcode templates to create a SFML app.



回答2:

SFML assumes you're building a .app bundle. Notice it's complaining about not finding FreeType, which is a dependency of SFML (it's not complaining about finding SFML). And notice where it's looking for FreeType: @executable_path/../Frameworks/freetype.framework/Versions/A/freetype.

If your program (keeper) is in ., then OS X is looking for FreeType in ./../Frameworks/freetype.framework/Versions/A/freetype, and it's complaining that it can't find it. That because those SFML libraries think you've created a .app bundle, which would then have the necessary/assumed folder structure.

Your options are:

  • Build a .app bundle that includes everything
  • Put the dependencies (FreeType and sndfile) in the right spot manually (i.e. @executable_path/../Frameworks/freetype.framework/Versions/A/freetype)
  • Build SFML yourself and change where/how it looks for its dependencies