【问题标题】:Include external libraries into CLion project through CMake通过 CMake 将外部库包含到 CLion 项目中
【发布时间】:2018-04-10 12:47:47
【问题描述】:

我很难让 GLFW Windows 预编译的二进制文件在我的 CLion 项目中工作。这些库放置在外部目录中。我不希望它们出现在我的项目库中,但应该(当然)在发布应用程序时提供。我是 C++ 新手,但我认为实现这一点可能和在 Java 中一样容易(Intellij Idea -> 依赖项 -> ...)。

GLFW Windows pre-compiled binaries

我使用 MinGW 5.0 和 CMake 3.10.2; 我的 CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)
project(Hatsudouki_core)

set(CMAKE_CXX_STANDARD 17)

link_directories(F:\\C++\\ExternalLibraries\\GLFW\\lib-mingw-w64)
include_directories(F:\\C++\\ExternalLibraries\\GLFW\\include)

add_executable(Hatsudouki_core main.cpp)

target_link_libraries(Hatsudouki_core glfw3)

Main.cpp

#include <iostream>
#include <GLFW/glfw3.h>

int main() {
    if (!glfwInit())
         std::cout << "error!" << std::endl;
    else
         std::cout << "success!" << std::endl;
    return 0;
}

构建输出

"F:\C++\CLion 2018.1\bin\cmake\bin\cmake.exe" --build C:\Users\simon\CLionProjects\Hatsudouki-core\cmake-build-debug --target Hatsudouki_core -- -j 4
[ 50%] Linking CXX executable Hatsudouki_core.exe
CMakeFiles\Hatsudouki_core.dir/objects.a(main.cpp.obj): In function `main':
C:/Users/simon/CLionProjects/Hatsudouki-core/main.cpp:5: undefined reference to `glfwInit'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[3]: *** [Hatsudouki_core.exe] Error 1
CMakeFiles\Hatsudouki_core.dir\build.make:96: recipe for target 'Hatsudouki_core.exe' failed
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/Hatsudouki_core.dir/all' failed
mingw32-make.exe[2]: *** [CMakeFiles/Hatsudouki_core.dir/all] Error 2
CMakeFiles\Makefile2:78: recipe for target 'CMakeFiles/Hatsudouki_core.dir/rule' failed
mingw32-make.exe[1]: *** [CMakeFiles/Hatsudouki_core.dir/rule] Error 2
Makefile:117: recipe for target 'Hatsudouki_core' failed
mingw32-make.exe: *** [Hatsudouki_core] Error 2

我尝试了这里提到的以下解决方案:
- GLFW docGLFW doc2(查找包不起作用,没有 CMake 文件)
- Github issue reportGithub issue report 2 相关,然后导致将FindGLFW.cmake 放入某个目录的解决方案?试图把它放在这里 GLFW\FindGLFW.cmake 但不起作用
- 链接没有像这里提到的那样工作:Stackoverflow

图片 GLFW 目录:GLFW Windows pre-compiled binaries

我想我只是不明白 CMake、外部库和 C++ 如何协同工作来完成这个相当简单的任务。我相信与 Java 的比较会有所帮助(用于使用 gradle)

编辑 1 正如建议的那样,我添加了以下内容: 我将Findglfw3.cmake 放入PROJECT/cmake/Modules/

# Copyright (c) 2015 Andrew Kelley
# This file is MIT licensed.
# See http://opensource.org/licenses/MIT

# GLFW_FOUND
# GLFW_INCLUDE_DIR
# GLFW_LIBRARY

find_path(GLFW_INCLUDE_DIR NAMES F:\\C++\\ExternalLibraries\\GLFW\\include\\GLFW\\glfw3.h)

find_library(GLFW_LIBRARY NAMES glfw glfw3)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GLFW DEFAULT_MSG GLFW_LIBRARY GLFW_INCLUDE_DIR)

mark_as_advanced(GLFW_INCLUDE_DIR GLFW_LIBRARY)

并在我的 CMakeLists.txt 中添加了以下几行:

find_package(glfw3 REQUIRED)
include_directories(${glfw3_INCLUDE_DIRS})
set(LIBS ${LIBS} ${glfw3_LIBRARIES})
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")

target_link_libraries(hatsudouki_core ${LIBS})

我也在 Findglfw3.cmake 中试过:

find_path(GLFW_INCLUDE_DIR NAMES GLFW/glfw3.h)

这在原始文件中是相同的。两者都不起作用;错误:

"F:\C++\CLion 2018.1\bin\cmake\bin\cmake.exe" --build C:\Users\simon\CLionProjects\Hatsudouki-core\cmake-build-debug --target Hatsudouki_core -- -j 4
CMake Error at CMakeLists.txt:6 (find_package):
-- Configuring incomplete, errors occurred!
By not providing "Findglfw3.cmake" in CMAKE_MODULE_PATH this project has
See also "C:/Users/simon/CLionProjects/Hatsudouki-core/cmake-build-debug/CMakeFiles/CMakeOutput.log".
asked CMake to find a package configuration file provided by "glfw3", but
CMake did not find one.

