GLFW - UBuntu 14.04 LTS上的链接器错误

时间:2014-06-21 20:01:47

标签: opengl ubuntu linker cmake glfw

我想从这个site(在底部)编译一个示例代码。我下载了GLFW 3.0.4源代码,并将其构建在自定义位置。我使用默认设置,GLFW构建为静态库。我的CMakeLists.txt看起来像这样:

cmake_minimum_required(VERSION 2.8)
project(glfw_test_project)

SET(CMAKE_CXX_FLAGS "-Wall -Werror -g -std=c++11")

find_package(OpenGL REQUIRED)

include_directories(/home/user/MyLibs/OpenGL/glfw-3.0.4/include)
link_directories(/home/user/MyLibs/OpenGL/glfw-3.0.4/build/src)

add_executable(glfw_test main.cpp)

target_link_libraries(glfw_test ${OPENGL_gl_LIBRARY})
target_link_libraries(glfw_test glfw3)

当我运行 make 时,我会收到以下信息:

Linking CXX executable glfw_test
/usr/bin/ld: /home/user/MyLibs/OpenGL/glfw-3.0.4/build/src/libglfw3.a(x11_clipboard.c.o): undefined reference to symbol 'XConvertSelection'
//usr/lib/x86_64-linux-gnu/libX11.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make[2]: *** [glfw_test] Error 1
make[1]: *** [CMakeFiles/glfw_test.dir/all] Error 2
make: *** [all] Error 2

有什么问题?

EDIT1 当我将GLFW构建为动态库时,一切正常。然后我的CMakeLists.txt中的最后一行必须替换为:

target_link_libraries(glfw_test glfw)

使用静态库时有什么问题?

2 个答案:

答案 0 :(得分:6)

我在Ubuntu 14.04 LTS上遇到了同样的问题。

首先error adding symbols: DSO missing from command line显示错误的顺序的链接器命令行参数。这post让我意识到了这一点。您需要调用$ make VERBOSE=1来查看链接器调用并亲自检查它。请注意:TARGET_LINK_LIBRARIES()应该是CMakeLists.txt中的最后一个命令,并查看此order explanation

第二:如果您针对静态GLFW3库进行构建,则所有X11库都不会自动添加到您的链接器调用中,因为atsui已在上面显示。在GLFW-Documentation中,您可以找到符合您需求的cmake变量:${GLFW_STATIC_LIBRARIES}。要使用它并启用更自动的构建过程,让pkg-config找到X11库的所有依赖项:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(myProject)

FIND_PACKAGE( PkgConfig REQUIRED )
pkg_search_module( GLFW3 REQUIRED glfw3 ) # sets GLFW3 as prefix for glfw vars

# now ${GLFW3_INCLUDE_DIR}, ${GLFW3_LIBRARIES} and ${GLFW3_STATIC_LIBRARIES} 
# are set

INCLUDE_DIRECTORIES( ${GLFW3_INCLUDE_DIR} )
ADD_EXECUTABLE( myProject mySource.cpp )

TARGET_LINK_LIBRARIES( myProject ${GLFW_STATIC_LIBRARIES} )
# they include X11 libs

现在用$ make VERBOSE=1再次检查链接器lib参数,你会发现更多的X11库,如: -lXrandr -lXi -lXrender -ldrm -lXdamage -lXxf86vm -lXext -lX11-lpthread

第三:在链接共享库时,动态解析与X11等的依赖关系。这就是为什么您不需要向链接器显式添加X11 lib标志的原因。在这种情况下,您只需要: TARGET_LINK_LIBRARIES( myProject ${GLFW_LIBRARIES} )

第四:在我看来,有些glfwCommands有undefined reference to - 链接器错误。我发现,我在/usr/local/lib中安装了GLFW3,但链接器只给出了LD_LIBRARY_PATH环境变量,该变量仅设置为/usr/lib32。添加参数-L/usr/local/lib解决了参考问题。为了避免以后我设置LD_LIBRARY_PATH=/usr/lib32;/usr/local/lib;

提示:检查GLFW cmake变量中的值,在构建期间打印它们:

FOREACH(item ${GLFW3_STATIC_LIBRARIES})
    MESSAGE(STATUS "  using lib: " ${item})
ENDFOREACH()

答案 1 :(得分:2)

您似乎通过将GLFW重建为共享库并将示例代码与其链接来解决您自己的问题。相反,我会尝试回答您的后续问题,即当您尝试链接静态库时它为什么不起作用。

基本上,如果要链接静态库libglfw3.a,则需要链接所有依赖的X11库。链接静态库时出错,因为您没有指定任何其他要链接的库,CMake也不知道这些依赖项是什么。链接共享库libglfw.so时,您不会收到错误,因为X11库链接到共享库,而CMake知道会自动为您提供这些库。

如果要使用静态库,可以按如下方式确定要链接的必要库。根据GLFW中的.pc文件,您可以在命令行中键入它以找出它们是什么:

pkg-config --static --libs x11 xrandr xi xxf86vm gl

如果将其转换为CMake命令,它将如下所示:

target_link_libraries( glfw_test glfw3 Xrandr Xrender Xi GL m dl drm Xdamage X11-xcb xcb-glx xcb-dri2 xcb-dri3 xcb-present xcb-sync xshmfence Xxf86vm Xfixes Xext X11 pthread xcb Xau Xdmcp)

因此,如果将其添加到CMakeLists.txt,示例代码应该构建没有问题。

顺便说一下,您可以通过以下方式使用CMake自动查找X11库:

find_package(X11 REQUIRED)
target_link_libraries( my_program ${X11_LIBRARIES} )

但是,存储在X11_LIBRARIES变量中的库集只包含静态链接GLFW所需的库的子集。

我不确定如何在CMake中正确处理静态/动态链接,但我希望这会有所帮助。