How to build & install GLFW 3 and use it in a Linux project
Asked Answered
W

10

115

GLFW3

Last night I was working late trying to build the GLFW 3 packages for Linux from source. This process took me a very long time, about 3 hours in total, partly because I am unfamiliar with CMake, and partly because I am was unfamiliar with GLFW.

I hope that this post will save you from the difficulty I had yesterday! I thought I should make a short write-up, and hopefully save you several hours of your life...

Thanks to "urraka", "b6" and "niklas" on the #glfw IRC channel, I have been able to get glfw version 3.0.1 working.

It turns out this is not a trivial process (certainly not for me, I am no expert) as there is not much documentation on the web about glfw3, particularly about setting it up with CMake.

I was asked to split this into a question and answer section, and so I have done that, and the answer parts are now below.

Are you a maintainer of GLFW, or a member of the GLFW team?

If any of the maintainers of GLFW3 see this, then my message to them is please add a "setting up GLFW3 on Windows, Mac OS X and Linux" section to your website! It is quite easy to write programs with GLFW, since the online documentation is quite good, a quick scan of all the available classes and modules and you'll be ready to go. The example of a test project featured here is also very good. The two main problems I found were, firstly how do I set up GLFW3 on my system, and secondly how to I build a GLFW3 project? These two things perhaps aren't quite clear enough for a non-expert.

Edit

Had a brief look today (Date: 2014-01-14) it looks as if the GLFW website has undergone heavy changes since I last looked and there is now a section on compiling GLFW and buliding programs with GLFW, which I think are new.

Weintraub answered 21/7, 2013 at 0:30 Comment(8)
Thanks for putting this up here - obviously a lot of work has gone into it. Would you mind splitting it into a question and answer though? You can add your own answer to your own question and mark it as correct.Agripina
@Agripina Yes of course if you think it would be better that wayWeintraub
I second that. I like GLFW very much but was really frustrated not to find any documentation regarding how to compile v3 under Mac, etc.Margetmargette
@Margetmargette Yeah I found that kind of surprising, since GLFW seems to be "a better glut". I'm sure they mentioned in their documentation that glut is only good for learning and if you want a professional window lib, use GLFW. So the surprising thing is they tell you how good it is but don't tell you how to install it! (Quite unlike SFML)Weintraub
@Edward Bird. I finally found some useful information on this webpage regarding installing GLFW: scratchapixel.com/lessons/3d-basic-lessons/lesson-2-get-started/…Margetmargette
I'll see about adding that.Paralyse
Note that starting with Ubuntu 14.10, GLFW3 is in the official repository.Overslaugh
The installation instructions are now available in GLFW's official website: glfw.org/docs/latest/compile_guide.htmlMonotone
W
18

2020 Updated Answer

It is 2020 (7 years later) and I have learned more about Linux during this time. Specifically that it might not be a good idea to run sudo make install when installing libraries, as these may interfere with the package management system. (In this case apt as I am using Debian 10.)

If this is not correct, please correct me in the comments.

Alternative proposed solution

This information is taken from the GLFW docs, however I have expanded/streamlined the information which is relevant to Linux users.

  • Go to home directory and clone glfw repository from github
cd ~
git clone https://github.com/glfw/glfw.git
cd glfw
  • You can at this point create a build directory and follow the instructions here (glfw build instructions), however I chose not to do that. The following command still seems to work in 2020 however it is not explicitly stated by the glfw online instructions.
cmake -G "Unix Makefiles"
  • You may need to run sudo apt-get build-dep glfw3 before (?). I ran both this command and sudo apt install xorg-dev as per the instructions.

  • Finally run make

  • Now in your project directory, do the following. (Go to your project which uses the glfw libs)

  • Create a CMakeLists.txt, mine looks like this

CMAKE_MINIMUM_REQUIRED(VERSION 3.7)
PROJECT(project)

SET(CMAKE_CXX_STANDARD 14)
SET(CMAKE_BUILD_TYPE DEBUG)

set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)

add_subdirectory(/home/<user>/glfw /home/<user>/glfw/src)


FIND_PACKAGE(OpenGL REQUIRED)

SET(SOURCE_FILES main.cpp)

ADD_EXECUTABLE(project ${SOURCE_FILES})
TARGET_LINK_LIBRARIES(project glfw)
TARGET_LINK_LIBRARIES(project OpenGL::GL)
  • If you don't like CMake then I appologize but in my opinion it is the easiest way to get your project working quickly. I would recommend learning to use it, at least to a basic level. Regretably I do not know of any good CMake tutorial

  • Then do cmake . and make, your project should be built and linked against glfw3 shared lib

  • There is some way of creating a dynamic linked lib. I believe I have used the static method here. Please comment / add a section in this answer below if you know more than I do

  • This should work on other systems, if not let me know and I will help if I am able to

Weintraub answered 15/7, 2020 at 0:36 Comment(3)
2021 update: if you run into errors like No rule to make target '/usr/lib/libNAME.so', you must create symlinks to problem libraries: sudo ln -s /usr/lib/x86_64-linux-gnu/libNAME.so /usr/lib/libNAME.soIllnatured
I followed GLFW's instuctions from their website (instead of maling your CMakeLists.txt file) for linux, they work as expected. For raspberry pi 3 A+ :pBaiss
@ChristianidisVasileios It might be in the 3 years since I posted this answer, and the 10 years since I posted the original question + answer, that things have improved substantially. I would have hoped as much. If the situation has changed, please post a new answer with details.Weintraub
B
153

Step 1: Installing GLFW 3 on your system with CMAKE

For this install, I was using KUbuntu 13.04, 64bit.

The first step is to download the latest version (assuming versions in the future work in a similar way) from www.glfw.org, probably using this link.

The next step is to extract the archive, and open a terminal. cd into the glfw-3.X.X directory and run cmake -G "Unix Makefiles" you may need elevated privileges, and you may also need to install build dependencies first. To do this, try sudo apt-get build-dep glfw or sudo apt-get build-dep glfw3 or do it manually, as I did using sudo apt-get install cmake xorg-dev libglu1-mesa-dev... There may be other libs you require such as the pthread libraries... Apparently I had them already. (See the -l options given to the g++ linker stage, below.)

Now you can type make and then make install, which will probably require you to sudo first.

Okay, you should get some verbose output on the last three CMake stages, telling you what has been built or where it has been placed. (In /usr/include, for example.)

Step 2: Create a test program and compile

The next step is to fire up vim ("what?! vim?!" you say) or your preferred IDE / text editor... I didn't use vim, I used Kate, because I am on KUbuntu 13.04... Anyway, download or copy the test program from here (at the bottom of the page) and save, exit.

Now compile using g++ -std=c++11 -c main.cpp - not sure if c++11 is required but I used nullptr so, I needed it... You may need to upgrade your gcc to version 4.7, or the upcoming version 4.8... Info on that here.

Then fix your errors if you typed the program by hand or tried to be "too clever" and something didn't work... Then link it using this monster! g++ main.o -o main.exec -lGL -lGLU -lglfw3 -lX11 -lXxf86vm -lXrandr -lpthread -lXi So you see, in the "install build dependencies" part, you may also want to check you have the GL, GLU, X11 Xxf86vm (whatever that is) Xrandr posix-thread and Xi (whatever that is) development libraries installed also. Maybe update your graphics drivers too, I think GLFW 3 may require OpenGL version 3 or higher? Perhaps someone can confirm that? You may also need to add the linker options -ldl -lXinerama -lXcursor to get it to work correctly if you are getting undefined references to dlclose (credit to @user2255242).

And, yes, I really did need that many -ls!

Step 3: You are finished, have a nice day!

Hopefully this information was correct and everything worked for you, and you enjoyed writing the GLFW test program. Also hopefully this guide has helped, or will help, a few people in the future who were struggling as I was today yesterday!

By the way, all the tags are the things I searched for on stackoverflow looking for an answer that didn't exist. (Until now.) Hopefully they are what you searched for if you were in a similar position to myself.

Author Note:

This might not be a good idea. This method (using sudo make install) might be harzardous to your system. (See Don't Break Debian)

Ideally I, or someone else, should propose a solution which does not just install lib files etc into the system default directories as these should be managed by package managers such as apt, and doing so may cause a conflict and break your package management system.

See the new "2020 answer" for an alternative solution.

Bucher answered 21/7, 2013 at 0:30 Comment(18)
I spent hours trying to figure this out. This answer worked for me: Ubuntu 13.04, x64. NetBeans C++ IDE (add the linker line in Project Properties->Build->Linker->Libraries->Add Option->Other Option - otherwise follow the instructions verbatim)Brachyuran
Apparently (with GLFW 3.0.3) something uses pow so adding -lm to the compile options fixed it.Evansville
Edward, thank you. I needed this sanity-check that all of the -l requirements didn't just mean that I was doing something wrong.Haim
You have missed -lrt when linking.Unending
@Unending What does -lrt do? I didn't seem to need it on my system.Weintraub
@EdwardBird for asynchronous IO apparently. I needed it on Centos 6.5 lehman.cuny.edu/cgi-bin/man-cgi?librt+3Unending
I just switched from SFML to GLFW3 on Linux Mint and my command line looked like this: -lGLEW -lglfw3 -lGL -lz -lXrandr -lXi. libGLEW and libz are dependencies that my applicaton use. Note that I did not have to link against libX11 libXxf86vm libpthread (also: libGLU and librt). Why is that?Wobble
If any of you are still around, I need to make a glfw shared object and have been having troubles linking. Here's the error I've been getting. I tried adding target_link_libraries(glfw ${glfw_LIBRARIES} -lGL -lGLU -lX11 -lXxf86vm -lXrandr -lpthread -lXi -lrt) to CMakeLists.txt, but this did not fix the problem. Any help would be greatly appreciated!Dextro
dude you are a fu**** GENIUS!!!! you got 3 hours, I got 3 days trying to do this (actually researching from where to start, reading about glut history and so on, anyway) thank you thank you very fu*** much; I would like also to advice that I read the glfw page, couldnt make the job following their tutorial, was almost giving up when I found this and they dont explain so simple and direct as you do. awesome job you did here!!Failure
@VictorOliveira Haha thanks, it's nice to know this info is still useful some months down the line.Weintraub
When I try to compile GLFW3 on Centos6 I have a crash? /bin/sh: line 1: 11702 Segmentation fault (core dumped) /usr/bin/doxygen. I switched documentation OFF in CMakeLists.txt but it still tries to create the Doxygen doc??? and it crashes. Any idea?Margetmargette
possibly also add -lrtDraw
On a clean Linux Mint I had to install these packages: sudo apt-get update && sudo apt-get install build-essential libevent-pthreads-2.0.5 doxygen xorg-dev libglu1-mesa-devCountdown
I have error on g++ main.o -o main.exec -lGL -lGLU -lglfw3 -lX11 -lXxf86vm -lXrandr -lpthread -lXi undefined reference to symbol XineramaQueryExtension. Can someone kindly help?Stetson
@ShiheZhang: add the Xinerama library to the list ;)Macule
Done Step 1 fine, command g++ main.cpp -o main.o run fine, but after g++ main.o -o main.exec -lGL -lGLU -lglfw3 -lX11 -lXxf86vm -lXrandr -lpthread -lXi I've got /usr/bin/ld: cannot find -lglfw3. What's wrong?Leatherman
Just a note for those who have issues compiling their open GL program after completing an install: I also needed the following libraries: -ldl -lXinerama -lXcursorKurgan
Your answer work like a charm. Steps 1 and 2 are all what is needed to do.Bolitho
A
22

I solved it in this way

A pkg-config file describes all necessary compile-time and link-time flags and dependencies needed to use a library.

pkg-config --static --libs glfw3

shows me that

-L/usr/local/lib -lglfw3 -lrt -lXrandr -lXinerama -lXi -lXcursor -lGL -lm -ldl -lXrender -ldrm -lXdamage -lX11-xcb -lxcb-glx -lxcb-dri2 -lxcb-dri3 -lxcb-present -lxcb-sync -lxshmfence -lXxf86vm -lXfixes -lXext -lX11 -lpthread -lxcb -lXau -lXdmcp  

I don't know if all these libs are actually necessary for compiling but for me it works...

Aronarondel answered 3/7, 2015 at 21:33 Comment(1)
This answer is a must see . I did not know about pkg-config earlier . But from today I will use it till the end , because it will help me solve any kind of linking dependency problem . Thanks for such an awesome answer.Thermobarograph
D
20

Note that you do not need that many -ls if you install glfw with the BUILD_SHARED_LIBS option. (You can enable this option by running ccmake first).

This way sudo make install will install the shared library in /usr/local/lib/libglfw.so. You can then compile the example file with a simple:

g++ main.cpp -L /usr/local/lib/ -lglfw

Then do not forget to add /usr/local/lib/ to the search path for shared libraries before running your program. This can be done using:

