【问题标题】:How to make config.cmake file of Dear ImGui with dependencies glfw, GLEW and GL如何使用依赖 glfw、GLEW 和 GL 制作 Dear ImGui 的 config.cmake 文件
【发布时间】:2020-07-27 23:16:23
【问题描述】:

目前我尝试制作 ImGuiConfig.cmake 文件以使用亲爱的 ImGui GUI 库

我想从外部项目中使用该库,如下所示。

find_package(ImGui REQUIRED)
add_executable(hello hello.cpp)
target_link_libraries(hello ${IMGUI_LIBRARIES})

CMakeLists.txt 之后是我为安装 ImGui 库而编写的文件。

cmake_minimum_required(VERSION 3.10)

# Project Name
project(ImGui)

# This cmake file try to make a lib of ImGui glfw backend
add_definitions(-fPIC)

set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)

# Get header and source file name
file(GLOB_RECURSE SOURCE_CPP RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ImGui/*.cpp)
file(GLOB_RECURSE SOURCE_HEADER RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ImGui/*.h)

# create target
add_library(${PROJECT_NAME} STATIC ${SOURCE_CPP})
target_link_libraries(${PROJECT_NAME} PUBLIC glfw GLEW GL)
set_target_properties(${PROJECT_NAME} PROPERTIES IMPORTED_LINK_LIBRARIES "glfw;GLEW;GL")
set_target_properties(${PROJECT_NAME} PROPERTIES INTERFACE_LINK_LIBRARIES "glfw;GLEW;GL")

install(TARGETS ${PROJECT_NAME} 
    EXPORT ImGuiConfig
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )

export(TARGETS ${PROJECT_NAME}
    FILE "${CMAKE_CURRENT_BINARY_DIR}/ImGuiConfig.cmake")

install(EXPORT ImGuiConfig
    DESTINATION lib/cmake/ImGui
    EXPORT_LINK_INTERFACE_LIBRARIES
    )

但是当我编译使用 ImGui 库的外部程序时,我得到了以下错误。

harumo@harumo-thinkpad-x1:~/program/cpp/imgui/hello/build$ make
Scanning dependencies of target hello
[ 50%] Building CXX object CMakeFiles/hello.dir/hello.cpp.o
[100%] Linking CXX executable hello
CMakeFiles/hello.dir/hello.cpp.o: In function `main':
hello.cpp:(.text+0x32): undefined reference to `glfwWindowHint'
hello.cpp:(.text+0x41): undefined reference to `glfwWindowHint'
hello.cpp:(.text+0x50): undefined reference to `glfwWindowHint'
hello.cpp:(.text+0x5f): undefined reference to `glfwWindowHint'
hello.cpp:(.text+0x82): undefined reference to `glfwCreateWindow'
hello.cpp:(.text+0x8f): undefined reference to `glfwMakeContextCurrent'
hello.cpp:(.text+0x99): undefined reference to `glfwSwapInterval'
hello.cpp:(.text+0x9e): undefined reference to `glewInit'
hello.cpp:(.text+0xd3): undefined reference to `ImGui::DebugCheckVersionAndDataLayout(char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)'
hello.cpp:(.text+0xe1): undefined reference to `ImGui::CreateContext(ImFontAtlas*)'
hello.cpp:(.text+0xea): undefined reference to `ImGui::GetIO()'
hello.cpp:(.text+0xf9): undefined reference to `ImGui::StyleColorsLight(ImGuiStyle*)'
hello.cpp:(.text+0x107): undefined reference to `ImGui_ImplGlfw_InitForOpenGL(GLFWwindow*, bool)'
hello.cpp:(.text+0x113): undefined reference to `ImGui_ImplOpenGL3_Init(char const*)'
hello.cpp:(.text+0x147): undefined reference to `glfwWindowShouldClose'
hello.cpp:(.text+0x155): undefined reference to `glfwPollEvents'
hello.cpp:(.text+0x15a): undefined reference to `ImGui_ImplOpenGL3_NewFrame()'
hello.cpp:(.text+0x15f): undefined reference to `ImGui_ImplGlfw_NewFrame()'
hello.cpp:(.text+0x164): undefined reference to `ImGui::NewFrame()'
hello.cpp:(.text+0x179): undefined reference to `ImGui::Begin(char const*, bool*, int)'
hello.cpp:(.text+0x18d): undefined reference to `ImGui::Text(char const*, ...)'
hello.cpp:(.text+0x1a4): undefined reference to `ImGui::Checkbox(char const*, bool*)'
hello.cpp:(.text+0x1ac): undefined reference to `ImGui::End()'
hello.cpp:(.text+0x1b1): undefined reference to `ImGui::Render()'
hello.cpp:(.text+0x1dc): undefined reference to `glfwGetFramebufferSize'
hello.cpp:(.text+0x1f0): undefined reference to `glViewport'
hello.cpp:(.text+0x209): undefined reference to `glClearColor'
hello.cpp:(.text+0x213): undefined reference to `glClear'
hello.cpp:(.text+0x218): undefined reference to `ImGui::GetDrawData()'
hello.cpp:(.text+0x220): undefined reference to `ImGui_ImplOpenGL3_RenderDrawData(ImDrawData*)'
hello.cpp:(.text+0x229): undefined reference to `glfwSwapBuffers'
hello.cpp:(.text+0x233): undefined reference to `ImGui_ImplOpenGL3_Shutdown()'
hello.cpp:(.text+0x238): undefined reference to `ImGui_ImplGlfw_Shutdown()'
hello.cpp:(.text+0x241): undefined reference to `ImGui::DestroyContext(ImGuiContext*)'
hello.cpp:(.text+0x24a): undefined reference to `glfwDestroyWindow'
hello.cpp:(.text+0x24f): undefined reference to `glfwTerminate'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
CMakeFiles/hello.dir/build.make:100: recipe for target 'hello' failed
make[2]: *** [hello] Error 1
CMakeFiles/Makefile2:92: recipe for target 'CMakeFiles/hello.dir/all' failed
make[1]: *** [CMakeFiles/hello.dir/all] Error 2
Makefile:100: recipe for target 'all' failed
make: *** [all] Error 2

glfw、GLEW、GL库好像没有导入。

如果您告诉我如何使用上面的 CMakeLists.txt 导入 glfw、GLEW 和 GL 库,我很高兴。 如果您需要更多信息,请随时告诉我。

提前致谢。


解决方案

多亏了 Tsyvarev 非常合适的 cmets,我才得以解决问题。 我改变了我的 CMakeLists.txt 如下。

cmake_minimum_required(VERSION 3.10)

# Project Name
project(ImGui)

# This cmake file try to make a lib of ImGui glfw backend
add_definitions(-fPIC)

set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)

# Get header and source file name
file(GLOB_RECURSE SOURCE_CPP RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ImGui/*.cpp)
file(GLOB_RECURSE SOURCE_HEADER RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ImGui/*.h)

# create target
add_library(${PROJECT_NAME} STATIC ${SOURCE_CPP})
target_link_libraries(${PROJECT_NAME} PUBLIC glfw GLEW GL)
set_target_properties(${PROJECT_NAME} PROPERTIES IMPORTED_LINK_LIBRARIES "glfw;GLEW;GL")
set_target_properties(${PROJECT_NAME} PROPERTIES INTERFACE_LINK_LIBRARIES "glfw;GLEW;GL")
set(IMGUI_LIBRARIES ImGui;glfw;GLEW;GL)

install(TARGETS ${PROJECT_NAME} 
    EXPORT ImGuiConfig
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

export(TARGETS ${PROJECT_NAME}
FILE "${CMAKE_CURRENT_BINARY_DIR}/ImGuiConfig.cmake")

install(EXPORT ImGuiConfig
    DESTINATION lib/cmake/ImGui
    EXPORT_LINK_INTERFACE_LIBRARIES
)

我刚刚添加到我的 CMakeLists.txt

set(IMGUI_LIBRARIES ImGui;glfw;GLEW;GL)

通过添加这一行,我定义了一个名为 IMGUI_LIBRARIES 的 CMAKE 变量。这个变量的内容是 ImGui;glfw;GLEW;GL。这允许用户通过执行以下操作来加载必要的库,例如 glfw、GLEW 和 GL。

target_link_libraries(hello ${IMGUI_LIBRARIES})

【问题讨论】:

  • 配置文件,由 CMake 生成,install(TARGETS ... EXPORT) 定义了与已安装目标名称相同的 IMPORTED 库目标。这个文件没有定义像IMGUI_LIBRARIES 这样的变量,所以${IMGUI_LIBRARIES} 被扩展为空。不是,该主配置文件(通过find_package 包含)通常由您编写。这个文件include()-s 是由 CMake 生成的文件,可能会执行额外的操作。我建议阅读CMake guide about packaging

标签: c++ cmake imgui


【解决方案1】:

感谢 Tsyvarev!

您的评论很有用。我改变了我的 CMakeLists.txt 如下。

cmake_minimum_required(VERSION 3.10)

# Project Name
project(ImGui)

# This cmake file try to make a lib of ImGui glfw backend
add_definitions(-fPIC)

set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)

# Get header and source file name
file(GLOB_RECURSE SOURCE_CPP RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ImGui/*.cpp)
file(GLOB_RECURSE SOURCE_HEADER RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ImGui/*.h)

# create target
add_library(${PROJECT_NAME} STATIC ${SOURCE_CPP})
target_link_libraries(${PROJECT_NAME} PUBLIC glfw GLEW GL)
set_target_properties(${PROJECT_NAME} PROPERTIES IMPORTED_LINK_LIBRARIES "glfw;GLEW;GL")
set_target_properties(${PROJECT_NAME} PROPERTIES INTERFACE_LINK_LIBRARIES "glfw;GLEW;GL")
set(IMGUI_LIBRARIES ImGui;glfw;GLEW;GL)

install(TARGETS ${PROJECT_NAME} 
    EXPORT ImGuiConfig
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

export(TARGETS ${PROJECT_NAME}
FILE "${CMAKE_CURRENT_BINARY_DIR}/ImGuiConfig.cmake")

install(EXPORT ImGuiConfig
    DESTINATION lib/cmake/ImGui
    EXPORT_LINK_INTERFACE_LIBRARIES
)

我刚刚添加到我的 CMakeLists.txt

set(IMGUI_LIBRARIES ImGui;glfw;GLEW;GL)

【讨论】:

  • 很高兴您在评论的帮助下回答了自己的问题!您能否编辑您的答案,以便无需先阅读评论即可理解?换句话说,解释问题是什么以及为什么添加该行可以解决问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-12
  • 2023-02-12
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 2015-02-24
  • 2021-12-23
相关资源
最近更新 更多