Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lightweight, Modular CMake Integration for ImGui #7992

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

pinwhell
Copy link

This commit introduces a minimal and clean CMake setup aimed at maintaining the simplicity of the project. The goal is to provide a foundation for modular build configurations, allowing for future additions (e.g., backend implementations, examples) without introducing bloat.

@pinwhell
Copy link
Author

pinwhell commented Sep 17, 2024

I had a few doubts, i was unsure, what is the more standard expected way when including backends

#include <backends/imgui_impl_xxxxx.h>

or directly

#include<imgui_impl_xxxxx.h>

also, what about, when installing imgui includes, is it supposed to be installed within a imgui root include folder in such a way that includes goes:

#include <imgui/imgui.h>
#include <imgui/xxxx/xxxx.h>

or direclty install imgui includes to the destination root include path, in such a way that includes looks like:

#include <imgui.h>
#include <imgui_xxxxx.h>

Note: Imgui already follows a flat looking convention when referring to includes, for example imgui consistently follows a pattern of prefixing its files with imgui_ thus suggesting that the proper decision would be to simply install the flat imgui includes that comes already namespaced in a way, i believe making the equivalence of having a imgui include folder in the installed include directory, on top of this project using imgui would benefit, by not breaking on a new convention, they will still see the flat convention as usual.

the aim is to have minimum amount of change and maximum amount of consistency.

@pinwhell
Copy link
Author

pinwhell commented Sep 18, 2024

Example:

find_package(imgui REQUIRED)
# or
# add_subdirectory(path/to/imgui)
add_executable(foo foo.cpp)
target_link_libraries(myexec 
imgui::core         # Core Agnostic Imgui Impl, ex imgui.cpp imgui_tables.cpp ... etc etc
imgui::freetype     # Imgui FreeType Implementation
...
imgui::win32        # Imgui Windows Backend
# imgui::opengl2    # Imgui Opengl2 Backend Implementation
imgui::opengl3      # Imgui Opengl3 Backend Implementation
...
)

As shown above, everything is very decoupled, concerns are very separated, in a way feels like composing your build with imgui modules!

// foo.cpp

#include <imgui.h>                  // From imgui::core
#include <imgui_impl_win32.h>       // From imgui::win32
//#include <imgui_impl_opengl2.h>   // From imgui::opengl2
#include <imgui_impl_opengl3.h>     // From imgui::opengl3
#include <imgui_freetype.h>         // From imgui::freetype

int main()
{
   Imgui:: .... (); 
}

Note: Each component shown above is automatically being linked statically! (including Freetype etc!)

@pinwhell pinwhell changed the title Add lightweight CMake setup for modular and scalable build configuration Lightweight, Modular CMake Integration for ImGui Sep 18, 2024
@rherilier
Copy link
Contributor

Hi,

Here are some feedbacks.

First, you should purely and solely ignore irrelevant backends for the target system: win32 can be ignored on unices, but it have to be build when cross-compiling for win32. From memory, the target system name is inCMAKE_SYSTEM_NAME and the build system name is in CMAKE_HOST_SYSTEM_NAME.

Next, why not having all options set to ON by default and let the installed packages discovery do the disabling? It make it simplier to test your code ;)

Having messages to tell which backends are enabled/disabled would be helpful too.

Fixing the indentation for all if statement would make your code more readable.

The files xxx-target.cmake are not generated when the .a are.

As I'm not used to the logic behind the files xxx-target.cmake, does it permit to set wanted components when calling find_packages(...)?

My CMake files used to look like:

find_package(Qt5 COMPONENTS Core Gui Wigets REQUIRED)
...
add_executable(MyProgram ...)
target_link_libraries(MyProgram PUBLIC Qt5::Core Qt5::Gui Qt5::Wigets)

In case of imgui as a subproject, I would expect to write something like:

add_subdirectory(subprojects/imgui)
...
find_package(imgui COMPONENTS sdl2 vulkan REQUIRED)
...
add_executable(MyAmazingProgram ...)
target_link_libraries(MyAmazingProgram PUBLIC imgui::core imgui::sdl2 imgui::vulkan)

To make it work, your main CMakeLists.txt could have some code like:

...
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
  # in main project mode
  include(GNUInstallDirs)
  set(IMGUI_INC_DIR ${CMAKE_INSTALL_INCLUDEDIR})
  set(IMGUI_LIB_DIR ${CMAKE_INSTALL_LIBDIR})
else()
  # in subproject mode
  set(imgui_DIR "${CMAKE_CURRENT_BINARY_DIR}" PARENT_SCOPE)
  set(IMGUI_INC_DIR ${CMAKE_CURRENT_SOURCE_DIR})
  set(IMGUI_LIB_DIR ${CMAKE_CURRENT_BINARY_DIR})
endif()

# generate the cmake script with IMGUI_LIB_DIR, IMGUI_INC_DIR and many other variables
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/imgui-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/imgui-config.cmake")
...

The trick is the line set (imgui_DIR ... PARENT_SCOPE) to make it findable by the parent CMakeLists.txt.

About the includes, I would say the 2 are expected (depending on the circumstances):

  • if installed, headers should be in a dedicated directory (i.e. #include <imgui/imgui.h>);
  • if used as a subproject, the root include directory can only be the source root directory (i.e. #include <imgui.h>).

And I also think backends/ and misc/ should be explicitly written by the developers (in regards to imgui's source tree).

mes 2¢

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