export LD_LIBRARY_PATH=/usr/local/lib:${LD_LIBRARY_PATH}

And you can put that in your ~/.bashrc so you don't have to type it all the time.

Dufour answered 23/11, 2013 at 17:3 Comment(5)
this information is really important for those who would like to setup one IDE instead of use terminal to compile and run; Could you give more details about how to do this? I tried but not successful at allFailure
Noob here! I know this is a bit old, but it really helped me. Can someone explain (or link to someone explaining) why using a shared library would make it so we don't have to link all those other libraries, many of which were also shared object files? Also, I had to set the LD_LIBRARY_PATH variable after compiling, or face the wrath of gnu errors when I try to run my newly compiled executable.Atlantes
Hi Sammaron, thanks for talking about the LD_LIBRARY_PATH, I will update my answer to include this. The reason you do not have to specify all the other libraries when using the glfw library is because glfw already loads them. You can use the command ldd to check what libraries are loaded by a program when it runs. It is also a good way to check that the libraries are found properly. You can use ldd on your program and on /usr/local/lib/libglfw.so to compare.Dufour
Thanks for the reply! Also, I wanted to correct myself a little bit: the LD_LIBRARY_PATH variable is a viable solution, but if the library was installed in the standard path that the loader will be searching anyway, running sudo ldconfig should solve this problem, and not require LD_LIBRARY_PATH to be configured every time. This answer provides a discussion as to why this might be preferred.Atlantes
After doing with build shared, I had to compile/link 2 others. g++ main.cpp -L /usr/local/lib/ -lglfw -lGLU -lGL worked for me.Japan
W
18

2020 Updated Answer

It is 2020 (7 years later) and I have learned more about Linux during this time. Specifically that it might not be a good idea to run sudo make install when installing libraries, as these may interfere with the package management system. (In this case apt as I am using Debian 10.)

If this is not correct, please correct me in the comments.

Alternative proposed solution

This information is taken from the GLFW docs, however I have expanded/streamlined the information which is relevant to Linux users.

  • Go to home directory and clone glfw repository from github
cd ~
git clone https://github.com/glfw/glfw.git
cd glfw
  • You can at this point create a build directory and follow the instructions here (glfw build instructions), however I chose not to do that. The following command still seems to work in 2020 however it is not explicitly stated by the glfw online instructions.
cmake -G "Unix Makefiles"
  • You may need to run sudo apt-get build-dep glfw3 before (?). I ran both this command and sudo apt install xorg-dev as per the instructions.

  • Finally run make

  • Now in your project directory, do the following. (Go to your project which uses the glfw libs)

  • Create a CMakeLists.txt, mine looks like this

CMAKE_MINIMUM_REQUIRED(VERSION 3.7)
PROJECT(project)

SET(CMAKE_CXX_STANDARD 14)
SET(CMAKE_BUILD_TYPE DEBUG)

set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)

add_subdirectory(/home/<user>/glfw /home/<user>/glfw/src)


FIND_PACKAGE(OpenGL REQUIRED)

SET(SOURCE_FILES main.cpp)

ADD_EXECUTABLE(project ${SOURCE_FILES})
TARGET_LINK_LIBRARIES(project glfw)
TARGET_LINK_LIBRARIES(project OpenGL::GL)
  • If you don't like CMake then I appologize but in my opinion it is the easiest way to get your project working quickly. I would recommend learning to use it, at least to a basic level. Regretably I do not know of any good CMake tutorial

  • Then do cmake . and make, your project should be built and linked against glfw3 shared lib

  • There is some way of creating a dynamic linked lib. I believe I have used the static method here. Please comment / add a section in this answer below if you know more than I do

  • This should work on other systems, if not let me know and I will help if I am able to

Weintraub answered 15/7, 2020 at 0:36 Comment(3)
2021 update: if you run into errors like No rule to make target '/usr/lib/libNAME.so', you must create symlinks to problem libraries: sudo ln -s /usr/lib/x86_64-linux-gnu/libNAME.so /usr/lib/libNAME.soIllnatured
I followed GLFW's instuctions from their website (instead of maling your CMakeLists.txt file) for linux, they work as expected. For raspberry pi 3 A+ :pBaiss
@ChristianidisVasileios It might be in the 3 years since I posted this answer, and the 10 years since I posted the original question + answer, that things have improved substantially. I would have hoped as much. If the situation has changed, please post a new answer with details.Weintraub
S
13

