2014-11-04 305 views
3

我在OS X 10.10上,尝试用GLUT和OpenGL构建C'项目。 我将它简化为展示我的问题的最小示例。我有以下CMakeLists.txtcmake在OS X上找不到gl.h的文件

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)尽管OPENGL_FOUND打印为TRUE,if块不能执行,c)glut.h不会出现这种问题?在这花了几个小时,无法理解为什么。

+1

正确的变量是'OPENGL_FOUND'。所有其他变量也是如此。使用大写的'OPENGL'。 'FindOpenGL'也不设置'LIBRARY_DIR'。你真的在看文档吗? – pmr 2014-11-04 21:42:09

+0

大写或无在这里没有任何区别。我也不确定它是否可以(?) 关于变量:是的,我尝试了几件事情。比如它声明了一个变量'OPENGL_LIBRARIES',我试过了,但问题不在于这里的连接步骤。 – oarfish 2014-11-04 22:02:47

+0

是的,cmake变量是区分大小写的。尝试使用正确的'OPENGL_INCLUDE_DIR'。对于MacOS上的CMake,这应该是'gl.h'的完整路径。问题是Mac OS上的框架有很奇怪的包含路径。 – pmr 2014-11-04 22:25:03

回答

0

正如指出的贝PMR,CMake的变量是大小写敏感的,所以变量OPENGL_FOUND必须进行查询。 另外,正如PeterT写的,标题在OS X上包含为#include <OpenGL/gl.h>

7

这是常见的做

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

你可以看到这是一个形式做或那样GLFW,GLEW,SFML和其他

+0

奇怪的是,它与'一起工作,尽管我确信我已经尝试过了。您能否详细说明包含过程的工作原理,即为什么当头文件不在具有该名称的目录中,而是位于前面提到的.framework/Headers目录中时,为什么要加前缀“OpenGL”? – oarfish 2014-11-04 22:05:43

2

我很惊讶,你发现OpenGL的头在/System/Library/Frameworks在OS X 10.10。我不认为他们已经安装在很多Xcode版本中。在10.10和Xcode 6.1最新的头文件应该在:

/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头,这是gl3.h,从OpenGL的框架,正确的包括语句:

#include <OpenGL/gl3.h> 

这将使你获得的最高的核心配置文件支持OpenGL版本(如果您拥有合理的新Mac,则为3.x或4.x)。或者,如果你想使用的OpenGL 2.1与传统的特点:

#include <OpenGL/gl.h> 
+0

我没有安装Xcode,当意识到cmdline工具可以单独安装时,我放弃了它。但是,如果我使用上面的cmake文件并更正了'OpenGL_FOUND'的外壳,虽然我只使用'#include '而没有框架名称(''也可以),但可以找到标题。 – oarfish 2014-11-05 12:12:37