oprypin / crsfml

Crystal bindings to SFML multimedia/game library
https://oprypin.github.io/crsfml
zlib License
350 stars 14 forks source link

Build fails with SFML 2.5.1 on Mac OS Mojave 10.14.3 #30

Closed crjaensch closed 4 years ago

crjaensch commented 5 years ago

I tried to install CrSFML on a MacBook Pro 2017 running Mac OS Mojave 10.14.3

I followed the installation instructions for Approach 1 described in https://github.com/oprypin/crsfml .

I started with the installation of SFML using homebrew. A week ago that installed SFML 2.4.2 and most recently (a day or two ago) that changed to installing SFML 2.5.1. This change broke everything!!!

It should be noted that the SFML 2.5.1 installation changed significantly, especially regarding the location and content of the cmake Modules.

Homebrew installs SFML 2.4.2 in the following directories:

with the following subdirectories:

Moreover, soft links are created in the following directories:

NOTE: with the SFML 2.4.2 directory setup described above, the CrSFML installation (using Approach 1, i.e. running the command: cmake . && make from the crsfml directory) works just fine :-).

In contrast, when SFML 2.5.1 is installed via homebrew, it seems to break the CrSFML cmake installation procedure. Homebrew install the newest SFML version in the following directories:

with the following subdirectories:

Moreover, soft links are created in the following directories:

In summary, the main differences are: 1) all cmake files are now stored in the lib/cmake/SFML subdirectory of the homebrew cellar. 2) these cmake files are now accessible via soft links via /usr/local/lib/cmake/SFML.

As a consequence, the installation of CrSFML (using Approach 1) fails as follows:

$ cmake . && make
-- The C compiler identification is AppleClang 10.0.0.10001044
-- The CXX compiler identification is AppleClang 10.0.0.10001044
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found SFML 2.5.1 in /usr/local/lib/cmake/SFML
-- Found SFML 2.5.1 in /usr/local/lib/cmake/SFML
-- Configuring done
CMake Warning (dev):
  Policy CMP0068 is not set: RPATH settings on macOS do not affect
  install_name.  Run "cmake --help-policy CMP0068" for policy details.  Use
  the cmake_policy command to set the policy and suppress this warning.

  For compatibility with older versions of CMake, the install_name fields for
  the following targets are still affected by RPATH settings:

   voidcsfml-audio
   voidcsfml-graphics
   voidcsfml-network
   voidcsfml-system
   voidcsfml-window

This warning is for project developers.  Use -Wno-dev to suppress it.

-- Generating done
-- Build files have been written to: /Users/cjaensch/Dev/Crystal/3rdparty/crsfml
Scanning dependencies of target c-sources
[  8%] Generating voidcsfml/include/voidcsfml/system.h, voidcsfml/src/voidcsfml/system.cpp, voidcsfml/include/voidcsfml/window.h, voidcsfml/src/voidcsfml/window.cpp, voidcsfml/include/voidcsfml/graphics.h, voidcsfml/src/voidcsfml/graphics.cpp, voidcsfml/include/voidcsfml/audio.h, voidcsfml/src/voidcsfml/audio.cpp, voidcsfml/include/voidcsfml/network.h, voidcsfml/src/voidcsfml/network.cpp, src/system/lib.cr, src/system/obj.cr, src/window/lib.cr, src/window/obj.cr, src/graphics/lib.cr, src/graphics/obj.cr, src/audio/lib.cr, src/audio/obj.cr, src/network/lib.cr, src/network/obj.cr
Unhandled exception: Error opening file '/usr/include/SFML/System.hpp' with mode 'r': No such file or directory (Errno)
  from /usr/local/Cellar/crystal/0.27.2/src/crystal/system/unix/file.cr:10:7 in 'open'
  from /usr/local/Cellar/crystal/0.27.2/src/file.cr:104:10 in 'new'
  from generate.cr:683:5 in 'process_file'
  from generate.cr:1580:5 in 'initialize'
  from generate.cr:1565:3 in 'new'
  from /usr/local/Cellar/crystal/0.27.2/src/array.cr:130:9 in '__crystal_main'
  from /usr/local/Cellar/crystal/0.27.2/src/crystal/main.cr:97:5 in 'main_user_code'
  from /usr/local/Cellar/crystal/0.27.2/src/crystal/main.cr:86:7 in 'main'
  from /usr/local/Cellar/crystal/0.27.2/src/crystal/main.cr:106:3 in 'main'
