如何在Linux中使用CMake和Kdevelop编译GLUT + OpenGL项目?

54

正如标题所述,我似乎无法使用OpenGL和Glut构建项目。

我得到了OpenGL函数的未定义引用错误。

我尝试过:

project(testas)
find_package(OpenGL)
find_package(GLUT)
add_executable(testas main.cpp)

但是那样不起作用。

有什么建议吗?

4个回答

110

find_package(OpenGL)会为您找到包,但不会将该包链接到目标。

要链接到库,可以使用target_link_libraries(<target> <item>)。另外,您还需要设置include directory,这样链接器就知道在哪里查找文件。这可以通过include_directories来完成。

下面是一个示例的CMakeLists.txt:


cmake_minimum_required(VERSION 2.8)

project(testas)
add_executable(testas main.cpp)
find_package(OpenGL REQUIRED)
find_package(GLUT REQUIRED)
include_directories( ${OPENGL_INCLUDE_DIRS}  ${GLUT_INCLUDE_DIRS} )

target_link_libraries(testas ${OPENGL_LIBRARIES} ${GLUT_LIBRARY} )
如果你的项目需要使用OpenGL,你可以考虑在执行find_package(OpenGL)后测试OpenGL_FOUND或者使用REQUIRED,这会在没有找到OpenGL的情况下让cmake停止运行。更多信息和更好的示例请查看以下资源:
特别是CMake Wiki和cmake和opengl链接将提供足够的信息帮助你使事情正常运作。

谢谢您的回答。现在我遇到了一个错误,它找不到它们,但我已经安装了它们。/usr/bin/ld: error: cannot find -lOpenGL /usr/bin/ld: error: cannot find -lGLUT - Ren
哎呀,我在答案中输错了 target_link_libraries。现在已经更正过来,并且检查了一下它能否正常工作。 :) - simont
我理解链接到OpenGLGLUT没有问题,是吗?这种错误表明GLUT_XiGLUT_Xmu未安装(它们未被cmake找到)。如果您使用的是Ubuntu,请查看此链接。如果不是,请尝试为您的系统安装GLUT_XiGLUT_Xmu - simont
好的,我现在有一个可用的 CMakeLists.txt 文件了。将其添加到答案中。 - simont
2
您可能希望更新您的答案,使用导入目标,如target_link_libraries(testas PRIVATE OpenGL::OpenGL GLUT::GLUT)。然后您就不需要include_directories()这样的东西了。cmake_minimum也应该更新,但我不太记得最低要求是多少了。我猜是3.0,但如果是3.6,那就一定没问题了。 - Slava
显示剩余6条评论

21

最近的CMake版本(3.10+)有一种新的使用OpenGL的方法,使用所谓的 IMPORTED target

cmake_minimum_required(VERSION 3.10)

project(testas)
add_executable(testas main.cpp)
find_package(OpenGL REQUIRED COMPONENTS OpenGL)
find_package(GLUT REQUIRED)

add_dependencies(testas OpenGL::OpenGL)
include_directories(${GLUT_INCLUDE_DIRS} )

target_link_libraries(testas OpenGL::OpenGL ${GLUT_LIBRARY} )

目前唯一实际的区别似乎只存在于Linux上(如果可用,则使用GLVND),但是这个解决方案应该更具未来性,因为CMake有关于你意图的更多信息,其他解析你的CMakeFiles的工具将更好地理解依赖树。


1
这对我在 macOS Mojave 10.14.3 上使用 GitHub 项目 vsthost by wtrsltnk 有效。 - vaid
2
请注意,我不得不使用${GLUT_LIBRARIES}(复数形式)。 - Alexis Wilke
在 Mac 上(我的版本是 Big Sur 11.2),由于 Apple 自带的 OpenGL 没有 OpenGL::OpenGL 目标,因此必须退回到 target_link_libraries(testas ${OPENGL_LIBRARIES} ${GLUT_LIBRARY}) - honey_badger

5

最近,您可以使用 GLUT::GLUT

cmake_minimum_required(VERSION 2.8)

project(testas)

find_package(OpenGL REQUIRED)
find_package(GLUT REQUIRED)

add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} OpenGL::GL GLUT::GLUT)

-4

我使用这两个cmake文件来构建我的OpenGL项目,它们都运行良好。

我只在Deepin Linux下测试了这两个cmake文件。Deepin Linux是一个类似于Ubuntu或Debian的中国本土Linux系统。

首先,主要的CMakeLists.txt

cmake_minimum_required(VERSION 3.1.0)
project(project_name)

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/")

find_package(OpenGL REQUIRED)
find_package(FREEGLUT REQUIRED)
find_package(GLEW REQUIRED)

if(NOT ${OPENGL_FOUND})
    message("OPENGL not found")
endif()

include_directories(
    ${PROJECT_SOURCE_DIR}
    ${FREEGLUT_INCLUDE_DIR}
    ${GLEW_INCLUDE_DIR}
    ${OPENGL_INCLUDE_DIR}
    )

message(${OPENGL_INCLUDE_DIR})
add_executable(${PROJECT_NAME}  ${PROJECT_SOURCE_DIR}/filename.cpp) 
target_link_libraries(${PROJECT_NAME} 
${OPENGL_LIBRARY}
${FREEGLUT_LIBRARY}
${GLEW_LIBRARY}
)

第二步,在CMakeModules目录下找到GLUT的cmake文件。
# Try to find the FREEGLUT library
#
# FREEGLUT_INCLUDE_DIR
# FREEGLUT_LIBRARY
# FREEGLUT_FOUND

FIND_PATH(
  FREEGLUT_INCLUDE_DIR GL/freeglut.h GL/gl.h GL/glu.h GL/glew.h
  ${CMAKE_INCLUDE_PATH}
  $ENV{include}
  ${OPENGL_INCLUDE_DIR}
  /usr/include
  /usr/local/include
)

SET(STORE_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK})
SET(CMAKE_FIND_FRAMEWORK NEVER)

FIND_LIBRARY(
  FREEGLUT_LIBRARY
  NAMES freeglut_static freeglut glut GL
  PATH
    /opt/local/lib
    ${CMAKE_LIBRARY_PATH}
    $ENV{lib}
    /usr/lib
    /usr/local/lib
)

SET(CMAKE_FIND_FRAMEWORK ${STORE_CMAKE_FIND_FRAMEWORK})

IF (FREEGLUT_INCLUDE_DIR AND FREEGLUT_LIBRARY)
   SET(FREEGLUT_FOUND TRUE)
ENDIF (FREEGLUT_INCLUDE_DIR AND FREEGLUT_LIBRARY)

IF (FREEGLUT_FOUND)
   IF (NOT FREEGLUT_FIND_QUIETLY)
      MESSAGE(STATUS "Found FREEGLUT: ${FREEGLUT_LIBRARY}")
   ENDIF (NOT FREEGLUT_FIND_QUIETLY)
ELSE (FREEGLUT_FOUND)
   IF (FREEGLUT_FIND_REQUIRED)
      MESSAGE(FATAL_ERROR "Could not find FREEGLUT")
   ENDIF (FREEGLUT_FIND_REQUIRED)
ENDIF (FREEGLUT_FOUND)

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