首页 > 解决方案 > 如何使用依赖 glfw、GLEW 和 GL 制作 Dear ImGui 的 config.cmake 文件

问题描述

目前我尝试制作 ImGuiConfig.cmake 文件以使用Dear ImGui GUI library

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

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 非常恰当的评论,我得以解决问题。我改变了我的 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})

标签: c++cmakeimgui

解决方案


谢谢齐瓦列夫!

你的评论很有用。我改变了我的 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)

推荐阅读