CLion and CMake dependeny issue GLEW



  • Hallo liebe Leute.

    Ich bin Anfaenger was C++ angeht und fange langsam an wahnsinning zu werden. Fuer den Einstieg habe ich mir ein Tutorial auf Youtube angeguckt und das verstehe ich auch. Aber sobald es an die dependencies geht funktioniert nichts. Das liegt daran, dass ich nicht Visual Studio benutze (wie im Video), sondern Jetbeans CLion welches als project build tool CMake benutzt. Weiterhin benutze ich als compiler MinGW (32 bit), alles auf Windows 7 64bit.

    Nun mein Problem:
    Ich verstehe nicht, wie dependencies bzw. libraries in C++ miteinander agieren. Ich lade mir die binaries von GLEW runter und fuege in meiner CMake alle notwendigen Pfade hinzu. Die header files werden gefunden, aber die .lib nicht. Exakt das gleiche mache ich mit den binaries von GLFW und es funktioniert alles reibunglos. Der einzige Unterschied ist, dass ich bei GLFW .a bzw. .dll Dateien habe.

    Um nun endlich Gewissheit zu haben. Wie fuege ich .a, .dll, .lib hinzu und was ist die beste Art und Weise dafuer. Als Ziel moechte ich einfach nur ein Programm (in dem Fall eine Game-Engine) schreiben, das alle notwendigen libraries nach dem Compilieren zusammengefuegt hat, sodass ich im Prinzip den Ordner auf eine andere Windows Maschine raufkopieren kann und sofort los-(gespielt) werden kann. Es soll nichts zusaetzlich runtergeladen werden muessen.

    In Java fuegt man alles mit ein paar Mausklicks zusammen, z.B. mit Gradle oder Ant. Wieso ist das in C++ sooooooo unglaublich komplex? Ok, das soll nicht die Frage sein.

    Ich habe kein Problem selber zu builden, wenn das sinnvoller oder einfacher ist, solange ihr mir Tipps gebt, wie das funktioniert :p .

    Ich sitze seit zwei Tagen und mehr als 10 Stunden daran nur GLFW und GLEW in mein Project einzubinden. Ich habe sogar eine Frage auf Stackoverflow gestellt, diese wurde aber nicht beantwortet. 😞

    Hilfe!!

    Hier meine CMake files:
    1. CMakeLists.txt

    cmake_minimum_required(VERSION 3.10)
    project(Hatsudouki_core)
    
    set(CMAKE_CXX_STANDARD 17)
    
    #Define module path
    list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/Modules")
    
    #Define static GLEW libraries and header files
    find_package(GLEW REQUIRED)
    include_directories(${GLEW_INCLUDE_DIR})
    
    #Define static GLFW libraries and header files
    find_package(glfw3 REQUIRED)
    include_directories(${GLFW_INCLUDE_DIR})
    
    #Define openGL
    find_package(openGL REQUIRED)
    
    add_executable(Hatsudouki_core main.cpp src/graphics/window.h src/graphics/window.cpp)
    
    target_link_libraries(Hatsudouki_core ${GLEW_LIBRARY} ${GLFW_LIBRARY} ${OPENGL_gl_LIBRARY})
    

    2. Findglew32.cmake

    # GLEW_FOUND
    # GLEW_INCLUDE_DIR
    # GLEW_LIBRARY
    
    set(FIND_GLEW_PATHS F:\\C++\\ExternalLibraries\\GLEW)
    
    find_path(GLEW_INCLUDE_DIR PATH_SUFFIXES include PATHS ${FIND_GLEW_PATHS})
    find_library(GLEW_LIBRARY PATH_SUFFIXES lib PATHS ${FIND_GLEW_PATHS})
    
    include(FindPackageHandleStandardArgs)
    find_package_handle_standard_args(GLEW DEFAULT_MSG GLEW_LIBRARY GLEW_INCLUDE_DIR)
    
    mark_as_advanced(GLEW_INCLUDE_DIR GLEW_LIBRARY)
    

    3. Findglfw3.cmake

    # GLFW_FOUND
    # GLFW_INCLUDE_DIR
    # GLFW_LIBRARY
    
    set(FIND_GLFW_PATHS F:\\C++\\ExternalLibraries\\GLFW)
    
    find_path(GLFW_INCLUDE_DIR PATH_SUFFIXES include PATHS ${FIND_GLFW_PATHS})
    find_library(GLFW_LIBRARY PATH_SUFFIXES lib-mingw PATHS ${FIND_GLFW_PATHS})
    
    include(FindPackageHandleStandardArgs)
    find_package_handle_standard_args(GLFW DEFAULT_MSG GLFW_LIBRARY GLFW_INCLUDE_DIR)
    
    mark_as_advanced(GLFW_INCLUDE_DIR GLFW_LIBRARY)
    

    GLEW download page
    GLFW download page

    Wenn ich folgendes einfuege (header werden gefunden, build gibt kein Problem mit lib aus):

    if (glewInit() == GLEW_OK) {
                    std::cout << "Could not initialize Glew!" << std::endl;
                    return false;
                }
    

    passier nichts ausser, dass das Programm startet und sofort crashed. Entferne ich die drei Zeilen code, dann funkioniert alles.

    Process finished with exit code -1073741515 (0xC0000135)
    

    Vielen Dank im Voraus!



  • Merkaber schrieb:

    , dann funkioniert alles.

    Process finished with exit code -1073741515 (0xC0000135)
    

    Woran erkennst du genau, dass „alles funktioniert”?
    0xC0000135 ist in WinNt.h als STATUS_DLL_NOT_FOUND definiert, es sieht so aus, als ob irgendwo exit(STATUS_DLL_NOT_FOUND); aufgerufen wird.



  • Ich habe einfach nur ein Fenster erzeugt und ein Rechteck dargestellt mit GLFW. Wenn ich aber die 3 Zeilen code, die GLEW benoetigen, also initGlew() einfuege, kommt gleich dieser Exit code. Sind diese Zeilen nicht im Code, oeffnet sich das Fenster und bleibt auch so.



  • Hat dein Programm Zugriff auf die "glew32.dll"? (dies ist also kein Problem mit dem Build-Prozess)

    s.a. GLEW: Installation



  • Ich denke, dass genau das das Problem ist. Der Zugriff auf die library. Wie du in der CMake siehst, habe ich alle so wie bei GLFW gemacht, jedoch ist die Ordnerstruktur bei GLEW anders.

    Bei GLFW:
    F:/.../GLFW/include/GLFW/glfw3.h
    F:/.../GLFW/lib-mingw/glfw3.dll und glfw3.a und glfw3dll.a

    Bei GLEW:
    F:/.../GLEW/include/GL/glew.h
    F:/.../GLEW/lib/Release/Win32/glew32.lib und glew32s.lib UND
    F:/.../GLEW/bin/Release/Win32/glew32.dll und glewinfo.exe und visualinfo.exe

    Beim build Prozess gab es immer Fehlermeldungen, jedoch hoerten die irgendwann einfach auf. Ich weiss nicht ob das am cashing oder was liegt, jedoch hat mich das auch gewundert. Die CMake files siehst du ja oben.
    Da ich gelesen habe, dass es allgemein besser ist nur statische libraries zu benutzen habe ich deshalb den Pfad fuer die .lib Dateien angegeben. Das sollte doch auch funkionieren oder nicht? Ich habe jetzt mal versucht das zu in der Findglew32.cmake folgend zu aendern.

    find_library(GLEW_LIBRARY NAMES glew32 PATH_SUFFIXES bin PATHS ${FIND_GLEW_PATHS})
    

    Dabei hat er es nicht gefunden. Dann habe ich den direkten Pfad in der CMakeLists.txt verwendet, was man nicht machen soll:

    #Define static GLEW libraries and header files
    find_package(GLEW REQUIRED)
    include_directories(${GLEW_INCLUDE_DIR})
    link_directories(F:\\C++\\ExternalLibraries\\GLEW\\bin\\Release\\Win32)
    
    ...
    
    target_link_libraries(Hatsudouki_core glew32 ${GLFW_LIBRARY} ${OPENGL_gl_LIBRARY})
    

    Nun findet der die .dll anscheinend, aber gibt folgenden Fehler aus:

    C:/Users/Merkaber/CLionProjects/Hatsudouki-core/src/graphics/window.cpp:35: undefined reference to `_imp__glewInit@0'
    

    Gut, den Fehler erstmal dahingestellt (falls du eine Ahnung hast, bin ich sehr Dankbar), wieso funktioniert das linken zu den statischen libraries nicht und wo ist mein Fehler in der der Findglew32.cmake, dass der die nicht findet? Wie kann ich die statischen .lib bzw. .a Dateien verwenden anstatt die .dll?

    Danke!



  • Mit CMake kenne ich mich leider nicht aus.

    Kannst du denn bei deinem Originalcode (bzw. makefile) einfach mal die "glew32.dll" (und evtl. alle weiteren abhängigen) aus dem Ordner "F:/.../GLEW/bin/Release/Win32/" in das gleiche Verzeichnis wie deine EXE kopieren?
    Oder zur Windows PATH-Variable dieses Verzeichnis hinzufügen.

    Für das statische Linken sollte es reichen (statt "glew32.lib") die Datei "glew32s.lib" anzugeben (und evtl. dann in dem Compileroptionen "GLEW_STATIC" - kann aber auch sein, daß dies nur zum Bauen der Lib benötigt wird).



  • Der gleich Fehler "_imp__glewInit@0" tritt dann auch auf. Leider weiss ich nicht, wie ich das mit dem compiler machen soll. 😕
    So wie hier beschrieben habe ich nun die glew.c aus dem Sourcecode in mein Project unter src/dependencies/glew/glew.c eingefuegt. Dennoch kommt der gleiche Fehler.

    Hier das komplette Project: Github



  • s. How to add linker or compile flag in cmake file?

    Du mußt also noch "-DGLEW_STATIC" mittels "target_compile_options" setzen.



  • Da ich nicht wusste, was ich in die target_compile_options setzen soll, habe ich nochmal in den Docs geschaut. Da steht leider nichts von STATIC.

    docs

    Ich habe wirklich keine Ahnung, wie ich das deklarieren soll. Die libraries wurden gefunden, die headers wurden gefunden (alles nach ewigen rumdoktern). Nun aber immer der gleiche Fehler. Und die glew.c funktioniert auch nicht, bzw. weiss ich nicht, wie ich die benutzen soll.

    Hier nochmal mein neues Github

    Fehler:

    "F:\C++\CLion 2018.1\bin\cmake\bin\cmake.exe" --build C:\Users\Merkaber\CLionProjects\Hatsudouki-core\cmake-build-debug --target all -- -j 4
    [ 25%] Linking CXX executable Hatsudouki_core.exe
    CMakeFiles\Hatsudouki_core.dir/objects.a(window.cpp.obj): In function `ZN10hatsudouki8graphics6Window4initEv':
    C:/Users/Merkaber/CLionProjects/Hatsudouki-core/src/graphics/window.cpp:35: undefined reference to `_imp__glewInit@0'
    collect2.exe: error: ld returned 1 exit status
    mingw32-make.exe[2]: *** [Hatsudouki_core.exe] Error 1
    CMakeFiles\Hatsudouki_core.dir\build.make:152: recipe for target 'Hatsudouki_core.exe' failed
    mingw32-make.exe[1]: *** [CMakeFiles/Hatsudouki_core.dir/all] Error 2
    CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/Hatsudouki_core.dir/all' failed
    mingw32-make.exe: *** [all] Error 2
    Makefile:82: recipe for target 'all' failed
    

    EDIT:
    Nachdem ich mit MinGW GLEW selber compiled habe bekomme ich nun wieder folgenden Fehler:

    Process finished with exit code -1073741515 (0xC0000135)
    

    Die libraries werden gefunden, da der built ohne Probleme funkioniert und CMake nicht mekkert. Ich weiss echt nicht mehr wo ich noch ansetzen soll. Ich glaube ich lass C++ einfach 😡

    Dennoch danke fuer die Hilfe. Die neuen Files etc. sind noch in der Git repository.





  • WOW vielen Dank, das hat wirklich geholfen. Mein Programm startet und crashed nicht mehr auch, wenn GLEW noch nicht richtig initialisiert ist, aber das ist egal.

    Falls ich noch kurz fragen darf, was bedeutet das jetzt fuer mich, wenn die .dll in dem Systemordner liegen muss? Muss jeder der das Programm dann benutzen moechte die .dll seperat installieren oder kann man das per installer spaeter machen?

    Jedenfalls vielen Dank, du hast mich gerettet!



  • Darum hatte ich ja folgendes empfohlen:

    Th69 schrieb:

    Kannst du denn bei deinem Originalcode (bzw. makefile) einfach mal die "glew32.dll" (und evtl. alle weiteren abhängigen) aus dem Ordner "F:/.../GLEW/bin/Release/Win32/" in das gleiche Verzeichnis wie deine EXE kopieren?

    Wenn du dann alle DLLs per Installer kopieren läßt, dann sollte es auf jedem anderen Rechner auch laufen.



  • Ich hatte das leider uebersehen, aber ich habe es jetzt nochmal ausprobiert die .dll in den Project ordner zu legen, da wo auch die main.cpp liegt, aber das bringt nichts. Woher weiss ich denn, wo die library, also glew an sich Zugriff auf die .dll haben moechte und wo kann ich dafuer den Pfad aendern, z.B. in den Ordner der spaeteren .exe meines Programmes. In dem Stackoverflow wird empfohlen, dass man die .dll's nicht in die Windows ordner packen soll. Wie kann ich das nun richtig einstellen?



  • Also ich habe es nun auch geschafft die statischen libraries hinzuzufuegen. Vielen Dank nochmal fuer deine Hilfe. Mittlerweile verstehe ich langsam wie CMake arbeitet. Folgender Loesungsansatz:

    1. Die glew library muss als erstes gelinkt werden, auch vor openGL

    target_link_libraries(Hatsudouki_core ${GLEW_LIBRARY} ${OPENGL_gl_LIBRARY} ${GLFW_LIBRARY})
    

    2. Findglew32s.cmake sollte auf die pre-compiled glew32s.lib verweisen:

    # GLEW_FOUND
    # GLEW_INCLUDE_DIR
    # GLEW_LIBRARY
    
    set(FIND_GLEW_PATHS F:\\C++\\ExternalLibraries\\GLEW)
    set(FIND_GLEW_LIB_PATHS F:\\C++\\ExternalLibraries\\GLEW\\lib\\Release)
    
    find_path(GLEW_INCLUDE_DIR NAMES GL/glew GL/glew.h PATH_SUFFIXES include PATHS ${FIND_GLEW_PATHS})
    find_library(GLEW_LIBRARY NAMES glew32s glew32s.lib PATH_SUFFIXES Win32 PATHS ${FIND_GLEW_LIB_PATHS})
    
    include(FindPackageHandleStandardArgs)
    find_package_handle_standard_args(GLEW DEFAULT_MSG GLEW_LIBRARY GLEW_INCLUDE_DIR)
    
    mark_as_advanced(GLEW_INCLUDE_DIR GLEW_LIBRARY)
    

    3. Den Verweis auch in die CMakeLists.txt eintragen:

    #Define static GLEW libraries and header files
    find_package(glew32s REQUIRED)
    include_directories(${GLEW_INCLUDE_DIR})
    ...
    target_link_libraries(Hatsudouki_core ${GLEW_LIBRARY})
    

    4. Dem precompiler den Hinwei geben, dass die glew32s library statisch ist, auch in der CMakeLists.txt:

    #define glew as linked to a static library
    add_definitions(-DGLEW_STATIC=Debug)
    

    Am besten vor dem linken der library

    Und in CLion unter Tools -> CMake -> Reset Cache and Reload Project, danach alles neu laden lassen, weil CMake manchmal mit dem alten Cache rumspinnt.

    Wieso meine selbst compiled .a libraries nicht auf die selber Art und Weise funktionieren weiss ich leider nicht. Anscheinend wollen die auch wieder die .dll, aber gut, so funktioniert es.


Anmelden zum Antworten