5

I am on OS X 10.10 and trying to build a C 'project' with GLUT and OpenGL. I reduced it to a minimal example showcasing my problem. I have the following CMakeLists.txt:

cmake_minimum_required(VERSION 2.8)
FIND_PACKAGE(OpenGL REQUIRED)
FIND_PACKAGE(GLUT REQUIRED)

if(OpenGL_FOUND) # never true, but printed as true
    link_directories(${OpenGL_LIBRARY_DIRS})
    include_directories(${OpenGL_INCLUDE_DIR})
endif(OpenGL_FOUND)

if(GLUT_FOUND)
    link_directories(${GLUT_LIBRARY_DIR})
    include_directories(${GLUT_INCLUDE_DIR})
endif(GLUT_FOUND)

# print all vars because wtf
get_cmake_property(_v VARIABLES)
foreach(_v ${_v})
   message(STATUS "${_v}=${${_v}}")
endforeach()


add_executable(main main.c)

target_link_libraries(main ${GLUT_LIBRARY} ${OPENGL_LIBRARY})

The main.c is just a dummy including two headers:

#include <gl.h>
#include <glut.h>
int main()
{    
   return 0;
}

Now, cmake . runs fine and for debugging purposes prints all variables. I took the code from somewhere, I do not know enough about cmake to know whether it's doing what I think it is. Anyway, running make returns

main.c:1:10: fatal error: 'gl.h' file not found
#include <gl.h>
         ^
1 error generated.

The header gl.h is actually present in /System/Library/Frameworks/OpenGL.framework/Headers and as such should be found by cmake, especially since glut.h is in the same structure (simply replace OpenGL with GLUT) and is found just fine. Also, what is confusing to me is that the block in if(GLUT_FOUND)... is never executed (try to put a message statement into it), but among the printed variables it says OPENGL_FOUND=TRUE. But removing the if-condition does not change anything.

The actual question: What the hell is going on? Why does a) cmake not find the header unless specifically included, b) the if-block not execute although OPENGL_FOUND prints as TRUE, c) no such problems occur with glut.h? Spent hours on this and can't fathom why.

oarfish
  • 4,116
  • 4
  • 37
  • 66
  • 1
    The correct variable would be `OPENGL_FOUND`. The same is true for all other variables. Use uppercase `OPENGL`. `FindOpenGL` also does not set a `LIBRARY_DIR`. Are you actually looking at the documentation? – pmr Nov 04 '14 at 21:42
  • Uppercase or no does not make any difference here. I am also not sure whether it does at all (?) About the variable: Yes, I have tried several things. For instance it does declare a variable `OPENGL_LIBRARIES`, which I tried, but the problem is not the linking step here. – oarfish Nov 04 '14 at 22:02
  • Yes, cmake variables are case sensitive. Try using the correct `OPENGL_INCLUDE_DIR`. With CMake on MacOS this should be the full path to `gl.h`. The issue is the frameworks on Mac OS which have weird include paths. – pmr Nov 04 '14 at 22:25
  • Yeah, I tried that one too and that variable is printed with the correct value, however – to my astonishment – I get that error mentioned above. – oarfish Nov 04 '14 at 22:35
  • I must revert my previous statement, uppercasing `OPENGL_FOUND` does make a difference, just as you said. I denied that because I had tried exactly that before, but to know avail. So there must have been some confounding variable which changed. – oarfish Nov 04 '14 at 22:51
  • Did you also check the spelling of the INCLUDE_DIRS variable and its value? After that did you try `make VERBOSE=1` to see the full compiler invocation? Does it contain the correct include directory? If everything fails, delete the CMakeCache. – pmr Nov 04 '14 at 22:55
  • Yes and yes and yes and no. As I pointed out above, the Opengl_found variable was not capitatlized although I did it once which din not help. That was the reason why the if block was not executed and `OPENGL_FOUND` was true while the path was not actually present in the compiler invocation. I also always deleted the cache and rebuilt from scratch to get rid of that confounding factor. – oarfish Nov 04 '14 at 23:03
  • @pmr I suggest you make your first comment an answer, since it actually solved the problem. One of my instructors (the cmake file is his) also told some tales about how on some systems, the variable names might be different or case-insensitive and how he never had that problem before, so I get the impression that either the FindOpenGL modules don't always do the same thing or that cmake does not care about variable case on some systems. – oarfish Nov 06 '14 at 17:49
  • Your instructor is wrong. CMake has always treated variables as case sensitive and that part of `FindOpenGL` hasn't changed since ages. What likely happened is that your instructor was using a platform with sensible default paths (Unix...) and never had to actually set the include path. Your tutor is also wrong in using `link_directories`. Almost nothing ever requires it since a `*_LIBRARY` variable should always use a full path. – pmr Nov 06 '14 at 23:54

4 Answers4

19

It's common to do

#if defined(__APPLE__)
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#endif

You can see this being done in one form or another in glfw, glew, sfml and others

PeterT
  • 7,981
  • 1
  • 26
  • 34
  • 2
    Strangely, it works with `, although I was sure I had tried that. Can you elaborate on how the inclusion process works, i.e. why do I prefix `OpenGL` when the header is not in a directory with that name but in the aforementioned .framework/Headers directory? – oarfish Nov 04 '14 at 22:05
4

I'm surprised that you found OpenGL headers in /System/Library/Frameworks in OS X 10.10. I don't think they have been installed there in quite a few Xcode releases. The most recent header files with Xcode 6.1 on 10.10 should be in:

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/System/Library/Frameworks/OpenGL.framework/Headers

You don't really need to know this path, unless you want to go look at the headers. I believe the compiler automatically uses the SDK that matches the OS you're compiling on. If for some reason you wanted to build for a different platform, you can override that logic with the -isysroot compiler option.

With header files that come from a framework, the naming you use in your #include statement is:

#include <FrameworkName/HeaderFileName.h>

The compiler will resolve this to the actual pathname of the header within the framework.

Therefore, if you want to use the current OpenGL header, which is gl3.h, from the OpenGL framework, the correct include statement is:

#include <OpenGL/gl3.h>

This will give you access to the Core Profile of the highest supported OpenGL version (which is 3.x or 4.x if you have a reasonably new Mac). Or if you want to use OpenGL 2.1 with legacy features:

#include <OpenGL/gl.h>
Reto Koradi
  • 53,228
  • 8
  • 93
  • 133
  • I do not have Xcode installed, I ditched it when realising the cmdline tools could be installed separately. But if I use the above cmake file and correct the casing of `OpenGL_FOUND`, the header is found although I only use `#include ` without the framework name (`` works too). – oarfish Nov 05 '14 at 12:12
4

As pointed out bei pmr, CMake variables are case-sensitive, so the variable OPENGL_FOUND must be queried. Also, as PeterT wrote, the header is included as #include <OpenGL/gl.h> on OS X.

oarfish
  • 4,116
  • 4
  • 37
  • 66
1

I ended up coming to this question after updating qt installed from homebrew and had the same error messages. Going off of Reto's comment, I updated CMAKE_OSX_SYSROOT to /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk and everything went back to working as expected.

IntelXDesign
  • 163
  • 5
  • ... and for those using the Command Line Tools (as opposed to the full **XCode.app**), the path is `/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk` – Gwyneth Llewelyn Aug 19 '22 at 02:06