Makefile:175: recipe for target 'cmake_check_build_system' failed
Could not find a package configuration file provided by "glfw3" with any of
the following names:

glfw3Config.cmake
glfw3-config.cmake

Add the installation prefix of "glfw3" to CMAKE_PREFIX_PATH or set
"glfw3_DIR" to a directory containing one of the above files.  If "glfw3"
provides a separate development package or SDK, be sure it has been
installed.
mingw32-make.exe: *** [cmake_check_build_system] Error 1

【问题讨论】:

  • C++ 链接和 Java 是两个非常不同的东西。试图比较它们只会让你更加困惑。您的CMakeLists.txt 硬连线路径;不应该这样做。您应该将FindGLFW.cmake 放在CMake 可以找到它的位置(例如,通过将放置它的目录添加到CMAKE_MODULE_PATH),然后使用CMake 命令find_package( GLFW )。一般来说,你的问题是很多问题,因此有点难以正确回答......
  • 您的 CMakeLists.txt 文件缺少 find_package(glfw3) 并且在 target_link_libraries 调用中您需要引用 glfw。您可能需要将 glfw3 库的路径添加到您的CMAKE_MODULE_PATH。请参阅glfw.org/docs/latest/build_guide.html#build_link_cmake_source 了解更多信息。
  • 实际上,CMake 代码似乎没问题(它不是完美,因为它使用硬编码路径而不是find_package(),但它应该可以工作)。错误“undefined reference to 'glfwInit'”表示: 1. 已找到 GLFW 头文件。 2. GLFW 库已找到。 3. 该库不包含适用于给定平台的glfwInit 函数。换句话说,问题似乎是兼容性问题。
  • @Tsyvarev 那么我该如何解决这个兼容性问题,甚至找出它是否是一个兼容性问题?

标签: c++ cmake libraries clion glfw


【解决方案1】:

正如here解释的那样

  1. PROJECT/cmake/Modules/ 中创建Findglfw3.cmake 文件,看起来像

    # GLFW_FOUND
    # GLFW_INCLUDE_DIR
    # GLFW_LIBRARY
    
    set(FIND_GLFW_PATHS "F:\\C++\\ExternalLibraries\\GLFW")
    
    find_path(GLFW_INCLUDE_DIR NAMES GLFW/glfw3 GLFW/glfw3.h PATH_SUFFIXES include PATHS ${FIND_GLFW_PATHS})
    find_library(GLFW_LIBRARY NAMES glfw3 glfw3.a libglfw3 libglfw3.a PATH_SUFFIXES lib-mingw PATHS ${FIND_GLFW_PATHS})
    
    include(FindPackageHandleStandardArgs)
    find_package_handle_standard_args(GLFW DEFAULT_MSG GLFW_LIBRARY GLFW_INCLUDE_DIR)
    
    mark_as_advanced(GLFW_INCLUDE_DIR GLFW_LIBRARY)
    
  2. CMakeLists.txt中定义模块路径

    #Define module path
    list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/Modules")
    
  3. 还将包含目录和库与CMakeLists.txt中的项目链接

    #Define static GLFW libraries and header files
    find_package(glfw3 REQUIRED)
    include_directories(${GLFW_INCLUDE_DIR})
    ...
    target_link_libraries(Hatsudouki_core ${GLFW_LIBRARY})
    

【讨论】:

    【解决方案2】:

    首先你需要安装glfw 包。如果您使用的是MSYS2,那么可以在 64 位 Windows 上使用 pacman -S mingw-w64-x86_64-glfw 和在 32 位 Windows 上使用 pacman -S mingw-w64-i686-glfw 安装它。并且您需要使用find_packagecmake 自动定位glfw 库,而不是手动定位它们。如果您使用MSYS2,那么这可能有点困难。看看这段代码。

    cmake_minimum_required(VERSION 3.10)
    project(Hatsudouki_core)
    
    set(CMAKE_CXX_STANDARD 17)
    
    add_executable(Hatsudouki_core main.cpp)
    
    find_package(glfw3 REQUIRED) # Find the GLFW library
    target_link_libraries(Hatsudouki_core PRIVATE glfw) # Finally, link to them.
    

    如果你需要预编译的库,我建议你使用 MSYS2。它有一个非常好的包管理器,叫做pacman

    【讨论】:

    • 感谢您的回答!我没有使用或没有 MSYS2。因此,我尝试了 cmets 中的其他建议。我认为可能有一个解决方案,而无需安装我想使用的每个库。如果其他建议不起作用,我会尝试您的建议。
    猜你喜欢
    • 2015-04-29
    • 1970-01-01
    • 1970-01-01
    • 2014-05-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多