Skip to content

Add cmake library support.#9258

Open
edowson wants to merge 2 commits intoocornut:dockingfrom
edowson:pull-request
Open

Add cmake library support.#9258
edowson wants to merge 2 commits intoocornut:dockingfrom
edowson:pull-request

Conversation

@edowson
Copy link
Copy Markdown

@edowson edowson commented Feb 22, 2026

This pull request adds a top-level CMakeLists.txt file to allow an application to fetchcontent and link imgui with supported backends.

# conditionally fetch and build external libraries
option(BUILD_IMGUI             "Enable building imgui"             ON)

if (BUILD_IMGUI)

  # declare external library: imgui
  # ----------------------------------
  FetchContent_Declare(
    imgui
    GIT_REPOSITORY "https://github.com/ocornut/imgui.git"
    GIT_TAG         "docking"
    GIT_SHALLOW ON
    FIND_PACKAGE_ARGS NAMES imgui
  )

  # set the build option to override
  set(IMGUI_BACKEND_GLFW    ON CACHE INTERNAL "Turn on GLFW   backend support for imgui" FORCE)
  set(IMGUI_BACKEND_OPENGL3 ON CACHE INTERNAL "Turn on GLFW   backend support for imgui" FORCE)
  set(IMGUI_BACKEND_VULKAN  ON CACHE INTERNAL "Turn on VULKAN backend support for imgui" FORCE)

  FetchContent_MakeAvailable(imgui)

endif()

Here is an example CMakeLists.txt for building the imgui-gmfw-opengl3 example.

cmake_minimum_required(VERSION 3.18)

project(imgui-glfw-opengl3
        LANGUAGES CXX C
        VERSION 1.0.0.0)

# find the libraries which will be needed by imgui-glfw-opengl3
find_package(glfw3         REQUIRED)

set(OpenGL_GL_PREFERENCE "GLVND") # Following `cmake --help-policy CMP0072`
find_package(OpenGL        REQUIRED)

find_package(imgui CONFIG REQUIRED)
if(${imgui_FOUND})
    message(STATUS "Found imgui library.")
    message(STATUS "imgui_SOURCE_DIR: ${imgui_SOURCE_DIR}")
else()
    message(FATAL_ERROR "Could not locate imgui library. Please install the required development files.")
endif()

# Print status messages to show what variables were set by find_package(imgui)
# Reference: https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html#properties-on-targets

if(TARGET imgui)
    # get the VERSION property
    get_target_property(IMGUI_PACKAGE_VERSION imgui VERSION)
    message(STATUS "imgui library version: ${IMGUI_PACKAGE_VERSION}")

    # get the INTERFACE_INCLUDE_DIRECTORIES property
    get_target_property(IMGUI_PACKAGE_INCLUDE_DIRS imgui INTERFACE_INCLUDE_DIRECTORIES)
    message(STATUS "imgui interface include directories: ${IMGUI_PACKAGE_INCLUDE_DIRS}")

    else()
    message(STATUS "imgui target not found, please check top-level CMakeLists.txt and ensure it correctly fetches the imgui library.")
endif()

set(EXE_TARGET_NAME ${PROJECT_NAME}.exe)

set(${EXE_TARGET_NAME}_HEADER_FILES

  )

set(${EXE_TARGET_NAME}_SOURCE_FILES
      src/main.cpp
  )

set(${EXE_TARGET_NAME}_LINK_LIBRARIES 
  PUBLIC
  imgui::imgui
  glfw
  OpenGL::GL
  m
)

add_executable(
  ${EXE_TARGET_NAME}
  ${${EXE_TARGET_NAME}_SOURCE_FILES} 
  ${${EXE_TARGET_NAME}_HEADER_FILES})

target_link_libraries(
  ${EXE_TARGET_NAME} 
  ${${EXE_TARGET_NAME}_LINK_LIBRARIES})

# install target
install(TARGETS ${EXE_TARGET_NAME} 
        DESTINATION bin)

message(STATUS "Created target ${EXE_TARGET_NAME} for ${PROJECT_NAME}.")

This commit adds support for building imgui using cmake.

Signed-off-by: Elvis Dowson <elvis.dowson@gmail.com>
…ibrary target.

This commit adds FILE_SET features to target_sources and install(TARGETS)
in order to associate a set of headers and their containing include
directory with a target.

Installing the target installs the headers in the same layout,
and provides the include directory to consumers.

Signed-off-by: Elvis Dowson <elvis.dowson@gmail.com>
@Marsimplodation
Copy link
Copy Markdown

Marsimplodation commented Feb 22, 2026

would be nice if there was a way to force disable the use of this CMakeLists.txt (like a simple flag you set) so you can still manually define the library with custom backends (like rlImGui) while still using fetchcontent.

With custom backends you might end up with the following:

FetchContent_MakeAvailable(raylib imgui rlimgui)

add_library(imgui
  ${imgui_SOURCE_DIR}/imgui.cpp
  ${imgui_SOURCE_DIR}/imgui_demo.cpp
  ${imgui_SOURCE_DIR}/imgui_draw.cpp
  ${imgui_SOURCE_DIR}/imgui_tables.cpp
  ${imgui_SOURCE_DIR}/imgui_widgets.cpp
  ${rlimgui_SOURCE_DIR}/rlImGui.cpp
)
target_include_directories(imgui PUBLIC ${imgui_SOURCE_DIR}  ${rlimgui_SOURCE_DIR})
target_link_libraries(imgui raylib)

This would break with the inclusion of the CMakeLists.txt file. And since FetchContent_Populate is deprecated now the workaround would be sketchy.