make[2]: *** [voidcsfml/include/voidcsfml/system.h] Error 1
make[1]: *** [CMakeFiles/c-sources.dir/all] Error 2
make: *** [all] Error 2

The above error message clearly indicates that a SFML include header is not found and in fact looked up in the wrong directory. In order to fix this, I tried the cmake options explanation provided in: https://github.com/oprypin/crsfml/blob/master/voidcsfml/README.md#cmake-options .

When I ran the following command:

cmake -DSFML_INCLUDE_DIR="/usr/local/include" . && make

the installation managed to find the SFML header files. But now the installation fails to resolve the location of the SFML dynamic libraries (libsfml-*.dylib). The associated cmd output is shown below:

...
-- Generating done
-- Build files have been written to: /Users/cjaensch/Dev/Crystal/3rdparty/crsfml
[  8%] Generating voidcsfml/include/voidcsfml/system.h, voidcsfml/src/voidcsfml/system.cpp, voidcsfml/include/voidcsfml/window.h, voidcsfml/src/voidcsfml/window.cpp, voidcsfml/include/voidcsfml/graphics.h, voidcsfml/src/voidcsfml/graphics.cpp, voidcsfml/include/voidcsfml/audio.h, voidcsfml/src/voidcsfml/audio.cpp, voidcsfml/include/voidcsfml/network.h, voidcsfml/src/voidcsfml/network.cpp, src/system/lib.cr, src/system/obj.cr, src/window/lib.cr, src/window/obj.cr, src/graphics/lib.cr, src/graphics/obj.cr, src/audio/lib.cr, src/audio/obj.cr, src/network/lib.cr, src/network/obj.cr
[  8%] Built target c-sources
Scanning dependencies of target voidcsfml-window
[ 16%] Building CXX object voidcsfml/CMakeFiles/voidcsfml-window.dir/src/voidcsfml/window.cpp.o
[ 25%] Linking CXX shared library libvoidcsfml-window.dylib
Undefined symbols for architecture x86_64:
  "sf::Mouse::getPosition(sf::Window const&)", referenced from:
      _sfml_mouse_getposition_JRh in window.cpp.o
  "sf::Mouse::getPosition()", referenced from:
      _sfml_mouse_getposition in window.cpp.o 

I finally tried the following command, hoping that explicitly setting the cmake module path might help. But I still get the same message as shown above, i.e. it fails to resolve the SFML library path during linkage.

sfml=(/usr/local/Cellar/sfml/2.5.1)
cmake -DSFML_INCLUDE_DIR="/usr/local/include" -DCMAKE_MODULE_PATH="$sfml/lib/cmake/SFML" . && make

NOTE: I have no experience with cmake, otherwise I would have fixed this. Obviously, the linkage step fails to resolve the SFML library path and this despite the fact that all libraries are accessible from /usr/local/lib through soft links.

For now, the only way I managed to install CrSFML is using SFML 2.4.2. This wouldn't be half as bad, if homebrew still offered to install a previous version of SFML out-of-the-box. I took me a few hours to finally figure out how to trick homebrew to do so.

I hope you can offer some help on getting CrSFML installed with SFML 2.5.1. Any help is highly appreciated!!!

andrewoconnor commented 5 years ago

@crjaensch I closed my issue https://github.com/oprypin/crsfml/issues/29 too early. Forgot to try rebuilding VoidCSFML after upgrading. You can try the workaround I detail there.

Here's the old FindSFML.cmake: https://raw.githubusercontent.com/SFML/SFML/5c20c67469e2be17a727bf6cfe3f5672bf50df83/cmake/Modules/FindSFML.cmake

crjaensch commented 5 years ago

@andrewoconnor I am not sure what you are trying to tell me. Does closing https://github.com/oprypin/crsfml/issues/29 too early mean that it's still not working for you?

As I explained, it's the changed cmake structure and/or content introduced in SFML 2.5.1 that is most likely causing the problem. Unfortunately, I don't know enough about cmake to fix it myself.

