glewInit () «Отсутствует версия GL» только в сборках CMake Release - PullRequest
1 голос
/ 18 октября 2019

Я строю свой проект OpenGL, используя CMake с MSVC. Он использует GLEW с GLFW. Он работает нормально при сборке с --config Debug, но glewInit () завершается ошибкой, когда я запускаю команду сборки с --config Release. Я пробовал как 64-, так и 32-битные сборки, и он работает в режиме отладки, но не в обоих случаях.

Я использовал add_definitions(-DGLEW_STATIC) в моем файле CMakeLists.txt, чтобы избежать необходимости везде #define GLEW_STATIC,но я пробовал оба, и это не имеет значения.

Я вижу, что выпускается релиз glew.libglewd.lib создается для отладочных сборок), и если я проверяюсвойства проекта в VS, правильное в списке входов компоновщика.

Я пробовал с подсказками окна и без них перед созданием контекста GL.

Есть что-то, чего я не делаюпонимаю, что происходит здесь. Почему моя версия GL отсутствует, только для конфигурации сборки выпуска?


РЕДАКТИРОВАТЬ: Добавление минимального воспроизводимого примера (спасибо squareskittles за предложение).

Этоmy CMakeLists.exe file:

cmake_minimum_required(VERSION 3.14)
project(Demo LANGUAGES CXX)

# Make sure GLEW gets built as a static lib
add_definitions(-DGLEW_STATIC)
option( glew-cmake_BUILD_SHARED "Build the shared glew library" OFF )
option( glew-cmake_BUILD_STATIC "Build the static glew library" ON )

# Build dependencies
add_subdirectory(glew)
add_subdirectory(glfw)

add_executable(demo demo/main.cpp)

target_compile_features(demo PUBLIC cxx_std_17)
target_compile_definitions(demo PRIVATE -D_SCL_SECURE_NO_WARNINGS)
target_include_directories(demo PUBLIC glew/include)
target_include_directories(demo PUBLIC glfw/include)

# Link dependencies
target_link_libraries(demo libglew_static glfw ${GLFW_LIBRARIES})

Может быть важно знать, что glew-cmake находится в моем каталоге glew.

И demo/main.cpp:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <cassert>

int main(int argc, char** argv)
{
    // Open a window and initialize Glew
    assert(glfwInit());
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 
    GLFWwindow* window = glfwCreateWindow(600, 400, "window", 0, 0);
    glfwMakeContextCurrent(window);
    std::cout << "GLFW: " << glfwGetVersionString() << "\n";
    std::cout << "GLEW: " << glewGetString(GLEW_VERSION) << "\n";
    GLenum glewStatus = glewInit();
    if (glewStatus != GLEW_OK) {
        std::cout << "GLEW ERROR: " << glewGetErrorString(glewStatus) << "\n";
        exit(1);
    }
    std::cout << "GL:   " << glGetString(GL_VERSION) << "\n";

    // Shut down graphics
    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}

Мои команды сборки выполняются из каталога чуть ниже уровня моего файла CMakeLists.txt. Моя команда отладочной сборки:

cmake ..
cmake --build . --config Debug

Если я собираю и запускаю исполняемый файл отладки, перед завершением открывается окно, и вывод:

GLFW: 3.3.0 Win32 WGL EGL VisualC
GLEW: 2.2.0
GL:   3.2.0 - Build 25.20.100.6617

И моя команда сборки выпуска:

cmake ..
cmake --build . --config Release

Если я собрал и запустил исполняемый файл релиза, я нажал на строку exit(1) и вывел:

GLFW: 3.3.0 Win32 WGL EGL VisualC
GLEW: 2.2.0
GLEW ERROR: Missing GL version

ОБНОВЛЕНИЕ: Я пыталсясвязывание с общими библиотеками (dll) вместо статических библиотек, и было подтверждено, что ошибка все еще воспроизводится.

ОБНОВЛЕНИЕ: я пытался создать проект VS с нуля только с моим минимальным воспроизводимым случаем, указав вручную статический илидинамические связи, и это на самом деле работает ! Так что, похоже, что-то с моей конфигурацией CMake.

1 Ответ

1 голос
/ 19 октября 2019

Я обнаружил, что смогу заставить сборки выпуска работать с точно такими же связями, если бы я вручную настроил проект в VS. Я разобрал файл vcxproj, который я создал вручную, с файлом, созданным CMake, чтобы выяснить различия в конфигурациях выпуска. Все сводилось к определению препроцессора NDEBUG.

Я не понимаю, почему это определение не позволяет найти OpenGL (я полагаю, это другой вопрос, но если вы сможете ответить на него здесь, я награжу васответ). Если я добавлю строку

string( REPLACE "/DNDEBUG" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")

в мой файл CMakeLists.txt, я смогу построить и запустить в режиме выпуска!

...