为什么CMake无法链接我的静态库?

nzkunb0c  于 2023-01-05  发布在  其他
关注(0)|答案(1)|浏览(339)

我尝试将我从assimp source编译的静态库链接到我的可执行CMake项目,这样它就不必经常编译assimp,因为它是一个很大的库。
我使用CMake编译了它,命令如下:

git clone https://github.com/assimp/assimp/
cd assimp
mkdir build
cd build
cmake -DBUILD_SHARED_LIBS=OFF ../CMakeLists.txt
cmake --build .

我的项目结构如下所示:

.
OpenGL
├── OpenGL
│   ├── res
│   ├── src
│   |   └── (my .cpp and .h files)
│   └── CMakeLists.txt
├── libraries
│       └── glfw, glew, imgui...
└── CMakeLists.txt

我现在将assimp/includeassimp/build/bin/Debug/config.h复制到OpenGL/libraries/assimp/include
然后assimp/build/lib/DebugOpenGL/libraries/assimp/lib
我的CMakeLists.txt看起来像这样:

cmake_minimum_required(VERSION 3.8)

project(OpenGL LANGUAGES CXX C)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

set(CMAKE_FIND_DEBUG_MODE)

if (NOT MSVC)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1")
endif()

if (CMAKE_BUILD_TYPE STREQUAL Debug)
    add_definitions(-DDEBUG) # preprocessor macro
else()
    if (MSVC)
        set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup") # if running on release mode remove the cmd prompt on windows
    endif()
endif()

add_subdirectory(OpenGL)
add_subdirectory(libraries/glfw)
add_subdirectory(libraries/glew)
add_subdirectory(libraries/nativefiledialog)

target_include_directories(${PROJECT_NAME} PRIVATE 
    ${CMAKE_CURRENT_SOURCE_DIR}/libraries/glfw/include
    ${CMAKE_CURRENT_SOURCE_DIR}/libraries/glew/include
    OpenGL/src
    libraries
    libraries/stb
    libraries/assimp/include
    libraries/nativefiledialog/src/include
)

以及

cmake_minimum_required(VERSION 3.8)

file(GLOB_RECURSE OpenGL_sources *.cpp ../libraries/imgui/*.cpp ../libraries/stb/*.cpp)

add_executable(${PROJECT_NAME} ${OpenGL_sources} "src/engine/input/Key.cpp" "src/engine/input/Buttons.h" "src/engine/input/Button.h" "src/engine/input/Button.cpp" "src/engine/input/MouseButton.h" "src/engine/input/MouseButton.cpp" "src/engine/rendering/objects/Model.h" "src/engine/rendering/objects/Model.cpp")

target_link_libraries(${PROJECT_NAME} PUBLIC
    glfw
    libglew_static
    ${CMAKE_SOURCE_DIR}/libraries/assimp/lib/assimp-vc143-mtd.lib
    nativefiledialog
)

cmake_minimum_required(VERSION 3.8)

add_library( assimp STATIC IMPORTED )
set_property( TARGET assimp PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libraries/assimp/lib/assimp-vc143-mtd.lib)

file(GLOB_RECURSE OpenGL_sources *.cpp ../libraries/imgui/*.cpp ../libraries/stb/*.cpp)

add_executable(${PROJECT_NAME} ${OpenGL_sources} "src/engine/input/Key.cpp" "src/engine/input/Buttons.h" "src/engine/input/Button.h" "src/engine/input/Button.cpp" "src/engine/input/MouseButton.h" "src/engine/input/MouseButton.cpp" "src/engine/rendering/objects/Model.h" "src/engine/rendering/objects/Model.cpp")

target_link_libraries(${PROJECT_NAME} PUBLIC
    glfw
    libglew_static
    assimp
    nativefiledialog
)

(Both配置给予相同的错误)
OpenGL/build运行cmake ..成功完成,我认为这意味着CMake能够找到assimp库。
现在,当我运行cmake --build .时,会出现以下错误。

assimp-vc143-mtd.lib(AssbinLoader.obj) : error LNK2019: unresolved external symbol uncompress referenced in function "public: virtual void __cdecl Assimp::AssbinImporter::InternReadFile(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,struct aiScene *,class Assimp::IOSystem *)" (?InternReadFile@AssbinImporter@Assimp@@UEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEAUaiScene@@PEAVIOSystem@2@@Z) [F:\dev\cpp\OpenGL\build\OpenGL\OpenGL.vcxproj]
assimp-vc143-mtd.lib(Compression.obj) : error LNK2019: unresolved external symbol inflate referenced in function "public: unsigned __int64 __cdecl Assimp::Compression::decompress(void const *,unsigned __int64,class std::vector<char,class std::allocator<char> > &)" (?decompress@Compression@Assimp@@QEAA_KPEBX_KAEAV?$vector@DV?$allocator@D@std@@@std@@@Z) [F:\dev\cpp\OpenGL\build\OpenGL\OpenGL.vcxproj]
etc...

我相信这意味着没有找到应该在.lib中编译的函数体。
如何成功链接库?

tpgth1q7

tpgth1q71#

这些函数(uncompressinflate)属于ZLIB库。虽然assimp CMake链接ZLIB以使用它-这足以构建assimp本身,但您还必须使用link ZLIB directly to your executable才能在可执行上下文中使用它。

相关问题