在Mac OS X上,cmake找不到gl.h。

5

我在使用OS X 10.10构建一个包含GLUT和OpenGL的C语言“项目”。 我将它简化为一个最小的示例,展示我的问题。我有以下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})

main.c只是一个虚拟文件,包含了两个头文件:

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

现在,cmake . 运行良好,用于调试目的打印所有变量。我从某个地方获取了代码,我不太了解cmake是否正在执行我认为它正在执行的操作。无论如何,运行 make 返回:
main.c:1:10: fatal error: 'gl.h' file not found
#include <gl.h>
         ^
1 error generated.

头文件gl.h实际上位于/System/Library/Frameworks/OpenGL.framework/Headers中,因此应该由cmake找到,特别是因为glut.h也在相同的结构中(只需用GLUT替换OpenGL),而且会被正确找到。此外,令我困惑的是,在if(GLUT_FOUND)...块中的代码从未执行过(尝试在其中添加一条message语句),但在打印出的变量中,它说OPENGL_FOUND=TRUE。但是,删除if条件并没有改变任何东西。

实际问题:到底发生了什么?为什么a) cmake不能找到头文件,除非明确包含,b) if块不执行,尽管OPENGL_FOUND打印为TRUE,c)使用glut.h时不会出现这些问题?花了几个小时还是搞不清楚为什么。


1
正确的变量应该是OPENGL_FOUND。对于所有其他变量也是如此。使用大写字母OPENGLFindOpenGL也不会设置LIBRARY_DIR。你真的在查看文档吗? - pmr
关于变量:是的,我尝试了几种方法。例如,它确实声明了一个名为OPENGL_LIBRARIES的变量,我已经尝试过了,但问题并不在链接步骤上。 - oarfish
是的,我也尝试过那个方法,并且该变量打印出了正确的值,但是令我惊讶的是,我收到了上述错误。 - oarfish
你是否也检查了INCLUDE_DIRS变量及其值的拼写?之后,你尝试过使用make VERBOSE=1来查看完整的编译器调用吗?它是否包含正确的包含目录?如果所有方法都失败了,请删除CMakeCache。 - pmr
是的,是的,是的,不是。正如我上面指出的那样,Opengl_found变量没有大写,尽管我曾经这样做过,但并没有帮助。这就是为什么if块没有被执行,而OPENGL_FOUND为真,而路径实际上并不存在于编译器调用中的原因。我也总是删除缓存并从头开始重建,以摆脱这个混淆因素。 - oarfish
显示剩余4条评论
4个回答

19

通常做法是

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

你可以在GLFW、GLEW、SFML等库中以某种形式看到这个被实现。


2
奇怪的是,它可以使用<OpenGL/gl.h>,尽管我确信我已经尝试过了。您能详细说明一下包含过程的工作原理吗?也就是说,为什么当头文件不在具有该名称的目录中而在上述的.framework/Headers目录中时,我要在前缀中加入OpenGL呢? - oarfish

5

我很惊讶你在OS X 10.10的/System/Library/Frameworks中找到了OpenGL头文件。我认为它们在很多Xcode版本中都没有安装在那里。最近的头文件应该在Xcode 6.1和10.10上的:

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

除非你想查看头文件,否则你不需要知道这个路径。我相信编译器会自动使用与你编译的操作系统匹配的SDK。如果出于某种原因你想为不同的平台构建,你可以使用-isysroot编译器选项覆盖该逻辑。

对于来自框架的头文件,你在#include语句中使用的名称是:

#include <FrameworkName/HeaderFileName.h>

编译器将解析为框架内头文件的实际路径。因此,如果您想要从OpenGL框架中使用当前的OpenGL头文件(即gl3.h),正确的包含语句如下:
#include <OpenGL/gl3.h>

这将使你能够访问最高支持的OpenGL版本的核心配置文件(如果你有一个相对较新的Mac,那么这个版本是3.x或4.x)。或者,如果你想要使用带有旧特性的OpenGL 2.1:
#include <OpenGL/gl.h>

我没有安装Xcode,当我意识到命令行工具可以单独安装时就抛弃了它。但是,如果我使用上述的cmake文件,并纠正“OpenGL_FOUND”的大小写,那么头文件就会被找到,即使我只使用#include <gl.h>而不带框架名称(<OpenGL/gl.h>也可以) 。 - oarfish

4

正如pmr所指出的那样,CMake变量是区分大小写的,因此必须查询变量OPENGL_FOUND。 另外,正如PeterT所写的那样,在OS X上,头文件被包含为#include <OpenGL/gl.h>


1

我在更新了Homebrew安装的Qt后遇到了同样的错误信息,最终来到了这个问题。根据Reto的评论,我更新了CMAKE_OSX_SYSROOT为/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk,然后一切都恢复正常了。


对于那些使用命令行工具(而不是完整的XCode.app)的人来说,路径是/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk - Gwyneth Llewelyn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接