簡體   English   中英

如何正確鏈接庫與 cmake?

[英]How to properly link libraries with cmake?

我無法獲得正在使用的其他庫以正確鏈接到我的項目。

我正在使用 CLion,它使用 cmake 來構建它的項目。 我正在嘗試將幾個庫與 OpenGL 結合使用來對某些對象進行紋理處理。 我最初在 Visual Studio 中構建它,因為我無法弄清楚如何讓 cmake 與 Clion 一起工作。 但是,既然代碼都可以運行(無論如何在 Visual Studio 中),我希望能夠使用 CLion,因為這是我首選的 IDE。

我還是 cmake 的新手,我不明白我的CMakeLists.txt做錯了什么。 這是我所擁有的:

cmake_minimum_required(VERSION 3.3)
project(texture_mapping)
find_package(OpenGL REQUIRED)
link_directories(${OPENGL_gl_LIBRARY})

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

set(SOURCE_FILES main.cpp camera.h display.h display.cpp mesh.cpp mesh.h obj_loader.cpp obj_loader.h shader.cpp shader.h stb_image.c stb_image.h texture.cpp texture.h transform.h)

link_directories(texture_mapping ${PROJECT_SOURCE_DIR}/lib)

add_executable(texture_mapping ${SOURCE_FILES})