As I stated previously, I got around it, by pulling an older SFML homebrew formula from the repo (https://github.com/Homebrew/homebrew-core) and installing that. More specifically, I created a formula file with the filename sfml@2.4.2.rband ran that locally using the command: brew install --build-from-source <formula-filename.rb>.

I would love to install the most recent version of SFML (i.e. 2.5.1), sadly that's not working for me so far.

For the sake of completeness, I am showing the content of sfml@2.4.2.rb below:

class  SfmlAT242 < Formula
  # Don't update SFML until there's a corresponding CSFML release
  desc "Multi-media library with bindings for multiple languages"
  homepage "https://www.sfml-dev.org/"
  url "https://www.sfml-dev.org/files/SFML-2.4.2-sources.zip"
  sha256 "8ba04f6fde6a7b42527d69742c49da2ac529354f71f553409f9f821d618de4b6"
  revision 1
  head "https://github.com/SFML/SFML.git"

  bottle do
    cellar :any
    rebuild 1
    sha256 "1c5fc7fdb1a59664f2128d309c3a198fffd60cb9f930fbe8ed7f8eb52753250b" => :mojave
    sha256 "ed02627dfaff55b60f9271379256d99adfb010df3f4842b0e33fd366eb62df6e" => :high_sierra
    sha256 "76c3949dad4b907b87d219f10eb2dae44d43cb76963a083f70935f138832d13c" => :sierra
    sha256 "976560145b126bd482696148767f333ceda470d847064a5682abcd5c329937bd" => :el_capitan
    sha256 "43dbf56a522f7bce55db7e5354ee0810b7abad63b97178a1ed7a73356c52577c" => :yosemite
  end

  depends_on "cmake" => :build
  depends_on "doxygen" => :build
  depends_on "flac"
  depends_on "freetype"
  depends_on "jpeg"
  depends_on "libogg"
  depends_on "libvorbis"

  # https://github.com/Homebrew/homebrew/issues/40301

  def install
    # Install pkg-config files, adding the CMake flag below isn't enough, as
    # the CMakeLists.txt file currently doesn't consider MacOS X.
    # This was fixed upstream for the future 2.5.0 release on 2016-12-19 in:
    # https://github.com/SFML/SFML/commit/5fe5e5d6d7792e37685a437551ffa8ed5161fcc1
    inreplace "CMakeLists.txt",
              "if(SFML_OS_LINUX OR SFML_OS_FREEBSD)",
              "if(SFML_OS_LINUX OR SFML_OS_FREEBSD OR SFML_OS_MACOSX)"

    # Always remove the "extlibs" to avoid install_name_tool failure
    # (https://github.com/Homebrew/homebrew/pull/35279) but leave the
    # headers that were moved there in https://github.com/SFML/SFML/pull/795
    rm_rf Dir["extlibs/*"] - ["extlibs/headers"]

    system "cmake", ".", *std_cmake_args,
                         "-DSFML_INSTALL_PKGCONFIG_FILES=TRUE",
                         "-DSFML_BUILD_DOC=TRUE"
    system "make", "install"
  end

  test do
    (testpath/"test.cpp").write <<~EOS
      #include "Time.hpp"
      int main() {
        sf::Time t1 = sf::milliseconds(10);
        return 0;
      }
    EOS
    system ENV.cxx, "-I#{include}/SFML/System", "-L#{lib}", "-lsfml-system",
           testpath/"test.cpp", "-o", "test"
    system "./test"
  end
end
andrewoconnor commented 5 years ago

@crjaensch 2.5.1 works for me with the workaround I explain in that issue. You need to recreate the directory structure so that it matches 2.4. This solves the linking issues.

cd /usr/local/opt/sfml/share/sfml
mkdir cmake
cd cmake
ln -s /usr/local/opt/sfml/lib/cmake/SFML Modules

Then drop the FindSFML.cmake I linked above in /usr/local/opt/sfml/lib/cmake/SFML

crjaensch commented 5 years ago

@andrewoconnor Thanks for the clarification. I will try that :-)

