web-dev-qa-db-ja.com

ライブラリをcmakeに適切にリンクする方法は?

自分のプロジェクトに適切にリンクするために作業している追加のライブラリを取得できません。

私はCLionを使用しています。CLionはcmakeを使用してプロジェクトをビルドしています。 OpenGLと組み合わせていくつかのライブラリを使用して、いくつかのオブジェクトをテクスチャリングしようとしています。 Clionを使用してcmakeを動作させる方法がわからなかったため、最初にVisual Studioで構築しました。ただし、コードはすべて(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でエラーが発生しなくなるまで微調整しましたが、ヘッダーファイルはまだコードで認識されません。

私のプロジェクトの構造は次のとおりです。
project structure

したがって、必要なすべてのライブラリを配置しましたが、コードでそれらを認識しているようには見えません。 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を使用するたびにエラーが発生しますが、glmではなくエラーが発生します。

CMakeLists.txtで何が間違っていますか?

24
Cache Staheli

私の推奨事項は、シンプルに始めてから、プロジェクトをさらに複雑にすることです。

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とリンクします

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変数に含めて、プログラムをそれらにリンクできるようにします。 ブーストのためにこれを行う方法はここにあります 、例えば。

62