Mac 에서 freeglut과 glew 를 링크하는 법

freeglut이란?
위 포스팅에서 freeglut 에 대해 설명하고 cmake를 이용해 mac에서 링크하는 법에 대해 알아보았다. 본 포스팅에서는 왜 freeglut 을 링크할때 주의해야하며 glew는 어떻게 링크하는지 개인적인 경험을 이야기해보고자 한다.

왜 cmake의 find_package 가 안될까?

Linux 에서는 cmake 의 find_package 함수를 이용하면 freeglut 을 적절히 찾았다. 그런데 필자가 Mac 에서 같은 방식으로 freeglut 을 링킹하려고 했을 때 계속해서 링커에러가 나오게 되었다. 그래서 이에대해 찾아본 결과

  • Cmake 에서 find_packages(GLUT) 함수는 FindGLUT.cmake에 정의되어었다.
  • FindGLUT.cmake 에 따르면 mac 에서는 freeglut path, library를 찾는 함수가 정의되어있지 않다.
  • 우선적으로 glut,cocoa 라는 path 를 찾게된다.
  • 그래서 필자의 경우도 find_packages(GLUT) 의 결과로 Cocoa framework 가 나오게 되었다.
  • 따라서 freeglut 을 사용하기 위해서 path 와 library 를 직접 설정해줬다.

설정 방법은 다음과 같다.

#find_package(GLUT REQUIRED) -> 잘못 찾아진다.

# 개인의 환경에 맞게 path 와 library 를 직접 설정해준다.
set(GLUT_LIBRARIES libglut.3.dylib)
set(GLUT_INCLUDE_DIRS /usr/local/Cellar/freeglut/3.0.0/include)
set(GLUT_LIBRARY_DIRS /usr/local/Cellar/freeglut/3.0.0/lib)

기본적으로 homebrew 를 이용해 받은 경우

  • /usr/local/Cellar/freeglut/3.0.0/
    혹은
  • /opt/X11/include/GL

이 위치에 freeglut 이 위치한다. library 와 헤더파일 위치를 적절히 찾으면 되겠다.

MAC 에서 glew 설치하기

먼저 glew 를 다운 받는 방법은 freeglut 과 마찬가지로 homebrew 를 이용하면 쉽게 받을 수 있다. 여기 에 들어가면 방법을 설명해준다.

Glew path 확인

glew 을 다운받았다면 어디에 저장되어었는지 확인해보자. 잘 받았다면

/usr/local/Cellar/glew/2.1.0/include   => 헤더
/usr/local/Cellar/glew/2.1.0/lib       => 라이브러리 경로
libGLEW.dylib                      => 라이브러리 명

혹은

/usr/local/include/GL   => 헤더
/usr/local/lib          => 라이브러리 경로
libGLEW.dylib           => 라이브러리 명

에 잘 저장되어 있을 것이다.

cmake 에서 glew 설정

#OpenGL 라이브러리 설정시 find_packages 는 모든 OS 에서 잘 작동함.
find_package(OpenGL REQUIRED)

#freeglut 라이브러리 설정
set(GLUT_LIBRARIES libglut.3.dylib)
set(GLUT_INCLUDE_DIRS /usr/local/Cellar/freeglut/3.0.0/include)
set(GLUT_LIBRARY_DIRS /usr/local/Cellar/freeglut/3.0.0/lib)

#GLEW 라이브러리 설정
set(GLEW_LIBRARIES libGLEW.dylib)
set(GLEW_INCLUDE_DIRS /usr/local/Cellar/glew/2.1.0/include)
set(GLEW_LIBRARY_DIRS /usr/local/Cellar/glew/2.1.0/lib)

INCLUDE_DIRECTORIES ( ${OPENGL_INCLUDE_DIRS} ${GLUT_INCLUDE_DIRS} ${GLEW_INCLUDE_DIRS})
LINK_LIBRARIES( ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${GLEW_LIBRARIES})
LINK_DIRECTORIES ( ${OPENGL_LIBRARY_DIRS} ${GLUT_LIBRARY_DIRS} ${GLEW_LIBRARY_DIRS})

다음과 같이 inlcude 경로, 라이브러리 경로, 라이브러리 링킹을 해주면 된다.

확인하기

#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>

void display() {
   glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque
   glClear(GL_COLOR_BUFFER_BIT);         // Clear the color buffer

   // Draw a Red 1x1 Square centered at origin
   glBegin(GL_QUADS);              // Each set of 4 vertices form a quad
      glColor3f(1.0f, 0.0f, 0.0f); // Red
      glVertex2f(-0.5f, -0.5f);    // x, y
      glVertex2f( 0.5f, -0.5f);
      glVertex2f( 0.5f,  0.5f);
      glVertex2f(-0.5f,  0.5f);
   glEnd();

   glFlush();  // Render now
}

/* Main function: GLUT runs as a console application starting at main()  */
int main(int argc, char** argv) {


   glutInit(&argc, argv);                 // Initialize GLUT
   glutCreateWindow("OpenGL Setup Test"); // Create a window with the given title
   glutInitWindowSize(320, 320);   // Set the window's initial width & height
   glutInitWindowPosition(50, 50); // Position the window's initial top-left corner

   GLenum err = glewInit();
   if(GLEW_OK != err){
      std::cout<<glewGetErrorString(err)<<std::endl;
      return -1;
   }
   else
      std::cout<<glewGetErrorString(err)<<std::endl;
   glutDisplayFunc(display); // Register display callback handler for window re-paint
   glutMainLoop();           // Enter the infinitely event-processing loop
   return 0;
}

잘 작동한다면 다음 cpp 파일 컴파일후 실행시

No error

라는 메세지가 출력된다.

주의할점은 ,

GLenum err = glewInit();
   if(GLEW_OK != err){
      std::cout<<glewGetErrorString(err)<<std::endl;
      return -1;
   }
   else
      std::cout<<glewGetErrorString(err)<<std::endl;

이 구문은 OpenGL 컨텍스트가 존재해야 잘 동작하므로 createWindow 후에 call 되어야 한다.

요약

  • freeglut 과 glew 를 잘 받았다면 라이브러리 경로는,
/usr/local/Cellar/glew/[version]/
/usr/local/Cellar/freeglut/[version]/

에 있다.

  • 필자는 MAC OS 에서 CMake 를 이용하였고 freeglut,glew 위치를 직접 잡아주었다.
  • 직접 잡아주지 않고 find_packages 를 사용했을 때는 링커에러가 발생했다.

필자의 개발환경이기 때문에 맹신하지 말고 본인의 환경에 맞게 이 글을 활용하면 될것 같습니다.