imgui
imgui copied to clipboard
Add CMake project
Add CMake project
Now implemented:
Export Dear ImGui as CMake's ImGui package.
Options:
- ImGui_USER_CONFIG;
- ImGui_EXAMPLES;
- ImGui_BACKENDS;
- ImGui_MISC;
- ImGui_3RDPARTY;
- ImGui_OPENGL_LOADER;
- ImGui_FREETYPE;
- ImGui_TOOLS;
- ImGui_PACKAGE.
Export targets:
- ImGui::Core;
- ImGui::ImplGLUT;
- ImGui::ImplSDL2;
- ImGui::ImplSDLRenderer2;
- ImGui::ImplSDL3;
- ImGui::ImplSDLRenderer3;
- ImGui::ImplGlfw;
- ImGui::ImplOpenGL2;
- ImGui::ImplOpenGL3;
- ImGui::ImplVulkan;
- ImGui::FreeType;
- ImGui::StdLib;
- ImGui::BinaryToCompressedC.
Import targets from:
- build directory;
- installed package.
Examples:
- example_null;
- example_glut_opengl2
- example_sdl2_sdlrenderer2;
- example_sdl2_opengl2;
- example_sdl2_opengl3;
- example_sdl2_vulkan;
- example_sdl3_sdlrenderer3;
- example_sdl3_opengl3;
- example_sdl3_vulkan;
- example_glfw_opengl2;
- example_glfw_opengl3;
- example_glfw_vulkan.
[NEW] Presets:
- vcpkg (require $env{VCPKG_ROOT});
- emscripten (inherits vcpkg and require $env{EMSCRIPTEN_ROOT}).
Users can easy link ImGui::XXX or ImGui::ImplXXX libraries and use example binding implementation ore other misc features in custom projects.
Tested with MinGW-w64, MSVC, Emscripten.
Live Preview
Previous CMake issues/pull requests: https://github.com/ocornut/imgui/issues/1144 https://github.com/ocornut/imgui/issues/5
https://github.com/ocornut/imgui/pull/1573 https://github.com/ocornut/imgui/pull/397 https://github.com/ocornut/imgui/pull/255
The emscripten bits seem nice though :)
Note that i’ve been refactoring examples as part of the default branch, and will probably end up providing both premake and cmake files for the examples/ bits.
@franciscod, thanks for links. Now I have some ground to think about.
Looks like @tamaskenez make good work about this topic.
Another idea: publish default imgui_imp* code/libraries to simplify using of the ImGui.
Hi @ocornut, I implement idea to share ImGui_Impl* methods with users via CMake's package to easy create more examples or custom projects.
Please review examples/opengl2_example/CMakeLists.txt or examples/sdl_opengl2_example/CMakeLists.txt project files to see how users can use it.
Only one install ImGui package to your environment and use it anyware.
What your think about there idea?
@podgorskiy I understand why cmake is used. I personally think it's unnecessary for imgui as the point of the library is that you can register the .cpp file in your application and I encourage you to do so (you can add imgui cpp files from your main app cmake file).
Surely registering a few cpp files in your project shouldn't be harder than maintaining and registering a separate cmake file from your project?
Only one install ImGui package to your environment and use it anyware.
It is a little harmful as it prevents people from configuring ImGui for their application via imconfig.h. While people are free to repackage imgui if they like I think we shouldn't encourage it. ImGui is designed to be compiled in your engine/application and it is easy to compile (the absence of build files is an indicator that it doesn't need anything to be built).
That said, to provide the example applications I will maintain premake/cmake, but I won't tackle that until the examples are refactored in a later version. Your cmake references will be useful here. Thank you!
Also note that your PR also mix and matches multiple unrelated changes in a single commit so it's hard to review or pull.
FYI I made some comments but don't worry about reworking or splitting the PR. Since the examples are being refactored in the viewport branch, I won't be able take this PR soon. But I will pull the cmake/emscripten information from it so it is useful. Thanks again!
@podgorskiy I understand why cmake is used. I personally think it's unnecessary for imgui as the point of the library is that you can register the .cpp file in your application and I encourage you to do so (you can add imgui cpp files from your main app cmake file).
Surely registering a few cpp files in your project shouldn't be harder than maintaining and registering a separate cmake file from your project?
Just to play an advocate, I hate hate hate pulling in dependency code directly into my projects as it pollutes my repositories with code that is not mine to maintain.
As for ease of use, with cmake when I want to bring in a dependency then I'll add something like this in my CMake file (I'm using boost compiled libraries as an example as those are generally fairly painful otherwise, this shows the ease of use):
hunter_add_package(Boost COMPONENTS system filesystem)
At this point all the files needed for the system and filesystem parts of boost are downloaded and compiled at the default version in my linked repo (latest stable, others are available, and I can specify a version on the above line if you want a specific version that is older than the one in the dep lock file). I then use it like any other library:
find_package(Boost CONFIG REQUIRED system filesystem)
target_link_libraries(my_project Boost::system Boost::filesystem)
And that's it. To specify a lock file I just do:
HunterGate(
URL "https://github.com/ruslo/hunter/archive/v0.16.15.tar.gz"
SHA1 "6974c2150fc0d3b09de3ad1efcbf15d360647ffa"
)
And I can use multiple lock files if I so wish, which are combined in order as specified (so, just as an example, imgui could have it's own lock files of it's own versions if it didn't want to be listed in the main 'main' hunter dependency repository). If imgui could be built as a bog-standard cmake system then it could be added to such a repository system with trivial ease. There can be many versions of imgui there-of in the dependency system, for different branches, different actual versions, could be broken up into component parts or not, and the user doesn't have to worry about the API ever changing until they actually update HunterGate call's and/or change the version listed, it is very reproducible builds all while keeping third-party code out of your own code repository.
@ocornut, I review changes in vieport branch and can say - it's good :-)
It's okay that my changes can not be applied right now. We live in an era of change and this is normal. I am glad that there is a discussion on an interesting topic for me and that the results can be useful for everyone. In my spare time I will track your changes and adopt my ideas.
I also think that I need to take into account the experience of @tamaskenez.
By the way, about the changes: what about moving the Demo functions in a separate header (for example, imgui_demo.h), because from the implementation is already separated.
Rebase on master and refactoring. Applied some experience from PR #1778.
Dear @ocornut, please review again and merge if possible.
Now possible install ImGui like:
cd examples mkdir build && cd build cmake .. make install
Then copy example directory (for example example_glfw_opengl2) and use it as base for custom project.
Rebase on master. Add more bindings and examples.
Dear @ocornut, please review again and merge if possible.
Now implemented:
Export targets:
- ImGui::Library;
- ImGui::ImplFreeGLUT;
- ImGui::ImplSDL2;
- ImGui::ImplGlfw;
- ImGui::ImplOpenGL2;
- ImGui::ImplVulkan.
Import targets from:
- build directory;
- installed package.
Examples:
- example_null;
- example_freeglut_opengl2
- example_sdl_opengl2;
- example_sdl_vulkan;
- example_glfw_opengl2;
- example_glfw_vulkan.
Sorry I don't know when I can look at this in great details yet, but this looks solid. Thanks! Some quick observations:
-
Would it be possible to merge all the .cmake files into the same CMakeLists list so in examples/ it's all contained in less files? What's the reasoning for having CMakeList + ImGuiConfig.cmake + ImGuiModule.cmake + ImGuiTargets.cmake? How will the user interact with those files?
-
Would it be possible to add a little more comments in the merged CMakeLists, with an emphasis at guiding people who are not expert of cmake who make want to look in there, maybe be able to make some changes if needed later, etc.
-
Which are the
.userfile(s) added in the gitignore file? -
Do you think
ImGui::Librarywould be more suitably renamedImGui::Core? Or is::Librarya common thing in cmake world?
Short ansver for .gitignore changes in #1919.
Ok. I will rename ImGui::Library to ImGui::Core (It's will be like Qt5::Core).
Technically I can implement everything in one file, but it will be difficult to understand. I think several files are good, because every file does its job well.
OK let me inspect all of this later. I may want to also include matching Premake5 files this is what I'm not sure about having many files, but we can wait before deciding on that.
What will be important for me is that the generated .sln/.vcproj look sane and friendly to Windows users.
When will it be possible to see CMakeLists.txt in the project? Thanks.
@ocornut done, please review again.
I have problems with spoken English, I will try to comment more when the changes stop changing.
@irov You can merge this PR and provide feedback, it'll be helpful.
@irov now, please see examples/example_XXX/CMakeLists.txt in changes.
Oops. I forgot install stb_XXX.h headers. It's mandatory for use installed package. Will be fixed.
Rebase on master. Fix bug with stb_XXX.h header files.
Add OpenGL3 binding and examples.
You need build gl3w on your PC to use it via CMake's package register.
I also add PR skaslev/gl3w#59 to add install rules for gl3w project.
The FreeGLUT binding should work with FreeGLUT package installed from latest code in git_master branch.
Rebase on master. Small fix and refactoring.
Hello @ocornut, can you add TODO list for me to merge this PR and any other plan about this PR?
I think with current PR code base we can easy fix the vcpkg's imgui port and provide quick and easy access to ImGui's core and bindings for all vcpkg users.
Hello @ocornut, can you add TODO list for me to merge this PR and any other plan about this PR?
Please be patient. I have to juggle a lots of other things. It’s great that the PR is ready (no need to rebase it every day) for now I have also added a link from the wiki and will promote this when people refer to cmake.
Rebase on master. Add ImGui_3THPARTY option to control auto searching and linking 3-th party dependencies.
This is well done. Looking forward to this.
@podsvirov why is there no top-level CMakeLists.txt? How can I import ImGui in my project with your CMake modules? I see ImGuiModule.cmake in examples folder, but there still should be CMakeLists.txt in the root so that I can just do:
add_directory({imgui_SRC})
... and have targets available.
I fully agree with @OvermindDL1 that having CMake will greatly simplify inclusion of ImGui into almost any project type. Given that ImGui doesn't change frequently, CMake files won't have to change a lot and I'm sure there'll be a lot of people who'll maintain CMake files.
Hello @eliasdaler, thanks for review.
We have no CMakeLists.txt in the root foldef because this is the requirement of @ocornut (the author of the library).
Please use the CMakeLists.txt file from the examples subfolder.
Once download and configure the ImGui project then in your project set ImGui_DIR variable to the build directory and use ImGui package as in any example from this PR.
What's the current state of this PR? @ocornut
@ice1000 I'll merge it when I have time to investigate it and see how it fare with the quality of e.g. visual studio projects output. Sorry I don't have infinite time and energy..
Btw from the comments above
- I agree that 3THPARTY should be 3RDPARTY.
- I suggested "ImGui::Core" as a replacement of "ImGui::Library" but Elias may be right that "ImGui::ImGui" could be better suited, so we are not introducing new terminology which is unused elsewhere.
(I actually like the "Core" terminology, and may decide to put more emphasis on this term on other areas of the documentation. It may help people to understand where to draw the line and facilitate communication "Core" vs "Bindings".)
@ice1000 To clarify, I think the PR is probably good, its just that if I merge something I also likely need to maintain it for a while so I need to be acquainted and confident enough with it to take on this responsibility. I want to see if I can get reasonable Visual Studio projects out of it, as by default cmake output weird, non-VS-standard projects. Otherwise I'll probably want to include Premake files along with Cmake (I personally find Premake much more elegant, but it doesn't have the same sets of features).
Also it is important for me to keep the focus that those projects are meant to compile the Examples application. If as a by-product people can compile an imgui.lib I don't mind but we need people to understand that imgui needs to be compiled with a modified imconfig.h. "Installing" imgui output in a standard location is thus really counterproductive and not recommended and we need to make that clear. dear imgui is meant to be included within the project that uses it.
Only last week I read comments on a forum of someone who was struggling with maths type conversions and it turns out they wasn't aware of the imconfig.h facility. If everyone used an installed imgui they would miss on that.
Thanks @ocornut happy to hear that
Only last week I read comments on a forum of someone who was struggling with maths type conversions and it turns out they wasn't aware of the imconfig.h facility. If everyone used an installed imgui they would miss on that.
What should happen is that cmake should generate any project specific configuration files like that via options.
Rebase on master. Fix option name 3THPARTY -> 3RDPARTY .
Rebase on master.
Add ImGui_MISC option and ImGui::FreeType and ImGui::STL target for features from misc subfolder.
Add example_glfw_opengl2_freetype to test features from imgui_freetype.h.
Hello @eliasdaler, can your check latest changes and try link ImGui::STL to use std::strig with ImGui from imgui_stl.h header file.
I known that your have experience to use STL with ImGui.
@podsvirov, may I suggest changing the SOURCES list to be an automatic imgui*.cpp glob instead of individually listing the files?
In 1.64 i will add imgui_widgets.cpp so it'll be ready for it.
(I'll also link to this thread in the 1.64 release note.)
@ocornut it's possible, but not recommended (see doc for file(GLOB ...) command).
@podsvirov
- STL - looks good
- file(GLOB ...) is better here, because we don't use it as a main build system and we want CMakes to work well even if no one updates them for a long time.
@eliasdaler, thanks for reply.
Okay. Two against one - I'll do it. All files imgui*.cpp in the root directory will be added as SOURCES for the ImGui::Core target.
@ocornut and @eliasdaler, done.
Rebase on master.
Change SOURCES ... to SOURCES_GLOB imgui*.cpp.
Please review against.
CMake 3.12 added a CONFIGURE_DEPENDS flag to file(GLOB... which tell CMake to rerun glob expression to see if output changed and rerun configuration if it does. Please see file(GLOB) documentation.
Since script ended up using glob expression this flag may be added as well (if used CMake version is high enough). What do you think?
@thedmd, thanks for reply - good catch. We can add there flag too. But after merging this PR to support more CMake versions.
@thedmd @podsvirov That link from @thedmd even stated this:
Note We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate. The CONFIGURE_DEPENDS flag may not work reliably on all generators, or if a new generator is added in the future that cannot support it, projects using it will be stuck. Even if CONFIGURE_DEPENDS works reliably, there is still a cost to perform the check on every rebuild.
GLOB's should not be used.
@OvermindDL1 Thanks, I'm aware of that note.
It is a recommendation, not a rule. Glob is a tool, not a forbidden fruit. Current script use glob to locate sources and CONFIGURE_DEPENDS will make it work better.
Decision how to use it belong to the author or this script.
It is a recommendation because of its costs, and using CONFIGURE_DEPENDS does not remove all the costs associated with it.
CONFIGURE_DEPENDS actually adds to the cost, because on every subsequent configuration CMake will execute glob expression again to seek for changes.
Yes, performance it is trade off. There are dozens of files at the best. Taking that under consideration cost should be neglectable.
CONFIGURE_DEPENDS does add to the runtime cost yes, but I was more speaking of it reducing the 'usage' cost (needing to regen the cmake files on file change). But regardless, imgui's files don't change that often, so again, why GLOB at all, that's a needless cost that would be pulled down into countless dependents?
@OvermindDL1 You made a point. If people start to depend on it, it looks like good move to use actually use a list. What do you think@podsvirov?
I originally chose to use the list of files, but in this project there are conventions for which we can use glob expressions. When @ocornut writes 10,000 more lines of code and takes them to a separate file, he will not need to add another line to the ImGuiTargets.cmake file.
Just to chime in my small vote. I've been using GLOB on all my projects for years. It makes things much easier and works just fine.
Using GLOB in an end project is also an entirely different issue compared to using it in a library with many dependents.
As for easier, I'm guessing you have an IDE that regenerates the cmake project for you if you add a new file as just adding a new file and compiling without regenerating the project would fail if using a glob.
I break my projects up into lots of modules/libraries so I don't agree with your statement 'entirely different'.
I have been using this across multiple platforms in our build systems. (Plain ninja, Xcode, etc.)
@OvermindDL1 this CMake is for building examples, not ImGui itself, so people shouldn't depend on it.
The bindings such as ImGui-SFML should make their own CMake which will somehow incorporate ImGui into themself. There, GLOB won't be used.
Let me make some comments.
The side effect of this PR is a real CMake's package named ImGui, that is used to create examples, but can be used anywhere.
The GLOB is used only once during the configuration of the ImGui itself, then only the result files list are used to configure examples or custom projects.
Oh, that's very good to know. But that means that we'd better put top-level CMake in the root (leaving stuff concerning examples in examples/CMakeLists.txt)
@ocornut has previously said that he doesn't want to deal with users who will try to compile just ImGui... but there's a nice solution to that - message an error if ImGui is build as a top-level project! (by comparing CMAKE_SOURCE_DIR with CMAKE_CURRENT_SOURCE_DIR we can tell if ImGui is being compiled as a part of another project or not).
By default, we can do EXCLUDE_FROM_ALL for ImGui target and only have examples compile if the user specifies that he wants to do that.
@eliasdaler I have two things in mind:
1- I strongly want to discourage building/packaging imgui WITHOUT making custom modifications made to imconfig.h.
2- I would prefer not signaling presence of build cruft in the root folder, to strongly signify that it is optional.
As such, as Konstantin pointed out, it's perfectly ok if the CMakefile provide that functionality as long as it has a solution to handle (1) and this is well documented.
message an error if ImGui is build as a top-level project!
I'm not sure I understand this fully but it seems wrong. We don't want to strongly enforce hard constraints. I have strong design view on (1) and somehow (2) and that's one thing but flexibility is more important.
(I have to apologies again if it seems that this PR feels neglected, I do have a large amount of stuff on my plate and current priority is to advance viewport/docking. I'm happy the PR is here and stable. If anything, I would much rather focus on getting satisfying VS-like .sln output from the CMakefile than anything else.).
I strongly want to discourage building/packaging imgui WITHOUT making custom modifications made to imconfig.h.
Why? For example, it's pretty easy to make ImGui-SFML work without any modifications to imconfig.h. Currently, they're used for converting between ImGui's and SFML's color and vector types. I gain nothing by not doing it inside ImGui-SFML by hand instead of relying on user modifying imconfig.h
I would prefer not signaling presence of build cruft in the root folder, to strongly signify that it is optional
I don't really know many people who will see "CMakeLists.txt" as an indicator of CMake build being mandatory. For example, do people see "Makefile" in the root as if it should only be built by "make"?
Having CMakeLists.txt in the root of the repo is a clear indicator that the project supports CMake. Yes, it can be documented in docs somehow. But people are lazy, and searching for it in docs requires more effort than just looking at the source tree of the repo.
If you're absolutely against it, maybe we can have "cmake" folder which will contain top-level CMake file, but I'm not 100% sure it'll be easy to work in if you build ImGui as a part of your project...
We don't want to strongly enforce hard constraints
Okay, we can make it a warning. Or, as I've previously said, don't include "ImGui" target in "all" target, so the user should try really hard to build ImGui without a binding to go with it.
One of the reasons I want to have top-level CMakeLists.txt is that it will alllow me to say "add_subdirectory(imgui)" and be done with it. "add_subdirectory(imgui/examples)" seems really wrong.
Why? For example, it's pretty easy to make ImGui-SFML work without any modifications to imconfig.h.
Using the imconfig facility (in imconfig.h or another named file) is what I was referring to. A naive "precompiled package" the kind of people are tempted to share would break that possibility. Compile your own source + well documented mechanism to inject compile-time configuration is good.
I don't really know many people who will see "CMakeLists.txt" as an indicator of CMake build being mandatory.
To me it is synonymous with "there will likely be trouble" mostly because of past experiences where compiling anything under Windows is problematic. CMake file come from a culture of Un*x users, as a result the Windows experience is usually poor because the project maintainer don't care enough about that side of the fence.
The LACK of build cruft combined with explicit declaration that the files can be compiled in any manner is generally a better indicator that the code will work in many situations. AAA game developers through dealing with complexity are often forced to come up with their own scheme (which is not cmake).
I'm not 100% against moving in the root folder in the future but I would like to combine it with an alternative (premake5 likely) and make sure the Visual Studio output is nice. The problem is that CMake tends to provide a poor experience to Windows and Visual Studio users, and this is what console game developers use the most. I want the Windows programmer to be able to download imgui from github and SUCCEED at building it.
The generated Visual Studio projects tends to feel off and departing strongly from VS standards. I don't know if it is possible with CMake to make nice looking VS files (I know it is possible with premake5 with some effort).
Current experience is:
D:\T-Work\GitHub\imgui\examples\build>cmake ..
-- Building for: Visual Studio 15 2017
CMake Error at CMakeLists.txt:1 (cmake_minimum_required):
CMake 3.11 or higher is required. You are running version 3.8.0-rc4
Go to website, which explicitly request you to first uninstall:

Uninstall

Reinstall. Note it creates 5303 files??! (Premake is 1 file)

Running again
D:\T-Work\GitHub\imgui\examples\build>cmake ..
-- Selecting Windows SDK version 10.0.16299.0 to target Windows 10.0.17134.
-- The CXX compiler identification is MSVC 19.13.26129.0
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.13.26128/bin/Hostx86/x86/cl.exe
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.13.26128/bin/Hostx86/x86/cl.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Skip ImplFreeGLUT library because not all dependencies found
CMake Error at D:/T-Work/Libs/SDL/SDL2/SDL2Config.cmake:1 (include):
include could not find load file:
D:/T-Work/Libs/SDL/SDL2/SDL2Targets.cmake
Call Stack (most recent call first):
ImGuiModule.cmake:89 (find_package)
ImGuiModule.cmake:176 (imgui_library)
ImGuiTargets.cmake:24 (imgui_binding)
CMakeLists.txt:20 (include)
-- Skip ImplSDL2 library because not all dependencies found
-- Skip ImplGlfw library because not all dependencies found
-- Skip ImplOpenGL3 library because not all dependencies found
-- Skip example_freeglut_opengl2 because not all dependencies found
-- Skip example_sdl_opengl2 because not all dependencies found
-- Skip example_sdl_opengl3 because not all dependencies found
-- Skip example_sdl_vulkan because not all dependencies found
-- Skip example_glfw_opengl2 because not all dependencies found
-- Skip example_glfw_opengl2_freetype because not all dependencies found
-- Skip example_glfw_opengl3 because not all dependencies found
-- Skip example_glfw_vulkan because not all dependencies found
-- Configuring incomplete, errors occurred!
See also "D:/T-Work/GitHub/imgui/examples/build/CMakeFiles/CMakeOutput.log".
I now have 11 folders but zero .sln file. I don't know what mechanism it is using to find dependencies:
-- Skip ImplGlfw library because not all dependencies found
-- Skip ImplOpenGL3 library because not all dependencies found
So current experience for me: it doesn't work. I don't have any .sln file to compile even Win32+DX11 or Win32+OpenGL or GLFW+OpenGL. I'm sure it can be fixed/improved and there are step forwards. Much of it lies in the gap between Un*x and Windows users. This sort of project needs to be looked together with someone who can test under Windows and knows cmake well. Maybe @podsvirov can find such person to help?
Until the cmakefile setup can bring an experience that is as robust and working as the existing hard-coded .sln file, we can't make it a prominent thing (e.g. root directory).
To provide a little more indirect feedback, this was my draft of attempting a similar thing with premake. It's old and incomplete but there are some ideas in there:
Building Library (no support for imconfig.h) https://github.com/ocornut/imgui/blob/premake/examples/premake5-lib.lua
Building Examples https://github.com/ocornut/imgui/blob/premake/examples/premake5.lua
It's not finished and has different pros and cons compare to cmake equivalent (and there's barely any real dependency checking/pulling) but a few things of note:
- There's explicit documentation for people who doesn't know premake very well.
- It adds .txt and .natvis file to the vsproj file.
- The output .sln / .vsproj file looks like "standard" visual studio projects
- It can output Makefile, visual studio, xcode projects.
- IMHO it is written in a language anyone can read and debug (tho premake has its own quirks!)
That amount of user-centric polish needs to be done if we want to even consider putting files in the root directory. The BIG problem with premake5 is that even though it is a 1 file download, it is not currently available in common repositories like apt-get and that's an issue :(
I think that CMake is not meant to be used with expectations that it will generate good-looking VS projects. It's a miracle that premake makes nice VS projects, but really, if you want to have good-looking and maintainable VS project, you need to maintain it by hand, not generate it via some tool.
CMake build of a thirdparty lib is a temporary step. Suppose that a user wants to add ImGui-SFML to their project. The only things they need to do is:
- Run cmake (and tell it where ImGui is by specifying IMGUI_ROOT variable)
- Build a project in needed configurations
- Run "cmake build . --target install" which will "install" ImGui-SFML with all needed stuff to a specified folder (note that ImGui-SFML doesn't support it yet, but will do it in the future)
Now the user has a "bin" directory, which contains "ImGui-SFML.dll", "lib" directory which contains "ImGui-SFML.h" and "include" directory with ImGui's/ImGui-SFML's include files. Now, this can be easily added to existing manually maintained Visual Studio project. That's what I mean by CMake being a temporary step.
And there's nothing preventing users from building ImGui easily by providing them a helper in the form of CMake. Right now, there's no easy way to build ImGui. The user has to manually add all the needed files and include directories manually. But CMake can do it for the user automatically, and we can make it highly customizable so if the user wants to add some "imconfig" file to their install, it'll be possible to do it without modifying anything in ImGui's folder.
I think that you're confusing CMake and Makefile's a bit... In my experience, all CMake projects for established libs are buildable on non-*nix platforms, while projects which only support "make" usually only care about Linux, BSD and sometimes VS (by having Makefile.vc6 file or something like that).
On the other hand, I've seen a lot of projects which use CMake which can be easily compiled on Windows, macOS, Linux, BSD, Anroid, iOS and so on. CMake is a step forward due to portability compared to Makefiles. A lot of very successful and very influential projects use CMake. SDL, LLVM, Qt, zlib, libpng, Blender, OpenCV... The list goes on and on. :)
Premake is nice, I agree. But we can support both. If you think that supporting both CMake and Premake is too hard for you, I'm sure we can find people willing to maintain CMake as the ImGui evolves.
As for the dependencies... That's a pain point of C++, yes. In the Linux world, we deal with that by installing "-devel" packages which make CMake work magically. You just install "boost-devel" and now "find_package(Boost)" works in CMake. On Windows, the closest to that is vcpkg which can manage such dependencies and then "inject" them into your build magically (I don't really know how it works)
Now, returning to ImGui. Suppose that the user want to build ImGui's SDL example. They'll either need to build SDL themselves or get SDL's binaries and tell VS/CMake/whatever where to find them. And here comes the CMake magic: it's possible to create a CMake script which will download SDL from Github and build it without user having to do anything. And that's pretty cool, but also pretty complicated. I know enough CMake to make it work, and if there's enough interest, I can start working in that direction.
Even if we maintain VS project ourselves, how does it help us compared to CMake's solution? You either store SDL's binaries in your repo or tell users to build SDL themselves and then change VS project to tell it where to look for SDL. Obviously, not so great.
So, in conclusion:
- CMake enables people to build ImGui and ImGui's bindings more easily
- It also allows creator of ImGui's bindings to add ImGui to their CMake's much easier
- It doesn't affect users which don't want to use CMake
- It can potentially make building examples much easier, which this PR already shows, but this can be even be improved more
- CMake is not the only alternative and won't be forced on people who don't want to use it.
- If CMake build is poorly maintained, it can be later dropped. But I think, there's enough interest in maintaining it.
By the way, I'm not saying that having nice-looking VS project with CMake is not possible, but yes, it'll require a bit more effort. I'll try checking out what can be solved immediately, and I think me and @podsvirov can continually improve CMake build to make VS output better. :)
To me it is synonymous with "there will likely be trouble" mostly because of past experiences where compiling anything under Windows is problematic. CMake file come from a culture of Un*x users, as a result the Windows experience is usually poor because the project maintainer don't care enough about that side of the fence.
Just as a note, this is entirely false. CMake is one of the only build systems that works fantastically on Windows, even the latest Visual Studio's has native support. You can install the GUI software if you want, but cmake itself is built in to so many things now that even windows-users generally don't need to. It is the sole buildsystem builder that does actually work everywhere.
Just as a note, this is entirely false. CMake is one of the only build systems that works fantastically on Windows, even the latest Visual Studio's has native support.
I'm more than happy to believe you and see that happens. I didn't say "cmake itself doesn't work". I said they is/was a cultural phenomenon were effectively the setups created by Linux users are often careless about the needs of Windows/VS users.
As of today when I tried the PR it didn't work for me. That's a pretty straightforward statement. Did I make a mistake with the command-line?
(Mind you I appreciate that dependencies in general are an incredibly messy/complex problem and even more so under Windows. My hard-coded .sln makes no attempt at finding dependencies, which effectively and ironically is more practical and easier to work-around than attempts at finding them if the user doesn't understand how/why it is failing).
You should see me as a useful target audience: I am clueless about cmake, make it work for me and I'll be on your side. My unfinished attempt at creating a Premake5 script gives you on the first few paragraph a few examples of commands that generate working project files. I don't think it is too much too ask.
Hello @ocornut, please try script that I wrote for you vcpkg-bootstrap-imgui.bat:
rem Find various executables
for %%C in (git.exe cmake.exe msbuild.exe) do set %%C=%%~$PATH:C
rem Check git.exe
if "%git.exe%" == "" (
if exist "C:\Program Files (x86)\Git\cmd\git.exe" (
set "git.exe=C:\Program Files (x86)\Git\cmd\git.exe"
) else (
if exist "C:\Program Files\Git\cmd\git.exe" (
set "git.exe=C:\Program Files\Git\cmd\git.exe"
) else (
echo "Please install Git first!"
exit /b 1
)
)
)
rem Check cmake.exe
if "%cmake.exe%" == "" (
if exist "C:\Program Files (x86)\CMake\bin\cmake.exe" (
set "cmake.exe=C:\Program Files (x86)\CMake\bin\cmake.exe"
) else (
if exist "C:\Program Files\Git\CMake\bin\cmake.exe" (
set "cmake.exe=C:\Program Files\CMake\bin\cmake.exe"
) else (
echo "Please install CMake first!"
exit /b 1
)
)
)
rem Check msbuild.exe
if "%msbuild.exe%" == "" (
if exist "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvars32.bat" (
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvars32.bat"
) else (
if exist "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat" (
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat"
)
)
)
rem Find msbuild.exe against
for %%C in (msbuild.exe) do set %%C=%%~$PATH:C
rem Check msbuild.exe against
if "%msbuild.exe%" == "" (
echo "Please install VisualStudio 2017 first!"
exit /b 1
)
if not exist "%~dp0vcpkg-bootstrap-imgui" (
mkdir "%~dp0vcpkg-bootstrap-imgui"
)
cd "%~dp0vcpkg-bootstrap-imgui"
if not exist ".\vcpkg" (
"%git.exe%" clone "https://github.com/Microsoft/vcpkg.git" vcpkg
cd .\vcpkg
call .\bootstrap-vcpkg.bat
call .\vcpkg.exe install sdl2 glfw3 freetype --recurse --triplet x86-windows
)
cd "%~dp0vcpkg-bootstrap-imgui"
if not exist ".\imgui" (
"%git.exe%" clone -b cmake "https://github.com/podsvirov/imgui.git" imgui
)
cd ".\imgui"
if not exist ".\examples\build" (
cd ".\examples"
mkdir ".\build" & cd ".\build"
"%cmake.exe%" -G"Visual Studio 15 2017" -DVCPKG_TARGET_TRIPLET=x86-windows -DCMAKE_TOOLCHAIN_FILE="%~dp0vcpkg-bootstrap-imgui\vcpkg\scripts\buildsystems\vcpkg.cmake" ..
)
cd "%~dp0vcpkg-bootstrap-imgui\imgui\examples\build"
rem Build ImGui examples
"%msbuild.exe%" ALL_BUILD.vcxproj /t:Build /m /nologo /v:m /p:Configuration=Release /p:Platform=Win32
The generated Visual Studio projects tends to feel off and departing strongly from VS standards. I don't know if it is possible with CMake to make nice looking VS files
Could you please elaborate on that, in what aspect are CMake-generated VS files inferior?
Could you please elaborate on that, in what aspect are CMake-generated VS files inferior?
Yeah I'm still curious on this myself, CMake generates absolutely fantastic VS projects nowadays, even more so now that Microsoft has first-class support for CMake projects in the modern Visual Studio anyway.
I’ll have a look next time I try it.
Rebase on master and fix some v1.65 breaking changes.
Rebase on master. Rename target ImGui::STL to ImGui::StdLib (#2035).
Rebase on master.
Rebase on master.
Hello all! I updated Live Preview (see description at the top).
New items that I noted:
- Demo:
Simple LayoutandStyle Editorare now using tabs (#261), - In
About Dear ImGuiwe can viewConfig/Build Information.
Hello @floooh! What you think about this PR? Please, share your mind :-) Please, review if you have a time.
Hi, I'm actually not that fluent in modern cmake (interface etc...) to give a very detailed feedback.
I like that the CMakeLists.txt files are "contained" in the examples directory and not up on the top-level, because I think ImGui as a library shouldn't dictate a specific build system, and this is best signalled by not having any build-system-files in the root directory. For building the examples it may be helpful though.
The 3.11 version requirement seems a bit harsh. On some Linux distros (like Debian) getting a somewhat recent cmake version may require additional fiddling with the package manager.
I'm afraid that's all from my side :)
Ah, maybe a few points how I would expect it to work from a user perspective:
# on Windows (scoop or any other package mgr):
> scoop install cmake
# on Linux some variation of:
> sudo apt-get install cmake
# on Mac (homebrew or any other package mgr):
> brew install cmake
# clone imgui, and build the examples
> git clone https://github.com/ocornut/imgui
> cd imgui/examples
> mkdir build
> cd build
# configure...
> cmake ..
# and build...
> cmake --build .
That should be it... ideally the cmake script would automatically detect the platform, select a suitable set of examples (GL, D3D11, ...) etc... configuration through the cmake configuration-tool should only be necessary when I want more control, like cross-platform-builds for emscripten, or building GL samples on Windows instead of D3D.
I like that the CMakeLists.txt files are "contained" in the examples directory and not up on the top-level, because I think ImGui as a library shouldn't dictate a specific build system, and this is best signalled by not having any build-system-files in the root directory.
Can't agree with that... If you take a look at most of the currently maintained C++ libraries, you'll either find CMakeLists.txt or Makefile there. And it's not like a "dictating" a specific build systems - it's helping users use your library more conveniently by doing something like this:
git clone https://github.com/ocornut/imgui.git
cd imgui
cmake .
cmake --build .
cmake install
Boom, done, now you can add this to your CMake:
find_package(ImGui)
...
target_link_libraries(your_project PRIVATE ImGui::ImGui)
Or if you store ImGui as git submodule (or just a local copy of a repo), you can just do something like:
add_subdirectory(path/to/imgui)
target_link_libraries(your_project PRIVATE ImGui::ImGui)
This doesn't affect ImGui itself in any way, it just gives user the power to use it more simply without having to do a lot of work. I don't see how having CMakeLists.txt in a root is very different from having it in examples/CMakeLists.txt and making people think that they can only build examples with it, not use ImGui in a convenient way in their CMake-based projects.
If @ocornut is very against it, maybe we can make "cmake" or "build" folders and have a strong indication that ImGui can be incorporated into CMake-based projects. It's a de-facto build system for C++ now, so if you want to be nice to your users, you need to help them set up your library without any problems.
Yes! You are right - this is what happens. And we can go further:
# then install
> cmake --build . --target install
And for example for GLFW and OpenGL2 on any platform we have simplest CMakeLists.txt (from examples/example_glfw_opengl2)
cmake_minimum_required(VERSION 3.11)
project(example_glfw_opengl2
LANGUAGES CXX)
find_package(ImGui CONFIG REQUIRED
COMPONENTS ImplGlfw ImplOpenGL2)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME}
PRIVATE ImGui::ImplGlfw ImGui::ImplOpenGL2)
And main.cpp for quick start (from examples/example_glfw_opengl2).
PS: I will try to downgrade CMake version after first merge.
Yeah sure, that's the "cmake approach", but cmake isn't the only build system in the world. For ImGui as a library I think it's best to just copy the ImGui sources directly into a project instead of using ImGui as an "external" dependency.
For building the examples having cmake files around is useful, but for building ImGui as a library that's debatable, since ImGui doesn't need any configuration from the build system anyway.
Another option might be to create a "imgui-cmake" project which includes imgui as a git submodule and adds the cmake build files outside of the imgui project, that's what we did to use ImGui as a fips dependency, and I could do this without needing Omar's approval ;)
This is "old-school" highly non-idiomatic cmake, but you get the idea:
https://github.com/fips-libs/fips-imgui
If it is of any help, here's how I have CMake set up for ImGui in Magnum -- since ImGui is updated very often and people are commonly using various branches / forks of it, it didn't make sense to bundle it in the repository (like bgfx does, for example). Instead, I have a FindImGui.cmake there, doing essentially this:
- first you specify
IMGUI_DIR(during the initial config run, or directly in yourCMakeLists.txtif you bundle imgui source in your app) - CMake then looks in this directory for all the headers and sources and creates two targets:
ImGui::ImGui, which is just anINTERFACEtarget, setting up an include path for the headers. Libraries using ImGui link to thisPUBLICly.ImGui::Sources, which is meant to be linkedPRIVATEly to a single target. This target hasImGui::ImGuias a dependency and exposes the source files throughINTERFACE_SOURCES, meaning any target linking to this will have the source filed compiled.
In addition to the above, there's a special handling for Vcpkg, which is (as far as I know) the only packaging system that provides a built ImGui library. It also includes a CMake config script, so in that case ImGui::ImGui is an alias to the imported target and ImGui::Sources is empty except for having a dependency on ImGui::ImGui. Some more business is there to handle symbol exporting for dynamic libs, but that's a minor thing.
This all works on CMake 3.1 and newer. As @floooh said, having a CMake buildsystem expecting at least 3.11 would be of no use for me, since I have to support LTS Linux distributions and I don't like to force people to manually install updated software unless absolutely needed. Old Debian Jessie has only 3.0 (and not long ago I was requiring only 2.8.12), but recently I pulled the plug for these old versions as the amount of workarounds was starting to get insufferable. CMake 3.1 is quite okay tho.
Agreed, 3.11 is too new and the reason for using 3.11 is very debatable. I think something betwen 3.2-3.8 would be ok.
Worth to take a look here and judge for yourself. People using very old Linux distributions are not very likely to use all convenience that CMake brings and hurting your scripts by trying to support incredibly old CMake versions is not worth it.
For building the examples having cmake files around is useful, but for building ImGui as a library that's debatable, since ImGui doesn't need any configuration from the build system anyway.
It has a list of .cpp files I need to include in my build and I don't like to list them explicitly and they might change from time to time. Plus, it has a number of headers which need to be installed when ImGui is used inside some other lib, right now I need to list these manually too... Not very handy. :(
I think something betwen 3.2-3.8 would be ok.
I went through quite some hell of backporting CMake features, so if you tell me why you need a particular version, I should be able to give you back a way how to do it on an older version :)
It has a list of .cpp files I need to include in my build and I don't like to list them explicitly and they might change from time to time.
Crazy idea: what about having both a CMake-based system for building the examples and the above FindImGui.cmake I described for integrating into other projects (but without requiring the users to build & install something first)?
I went through quite some hell of backporting CMake features, so if you tell me why you need a particular version, I should be able to give you back a way how to do it on an older version :)
@podsvirov, now you have a person to ask stuff :)
Crazy idea: what about having both a CMake-based system for building the examples and the above
FindImGui.cmakeI described for integrating into other projects (but without requiring the users to build & install something first)?
It won't be needed, I think. You will be able to just do add_subdirectory(${IMGUI_DIR}/examples) and have relevant targets available for your without building/installing anything.
For my own projects, 3.10 was reasonable, because it ships with Ubuntu 18.04, and that's what most of my Linux users seem to be running.
Hello to all!
The word library does not mean that something must be compiled and installed before use in a user project.
The main requirement from @ocornut is that the source code be included in the final user project, so that the user can, if necessary, specify additional directives of the preprocessor.
This can be done through the command target_sources that was added to the CMake 3.1 version.
Since this question does not arise the first time, I will try to make the appropriate changes to roll back to the 3.1 version.
Hello,
I use CMake with ImGui on Windows (VS) and Linux (make) and I find it very useful.
My CMakeFile is at project level and I include the ImGui source like so:
# imgui
include_directories("${SSB_3RDPARTY}/imgui/")
include_directories("${SSB_3RDPARTY}/imgui/misc/freetype")
file(
GLOB 3rdPartyImGui
"${SSB_3RDPARTY}/imgui/*.cpp"
"${SSB_3RDPARTY}/imgui/*.h"
"${SSB_3RDPARTY}/imgui/misc/freetype/imgui_freetype.cpp"
"${SSB_3RDPARTY}/imgui/misc/freetype/*.h"
)
source_group(3rdParty\\ImGui FILES ${3rdPartyImGui})
#freetype
include_directories("${SSB_3RDPARTY}/freetype/include")
link_directories("${SSB_3RDPARTY}/freetype/lib/x64")
#IconFontCppHeaders
include_directories("${SSB_3RDPARTY}/IconFontCppHeaders")
I also copy the files I need in that directory and keep the original ImGui git repository in a tmp folder and merge manually if needed.
Do not really feel the need for a CMakeFile at the top directory of ImGui. This is because ImGui is very much integrated with my projects. I suspect that if there's a CMakeFile at the top directory of ImGui I will end up not using it because I will end up editing it anyway.
On the other hand I do like CMakeFile files in the examples, no need to keep updated make and VS projects.
Cheers, Matteo
@meshula I have an experience that long-running (enterprise) projects are usually one LTS version behind (as e.g. cost of upgrading the internal build server would outweigh the gains). 16.04 has 3.5 AFAIK.
@podsvirov not sure if this is exactly your case, but the target_sources() can't be used on IMPORTED targets until 3.11 (source), you need to set the INTERFACE_SOURCES property manually using set_property(). Example is in the FindImGui.cmake file I linked above.
The 3.11 version requirement seems a bit harsh. On some Linux distros (like Debian) getting a somewhat recent cmake version may require additional fiddling with the package manager.
Debian/Ubuntu's repositories are so out of date with cmake, should instead use snap/flatpak/asdf (I use asdf for it since the sandbox'ing of the others can be quite irritating at times for a dev tool).
Instead, I have a FindImGui.cmake there, doing essentially this:
A Find*.cmake module should never be necessary if a library is properly installed via cmake, which created a BlahConfig.cmake file that accuratly defines all locations, files, build flags, etc... etc... A Find*.cmake is a often a sign of something broken or likely to break in the future as they are very hard to get right as libraries tend to be installed very poorly otherwise.
- first you specify
IMGUI_DIR
Like this, this is assuming the installed IMGUI has a root location that contains everything within it. Not all systems install like this.
In addition to the above, there's a special handling for Vcpkg, which is (as far as I know) the only packaging system that provides a built ImGui library.
No, hunter has an imgui package as well, and it doesn't require installing any secondary program or anything or assuming something about the system structure like vcpkg does. Hunter also supports building libraries managed by it in a variety of ways that vcpkg does not support, though many of those features are not taken advantage of for the imgui package due to imgui's simplicity and how irritating it is to update in hunter due to a lack of a proper cmake installer within imgui.
This all works on CMake 3.1 and newer. As @floooh said, having a CMake buildsystem expecting at least 3.11 would be of no use for me, since I have to support LTS Linux distributions and I don't like to force people to manually install updated software unless absolutely needed.
Hunter works down to 2.8 I think, something like that, though it suggest a minimum or 3.1, though sometimes later versions are required if you are building for something like android (3.6 I think?) some embedded system types, etc...
Agreed, 3.11 is too new and the reason for using 3.11 is very debatable. I think something betwen 3.2-3.8 would be ok.
Although I do think 3.11 is too new as a minimum requirement, it is not that new. 3.13 is the current release and 3.14 is in release candidate, about to become the new release and CMake does not update very often at all. Regardless, it is trivial to use an updated cmake via asdf/snap/flatpak/etc... I'd still set the minimum version to probably 3.6 personally due to certain bugfixes in it that I've ran across over time, and 3.6 is pretty ancient by now (3 or 4 years old now I think?).
The word
librarydoes not mean that something must be compiled and installed before use in a user project. The main requirement from @ocornut is that the source code be included in the final user project, so that the user can, if necessary, specify additional directives of the preprocessor.
Doesn't need to be compiled, though installing it is very useful as that just puts it into accessible locations in a specific format that is then defined in the *Config.cmake file. Not compiling it would be... odd however. The preprocessor directives should be defined on a specific install, not per project or it cannot be appropriately reused for identical flags. As an example, with Hunter you define that you have a dependency on a given project (and that project can contain many libraries, executables, whatever), that dependency line also takes options that defines how it is to be used, which can set things like preprocessor defines among others. Hunter then checks its global cache for that project and acquires it if it doesn't have it, then it checks its cache for a built version of that project with the defined options to the dependency command and builds and Installs it into a specific cache directory for those given options, then it exposes it to your project where you can target_link_library or whatever you wish as normal. You can even depend on a project with different options different times if it is so needed (this is one of many things vcpkg failed on last I saw) such as when you are making different output binaries for example.
Manually defining preprocessor directives is error prone though, you can pass in a misspelling and likely not catch it for quite some time, where a, for example, set of only known options can be checked for.
Personally I've used IMGUI just by git submoduling in a specific version of it and just manually defining an IMGUI project in my setup doing all this manually, which is a huge pain...
I suspect that if there's a CMakeFile at the top directory of ImGui I will end up not using it because I will end up editing it anyway.
Why would you need to edit it? By simply doing things like defining certain options the IMGUI CMake project should itself define the entire configuration file regardless. If an option isn't exposed then it is either a bug or not exposed for a Very Good Reason, in which case you could override it by pointing it to a different config template it generates from for example.
not sure if this is exactly your case, but the
target_sources()can't be used onIMPORTEDtargets until 3.11 (source), you need to set theINTERFACE_SOURCESproperty manually usingset_property().
Shouldn't be necessary to link in the sources anyway, that sounds like a pretty big misdesign there.
Rebase on master. Work on CMake 3.1 support. Update example_glfw_opengl2_freetype.
Rebase on master.
Add option ImGui_OPENGL_LOADER. Rename target ImGui::ImplFreeGLUT to ImGui::ImpGLUT. Move example example_freeglut_opengl2 to example_glut_opengl2.
Can we please please get this in? :)
Rebase on master.
Rebase on v1.72b.
Rebase on v1.73.
After msys2/MINGW-packages#5814 will be possible to build example_glut_opengl2 via MSYS2 software distro.