cmake not finding gl.h on OS X

2019-05-10 03:37发布

问题:

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.

回答1:

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



回答2:

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>


回答3:

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.