简体   繁体   中英

c++ cmake/make: linker ld does not find library (missing path?)

I'm currently struggling with linking a C++ project that requires linking with GLFW3, ie, ld is called with -lglfw3. The thing is that this worked before, and right now I have no clue, why it is not anymore.

sudo  pkg-config --libs glfw3 
-L/usr/local/lib -lglfw3  

The library exists also at that specific location printed by the statement above. However, ld says:

Linking CXX executable modeling_2014_framework
/usr/bin/ld: error: cannot find -lglfw3
CMakeFiles/modeling_2014_framework.dir/main.cpp.o:main.cpp:function init(): error: undefined reference to 'glfwInit'
...
collect2: error: ld returned 1 exit status
make[2]: *** [modeling_2014_framework] Error 1
make[1]: *** [CMakeFiles/modeling_2014_framework.dir/all] Error 2
make: *** [all] Error 2

I'm using cmake to create the makefile. This is how the CMakeLists looks like:

cmake_minimum_required (VERSION 2.8)

set (project_name modeling_2014_framework)

# create project
project (${project_name})

# sources
set(SOURCES main.cpp)

# add headers to the project
file(GLOB MY_HEADERS "src/*.h")
list(APPEND HEADERS ${MY_HEADERS})

# add sources to the project
file(GLOB MY_SOURCES "src/*.cpp")
list(APPEND SOURCES ${MY_SOURCES})

# i also tried to manually set them here, which however also does not help
#set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} /usr/local/lib)

# OpenGL
find_package(OpenGL REQUIRED)   
if (NOT OPENGL_FOUND)
    message (FATAL_ERROR "OpenGL not found!")
    return()
endif ()

# glew
if (UNIX)
    set(GLEW_LIBRARY libGLEW.so)                
else()
    set (GLEW_INCLUDE_DIR "" CACHE PATH "glew include directory")
    set (GLEW_LIBRARY_DIR "" CACHE PATH "glew build directory")
    if (GLEW_INCLUDE_DIR STREQUAL  "" AND GLEW_LIBRARY_DIR STREQUAL  "")
        return()
    else()
        find_library(GLEW_LIBRARY NAMES GLEW glew32 glew glew32s PATHS ${GLEW_LIBRARY_DIR})
    endif() 
endif(UNIX)

# glfw
set (GLFW_STATIC FALSE CACHE BOOL "link against static or dynamic glfw3 library")
if (WIN32)
    set (GLFW_INCLUDE_DIR "" CACHE PATH "GLFW include directory")
    set (GLFW_LIBRARY_DIR "" CACHE PATH "GLFW build directory")
    if (GLFW_INCLUDE_DIR STREQUAL "" AND GLFW_LIBRARY_DIR STREQUAL  "")
        return()
    else()
        if (GLFW_STATIC)
            find_library(GLFW_LIBS NAMES glfw3 PATHS ${GLFW_LIBRARY_DIR})
        else(GLFW_STATIC)
            find_library(GLFW_LIBS NAMES glfw3dll PATHS ${GLFW_LIBRARY_DIR})
        endif(GLFW_STATIC)  
    endif() 
else()
    find_package(PkgConfig REQUIRED)
    pkg_search_module(GLFW REQUIRED glfw3)
    if (GLFW_STATIC)
        set (GLFW_LIBS ${GLFW_STATIC_LIBRARIES})
    else(GLFW_STATIC)
        set (GLFW_LIBS ${GLFW_LIBRARIES})
    endif(GLFW_STATIC)
    list(APPEND GLFW_LIBS libXxf86vm.so)    
    list(APPEND GLFW_LIBS libGLU.so)        
    list(APPEND GLFW_LIBS libX11.so)
    list(APPEND GLFW_LIBS libXrandr.so)
    list(APPEND GLFW_LIBS libpthread.so)
    list(APPEND GLFW_LIBS libXi.so)
endif()

include_directories(${GLEW_INCLUDE_DIR}
                ${GLFW_INCLUDE_DIR}
                    ${OPENGL_INCLUDE_DIR}
                )

# executable
add_executable(${project_name} ${SOURCES} ${HEADERS})

target_link_libraries(${project_name} 
                      ${OPENGL_LIBRARIES}
                  ${GLEW_LIBRARY}
                  ${EXTRA_LIBS}
                  ${GLFW_LIBS}
                      )

If I run the ld command manually and add -L/usr/local/lib then the linker runs fine. So my most important question would be, how to make sure that cmake adds this path to the makefile so that ld runs fine.

Thanks in advance =)

Edit1: as per request, the stdout with verbose logging:

myname@fxt ~/courses/Modellierung/proj/exercise1 $ make VERBOSE=1
/usr/bin/cmake -H/home/myname/courses/Modellierung/proj/exercise1 -B/home/myname/courses/Modellierung/proj/exercise1 --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/myname/courses/Modellierung/proj/exercise1/CMakeFiles /home/myname/courses/Modellierung/proj/exercise1/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory `/home/myname/courses/Modellierung/proj/exercise1'
make -f CMakeFiles/modeling_2014_framework.dir/build.make CMakeFiles/modeling_2014_framework.dir/depend
make[2]: Entering directory `/home/myname/courses/Modellierung/proj/exercise1'
cd /home/myname/courses/Modellierung/proj/exercise1 && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/myname/courses/Modellierung/proj/exercise1 /home/myname/courses/Modellierung/proj/exercise1 /home/myname/courses/Modellierung/proj/exercise1 /home/myname/courses/Modellierung/proj/exercise1 /home/myname/courses/Modellierung/proj/exercise1/CMakeFiles/modeling_2014_framework.dir/DependInfo.cmake --color=
make[2]: Leaving directory `/home/myname/courses/Modellierung/proj/exercise1'
make -f CMakeFiles/modeling_2014_framework.dir/build.make CMakeFiles/modeling_2014_framework.dir/build
make[2]: Entering directory `/home/myname/courses/Modellierung/proj/exercise1'
Linking CXX executable modeling_2014_framework
/usr/bin/cmake -E cmake_link_script CMakeFiles/modeling_2014_framework.dir/link.txt --verbose=1
/usr/bin/g++   -g3 -gdwarf-2    CMakeFiles/modeling_2014_framework.dir/main.cpp.o CMakeFiles/modeling_2014_framework.dir/src/VertexBufferObjectAttribs.cpp.o CMakeFiles/modeling_2014_framework.dir/src/Vector3.cpp.o CMakeFiles/modeling_2014_framework.dir/src/Shader.cpp.o CMakeFiles/modeling_2014_framework.dir/src/Matrix4x4.cpp.o CMakeFiles/modeling_2014_framework.dir/src/Scene.cpp.o CMakeFiles/modeling_2014_framework.dir/src/TgaLoader.cpp.o CMakeFiles/modeling_2014_framework.dir/src/Vector4.cpp.o CMakeFiles/modeling_2014_framework.dir/src/Vector2.cpp.o CMakeFiles/modeling_2014_framework.dir/src/Renderer.cpp.o CMakeFiles/modeling_2014_framework.dir/src/Matrix3x3.cpp.o CMakeFiles/modeling_2014_framework.dir/src/Common.cpp.o CMakeFiles/modeling_2014_framework.dir/src/SkyCube.cpp.o  -o modeling_2014_framework -rdynamic -lGLU -lGL -lSM -lICE -lX11 -lXext -lGLEW -lglfw3 -lXxf86vm -lGLU -lX11 -lXrandr -lpthread -lXi 
/usr/bin/ld: error: cannot find -lglfw3
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:49: error: undefined reference to 'glfwInit'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:53: error: undefined reference to 'glfwInit'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:60: error: undefined reference to 'glfwSetErrorCallback'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:63: error: undefined reference to 'glfwWindowHint'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:64: error: undefined reference to 'glfwWindowHint'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:65: error: undefined reference to 'glfwWindowHint'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:66: error: undefined reference to 'glfwWindowHint'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:74: error: undefined reference to 'glfwCreateWindow'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:77: error: undefined reference to 'glfwSetKeyCallback'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:78: error: undefined reference to 'glfwSetWindowSizeCallback'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:79: error: undefined reference to 'glfwSetMouseButtonCallback'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:80: error: undefined reference to 'glfwSetCursorPosCallback'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:81: error: undefined reference to 'glfwSetScrollCallback'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:84: error: undefined reference to 'glfwMakeContextCurrent'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:164: error: undefined reference to 'glfwTerminate'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:170: error: undefined reference to 'glfwGetTime'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:171: error: undefined reference to 'glfwGetTime'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:189: error: undefined reference to 'glfwPollEvents'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:190: error: undefined reference to 'glfwSwapBuffers'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:192: error: undefined reference to 'glfwSetWindowTitle'
/home/myname/courses/Modellierung/proj/exercise1/main.cpp:186: error: undefined reference to 'glfwWindowShouldClose'
/home/myname/courses/Modellierung/proj/exercise1/src/Renderer.cpp:61: error: undefined reference to 'glfwGetTime'
/home/myname/courses/Modellierung/proj/exercise1/src/Renderer.cpp:64: error: undefined reference to 'glfwGetTime'
collect2: error: ld returned 1 exit status
make[2]: *** [modeling_2014_framework] Error 1
make[2]: Leaving directory `/home/myname/courses/Modellierung/proj/exercise1'
make[1]: *** [CMakeFiles/modeling_2014_framework.dir/all] Error 2
make[1]: Leaving directory `/home/myname/courses/Modellierung/proj/exercise1'
make: *** [all] Error 2
myname@fxt ~/courses/Modellierung/proj/exercise1 $ 

EDIT / QUICK HACK SOLUTION: I think this is not the real answer to the original problem, but at least I've found a workaround. I added

SET( CMAKE_EXE_LINKER_FLAGS   "-L/usr/local/lib")

to the CMakeLists.txt file, directly above add_executable(...)

Now it works, because the -L... option is correctly passed to the linker. However, since I've hardcoded the path this might not work on any computer.

Seems you are missing the library search directories from the the link command line. Try something like.

LINK_DIRECTORIES(${GLFW_LIBRARY_DIR})

after successfully finding for the GLFW libraries and before add_executable

http://www.cmake.org/cmake/help/v2.8.12/cmake.html#command:link_directories

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM