How to use ImGui, GLFW and OpenGL with vcpkg, Clion and CMake on Windows 11
Asked Answered
N

2

6

I use vcpkg manifest mode to install packages, vcpkg.json:

{
  "name": "vcpkgtest",
  "version": "1.0.0",
  "description": "learn vkpg & glfw & imgui & cmake",
  "dependencies": [
    "glfw3",
    {
      "name": "imgui",
      "features": ["glfw-binding", "opengl3-binding"]
    }
  ]
}

and installed them succesfully, CMakeLists.txt:

cmake_minimum_required(VERSION 3.25)
project(vcpkg_test)

set(CMAKE_CXX_STANDARD 17)

add_executable(vcpkg_test main.cpp)
## link packages
find_package(OpenGL REQUIRED)
target_link_libraries(vcpkg_test PRIVATE opengl32)

find_package(glfw3 CONFIG REQUIRED)
target_link_libraries(vcpkg_test PRIVATE glfw)

find_package(imgui CONFIG REQUIRED)
target_link_libraries(vcpkg_test PRIVATE imgui::imgui)

Run the following code main.cpp:

#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>

#include <GLFW/glfw3.h>

int main(void)
{
    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);

    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO(); (void)io;
    ImGui_ImplGlfw_InitForOpenGL(window, true);
    ImGui_ImplOpenGL3_Init("#version 330");

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();

        ImGui::Begin("My name is window, ImGUI window");
        ImGui::Text("Hello there new born!");
        ImGui::End();
        ImGui::Render();
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());


        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();

    glfwTerminate();
    return 0;
}

I get many undefined reference to 'ImGui::xxx':

[ 50%] Linking CXX executable vcpkg_test.exe
CMakeFiles\vcpkg_test.dir/objects.a(main.cpp.obj): In function `main':
E:/Fdisk/programming/vcpkg_test/main.cpp:26: undefined reference to `ImGui::DebugCheckVersionAndDataLayout(char const*, unsigned long long, unsigned long long, unsigned long long, unsigned long long, unsigned long long, unsigned long long)'
E:/Fdisk/programming/vcpkg_test/main.cpp:27: undefined reference to `ImGui::CreateContext(ImFontAtlas*)'
E:/Fdisk/programming/vcpkg_test/main.cpp:28: undefined reference to `ImGui::GetIO()'
E:/Fdisk/programming/vcpkg_test/main.cpp:29: undefined reference to `ImGui_ImplGlfw_InitForOpenGL(GLFWwindow*, bool)'
E:/Fdisk/programming/vcpkg_test/main.cpp:30: undefined reference to `ImGui_ImplOpenGL3_Init(char const*)'
E:/Fdisk/programming/vcpkg_test/main.cpp:38: undefined reference to `ImGui_ImplOpenGL3_NewFrame()'
E:/Fdisk/programming/vcpkg_test/main.cpp:39: undefined reference to `ImGui_ImplGlfw_NewFrame()'
E:/Fdisk/programming/vcpkg_test/main.cpp:40: undefined reference to `ImGui::NewFrame()'
E:/Fdisk/programming/vcpkg_test/main.cpp:42: undefined reference to `ImGui::Begin(char const*, bool*, int)'
E:/Fdisk/programming/vcpkg_test/main.cpp:43: undefined reference to `ImGui::Text(char const*, ...)'
E:/Fdisk/programming/vcpkg_test/main.cpp:44: undefined reference to `ImGui::End()'
E:/Fdisk/programming/vcpkg_test/main.cpp:45: undefined reference to `ImGui::Render()'
E:/Fdisk/programming/vcpkg_test/main.cpp:46: undefined reference to `ImGui::GetDrawData()'
E:/Fdisk/programming/vcpkg_test/main.cpp:46: undefined reference to `ImGui_ImplOpenGL3_RenderDrawData(ImDrawData*)'
E:/Fdisk/programming/vcpkg_test/main.cpp:56: undefined reference to `ImGui_ImplOpenGL3_Shutdown()'
E:/Fdisk/programming/vcpkg_test/main.cpp:57: undefined reference to `ImGui_ImplGlfw_Shutdown()'
E:/Fdisk/programming/vcpkg_test/main.cpp:58: undefined reference to `ImGui::DestroyContext(ImGuiContext*)'
collect2.exe: error: ld returned 1 exit status

I've directly used the source code of ImGui before to run the main.cpp successfully.

It's my first time to use vcpkg and ImGui, but it seems that the lib missed something. I'm sure that ["glfw-binding", "opengl3-binding"] are installed because I can see the corresponding header files in ./cmake-build-debug/vcpkg_installed/x64-windows/include.

So what's the problem?

Northman answered 13/12, 2022 at 5:28 Comment(1)
Do you run vcpkg in manifest mode?Enfeoff
G
0

The undefined references indicate that the libraries are not properly linked in your CMake configuration with vcpkg.

There could be several reasons.

  1. First off, make sure to set the install directory with vcpkg integrate install (at vcpkg install directory). In your CMakeLists.txt, you are missing the CMAKE_TOOLCHAIN_FILE variable setting with set(CMAKE_TOOLCHAIN_FILE "[path to vcpkg]/scripts/buildsystems/vcpkg.cmake").

  2. Make sure you are using the correct vcpkg triplet. In my case, I was using MinGW which requires you to use a MinGW triplet in vcpkg. Using the default x64-windows causes the linking error. To use MinGW triplets, I added

set(VCPKG_TARGET_TRIPLET "x64-mingw-static")
set(VCPKG_HOST_TRIPLET "x64-mingw-static")

to my CMakeLists.txt before calling project(myproject).

As pointed out in the comments, it is advised to specify CMAKE_TOOLCHAIN_FILE in project presets, thus defining vcpkg triplets may be advised to be defined in the presets as well. For that, I refer to the vcpkg documentation of triplets.

Grace answered 6/11, 2023 at 10:17 Comment(1)
The toolchain file should not be set inside a CMakeLists.txt. It should be set in the preset inside CMakePresets.json or in the command line arguments.Enfeoff
G
-1

If using the vcpkg way, find_package does not work for me. I get error. To resolve, add the following to your CMakeLists.txt

if(WIN32)
    find_library(imgui REQUIRED HINTS "${CMAKE_SOURCE_DIR}/vcpkg_installed/x64-windows/lib" NAMES imgui)
    include_directories("${CMAKE_SOURCE_DIR}/vcpkg_installed/x64-windows/include")
else()
    find_library(imgui REQUIRED HINTS "${CMAKE_SOURCE_DIR}/vcpkg_installed/x64-linux/lib" NAMES imgui)
    include_directories("${CMAKE_SOURCE_DIR}/vcpkg_installed/x64-linux/include")
endif()

and don't forget to link to your executable like so: target_link_libraries(main PRIVATE imgui)

This works

cmake_minimum_required(VERSION 3.20)

## vcpkg
SET(CMAKE_TOOLCHAIN_FILE "${CMAKE_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake")

project(shader-demo)

set(CMAKE_CXX_STANDARD 14)

set(OpenGL_GL_PREFERENCE GLVND)

find_package(OpenGL REQUIRED)
find_package(GLUT REQUIRED)
find_package(GLEW REQUIRED STATIC)
find_package(glfw3 REQUIRED)
find_package(Freetype REQUIRED)
find_package(glm REQUIRED)
if(WIN32)
    find_library(imgui REQUIRED HINTS "${CMAKE_SOURCE_DIR}/vcpkg_installed/x64-windows/lib" NAMES imgui)
    link_directories("${CMAKE_SOURCE_DIR}/vcpkg_installed/x64-windows/lib")
    include_directories("${CMAKE_SOURCE_DIR}/vcpkg_installed/x64-windows/include")
else()
    find_library(imgui REQUIRED HINTS "${CMAKE_SOURCE_DIR}/vcpkg_installed/x64-linux/lib" NAMES imgui)
    link_directories("${CMAKE_SOURCE_DIR}/vcpkg_installed/x64-linux/lib")
    include_directories("${CMAKE_SOURCE_DIR}/vcpkg_installed/x64-linux/include")
endif()

add_executable(main main.cpp)

target_link_libraries(main PRIVATE ${OPENGL_LIBRARIES} ${GLUT_LIBRARY} ${GLEW_LIBRARIES} glfw ${GLM_LIBRARIES} imgui ${FREETYPE_LIBRARIES})
Glandulous answered 14/4 at 13:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.