Since the accepted answer does not allow more edits, I'm going to summarize it with a single copy-paste command (Replace 3.2.1 with the latest version available in the first line):

version="3.2.1" && \
wget "https://github.com/glfw/glfw/releases/download/${version}/glfw-${version}.zip" && \
unzip glfw-${version}.zip && \
cd glfw-${version} && \
sudo apt-get install cmake xorg-dev libglu1-mesa-dev && \
sudo cmake -G "Unix Makefiles" && \
sudo make && \
sudo make install

If you want to compile a program use the following commands:

g++ -std=c++11 -c main.cpp && \
g++ main.o -o main.exec -lGL -lGLU -lglfw3 -lX11 -lXxf86vm -lXrandr -lpthread -lXi -ldl -lXinerama -lXcursor

If you are following the learnopengl.com tutorial you may have to set up GLAD as well. In such case click on this link

http://glad.dav1d.de/#profile=core&specification=gl&api=gl%3D3.3&api=gles1%3Dnone&api=gles2%3Dnone&api=glsc2%3Dnone&language=c&loader=on

and then click on the "Generate" button at the bottom right corner of the website and download the zip file. Extract it and compile the sources with the following command:

g++ glad/src/glad.c -c -Iglad/include

Now, the commands to compile your program become like this:

g++ -std=c++11 -c main.cpp -Iglad/include && \
g++ main.o glad.o -o main.exec -lGL -lGLU -lglfw3 -lX11 -lXxf86vm -lXrandr -lpthread -lXi -ldl -lXinerama -lXcursor
Sheley answered 18/6, 2017 at 13:1 Comment(1)
Brilliant! Worked for me on Ubuntu 16.04 with GLFW v3.2.1. Only two minor corrections: set version=X.X.X should simply be version="X.X.X" and there should be no .zip at the end of this line: cd glfw-${version}.zipWellthoughtof
B
7

this solved it to me:

sudo apt-get update
sudo apt-get install libglfw3
sudo apt-get install libglfw3-dev

taken from https://github.com/glfw/glfw/issues/808

Benzophenone answered 23/11, 2020 at 9:0 Comment(0)
Q
5

Great guide, thank you. Given most instructions here, it almost built for me but I did have one remaining error.

/usr/bin/ld: //usr/local/lib/libglfw3.a(glx_context.c.o): undefined reference to symbol 'dlclose@@GLIBC_2.2.5'
//lib/x86_64-linux-gnu/libdl.so.2: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

After searching for this error, I had to add -ldl to the command line.

g++ main.cpp -lglfw3 -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lGL -lpthread -ldl

Then the "hello GLFW" sample app compiled and linked.

I am pretty new to linux so I am not completely certain what exactly this extra library does... other than fix my linking error. I do see that cmd line switch in the post above, however.

Query answered 29/12, 2015 at 18:33 Comment(2)
I got .o and .exec file.. please help me that,how to run it?Thermodynamics
I think you can execute the exec file as ./main.exec . If not share what command you used to compile your code and generate .exec file.Palocz
M
0

If anyone's getting lazy and maybe perhaps doesn't know how to configure shell for all those libraries and -ls, then I created a python script(you have to have python3, most linux users have it.) that allows you to easily compile scripts and run them without worrying much, it just has regular system calls, just arranged neatly, I created it for my self but maybe it'd be useful: Here it is

Montane answered 18/7, 2018 at 10:11 Comment(0)
D
0

The well-described answer is already there, but I went through this SHORTER recipe:

  1. Install Linuxbrew
  2. $ brew install glfw
  3. cd /home/linuxbrew/.linuxbrew/Cellar/glfw/X.X/include
  4. sudo cp -R GLFW /usr/include

Explanation: We manage to build GLFW by CMAKE which is done by Linuxbrew (Linux port of beloved Homebrew). Then copy the header files to where Linux reads from (/usr/include).

Darbydarce answered 23/10, 2019 at 20:57 Comment(0)
I
0

Manually managing libraries is tiring and well, hard to manage. A lot of these solutions proposed by other people are great, but what I would recommend doing is using a cross-platform package manager that can manage all this stuff for you, like vcpkg. Just install vcpkg and you can easily install, uninstall, and just maintain whatever libraries you want.

Iwo answered 2/5, 2022 at 16:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.