FYI, I added Crystal language support for the QuickLook plugin QLColorCode (https://github.com/anthonygelibert/QLColorCode) and the associated highlight library. Just waiting to get the GitHub pull request / GitLab merge request approved.

oprypin commented 5 years ago

I should say, the build on Travis has been consistently failing as well with the good old

Undefined symbols for architecture x86_64:
  "sf::Mouse::getPosition(sf::Window const&)", referenced from:
      _sfml_mouse_getposition_JRh in window.cpp.o

https://travis-ci.org/oprypin/crsfml/jobs/540323730

But I still don't know what it wants

ryan-sgy commented 5 years ago

@oprypin @andrewoconnor @crjaensch I also meet the problem that CrSFML 2.5.1 can't be installed properly on Mac. Should I use the 2.4.2 instead of 2.5.1?

oprypin commented 5 years ago

:( I'm still really sad that this doesn't work and I still don't know what to do with it. Sure, I didn't put in nearly enough effort, but yeah...

Yes, you probably can use 2.4.2

oprypin commented 5 years ago

I still think this is a problem specifically with Homebrew, so perhaps now that you have all the deps through homebrew, maybe you can make install "normally".

I have not found any relevant changes in CSFML, which presumably would've needed to adapt here if something really changed. Also not found changes in Homebrew. So I presume that it (e.g. CSFML) works because std_cmake_args have been passed all along.

https://github.com/Homebrew/homebrew-core/blob/4a3ff0a6d0faacef4783006f2b88d29f3ef29ef3/Formula/csfml.rb#L20

https://github.com/Homebrew/brew/blob/5354ba84e679ba376897fa9036b3d2890e98e3aa/Library/Homebrew/formula.rb#L1324

Could someone try supplying these CMake options? Uhh you'd need to figure out what prefix means. I suppose if you don't want to dig through code (but can instead modify Homebrew's code) then you can add a debug output by replacing #{prefix} with #{puts("!!!", prefix)} and then installing e.g. CSFML in Homebrew

ryan-sgy commented 5 years ago

@oprypin Thank you. But I am still confused about how to install the old version of sfml by homebrew. Do you mean I go to the official website to download 2.4.2 and install ?

oprypin commented 5 years ago

No don't do that. Maybe it's not even possible, but you can try to find generic instructions how to install an old version of something with Homebrew.

May be easier to just use the workaround https://github.com/oprypin/crsfml/issues/30#issuecomment-470306277

ryan-sgy commented 5 years ago

@oprypin OK, I will have a try!

andrewoconnor commented 5 years ago

@oprypin Investigated a little further. With this modification the linking is solved:

https://github.com/andrewoconnor/crsfml/commit/28c9b455af944db7645485e3e2d4dddb30c2a8cb

built with these options: cmake -DSFML_DIR=/usr/local/opt/sfml/lib/cmake/SFML -DSFML_INCLUDE_DIR=/usr/local/opt/sfml/include . && make

oprypin commented 5 years ago

Thanks. The modification isn't supposed to change anything though? It's only removing the indirection of variables, and the only real change is that it removes dependencies. Or are those variables broken?

andrewoconnor commented 5 years ago
${SFML_${depend}_LIBRARY}
${SFML_${depend}_DEPENDENCIES}

both these variables seem to be empty when I added some debug messages

oprypin commented 5 years ago

Yea OK, your change is perfectly in line with recommendations in https://en.sfml-dev.org/forums/index.php?topic=24070.0

${SFML_LIBRARIES}, ${SFML_DEPENDENCIES} and ${SFML_INCLUDE_DIR} don't exist anymore

This is now mostly automated. The include directory no longer needs to be manually set, so this step can be completely removed. As for the libraries, all you need to specify is the dependencies on the highest level in a dependency tree. Meaning, if you want sfml-graphics, you only need to search for the graphics module and link the sfml-graphics library, CMake will take care of resolving the additionally dependencies like sfml-window or sfml-system. Even for static libraries, you don't need to specify the dependencies as CMake will do it for your.

oprypin commented 4 years ago

Mm I just looked into this issue and got a vague recollection that ${SFML_${depend}_DEPENDENCIES} business doesn't work anymore and that a simpler approach worked.

I did not realize that my memory is actually from @andrewoconnor 's investigation :man_facepalming: -- sorry. Credits to him.