The workaround you would need:

FetchContent_Declare(
	imgui
	#GIT_REPOSITORY https://github.com/ocornut/imgui.git
	GIT_REPOSITORY https://github.com/edowson/imgui.git
	GIT_TAG docking
	#Set SRC SUBDIR to something that does not exist,
	#so cmake does not run automatically
	SOURCE_SUBDIR        "adskmladfskljadfsklad"
)

@edowson
Copy link
Copy Markdown
Author

edowson commented Feb 22, 2026

would be nice if there was a way to force disable the use of this CMakeLists.txt (like a simple flag you set) so you can still manually define the library with custom backends (like rlImGui) while still using fetchcontent.

The imgui/CMakeLists.txt is intended to be basic library level infrastructure for a master project that could conditionally include it by setting an option as follows:

# conditionally fetch and build external libraries
option(BUILD_IMGUI             "Enable building imgui"             ON)

# fetch content
include(FetchContent)

if (BUILD_IMGUI)

  # declare external library: imgui
  # -------------------------------
  FetchContent_Declare(
    imgui
    GIT_REPOSITORY "https://github.com/ocornut/imgui.git"
    GIT_TAG         "docking"
    GIT_SHALLOW ON
    FIND_PACKAGE_ARGS NAMES imgui
  )

  # set the build option to override
  set(IMGUI_BACKEND_GLFW    ON CACHE INTERNAL "Turn on GLFW   backend support for imgui" FORCE)
  set(IMGUI_BACKEND_OPENGL3 ON CACHE INTERNAL "Turn on GLFW   backend support for imgui" FORCE)
  set(IMGUI_BACKEND_VULKAN  ON CACHE INTERNAL "Turn on VULKAN backend support for imgui" FORCE)

  FetchContent_MakeAvailable(imgui)

endif()

The master project could have sub-directories, which have their own CMakeLists.txt file, to build examples that use the imgui library. These sub-directories can be activitated by a CMakeLists.txt file as well, based on the above option.

# add subdirectories
if (BUILD_IMGUI)
  add_subdirectory(imgui-glfw-opengl3)
  add_subdirectory(imgui-glfw-vulkan)
endif()

if (BUILD_IMPLOT AND BUILD_IMGUI)
  add_subdirectory(implot-demo)
endif()

if (BUILD_IMPLOT3D AND BUILD_IMGUI)
  add_subdirectory(implot3d-demo)
endif()

This is the example I have for the imgui-glfw-opengl3/CMakeLists.txt file:

cmake_minimum_required(VERSION 3.18)

project(imgui-glfw-opengl3
        LANGUAGES CXX C
        VERSION 1.0.0.0)

# find the libraries which will be needed by imgui-glfw-opengl3
find_package(glfw3         REQUIRED)

set(OpenGL_GL_PREFERENCE "GLVND") # Following `cmake --help-policy CMP0072`
find_package(OpenGL        REQUIRED)

find_package(imgui CONFIG REQUIRED)
if(${imgui_FOUND})
    message(STATUS "Found imgui library.")
    message(STATUS "imgui_SOURCE_DIR: ${imgui_SOURCE_DIR}")
else()
    message(FATAL_ERROR "Could not locate imgui library. Please install the required development files.")
endif()

# Print status messages to show what variables were set by find_package(imgui)
# Reference: https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html#properties-on-targets

if(TARGET imgui)
    # get the VERSION property
    get_target_property(IMGUI_PACKAGE_VERSION imgui VERSION)
    message(STATUS "imgui library version: ${IMGUI_PACKAGE_VERSION}")

    # get the INTERFACE_INCLUDE_DIRECTORIES property
    get_target_property(IMGUI_PACKAGE_INCLUDE_DIRS imgui INTERFACE_INCLUDE_DIRECTORIES)
    message(STATUS "imgui interface include directories: ${IMGUI_PACKAGE_INCLUDE_DIRS}")

    else()
    message(STATUS "imgui target not found, please check top-level CMakeLists.txt and ensure it correctly fetches the imgui library.")
endif()

set(EXE_TARGET_NAME ${PROJECT_NAME}.exe)

set(${EXE_TARGET_NAME}_HEADER_FILES

  )

set(${EXE_TARGET_NAME}_SOURCE_FILES
      src/main.cpp
  )

set(${EXE_TARGET_NAME}_LINK_LIBRARIES
  PUBLIC
  imgui::imgui
  glfw
  OpenGL::GL
  m
)

add_executable(
  ${EXE_TARGET_NAME}
  ${${EXE_TARGET_NAME}_SOURCE_FILES}
  ${${EXE_TARGET_NAME}_HEADER_FILES})

target_link_libraries(
  ${EXE_TARGET_NAME}
  ${${EXE_TARGET_NAME}_LINK_LIBRARIES})

# install target
install(TARGETS ${EXE_TARGET_NAME}
        DESTINATION bin)

message(STATUS "Created target ${EXE_TARGET_NAME} for ${PROJECT_NAME}.")

As you can see, you master project can choose to include specific libraries, the inclusion of specific sub-directories that use specific examples can be controlled bu the build option, and I only have to call find_package(imgui CONFIG REQUIRED) and specify imgui::imgui in the call to target_link_libraries().

At the moment, several projects that depend on imgui keep defining cmake fetchcontent code fragments to manage pulling the source code dependency each time. The including of an imgui/CMakeLists.txt to build the library and the use of a build option in an external master project, will help control inclusion and usage of imgui as I have outlined above.


You can add a build option for rlimgui into your own CMakeLists.txt file to control which backend to use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants