Compile for Linux / GLFW question

edited January 11 in General Discussions
The wiki page at https://github.com/raysan5/raylib/wiki/Compile-for-GNU-Linux indicates I should compile the dependency glfw3 from source. Ubuntu 16.04 repositories contain packages for libglfw3, version 3.1.2-3. Can I use these instead? Should I?

Comments

  • Hi Rider8, I think you don't need to recompile GLFW3, you can download the package directly. Just take care to link with the correct libraries.

    Please, let me know how it works!
  • edited January 24
    Hola, gracias por responder. I have libraylib.a but not examples. I got a little lost in the makefiles but did find INCLUDES, LFLAGS, and LIBS. Going back through, I stopped when I saw the 2010 copyright date on /usr/include/GLFW/glfw.h. I'll give it one more go just to see if it works and if not, I'll uninstall the old package and start over at https://github.com/raysan5/raylib/wiki/Compile-for-GNU-Linux. I need the practice (^;
  • Hey Rider8! raylib uses latest GLFW, version 3.2.1.

    Please, keep me updated on this issue. :)
  • edited February 22
    I chose not to compile GLFW3. I'm pretty conservative and like to keep everything as integrated as possible since I'm on a "working" system AND I don't usually know what I'm doing. CMake is probably a fine system but I'll save that for later.

    Varied success with the packaged binary approach on three distributions. Ubuntu 16.04, with the old distro version, 3.1.2, of GLFW3, Kali Rolling with an up-to-date distro package, 3.2.1, of GLFW3, and Solus, also with v3.2.1 packages.

    In the Debian cases, raylib built and installed without memorable problems. It also built fine but failed to install on Solus. Solus doesn't provide `/usr/local/lib` or `/usr/local/include` as referenced in the `raylib/src/Makefile` so I created `/usr/local` and subdirectories rather than edit the hard-coded install locations in the Makefile, lines 342-345. What are the pros and cons of these approaches? Would editing this in the Makefile break things downstream?

    In all cases, compilation of the examples failed due to a difference in the `-lname` of GLFW3. Instead of `-lglfw3` in the LIBS assignment on line 148 in `raylib/examples/Makefile`, it is `-lglfw`. The package names vary but this -lname seems to be the norm on GNU/Linux. I haven't checked the Pi setup. Anyway, it seems mostly sorted.

    After that, the physics examples were the only ones that didn't compile. There is something about timing in physac.h that isn't working for GNU/Linux. Not sure where the ifdef conditions are coming from. The `examples/Makefile` ? `__linux`seems out of place? Yep. Should be `__LINUX` on lines 242, 270, 1955 in raylib/src/physac.h

    Alright! Now we're cooking with gas. (^:

    Why does `raylib/src/Makefile` `CFLAGS` have `-std=gnu99 -fgnu89-inline` for everything but `raylib/examples/Makefile` only has that for the Pi and has `std=c99` for `PLATFORM_DESKTOP`? Should I be using the former since I'm on GNU/Linux? I tried it. It worked. Is it right?

    Would it be easier to have a `PLATFORM_LINUX` than to split `PLATFORM_DESKTOP` into `PLATFORM_OS`?

    I'm still trying to understand libraries and headers.

    It seems like raylib will build in place without actually installing it's dependencies since it carries external headers in it's source. One just couldn't build anything further without installing the dependencies?

    How about compiling the examples without fully installing raylib? So long as the paths stay the same, it will work? it's only when I want to build something elsewhere that I need to install raylib system-wide?

    If it's not too much trouble, I'd like to make a pull request on github. I need to to learn how to do that and this may be a good opportunity. It might take another week.

    Thank you!
  • Hi Rider8! Wow! What a detailed explanation! Lots of points to comment!

    About Linux versions, it seems eery version has its own implementation details so it's difficult to find a standard implementation that does not break everything. Actually, about -lglfw3 vs -lglfw, I think it has been changed a couple of times... I believe it should be -lglfw3.

    About physac.h, that module was developed by Victor Fisac (https://github.com/victorfisac/Physac), I think the right define should be __linux__ or __LINUX, thanks for pointing that out, could you do a pull-request?

    About gnu99 vs c99, I don't remember exactly why I had to change that but it seems c99 implementation is different than gnu99 and RPI code required some of those features (probably some macro or define).

    About PLATFORM_DESKTOP, I thought about the possibility you comment but raylib uses for desktop platforms (Windows, Linux, OSX) the GLFW3 library, so, in terms of code organization it was easier to thread all those platforms as one (most of the glfw3 code is common) and just check in some situations for specific OS. Makefile was designed the same way for consistency with main codebase but there OS is very important and should be treated separately.

    I think you can build raylib library without installing dependencies, as you say, required headers come with the library but you need to install dependencies in order to compile examples because they need to be linked with additional libs (GLFW3, OpenAL Soft).

    Of course you can make any pull request you consider necessary, it would be a pleasure to review and discuss it. Just keep in mind that GitHub work branch is develop branch (https://github.com/raysan5/raylib/tree/develop), not master, you should use that branch for development and send updates.
  • edited February 22
    I see your point about the -lname. If that's how GLFW3 self-installs, ok. For those using packaged versions of GLFW3, counter to your instructions as must be noted, it may still come up now and then.

    Was it correct to add the install directories as needed instead of changing the makefile? Just a matter of opinion?

    Literally "__linux__ or __LINUX"? Those underscores are some kind of chain?

    Sure, with you, or upstream with him? I need to walk through git a couple of times so I get it right. So, use master branch for building games, develop branch for working on raylib? Thanks for the opportunity to contribute. I also have some runtime issues with those physics executables. Something to look forward to. (^;

    So, the code is c99? Nothing special going on because I'm using gcc not MinGW? Cool.

    Thanks yet again for your guidance.



  • I use Ubuntu 16.10. I too had to use -lglfw instead of -lglfw3 for the compilation of the examples to work. Perhaps because I already had GLFW3 installed.

    I compiled raylib to a dynamic library. make install copied libraylib.so to /usr/local/lib. Unfortunately this is not in the default LD_LIBRARY_PATH in Ubuntu 16.10. So the only minor annoyance is that I have to prefix LD_LIBRARY_PATH=/usr/local/lib to every binary example when I run it.

    I think I also have to manually copy raylib.h to /usr/include/raylib or /usr/local/include/raylib to compile my own programs using the Makefile in the examples folder.
  • edited March 15
    Hi krishna, the -lname issue is because of the way GLFW is compiled. When it is compiled and installed locally as a static library, it places libglfw3.a in /usr/local/lib. This is what happens when we follow raysan5's instructions and, as you may know, is common practice when installing third-party software from source. When a distribution's binary package is installed, it typically places a shared library named libglfw.so in /usr/lib. It seems static libraries are generally discouraged when developing for Linux.

    I think that the result of this is that when you build a game against the distro's shared library, it won't necessarily be portable to other computers. The host system will need to have a copy of libglfw.so to run your program just as it needs libopenal.so.

    I haven't tried compiling raylib as a shared library yet. I am interested to package raylib for my distro but that is down the list.

    Ahh, the makefiles... It sounds like 'make install' in ../src/Makefile isn't working.

    'cd ../raylib/src; make clean; sudo make install; ls /usr/local/lib; ls /usr/local/include'

    I am working on Linux improvements and sharing my progress over at https://github.com/RDR8/raylib. Please drop by if you have questions, comments, or suggestions.
  • Hi Rider8!

    Thank you very much for the detailed explanation about this issue!

    Any improvement on the build system will be welcome!

    :)
  • edited March 21
    Rider8,

    Thank you for your comment.

    At the moment I am only interested in using raylib in my Ubuntu laptop which is why I am going for a shared library installation. As I said, I already have GLFW3 and OpenAL installed through the package manager. So here are the changes I made in the Makefile in the src folder of the raylib package:

    Changed line no. 167 to this:

    SHAREDLIBS = -lopenal -lglfw

    Commented out lines nos. 196 and 198 since the include files are already present in the standard directories.

    Added these two lines after line no. 341:

    mkdir -p /usr/local/include/raylib
    cp --update raylib.h /usr/local/include/raylib/raylib.h

    With these changes I could build the raylib library successfully and have the header file and library binary file copied to the standard directories.

    To compile the examples I changed glfw3 to glfw in line no. 148 in the Makefile in the examples folder.

    With the header file and the shared library in standard directories, I could compile a simple program using raylib with a simple Makefile. For instance, I made a program with a small modification of one of the example programs( the modification moves the rectangle along x if the SHIFT key is pressed while rotating the wheel):

    /*******************************************************************************************
    *
    * raylib [core] examples - Mouse wheel
    *
    * This test has been created using raylib 1.1 (www.raylib.com)
    * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
    *
    * Copyright (c) 2014 Ramon Santamaria (@raysan5)
    *
    ********************************************************************************************/

    #include

    int main()
    {
    // Initialization
    //--------------------------------------------------------------------------------------
    int screenWidth = 800;
    int screenHeight = 450;

    InitWindow(screenWidth, screenHeight, "Wheel movement demo");

    int boxPositionX = screenWidth/2 - 40;
    int boxPositionY = screenHeight/2 - 40;
    int scrollSpeed = 4; // Scrolling speed in pixels

    SetTargetFPS(60);
    //--------------------------------------------------------------------------------------

    // Main game loop
    while (!WindowShouldClose()) // Detect window close button or ESC key
    {
    // Update
    //----------------------------------------------------------------------------------
    if (IsKeyDown(KEY_LEFT_SHIFT) || IsKeyDown(KEY_RIGHT_SHIFT)) {
    boxPositionX += (GetMouseWheelMove()*scrollSpeed);
    } else {
    boxPositionY += (GetMouseWheelMove()*scrollSpeed);
    }
    //----------------------------------------------------------------------------------

    // Draw
    //----------------------------------------------------------------------------------
    BeginDrawing();

    ClearBackground(RAYWHITE);

    DrawRectangle(boxPositionX, boxPositionY, 80, 80, MAROON);

    DrawText("Use mouse wheel to move the square up and down or\n(with SHIFT key pressed) left and right!", 10, 10, 20, GRAY);
    DrawText(FormatText("Box position X: %03i", boxPositionX), 10, 70, 20, LIGHTGRAY);
    DrawText(FormatText("Box position Y: %03i", boxPositionY), 10, 100, 20, LIGHTGRAY);

    EndDrawing();
    //----------------------------------------------------------------------------------
    }

    // De-Initialization
    //--------------------------------------------------------------------------------------
    CloseWindow(); // Close window and OpenGL context
    //--------------------------------------------------------------------------------------

    return 0;
    }
    The Makefile for compiling the above program was this:

    P = wheel_0
    CFLAGS = -g -Wall -O3 -std=gnu11
    LDLIBS = -lraylib -lglfw -lGL -lopenal -lm -lpthread -ldl
    CC = gcc

    $(P):


  • edited March 18
    The #include line in the above program is not showing properly. It should be <raylib/raylib.h>
  • edited March 19
    nm
  • edited March 19
    It might be interesting to automate this choice by reversing what is being done with OpenAL in src/Makefile. If that feature would be useful enough to implement...

    If GLFW did not change the -lname for static and shared versions, would this still be a problem? Is such name-changing common practice?

    Can we talk about the install locations in /usr/local/? It's important that the Makefiles in src/, examples/, and any other user build directories match up. It seems like it has been recently changed in examples/Makefile.The libraylib library and raylib header are installed by src/Makefile:334,350 to /usr/local/lib and /usr/local/include/, respectively. Yet, examples/Makefile:114 is looking in /usr/local/include/raylib/ for the header and doesn't reference /usr/local/include/, /usr/local/lib/ or /usr/local/lib/raylib/ at all. If someone could clarify where gcc/ld are looking for libs and headers by default...

    Furthermore, some distributions do not provide /usr/local/ by default so if one installed a distribution's packaged library and headers of GLFW or whatever, files may be in /usr/lib and /usr/include instead. It may be in the user's best interest to make local directories as needed instead of modifying every makefile that comes through. I think your mkdir -p is appropriate in the sense that we can ensure that libraylib and raylib.h are installed somewhere. Inserting `mkdir -p /usr/local/lib /usr/local/include; ` at src/Makefile:340,341 would have solved my original problem with installation on a distribution without /usr/local/. Stop me if it's a horrible idea.

    That said, can we standardize to /usr/local/? If we think that we may include many other related libraries like raygui then it may make sense to put them in /usr/local/lib/raylib/ and /usr/local/include/raylib/ but for now, I'm sticking with src/Makefile as-is since it works with GLFW and a single reference in any downstream makefiles will catch them both in /usr/local/lib. The change I would make is to example/Makefile:114 `INCLUDES += -I/usr/local/include`

    I do want to say that the standard procedure works well without changes. If you really want to have some fun, change src/Makefile:161 to CFLAGS = -O2 -s -Wall -std=c99
  • Maybe I wouldn't change examples/Makefile:114. Except maybe delete it. It should just work, even without the reference to /usr/local/include/raylib/.

    "By default, gcc searches the following directories for header files:
    /usr/local/include/
    /usr/include/
    and the following directories for libraries:
    /usr/local/lib/
    /usr/lib/" - http://www.network-theory.co.uk/docs/gccintro/gccintro_21.html
  • Hi krishna and Rider8,

    Thank you very much for your elavorated answers, actually, I don't know which is the best option, I feel it's very distribution dependant... adding extra INCLUDES or LIBRARY paths could be a solution despite overloading compilation line.

    Rider8, just proposed one solution and make a Pull Request. :)
  • Hi Rider,

    I think it is better to have a dedicated directory for raylib in /usr/local/include/ and have the header file placed there than directly in /usr/local/include, though, as you have pointed out, it would still work because of the default gcc search paths.
Sign In or Register to comment.