Pages

Sunday, February 19, 2012

CMake에서 debug/release library 따로 설정하기 (Setting debug/release libraries in cmake)

핵심은 debugoptimized 키워드. 다만, 이것은 Library에만 작동하는 듯 한다. ADD_DEFINITION과 같은 곳에는 작동하지 않는 것 같다. 더욱 더 자세한 사항은 FindQT4.cmake를 참고.

FIND_LIBRARY(QGL_RELEASE
    NAME ...
    PATHS ...
)

FIND_LIBRARY(QGL_DEBUG
    NAME ...
    PATHS ...
)

IF(QGL_RELEASE AND QGL_DEBUG)
    SET(QGL_LIBRARY
        debug $(QGL_DEBUG)
        optimized ${QGL_RELEASE})
ENDIF(QGL_RELEASE AND QGL_DEBUG)

단, debugoptimized 키워드는 뒤에 나오는 단 하나의 라이브러리에만 작동한다. 즉,
 debug Ad Bd optimized A B 
라고 하면 Debug모드에서는
 -lAd -lBd -lB 
Release모드에서는
 -lBd -lA -lB 
가 된다! 따라서 debug/optimized를 모든 라이브러리 앞에서 붙여 넣어야 한다.
SET(LIB_NAMES A B C)
FOREACH(NAME ${LIB_NAMES})
  SET(LIB ${LIB} debug ${NAME}D optimized ${NAME})
ENDFOREACH()


Summary
Add debug/optimized keywords before every each library, because these keywords only works with the following single library!

CMake에서 pkg-config 사용하기. (Using pkg-config in cmake)


FIND_PACKAGE(PkgConfig REQUIRED)
PKG_CHECK_MODULES(PREFIX REQUIRED PACKAGE-NAME)
INCLUDE_DIRECTORIES(${PREFIX_INCLUDE_DIRS})
LINK_DIRECTORIES(${PREFIX_LIBRARY_DIRS})

...

TARGET_LINK_LIBRARIES(... ${PREFIX_LIBRARIES})

여기서 중요한 부분은 PKG_CHECK_MODULES. 예를 들어 glew를 쓴다고 가정하자. 그러면 PREFIXGLEW를 집어넣고, PACKAGE-NAMEglew를 넣고 돌리면 다음과 같은 몇가지 변수가 생성된다.


PKG_CHECK_MODULES(GLEW REQUIRED glew)    

GLEW_INCLUDE_DIRS
GLEW_LIBRARY_DIRS
GLEW_LIBRARIES
....

다른 변수들은 FindPkgConfig.cmake를 뒤져보면 알 수 있다.

아 진짜. 찾느라 너무 고생했다. CMake관련해서 한글로 잘 정리된 자료를 찾는건 거의 불가능한것 같다.

GLSL 컴파일 에러 메시지 얻기.

GLSL의 컴파일 에러 메시지를 보기 위해서는 glGetShaderivglGetShaderInfoLog를 이용해서 메시지를 얻어와야 한다. 은근히 귀찮네...


    bool checkShaderCompileStatus(GLuint shader)
    {
        GLint shader_ok;
        glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok);
        if (!shader_ok) {
            GLint blen;
            GLsizei slen;
            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &blen);
            GLchar* compiler_log = (GLchar*)malloc(blen);

            glGetShaderInfoLog(shader, blen, &slen, compiler_log);
            qDebug("%s", compiler_log);
            free(compiler_log);
            return false;
        }
        return true;
    }

덤으로 shader loader. 사실은 Qt에서는 QGLShaderProgramQGLShader를 사용하면 된다.


    static
    GLuint initShader(const char* vs, const char* fs) {
        GLuint program;
        GLuint v = glCreateShader(GL_VERTEX_SHADER);
        GLuint f = glCreateShader(GL_FRAGMENT_SHADER);

        glShaderSource(v, 1, &vs, NULL);
        glShaderSource(f, 1, &fs, NULL);

        qDebug("GLSL: Compiling...");
        glCompileShader(v);
        if (!checkShaderCompileStatus(v))
            qFatal("Vertex Shader Compilation Failed");

        glCompileShader(f);
        if (!checkShaderCompileStatus(f))
            qFatal("Fragment Shader Compilation Failed");

        qDebug("GLSL: Linking...");
        program = glCreateProgram();
        glAttachShader(program, v);
        glAttachShader(program, f);

        glLinkProgram(program);
        qDebug("GLSL: Compiling and linking finished.");
        return program;
    }

Saturday, February 18, 2012

CMakeLists.txt Template

CMake는 다 좋은데 CMakeLists.txt를 만드는게 고역이다. http://oxygene.sk/lukas/2010/10/minimal-qt-cmake-template/에서 가져옴.


    CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

    PROJECT(myproject)

    FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED)
    INCLUDE(${QT_USE_FILE})

    SET(myproject_HEADERS someclass.h)
    SET(myproject_SOURCES someclass.cpp main.cpp)
    SET(myproject_UIS myproject.ui)
    SET(myproject_RESOURCES myproject.qrc)

    QT4_WRAP_CPP(myproject_MOC ${myproject_HEADERS})
    QT4_WRAP_UI(myproject_UIS_H ${myproject_UIS})
    QT4_ADD_RESOURCES(myproject_RESOURCES_CPP ${myproject_RESOURCES})

    INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})

    ADD_EXECUTABLE(myproject
        ${myproject_SOURCES}
        ${myproject_MOC}
        ${myproject_UIS_H}
        ${myproject_RESOURCES_CPP}
    )

    TARGET_LINK_LIBRARIES(myproject ${QT_LIBRARIES})

여기서 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})는 ui_*.h 파일 경로 때문에 추가한다.