First I have to say I am loving SFML; it's both easy and clean to code in and has great performance.
**My question is how do I compile code that depends on SFML to use a static linked copy of it instead of a dynamic library or framework on OSX?**
---
My objective is static linking for OSX, and in the future probably with Linux (and Windows as a matter of requirement). There was a thread about this [back in 2011](
http://en.sfml-dev.org/forums/index.php?topic=6162.0), for reference. I'll explain my reasoning as best I can.
I don't have anything against dynamic libraries; they do a great job saving hard drive space and eliminating code redundancy. However they impose some serious limitations that affect developers as well as users:
- Software changes and may cause code that depends on it to break unless it is also actively maintained.
- In software that is actively worked on and changes often this is a lot of extra work; fast moving software I see as a good thing.
- Software with dependencies on two (or more) incompatible versions of the same library becomes a problem.
- Anyone who wants to install this software must run through an extra step to install its dependencies, and added complexity reduces users.
As SFML continues to improve I suspect the code may change, and instead of worrying about my software breaking, or adding complexity to installation, I would rather resolve both problems pre-emptively by compiling a copy of the version of SFML that my software depends on, and in a way that does not interfere with anything else on the system. The only cost here is megabytes.
---
Let me preface this by saying **I do not use xCode**, therefore any xCode related answers are not going to help me.
I use Sublime Text, and a terminal. This has worked for me for years, I have no desire to switch to an overcomplicated IDE, which only hides the commands being run and the logic surrounding them.
I have installed gcc and g++ 4.8 via homebrew, and have been using this to compile and build my c++ tests.
I initially installed a global copy of SFML using the supplied `install.sh` script, but have since removed them to test static linking of a local copy of SFML.
---
Here is my complete scenario to clarify my problem.
Let's assume the following layout:
- `src/example.cpp`
- `lib/SFML-2.1/`
The `example.cpp` file contains a simple window that exits on close:
#include <iostream>
#include <string>
#include <SFML/Graphics.hpp>
int main() {
sf::RenderWindow window(sf::VideoMode(600, 600), L"ありがとう");
while(window.isOpen()) {
sf::Event e;
while(window.pollEvent(e)) {
if (e.type == sf::Event::Closed) {
window.close();
}
}
}
return 0;
}
Here are my attempted commands and subsequent errors:
g++ -I lib/SFML-2.1/include/ -c src/example.cpp
g++ -o sfml-example example.o
Undefined symbols for architecture x86_64:
"sf::RenderWindow::RenderWindow(sf::VideoMode, sf::String const&, unsigned int, sf::ContextSettings const&)", referenced from:
_main in example.o
"sf::RenderWindow::~RenderWindow()", referenced from:
_main in example.o
"sf::String::String(wchar_t const*)", referenced from:
_main in example.o
"sf::Window::close()", referenced from:
_main in example.o
"sf::Window::pollEvent(sf::Event&)", referenced from:
_main in example.o
"sf::VideoMode::VideoMode(unsigned int, unsigned int, unsigned int)", referenced from:
_main in example.o
"sf::Window::isOpen() const", referenced from:
_main in example.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
g++ -L lib/SFML-2.1/lib -lsfml-graphics -lsfml-network -lsfml-window -lsfml-system -lsfml-audio -o sfml-example example.o
./sfml-example
dyld: Library not loaded: @executable_path/../Frameworks/libsfml-graphics.2.dylib
Referenced from: /Users/cdelorme/git/test/./sfml-example
Reason: image not found
My assumption at this point is that maybe it won't allow me to use a local library and is forced to search for a dynamic one. So I tried adding the static flag to build:
g++ -static -L lib/SFML-2.1/lib -lsfml-graphics -lsfml-network -lsfml-window -lsfml-system -lsfml-audio -o sfml-example example.o
ld: library not found for -lcrt0.o
collect2: error: ld returned 1 exit status
g++ -static -I lib/SFML-2.1/include/ -c src/example.cpp
g++ -static -L lib/SFML-2.1/lib -lsfml-graphics -lsfml-network -lsfml-window -lsfml-system -lsfml-audio -o sfml-example example.o
ld: library not found for -lcrt0.o
collect2: error: ld returned 1 exit status
g++ -L lib/SFML-2.1/lib -lsfml-graphics -lsfml-network -lsfml-window -lsfml-system -lsfml-audio -o sfml-example example.o
./sfml-example
dyld: Library not loaded: @executable_path/../Frameworks/libsfml-graphics.2.dylib
Referenced from: /Users/cdelorme/git/test/./sfml-example
Reason: image not found
Trace/BPT trap: 5
Here is where I questioned whether or not the precompiled OSX code could even be used without Frameworks, since it appears to be a hardcoded dependency in the prebuilt SFML files. So my next step was trying to build and work around this problem.
_The next set of lines pertain to attempts to build SFML from source at the same `lib/` path, and then compile `example.cpp`:_
cd lib/SFML-2.1
cmake .
-- The C compiler identification is Clang 5.1.0
-- The CXX compiler identification is Clang 5.1.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Found OpenGL: /System/Library/Frameworks/OpenGL.framework
-- Found Freetype: /Users/cdelorme/git/test/lib/SFML-2.1/extlibs/libs-osx/Frameworks/freetype.framework (found version "2.4.11")
-- Found GLEW: /Users/cdelorme/git/test/lib/SFML-2.1/extlibs/libs-osx/lib/libGLEW.a
-- Found JPEG: /Users/cdelorme/git/test/lib/SFML-2.1/extlibs/libs-osx/lib/libjpeg.a
-- Found OpenAL: /System/Library/Frameworks/OpenAL.framework
-- Found SNDFILE: /Users/cdelorme/git/test/lib/SFML-2.1/extlibs/libs-osx/Frameworks/sndfile.framework
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/cdelorme/git/test/lib/SFML-2.1
make all
Scanning dependencies of target sfml-system
[ 1%] Building CXX object src/SFML/System/CMakeFiles/sfml-system.dir/Clock.cpp.o
[ 2%] Building CXX object src/SFML/System/CMakeFiles/sfml-system.dir/Err.cpp.o
[ 3%] Building CXX object src/SFML/System/CMakeFiles/sfml-system.dir/Lock.cpp.o
[ 4%] Building CXX object src/SFML/System/CMakeFiles/sfml-system.dir/Mutex.cpp.o
[ 5%] Building CXX object src/SFML/System/CMakeFiles/sfml-system.dir/Sleep.cpp.o
[ 6%] Building CXX object src/SFML/System/CMakeFiles/sfml-system.dir/String.cpp.o
[ 7%] Building CXX object src/SFML/System/CMakeFiles/sfml-system.dir/Thread.cpp.o
[ 9%] Building CXX object src/SFML/System/CMakeFiles/sfml-system.dir/ThreadLocal.cpp.o
[ 10%] Building CXX object src/SFML/System/CMakeFiles/sfml-system.dir/Time.cpp.o
[ 11%] Building CXX object src/SFML/System/CMakeFiles/sfml-system.dir/Unix/ClockImpl.cpp.o
[ 12%] Building CXX object src/SFML/System/CMakeFiles/sfml-system.dir/Unix/MutexImpl.cpp.o
[ 13%] Building CXX object src/SFML/System/CMakeFiles/sfml-system.dir/Unix/SleepImpl.cpp.o
[ 14%] Building CXX object src/SFML/System/CMakeFiles/sfml-system.dir/Unix/ThreadImpl.cpp.o
[ 15%] Building CXX object src/SFML/System/CMakeFiles/sfml-system.dir/Unix/ThreadLocalImpl.cpp.o
Linking CXX shared library ../../../lib/libsfml-system.dylib
[ 15%] Built target sfml-system
Scanning dependencies of target sfml-window
[ 17%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/Context.cpp.o
[ 18%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/GlContext.cpp.o
[ 19%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/GlResource.cpp.o
[ 20%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/Joystick.cpp.o
[ 21%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/JoystickManager.cpp.o
[ 22%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/Keyboard.cpp.o
[ 23%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/Mouse.cpp.o
[ 25%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/VideoMode.cpp.o
[ 26%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/Window.cpp.o
[ 27%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/WindowImpl.cpp.o
[ 28%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/OSX/cpp_objc_conversion.mm.o
[ 29%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/OSX/cg_sf_conversion.cpp.o
[ 30%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/OSX/InputImpl.mm.o
[ 31%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/OSX/HIDInputManager.mm.o
/Users/cdelorme/git/test/lib/SFML-2.1/src/SFML/Window/OSX/HIDInputManager.mm:923:2: warning: sf::Keyboard::Tilde might be in conflict with some other key.
[-W#warnings]
#warning sf::Keyboard::Tilde might be in conflict with some other key.
^
/Users/cdelorme/git/test/lib/SFML-2.1/src/SFML/Window/OSX/HIDInputManager.mm:1015:2: warning: keycode 0x1b is not bound to any key. [-W#warnings]
#warning keycode 0x1b is not bound to any key.
^
2 warnings generated.
[ 32%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/OSX/HIDJoystickManager.cpp.o
[ 34%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/OSX/JoystickImpl.cpp.o
[ 35%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/OSX/SFApplication.m.o
[ 36%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/OSX/SFContext.mm.o
[ 37%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/OSX/SFKeyboardModifiersHelper.mm.o
[ 38%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/OSX/SFOpenGLView.mm.o
[ 39%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/OSX/SFSilentResponder.m.o
[ 40%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/OSX/SFWindow.m.o
[ 42%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/OSX/SFWindowController.mm.o
[ 43%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/OSX/SFViewController.mm.o
[ 44%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/OSX/VideoModeImpl.cpp.o
[ 45%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/OSX/WindowImplCocoa.mm.o
/Users/cdelorme/git/test/lib/SFML-2.1/src/SFML/Window/OSX/WindowImplCocoa.mm:135:14: warning: 'GetCurrentProcess' is deprecated: first deprecated in OS X 10.9
[-Wdeprecated-declarations]
if (!GetCurrentProcess(&psn)) {
^
/System/Library/Frameworks/ApplicationServices.framework/Frameworks/HIServices.framework/Headers/Processes.h:415:1: note: 'GetCurrentProcess' declared here
MacGetCurrentProcess(ProcessSerialNumber * PSN) AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9;
^
/System/Library/Frameworks/ApplicationServices.framework/Frameworks/HIServices.framework/Headers/Processes.h:412:34: note: expanded from macro 'MacGetCurrentProcess'
#define MacGetCurrentProcess GetCurrentProcess
^
/Users/cdelorme/git/test/lib/SFML-2.1/src/SFML/Window/OSX/WindowImplCocoa.mm:137:13: warning: 'SetFrontProcess' is deprecated: first deprecated in OS X 10.9
[-Wdeprecated-declarations]
SetFrontProcess(&psn);
^
/System/Library/Frameworks/ApplicationServices.framework/Frameworks/HIServices.framework/Headers/Processes.h:603:1: note: 'SetFrontProcess' declared here
SetFrontProcess(const ProcessSerialNumber * PSN) AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_9;
^
2 warnings generated.
[ 46%] Building CXX object src/SFML/Window/CMakeFiles/sfml-window.dir/OSX/AutoreleasePoolWrapper.mm.o
Linking CXX shared library ../../../lib/libsfml-window.dylib
[ 46%] Built target sfml-window
Scanning dependencies of target sfml-network
[ 47%] Building CXX object src/SFML/Network/CMakeFiles/sfml-network.dir/Ftp.cpp.o
[ 48%] Building CXX object src/SFML/Network/CMakeFiles/sfml-network.dir/Http.cpp.o
[ 50%] Building CXX object src/SFML/Network/CMakeFiles/sfml-network.dir/IpAddress.cpp.o
[ 51%] Building CXX object src/SFML/Network/CMakeFiles/sfml-network.dir/Packet.cpp.o
[ 52%] Building CXX object src/SFML/Network/CMakeFiles/sfml-network.dir/Socket.cpp.o
[ 53%] Building CXX object src/SFML/Network/CMakeFiles/sfml-network.dir/SocketSelector.cpp.o
[ 54%] Building CXX object src/SFML/Network/CMakeFiles/sfml-network.dir/TcpListener.cpp.o
[ 55%] Building CXX object src/SFML/Network/CMakeFiles/sfml-network.dir/TcpSocket.cpp.o
[ 56%] Building CXX object src/SFML/Network/CMakeFiles/sfml-network.dir/UdpSocket.cpp.o
[ 57%] Building CXX object src/SFML/Network/CMakeFiles/sfml-network.dir/Unix/SocketImpl.cpp.o
Linking CXX shared library ../../../lib/libsfml-network.dylib
[ 57%] Built target sfml-network
Scanning dependencies of target sfml-graphics
[ 59%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/Color.cpp.o
[ 60%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/Font.cpp.o
[ 61%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/GLCheck.cpp.o
[ 62%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/Image.cpp.o
[ 63%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/ImageLoader.cpp.o
[ 64%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/RenderStates.cpp.o
[ 65%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/RenderTexture.cpp.o
[ 67%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/RenderTarget.cpp.o
[ 68%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/RenderWindow.cpp.o
[ 69%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/Shader.cpp.o
[ 70%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/Texture.cpp.o
[ 71%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/TextureSaver.cpp.o
[ 72%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/Transform.cpp.o
[ 73%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/Transformable.cpp.o
[ 75%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/View.cpp.o
[ 76%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/Vertex.cpp.o
[ 77%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/Shape.cpp.o
[ 78%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/CircleShape.cpp.o
[ 79%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/RectangleShape.cpp.o
[ 80%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/ConvexShape.cpp.o
[ 81%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/Sprite.cpp.o
[ 82%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/Text.cpp.o
[ 84%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/VertexArray.cpp.o
[ 85%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/RenderTextureImpl.cpp.o
[ 86%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/RenderTextureImplFBO.cpp.o
[ 87%] Building CXX object src/SFML/Graphics/CMakeFiles/sfml-graphics.dir/RenderTextureImplDefault.cpp.o
Linking CXX shared library ../../../lib/libsfml-graphics.dylib
[ 87%] Built target sfml-graphics
Scanning dependencies of target sfml-audio
[ 88%] Building CXX object src/SFML/Audio/CMakeFiles/sfml-audio.dir/ALCheck.cpp.o
[ 89%] Building CXX object src/SFML/Audio/CMakeFiles/sfml-audio.dir/AudioDevice.cpp.o
[ 90%] Building CXX object src/SFML/Audio/CMakeFiles/sfml-audio.dir/Listener.cpp.o
[ 92%] Building CXX object src/SFML/Audio/CMakeFiles/sfml-audio.dir/Music.cpp.o
[ 93%] Building CXX object src/SFML/Audio/CMakeFiles/sfml-audio.dir/Sound.cpp.o
[ 94%] Building CXX object src/SFML/Audio/CMakeFiles/sfml-audio.dir/SoundBuffer.cpp.o
[ 95%] Building CXX object src/SFML/Audio/CMakeFiles/sfml-audio.dir/SoundBufferRecorder.cpp.o
[ 96%] Building CXX object src/SFML/Audio/CMakeFiles/sfml-audio.dir/SoundFile.cpp.o
[ 97%] Building CXX object src/SFML/Audio/CMakeFiles/sfml-audio.dir/SoundRecorder.cpp.o
[ 98%] Building CXX object src/SFML/Audio/CMakeFiles/sfml-audio.dir/SoundSource.cpp.o
[100%] Building CXX object src/SFML/Audio/CMakeFiles/sfml-audio.dir/SoundStream.cpp.o
Linking CXX shared library ../../../lib/libsfml-audio.dylib
[100%] Built target sfml-audio
cd ../..
g++ -I lib/SFML-2.1/include/ -c src/example.cpp
g++ -L lib/SFML-2.1/lib -lsfml-graphics -lsfml-network -lsfml-window -lsfml-system -lsfml-audio -o sfml-example example.o
./sfml-example
dyld: Library not loaded: @executable_path/../Frameworks/libsfml-graphics.2.dylib
Referenced from: /Users/cdelorme/git/test/./sfml-example
Reason: image not found
Trace/BPT trap: 5
g++ -static -L lib/SFML-2.1/lib -lsfml-graphics -lsfml-network -lsfml-window -lsfml-system -lsfml-audio -o sfml-example example.o
g++ -static -L lib/SFML-2.1/lib -lsfml-graphics -lsfml-network -lsfml-window -lsfml-system -lsfml-audio -o sfml-example example.o
ld: library not found for -lcrt0.o
collect2: error: ld returned 1 exit status
I read up on [compiling sfml](
http://www.sfml-dev.org/tutorials/2.1/compile-with-cmake.php), unfortunately any attempt to set the various flags in cmake resulted in configuration failure, so I have no idea what I can or cannot modify. Obviously I would rather use gcc/g++ to build SFML, also I would like to **not** use frameworks, and in spite of static linking SFML dependencies being a "Windows Only" option, I would like the ability to do the same on OSX.
If you would like me to supply my alternative `cmake` attempts and `CMakeOutput.log` files I would be happy to.
---
This leaves me off back where I started.
**Repeating my original question from above, am I still wondering how to compile code that depends on SFML to use a static linked copy of it instead of a dynamic library or framework on OSX.**