How to use CMake to find and link OpenGL(mesa) package in Ubuntu

stanleyerror picture stanleyerror · Nov 30, 2015 · Viewed 12.2k times · Source

I am totally new in CMake and OpenGL. I now need to use OpenGL as a library in my project on my Ubuntu 15.04 64bit PC, which is built by CMake 3.0.2.

I have been working on this several days, nearly frustrated. I get confused with a bunch of problems.


mesa and OpenGL

First of all, I installed the mesa package with command sudo apt-get install mesa-common-dev, which get me mesa 10.5.2.

Then I browse the package files with dpkg -L mesa-common-dev:

/.
/usr
/usr/share
/usr/share/bug
...
/usr/share/bug/mesa-common-dev/control

/usr/share/doc
...
/usr/share/doc/mesa-common-dev/faq.html

/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/pkgconfig
/usr/lib/x86_64-linux-gnu/pkgconfig/dri.pc

/usr/include
/usr/include/GL
/usr/include/GL/gl.h
...
/usr/include/GL/glx_mangle.h

QUESTION 1: Where are the shared libraries (.so) and static libraries (.a)?


CMake

I now have a CMakeLists.txt, with the OpenGL module named OPENGL

...
find_package(OPENGL REQUIRED)  # here is CMakeLists.txt:45
...
include_directories(${OPENGL_INCLUDE_DIRS})
link_directories(${OPENGL_LIBRARY_DIRS})
target_link_libraries(MyProj ... ${OPENGL_LIBRARIES})
...

So I definitely need to have a cmake file, say FindOPENGL.cmake, like this (took GLEW's cmake file as a template):

# OPENGL_FOUND             If OPENGL is found
# OPENGL_LIBRARIES         OPENGL libraries
# OPENGL_INCLUDE_DIRS      OPENGL include directories
# OPENGL_LIBRARY_DIRS      OPENGL library directories

if(UNIX)
  set(OPENGL_INC_NAMES gl.h)
  set(OPENGL_LIB_NAMES libGL.so.1.2.0)
endif(UNIX)

# OPENGL static library     # line 17
find_library(OPENGL_LIBRARIES
    NAMES ${OPENGL_LIB_NAMES}
    PATHS /usr/x86_64-linux-gnu/mesa
    DOC "OPENGL library")

# OPENGL library dir        # line 23
find_path(OPENGL_LIBRARY_DIRS
    NAMES ${OPENGL_LIB_NAMES}
    PATHS /usr/x86_64-linux-gnu/mesa
    DOC "OPENGL include directories")

# OPENGL include dir        # line 29
find_path(OPENGL_INCLUDE_DIRS
    NAMES ${OPENGL_INC_NAMES}
    PATHS /usr/include/GL
    DOC "OPENGL include directories")

# Version
set(OPENGL_VERSION 1.13.0)

# Set package standard args
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OPENGL       # here is FindOPENGL.cmake:40
    REQUIRED_VARS OPENGL_LIBRARIES OPENGL_INCLUDE_DIRS OPENGL_LIBRARY_DIRS
    VERSION_VAR OPENGL_VERSION)

QUESTION 2: How to link static libraries and shared libraries in cmake file, and what is the difference between line 17/23/29?

I then run cmake and get following errors:

CMake Error at /usr/share/cmake-3.0/Modules/FindPackageHandleStandardArgs.cmake:136 (message):
  Cound NOT find OPENGL (missing: OPENGL_LIBRARIES OPENGL_LIBRARY_DIRS)
  (found version "1.13.0")
Call Stack (most recent call first):
  /usr/share/cmake-3.0/Modules/FindPackageHandleStandardArgs.cmake:343 (_FPHSA_FAILURE_MESSAGE)
  cmake/modules/FindOPENGL.cmake:40 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
  CMakeLists.txt:45 (find_package)

QUESTION 3: How come I get this error and how can I fix it? Did I do something wrong through the whole procedure?


Update

Thanks for @usr1234567 's answer, I then delete my FindOPENGL.cmake and try to make use of /usr/share/cmake-3.0/Modules/FindOpenGL.cmake. I still get the error missing: OPENGL_gl_LIBRARY. I look into this cmake file for the definition of OPENGL_gl_LIBRARY, and manually check the lib paths in it, unfortunately none of the paths listed exists.

Did I install mesa properly?

Answer

usr1234567 picture usr1234567 · Nov 30, 2015
  • Use CMake FindOpenGL, see https://cmake.org/cmake/help/v3.0/module/FindOpenGL.html.

  • The difference between lines 17 and 23 is that you look for a library (find_library in line 17) and for headers (find_path in line 23). In line 23 and 29 you look for gl.h in two different locations. Overall, this does not matter as you should write your own find routine because CMake provides one for you.

  • You can find static and shared libraries. By default you get the .so. For a second run / variable "Just ask for the archive name first: find_library(MYLIB NAMES libmylib.a mylib)" from https://cmake.org/pipermail/cmake/2010-December/041326.html

  • Question 3 could be solved by hinting CMake where to look. This can be done by adding the right path to CMAKE_PREFIX_PATH. In your case it should be found if you use FindOpenGL from CMake.