target_include_directories(texture_mapping PUBLIC ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(texture_mapping SDL2 SDL2main SDL2test glew32 glew32s ${OPENGL_gl_LIBRARY})

我調整了它,直到它在 CLion 中不再給我任何錯誤,但我的代碼中仍然無法識別頭文件。

這是我的項目的結構:
項目結構

所以,我把所有我需要的庫都放進去了,但它似乎沒有在代碼中識別它們。 Clion 在項目中識別它們(它們不會因錯誤而顯示為紅色),但是當它構建時(當我嘗試在 CLion 中運行它時),我收到以下錯誤:

CMakeFiles\texture_mapping.dir/objects.a(mesh.cpp.obj): In function `ZN4MeshD2Ev':
...texture-mapping/mesh.cpp:30: undefined reference to `_imp____glewDeleteVertexArrays'
CMakeFiles\texture_mapping.dir/objects.a(mesh.cpp.obj): In function `ZN4Mesh8InitMeshERK12IndexedModel':
...texture-mapping/mesh.cpp:36: undefined reference to `_imp____glewGenVertexArrays'
...texture-mapping/mesh.cpp:37: undefined reference to `_imp____glewBindVertexArray'
...texture-mapping/mesh.cpp:39: undefined reference to `_imp____glewGenBuffers'
...texture-mapping/mesh.cpp:40: undefined reference to `_imp____glewBindBuffer'
...texture-mapping/mesh.cpp:41: undefined reference to `_imp____glewBufferData'
...texture-mapping/mesh.cpp:43: undefined reference to `_imp____glewEnableVertexAttribArray'
...texture-mapping/mesh.cpp:44: undefined reference to `_imp____glewVertexAttribPointer'
...texture-mapping/mesh.cpp:46: undefined reference to `_imp____glewBindBuffer'
...texture-mapping/mesh.cpp:47: undefined reference to `_imp____glewBufferData'
...texture-mapping/mesh.cpp:49: undefined reference to `_imp____glewEnableVertexAttribArray'
...texture-mapping/mesh.cpp:50: undefined reference to `_imp____glewVertexAttribPointer'
...texture-mapping/mesh.cpp:52: undefined reference to `_imp____glewBindBuffer'
...texture-mapping/mesh.cpp:53: undefined reference to `_imp____glewBufferData'
...texture-mapping/mesh.cpp:55: undefined reference to `_imp____glewBindVertexArray'
...texture-mapping/mesh.cpp:56: undefined reference to `_imp____glewBindVertexArray'
CMakeFiles\texture_mapping.dir/objects.a(mesh.cpp.obj): In function `ZN4Mesh4DrawEv':
...texture-mapping/mesh.cpp:61: undefined reference to `_imp____glewBindVertexArray'
...texture-mapping/mesh.cpp:65: undefined reference to `_imp____glewBindVertexArray'
CMakeFiles\texture_mapping.dir/objects.a(shader.cpp.obj): In function `ZN6ShaderC2ERKSs':
...texture-mapping/shader.cpp:5: undefined reference to `_imp____glewCreateProgram'
...texture-mapping/shader.cpp:11: undefined reference to `_imp____glewAttachShader'
...texture-mapping/shader.cpp:14: undefined reference to `_imp____glewBindAttribLocation'
...texture-mapping/shader.cpp:15: undefined reference to `_imp____glewBindAttribLocation'
...texture-mapping/shader.cpp:17: undefined reference to `_imp____glewLinkProgram'
...texture-mapping/shader.cpp:20: undefined reference to `_imp____glewValidateProgram'
...texture-mapping/shader.cpp:23: undefined reference to `_imp____glewGetUniformLocation'
CMakeFiles\texture_mapping.dir/objects.a(shader.cpp.obj): In function `ZN6Shader4BindEv':
...texture-mapping/shader.cpp:28: undefined reference to `_imp____glewUseProgram'
CMakeFiles\texture_mapping.dir/objects.a(shader.cpp.obj): In function `ZN6Shader6UpdateERK9TransformRK6Camera':
...texture-mapping/shader.cpp:35: undefined reference to `_imp____glewUniformMatrix4fv'
CMakeFiles\texture_mapping.dir/objects.a(shader.cpp.obj): In function `ZN6ShaderD2Ev':
...texture-mapping/shader.cpp:42: undefined reference to `_imp____glewDetachShader'
...texture-mapping/shader.cpp:43: undefined reference to `_imp____glewDeleteShader'
...texture-mapping/shader.cpp:46: undefined reference to `_imp____glewDeleteProgram'
CMakeFiles\texture_mapping.dir/objects.a(shader.cpp.obj): In function `ZN6Shader16CheckShaderErrorEjjbRKSs':
...texture-mapping/shader.cpp:79: undefined reference to `_imp____glewGetProgramiv'
...texture-mapping/shader.cpp:81: undefined reference to `_imp____glewGetShaderiv'
...texture-mapping/shader.cpp:86: undefined reference to `_imp____glewGetProgramInfoLog'
...texture-mapping/shader.cpp:88: undefined reference to `_imp____glewGetShaderInfoLog'
CMakeFiles\texture_mapping.dir/objects.a(shader.cpp.obj): In function `ZN6Shader12CreateShaderERKSsj':
...texture-mapping/shader.cpp:96: undefined reference to `_imp____glewCreateShader'
...texture-mapping/shader.cpp:109: undefined reference to `_imp____glewShaderSource'
...texture-mapping/shader.cpp:110: undefined reference to `_imp____glewCompileShader'
CMakeFiles\texture_mapping.dir/objects.a(texture.cpp.obj): In function `ZN7Texture4BindEj':
...texture-mapping/texture.cpp:36: undefined reference to `_imp____glewActiveTexture'
...texture-mapping/lib/SDL2main.lib(./Win32/Release/SDL_windows_main.obj):(.text+0x24): undefined reference to `SDL_SetMainReady'
...texture-mapping/lib/SDL2main.lib(./Win32/Release/SDL_windows_main.obj):(.text+0x55): undefined reference to `SDL_malloc'
...texture-mapping/lib/SDL2main.lib(./Win32/Release/SDL_windows_main.obj):(.text+0x84): undefined reference to `SDL_wcslen'
...texture-mapping/lib/SDL2main.lib(./Win32/Release/SDL_windows_main.obj):(.text+0xa5): undefined reference to `SDL_iconv_string'
...texture-mapping/lib/SDL2main.lib(./Win32/Release/SDL_windows_main.obj):(.text+0xcf): undefined reference to `SDL_free'
...texture-mapping/lib/SDL2main.lib(./Win32/Release/SDL_windows_main.obj):(.text+0xf4): undefined reference to `SDL_wcslen'
...texture-mapping/lib/SDL2main.lib(./Win32/Release/SDL_windows_main.obj):(.text+0x10f): undefined reference to `SDL_iconv_string'
...texture-mapping/lib/SDL2main.lib(./Win32/Release/SDL_windows_main.obj):(.text+0x143): undefined reference to `SDL_malloc'
...texture-mapping/lib/SDL2main.lib(./Win32/Release/SDL_windows_main.obj):(.text+0x17f): undefined reference to `SDL_free'
...texture-mapping/lib/SDL2main.lib(./Win32/Release/SDL_windows_main.obj):(.text+0x18b): undefined reference to `SDL_free'
...texture-mapping/lib/SDL2main.lib(./Win32/Release/SDL_windows_main.obj):(.text+0x1d6): undefined reference to `SDL_isspace'
...texture-mapping/lib/SDL2main.lib(./Win32/Release/SDL_windows_main.obj):(.text+0x295): undefined reference to `SDL_isspace'
...texture-mapping/lib/SDL2main.lib(./Win32/Release/SDL_windows_main.obj):(.text+0x3a2): undefined reference to `SDL_ShowSimpleMessageBox'

基本上,每次使用 SDL 和 glew 都會出錯,但不是 glm,這很奇怪。

我的CMakeLists.txt什么問題?

我的建議是從簡單的開始,然后使您的項目進一步復雜化。

讓我試着解釋一下 CMake 中的鏈接是如何工作的。 這個想法是你在 CMake 中構建模塊,並將它們鏈接在一起。 讓我們暫時忽略頭文件,因為它們都可以包含在您的源文件中。

假設您有 file1.cpp、file2.cpp、main.cpp。 您可以通過以下方式將它們添加到您的項目中:

ADD_LIBRARY(LibsModule 
    file1.cpp
    file2.cpp
)

現在您將它們添加到名為LibsModule的模塊中。 記在腦子里。 假設您想鏈接到系統中已經存在的pthread 您可以使用以下命令將其與LibsModule結合使用:

target_link_libraries(LibsModule -lpthread)

如果你也想鏈接一個靜態庫,你可以這樣做:

target_link_libraries(LibsModule liblapack.a)

如果要添加任何這些庫所在的目錄,請執行以下操作:

target_link_libraries(LibsModule -L/home/user/libs/somelibpath/)

現在添加一個可執行文件,並將其與主文件鏈接:

ADD_EXECUTABLE(MyProgramExecBlaBla main.cpp)

(我添加了 BlaBla 只是為了表明名稱是自定義的)。 然后你將LibsModule與你的可執行模塊MyProgramExecBlaBla鏈接LibsModule

target_link_libraries(MyProgramExecBlaBla LibsModule)

這將做到。

我在你的 CMake 文件中看到的是很多冗余。 例如,為什么你有texture_mapping ,它是你的包含目錄中的一個可執行模塊? 所以你需要清理它並遵循我解釋的簡單邏輯。 希望它有效。


總之,它看起來像這樣:

project (MyProgramExecBlaBla)  #not sure whether this should be the same name of the executable, but I always see that "convention"
cmake_minimum_required(VERSION 2.8)

ADD_LIBRARY(LibsModule 
    file1.cpp
    file2.cpp
)

target_link_libraries(LibsModule -lpthread)
target_link_libraries(LibsModule liblapack.a)
target_link_libraries(LibsModule -L/home/user/libs/somelibpath/)
ADD_EXECUTABLE(MyProgramExecBlaBla main.cpp)
target_link_libraries(MyProgramExecBlaBla LibsModule)

要了解的最重要的事情是模塊結構,您可以在其中創建模塊並將它們與可執行文件鏈接在一起。 一旦成功,您可以使用更多細節進一步復雜化您的項目。 祝你好運!


注意:請記住,這是使用 CMake 的簡單方法。 更好的跨平台方式是使用find_package ,它定位一個包/庫,並提供庫和包含在 CMake 變量中,以便您可以將您的程序鏈接到它們。 例如,以下是如何為 boost 執行此操作

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM