1

I am in a rather small hobby project, we are creating a game, or at least trying to do so... The main issue we are facing is the fact that we are able to compile the project on MacOS and Linux, but not on Windows.

We are using GLFW as an interface to OpenGL, so it is required for us to get anything visible on the screen. Problem is that when we tell Make to do its thing, it compiles each individual module but fails to link them because of undefined references. While that may make sense the weird thing is that these unknown references all have the prefix __imp_, which isn't present in source. Example: We used the method glfwInit but when trying to make the project we get: graphicsengine/libgraphicsengine.a(graphics.cpp.obj):graphics.cpp:(.text+0xa): undefined reference to `_imp__glfwInit'

Having done some research I found This SO Question of which i tried the answer. It failed, due to the fact that the only lib in there after compilation is libglfw3.a, no sort of dll or hints at a dll. Renaming this file accordingly did not help, neither did placing the precompiled binary. Deleting this file results in it recompiling and reappearing, so clearly make knows where it is.

We also tried switching to clang because maybe it has a more intelligent linker, but it didn't want to compile anything in the first place.

I performed a lot of research on this and I found countless SO answers and forum threads of people with similar or even identical problems, every single one had a different solution and none of them worked for us.

To generate the Makefile we are using CMake with the following script in the main subdirectory (don't worry, it gets called from above, we got that working so far):

set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(GLFW_INSTALL OFF CACHE BOOL "" FORCE)

add_subdirectory(graphicsengine)
add_subdirectory(fileSys)
add_subdirectory(networking)
add_subdirectory(game)

add_subdirectory(glfw-3.2.1)
include_directories(glfw-3.2.1/include)

if (UNIX AND NOT APPLE)  
   find_package(OpenGL REQUIRED)
   include_directories(${OPENGL_INCLUDE_DIR})
endif()

add_executable(${PROJECT_NAME} "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp")

 target_link_libraries(${PROJECT_NAME} graphicsengine fileSys networking game)

if (APPLE)
   target_link_libraries(${PROJECT_NAME} "-framework OpenGL")
endif()
if (WIN32)
   target_link_libraries(${PROJECT_NAME} opengl32 gdi32)
endif()
if (UNIX AND NOT APPLE)  
   target_link_libraries(${PROJECT_NAME} ${OPENGL_gl_LIBRARY})
endif()

target_link_libraries(${PROJECT_NAME} glfw)

install(TARGETS ${PROJECT_NAME} DESTINATION ${INSTALL_DIR})

The rest of the important cmake calls are in the parent directory

Here is a full log of cmake/make that a custom build script calls:

debug
release
-- The CXX compiler identification is GNU 5.3.0
-- Check for working CXX compiler: D:/MinGW/bin/g++.exe
-- Check for working CXX compiler: D:/MinGW/bin/g++.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- The C compiler identification is GNU 5.3.0
-- Check for working C compiler: D:/MinGW/bin/gcc.exe
-- Check for working C compiler: D:/MinGW/bin/gcc.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Could NOT find Vulkan (missing:  VULKAN_INCLUDE_DIR)
-- Looking for dinput.h
-- Looking for dinput.h - not found
-- Looking for xinput.h
-- Looking for xinput.h - not found
-- Performing Test _GLFW_HAS_DEP
-- Performing Test _GLFW_HAS_DEP - Success
-- Performing Test _GLFW_HAS_ASLR
-- Performing Test _GLFW_HAS_ASLR - Success
-- Performing Test _GLFW_HAS_64ASLR
-- Performing Test _GLFW_HAS_64ASLR - Failed
-- Using Win32 for window creation
-- Configuring done
-- Generating done
-- Build files have been written to: D:/cpp-neon/Workspace/Supermerged
--------------MAKE STARTS HERE--------------
[ 60%] Built target glfw
[ 68%] Built target graphicsengine
[ 76%] Built target fileSys
[ 84%] Built target networking
[ 92%] Built target game
[ 96%] Linking CXX executable Submerged_PR0.exe
graphicsengine/libgraphicsengine.a(graphics.cpp.obj):graphics.cpp:(.text+0xa): undefined reference to `_imp__glfwInit'
graphicsengine/libgraphicsengine.a(graphics.cpp.obj):graphics.cpp:(.text+0x45): undefined reference to `_imp__glfwCreateWindow'
graphicsengine/libgraphicsengine.a(graphics.cpp.obj):graphics.cpp:(.text+0x55): undefined reference to `_imp__glfwTerminate'
graphicsengine/libgraphicsengine.a(graphics.cpp.obj):graphics.cpp:(.text+0x64): undefined reference to `_imp__glfwMakeContextCurrent'
graphicsengine/libgraphicsengine.a(graphics.cpp.obj):graphics.cpp:(.text+0x71): undefined reference to `_imp__glfwWindowShouldClose'
graphicsengine/libgraphicsengine.a(graphics.cpp.obj):graphics.cpp:(.text+0x98): undefined reference to `_imp__glfwSwapBuffers'
graphicsengine/libgraphicsengine.a(graphics.cpp.obj):graphics.cpp:(.text+0x9f): undefined reference to `_imp__glfwPollEvents'
graphicsengine/libgraphicsengine.a(graphics.cpp.obj):graphics.cpp:(.text+0xa8): undefined reference to `_imp__glfwTerminate'
collect2.exe: error: ld returned 1 exit status
source\CMakeFiles\Submerged_PR0.dir\build.make:101: recipe for target 'source/Submerged_PR0.exe' failed
mingw32-make[2]: *** [source/Submerged_PR0.exe] Error 1
CMakeFiles\Makefile2:102: recipe for target 'source/CMakeFiles/Submerged_PR0.dir/all' failed
mingw32-make[1]: *** [source/CMakeFiles/Submerged_PR0.dir/all] Error 2
Makefile:128: recipe for target 'all' failed
mingw32-make: *** [all] Error 2
Make Failed, Aborting Install
PS D:\cpp-neon\Workspace\Supermerged>

In case you want to know, this is our project structure:

The CMakeLists.txt above is the one you see in /source

The rest of the modules are built in the same way, except for glfw, which is the one you can find on their website

At this point in time we are more or less helpless and tired of looking for a solution, at the point where we just try stuff until it kind of works but ends up a giant mess of everything that should never have existed, we all know how that ends up... (cough) which of these branches was the one where i did the thing that made it do the other thing?(cough) We hope that some of you (SO) might have a better approach to finding the solution than any of us. Feel free to ask anything else that might help you find something that works!

Thanks in advance!

In the name of: sDev

7H3_H4CK3R
  • 133
  • 8
  • 1
    In you `CMakeLists.txt` you have `add_subdirectory(graphicsengine)`, then `add_subdirectory(glfw-3.2.1)`. But building order is **reversed**: `Built target glfw`, then `Built target graphicsengine`. How is it possible? And how do you link `graphicsengine` with `glfw`, as `glfw` target is **inaccessible** at the time you process `graphicsengine` folder? – Tsyvarev May 29 '17 at 16:28
  • @Tsyvarev indeed that is weird, but i think the build order really depends on the line `target_link_libraries(${PROJECT_NAME} graphicsengine fileSys networking game)` and then only later the line `target_link_libraries(${PROJECT_NAME} glfw)` – 7H3_H4CK3R May 29 '17 at 16:31
  • Actually, my second question is more vital: Under `graphicsengine` you build the library, which **uses** `glfw`. But `glfw` library is noted **later**, which means you doesn't provide even `glfw` headers for `graphicsengine`. It looks like `graphicsengine` uses **its own glfw** for headers and linking. And "its own glfw" is not compatible with your one. – Tsyvarev May 29 '17 at 16:41
  • @Tsyvarev I tried moving the call to `target_link_libraries(...glfw)` before the call that links everything else, the only thing that changes is the order of builds. Beginning with `Linking CXX executable Submerged_PR0.exe` the rest of the errors remain. – 7H3_H4CK3R May 29 '17 at 16:47
  • Simply swapping order of `add_subdirectory`s change nothing: If `graphicsengine` didn't link to `glfw` target, it won't link with it after swapping the order. Something wrong with `CMakeList.txt` of `graphicsengine`, but you don't show it. – Tsyvarev May 29 '17 at 16:58
  • @Tsyvarev /graphics/CMakeLists.txt: `add_library(graphicsengine STATIC graphics.hpp graphics.cpp)` You suggest we need to link something in there? – 7H3_H4CK3R May 29 '17 at 16:59
  • And how does this library know where to find `glfw` headers? – Tsyvarev May 29 '17 at 17:07
  • @Tsyvarev ...... it doesnt....... But you seem to know a little more about this than we do, do you have any idea how to tell cmake where it is? – 7H3_H4CK3R May 29 '17 at 17:09
  • @Tsyvarev we made it work, the problem was a header file. Still, _thank you_ – 7H3_H4CK3R May 29 '17 at 18:00

1 Answers1

0

We found it!

The problem was actually in our graphics.hpp:

We had the line #define GLFW_DLL

Which was wrong because it had to be

#define GLFW_STATIC

And now it works

7H3_H4CK3R
  • 133
  • 8