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

Author Topic: Static Linking 2014?  (Read 5810 times)

0 Members and 1 Guest are viewing this topic.

cdelorme

  • Newbie
  • *
  • Posts: 13
    • View Profile
Static Linking 2014?
« on: June 12, 2014, 04:47:36 am »
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"&#12354;&#12426;&#12364;&#12392;&#12358;");
        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:

Code: [Select]
    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:

Code: [Select]

    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`:_

Code: [Select]

    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.**
« Last Edit: June 12, 2014, 02:38:21 pm by cdelorme »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10838
    • View Profile
    • development blog
    • Email
Re: Static Linking 2014?
« Reply #1 on: June 12, 2014, 09:04:44 am »
For code please use the [code=cpp]// Your code[/code] tags and for commands use the [code]command[/code] tags. It will make your post a lot more readable.

You of course need to build the SFML libraries statically first, just running CMake will build the dynamic libraries. For me the easiest way to go about with CMake, if you don't know the flags etc, is to use the GUI version (cmake-gui). I've no idea how easy it work on OS X, but on Windows and Linux you essentially just have to uncheck BUILD_SHARED_LIBS. I guess since you're using the command line, you might want to uncheck SFML_BUILD_FRAMEWORKS and SFML_INSTALL_XCODE4_TEMPLATES, then again I've no idea about OS X development.

If everything goes right, you should get libraries with the suffix -s which indicates static libraries. From there on you can link the SFML libs against you application, but keep the link order in mind! A possible order would be sfml-graphics-s, sfml-window-s, sfml-network-s, sfml-audio-s, sfml-system-s - every module depends on sfml-system as such it has to be the last in the list.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

cdelorme

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Static Linking 2014?
« Reply #2 on: June 12, 2014, 02:47:04 pm »
Thank you very much for your reply eXpl0it3r.

I added code tags to my post, sorry about that.  Used to typing in markdown and rarely use bbcode.

The flags are documented in the [tutorial page](http://www.sfml-dev.org/tutorials/2.1/compile-with-cmake.php), and so far any attempt to change them has caused config errors.  I will try again tonight with cmake-gui and post the output.  OSX development should be very similar to linux, seeing as it is a unix derivative.  Unless I'm depending on specific OSX components in my code.

I'm assuming you've gotten the `-s` in the names on linux or windows.  Do you happen to know if it will also have a file extension like `.dylib`?  I was not aware of order importance; thank you for bringing that to my attention.

cdelorme

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Static Linking 2014?
« Reply #3 on: June 13, 2014, 06:30:09 am »
I gave it a go and still don't have it working.

It seems that osx does not have a cmake-gui, I looked and found nothing.  On my system I have `cmake`, `cmakexbuild` (which uses xcode).  Most references of running cmake from command line show arguments as being in the `-NAME=<value>` format, so I just worked under that assumption.

Starting with a fresh copy of SFML-2.1 source, from the source folder, here are the commands I issued and subsequent output:

Code: [Select]

    mkdir build
    cd build
    cmake -SFML_INSTALL_XCODE4_TEMPLATES=false -SFML_BUILD_FRAMEWORKS=false -BUILD_SHARED_LIBS=false ..
    -- 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/build


So far so good, it didn't throw configuration errors, next step:

Code: [Select]

    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


It built successfully.  However, this is where things diverge a bit.  The libs it created do not have the `-s` suffix, so I don't know if they are static.  Here are the names:

Code: [Select]

    libsfml-audio.2.1.dylib*
    libsfml-audio.2.dylib@ -> libsfml-audio.2.1.dylib
    libsfml-audio.dylib@ -> libsfml-audio.2.dylib
    libsfml-graphics.2.1.dylib*
    libsfml-graphics.2.dylib@ -> libsfml-graphics.2.1.dylib
    libsfml-graphics.dylib@ -> libsfml-graphics.2.dylib
    libsfml-network.2.1.dylib*
    libsfml-network.2.dylib@ -> libsfml-network.2.1.dylib
    libsfml-network.dylib@ -> libsfml-network.2.dylib
    libsfml-system.2.1.dylib*
    libsfml-system.2.dylib@ -> libsfml-system.2.1.dylib
    libsfml-system.dylib@ -> libsfml-system.2.dylib
    libsfml-window.2.1.dylib*
    libsfml-window.2.dylib@ -> libsfml-window.2.1.dylib
    libsfml-window.dylib@ -> libsfml-window.2.dylib


This is where my understanding of things falls short, and things begin to deviate from what might be expected.

First, I created the build directory to avoid making a mess inside of the main folder and I am assuming this won't cause any problems.  At the very least I'm assuming cmake accepted my arguments and should have built without a framework.  **The documentation says that the `SFML_USE_STATIC_STD_LIBS` flag is windows-only, so I haven't tried it.**

Hoping for the best I moved forward and tried building the `example.cpp` file from my first post (the simple one with a window):

Code: [Select]

    g++ -static -I lib/SFML-2.1/include/ -c src/example.cpp
    g++ -static -L lib/SFML-2.1/build/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 will say my knowledge of compiling C is fairly limited, as I have only been working with the language for a little while, and since everyone uses an IDE nobody describes the actual commands anymore in their tutorials.  For all I know there could be a single line that will both compile to .o, and build the final executable (or whether I'm even using the right terms for the right actions).  In particular I don't know if the `-static` flag is necessary when compiling to `.o` or when building to the executable.  **I do know that the includes have to be defined when compiling to a `.o` and the library path and lib flags (`-lsfml-*` ) have to be added when building the executable.

If my commands were invalid I'm sure the compiler would throw errors instead of building the files, or attempting to.

It should be safe to assume that my libraries didn't compile statically, so my next attempt is to verify whether it at least excluded the frameworks like I asked it to from the cmake argument:

Code: [Select]

    g++ -I lib/SFML-2.1/include/ -c src/example.cpp
    g++ -L lib/SFML-2.1/build/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/caseydelorme/git/test/./sfml-example
      Reason: image not found
    Trace/BPT trap: 5


Noting that it still references `@executable_path/../Frameworks/libsfml-graphics.2.dylib` I have to assume that not only did it still not compile statically, but it also is completely ignoring my CMAKE arguments.

In conclusion, I am still unsuccessful.  What should I try next?

cdelorme

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Static Linking 2014?
« Reply #4 on: June 13, 2014, 07:02:56 am »
I did a bit of reading on the error I was getting ("ld: library not found for -lcrt0.o"), and now I'm reading that g++/gcc won't compile with `-static` on mac to begin with.  I haven't confirmed for certain, most of what I'm finding is posts from years back, but if it's true I'm in a bind.

MacPorts doesn't seem to have SFML, and homebrew has a formula but can't actually fully install it, so the only option for mac users is to go to sfml-dev, download the zip, extract it, and run the install script with root privileges.

Is there another option without statically linking, such as including a copy of SFML source with my executable and having my executable use a relative path?

cdelorme

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Static Linking 2014?
« Reply #5 on: June 13, 2014, 07:21:50 am »
So, I have good news.  I think I'm figuring this out, found this good [stack overflow article](http://stackoverflow.com/questions/4677044/how-to-use-dylib-in-mac-os-x-c).

So, the article is saying it is intended for compiled .app files, where the frameworks would be within the executable .app, under the frameworks folder, generally a folder above the folder containing the executable.

So, I built it again using the prebuilt OSX files, and checked this error again:

Code: [Select]

    ./sfml-example
    dyld: Library not loaded: @executable_path/../Frameworks/libsfml-system.2.dylib
      Referenced from: /Users/caseydelorme/git/test/./sfml-example
      Reason: image not found
    Trace/BPT trap: 5


Then I copied the `lib/` folders `libsfml-*` files into a `Frameworks/` folder.  Then I saw errors about missing freetype framework, so I coppied the contents of `extlibs/` into `Frameworks/` (which included the sndfile & freetype frameworks), and now I can run the executable:

Code: [Select]

    ./sfml-example


I get my blank window!

My file structure ended up looking like this:

- src/example.cpp
- src/sfml-example*
- Frameworks/libsfml-*.dylib
- Frameworks/freetype.framework
- Frameworks/sndfile.framework

_I shorthanded the libsfml, because there are many._

**This is excellent progress thus far**, because it means that I might actually be able to get this working the way I was hoping to, although it's a bit hacky still.

I am now reading the section in the article I linked about modifying the `@executable_path` so that it will use the same path as the executable instead of a folder above it, and perhaps a more standard name like `libs`.

I will post back once I figure it out, but if anyone knows they are welcome to reply and save me some time/effort.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10838
    • View Profile
    • development blog
    • Email
AW: Static Linking 2014?
« Reply #6 on: June 13, 2014, 08:07:33 am »
You know there are formatting buttons for when one doesn't know BBCode, just writing Markdown, even though it's not supported, won't help... ::)
Meaning it's. [url=url]text[/url]

Anyways, you are aware though that your current solution is linked dynamically?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

cdelorme

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Static Linking 2014?
« Reply #7 on: June 13, 2014, 08:46:08 am »
I wish I could say everything I did made sense.  If you notice the size of my posts, I type them in an editor, not the forum page (too many times has that lost all my writing, so I built habits that work around it).  Since my editor supports markdown syntax highlighting I find it easier to re-read what I write so I don't have a bunch of mistakes.  I can fix my url tags and stuff, but it's not like they don't still work as links.  The code blocks I totally understand being a concern though.

Linked dynamically, using relative paths.  Is there a shorter, more specific, term for this besides "linked dynamically"?  I wish I understood the terminology, to me "linked dynamically" generally refers to any libraries installed by a package manager and linked via a global system path, not necessarily in the same folder as the executable.

Granted, it kind of deviates from the original thread title, but if this is the solution to my problem maybe it'll still be helpful.


---


I just played with two new tools, apparently `otool` and `install_name_tool` allow me to inspect the linker paths, and then also to modify them.

---

My goal hasn't changed since my first post.  I want to include a copy of the version of SFML I am using for my code, in a way that does not conflict with a globally installed SFML that may or may not be the same version, or other dependent applications.

Originally I thought to acheive this with static linking, but so far it seems that OSX doesn't make that possible.  With the commands I'm experimenting with it's looking like it could be possible to distribute a folder with the compiled files, and reference them via an executable relative path (apparently dynamic linking?).

Here is my desired file structure:

- sfml-app
- libs/

The libs folder would contain the sfml libraries and any other important dependencies.


---

Working off my last post, I managed to get the following folder structure to work:

- src/sfml-example*
- Frameworks/libsfml-graphics.2.1.dylib


With otool I can inspect dylib dependencies, for example:

Code: [Select]

    otool -l Frameworks/libsfml-graphics.2.1.dylib
    @executable_path/../Frameworks/libsfml-graphics.2.dylib
    @executable_path/../Frameworks/libsfml-window.2.dylib
    @executable_path/../Frameworks/libsfml-system.2.dylib
    @executable_path/../Frameworks/freetype.framework/Versions/A/freetype
    /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL
    /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
    /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit
    /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit
    /System/Library/Frameworks/Carbon.framework/Versions/A/Carbon


I can apply a filter like so:

Code: [Select]

    otool -L libsfml-graphics.2.1.dylib | grep "\.\./Frameworks" | awk -F' ' '{ print $1 }'
    @executable_path/../Frameworks/libsfml-graphics.2.dylib
    @executable_path/../Frameworks/libsfml-window.2.dylib
    @executable_path/../Frameworks/libsfml-system.2.dylib
    @executable_path/../Frameworks/freetype.framework/Versions/A/freetype


Next, I can change these paths using `install_name_tool`.  **It is important to understand that this will permanently augment the dylib files it is run against.**  It only has to be done once, and it will stop working the way it was compiled to originally.

I tested with this:

Code: [Select]

    install_name_tool -change @executable_path/../Frameworks/libsfml-window.2.dylib @executable_path/lib/libsfml-window.2.1.dylib libsfml-graphics.2.1.dylib


Then when I ran the otool command again, I get this:

Code: [Select]

        @executable_path/../Frameworks/libsfml-graphics.2.dylib (compatibility version 2.0.0, current version 2.1.0)
        @executable_path/lib/libsfml-window.2.1.dylib (compatibility version 2.0.0, current version 2.1.0)
        @executable_path/../Frameworks/libsfml-system.2.dylib (compatibility version 2.0.0, current version 2.1.0)
        @executable_path/../Frameworks/freetype.framework/Versions/A/freetype (compatibility version 17.0.0, current version 17.0.0)
        /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.1.4)
        /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 677.26.0)
        /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 949.54.0)
        /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
        /System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 136.0.0)
        /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 56.0.0)
        /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)



---

To try and make this process a bit faster I created a shell script, following the example in the stack overflow link in my earlier post:

Code: [Select]

    #!/bin/bash

    # define the new path
    NEWPATH="@executable_path/lib/"

    # grab all the dylibs
    DYLIBS=./*.dylib

    # iterate all the libs we want to modify
    for modlib in $DYLIBS
    do

        # don't modify the symlinks, only the actual files
        if [ ! -L $modlib ]
        then

            # grab the dependencies per .dylib
            DEPS=$(otool -L $modlib | grep "\.\./Frameworks" | awk -F' ' '{ print $1 }')

            # loop to fix
            for dlib in $DEPS
            do

                install_name_tool -change $dlib ${NEWPATH}/`basename $modlib` $modlib

            done

        fi

    done


The remaining problem is that when I check the libraries, I still see a self-reference to a symlink of the same file, and for whatever reason it ignores my `install_name_tool` commands so I do not yet know how to change it.

I tried for this structure to do a test build:

- lib/SFML-2.1/includes
- src/example.cpp
- src/lib/libsfml-*.dylib
- src/lib/freetype.framework
- src/lib/sndfile.framework

While I could compile, building failed, because it is trying to use that symbolic link which still uses the Frameworks path:

    cd src
    g++ -I ../lib/SFML-2.1/include -c example.cpp
    g++ -L 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/caseydelorme/git/test/src/./sfml-example
      Reason: image not found
    Trace/BPT trap: 5

Unfortunately, this is as far as I have gotten.  I need to get some sleep so I will continue looking into this tomorrow, but if anyone knows how to get this fully functioning and wants to reply please do!

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10838
    • View Profile
    • development blog
    • Email
Re: Static Linking 2014?
« Reply #8 on: June 13, 2014, 09:03:50 am »
If you notice the size of my posts, I type them in an editor, not the forum page (too many times has that lost all my writing, so I built habits that work around it).  Since my editor supports markdown syntax highlighting I find it easier to re-read what I write so I don't have a bunch of mistakes.  I can fix my url tags and stuff, but it's not like they don't still work as links.
I kind of understand that, it's just while it might be nicer for your to have Markdown everywhere, it would be really annoying for us forum members that read about every single post that gets written on the forum if everyone used their own styling. Overall I can only ask you to change it, but in the end it's your decision. ;)

Linked dynamically, using relative paths.  Is there a shorter, more specific, term for this besides "linked dynamically"?  I wish I understood the terminology, to me "linked dynamically" generally refers to any libraries installed by a package manager and linked via a global system path, not necessarily in the same folder as the executable.
No, linked dynamically or statically have nothing to do how you obtain said software. If something is statically linked, all the object files of the compiled library are directly included in the final binary, while dynamically linked libraries are binaries on their own that are built from the library object files.

I'm not sure how OS X handles dynamic libraries, but on Windows and Linux it doesn't really matter where you've placed the libraries. You just need to make sure it's in a directory that will be searched by your application. On Windows the order would be (iirc): Directly next to the binary, working directory, somewhere in PATH (environment variable), system directories (system32, etc.).
Thus I can only assume that it could be similar on OS X, but I really don't know. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Static Linking 2014?
« Reply #9 on: June 13, 2014, 09:11:49 am »
I don't know about Mac, but on Linux it's trivial to ship your own dynamic libraries alongside your executable. Just use the -rpath linker option and $ORIGIN (I know you are not on Linux, just wanted to give you some bits to Google).
This seems relevant to Mac though: https://blogs.oracle.com/dipol/entry/dynamic_libraries_rpath_and_mac

cdelorme

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Static Linking 2014?
« Reply #10 on: June 13, 2014, 09:17:49 am »
I'll do what I can with awkward formatting, wasn't trying to make things difficult for you all.

OSX doesn't appear to use environment variables for paths, instead that seems to be compiled into the dylibs, as well as control version requirements.  :(

Having trouble tearing myself away from the screen since I'm finally so close.  Figured out the problem with the first record from `otool -L` was the id or name of the file.  I was able to change it with `install_name_tool -id newname file`.

I messed up my shell script and replaced every dependency with the same name as the file itself, which of course broke my build attempts.  Working to fix it, I think I can get it done in another 30 minutes so I'm going to shoot for that.

cdelorme

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Static Linking 2014?
« Reply #11 on: June 13, 2014, 09:20:43 am »
@Jesper, ty for the information and link.  I think I'm on the right track now, I'll have it hashed out hopefully soon.  For linux do you use the rpath linker option when compiling?  I would love a reference on linux because I will be testing my program there soon as well.

cdelorme

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Static Linking 2014?
« Reply #12 on: June 13, 2014, 09:41:33 am »
Finally got it.

New script to convert the dylib files if anyone wants to take it and run with it:

Code: [Select]

    #!/bin/bash

    # define the new path
    NEWPATH="@executable_path/lib/"

    # grab all the dylibs
    DYLIBS=./*.dylib

    # iterate all the libs we want to modify
    for modlib in $DYLIBS
    do

        # don't modify the symlinks, only the actual files
        if [ ! -L $modlib ]
        then

            # grab the dependencies per .dylib
            DEPS=$(otool -L $modlib | grep "\.\./Frameworks" | awk -F' ' '{ print $1 }')

            # loop to fix
            for dlib in $DEPS
            do

                # fix it's dependencies
                tdlib=$(echo $dlib | sed 's/@executable_path\/..\/Frameworks\///')
                install_name_tool -change $dlib ${NEWPATH}$tdlib $modlib

            done

            # fix the id/name so that it isn't referring to the symlink of itself in the Frameworks folder
            install_name_tool -id ${NEWPATH}$(basename $(otool -XD $modlib)) $modlib

        fi

    done


Same structure as before, same build commands, and the application now works using a local copy of the files in `lib/`.  I hope this helps others tailor it to their needs, and that I wasn't redoing work that someone else had already covered elsewhere.

Thanks again for your help and patience eXpl0it3r, and I will certainly be around on the forums as I continue experimenting with SFML.

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Static Linking 2014?
« Reply #13 on: July 21, 2014, 08:53:30 pm »
@Jesper, ty for the information and link.  I think I'm on the right track now, I'll have it hashed out hopefully soon.  For linux do you use the rpath linker option when compiling?  I would love a reference on linux because I will be testing my program there soon as well.
Yes, you use it while building (specifically linking) your executable. Perhaps this or this will be useful :)