Imgui: Removing dependencies (Windows CRT)

Created on 13 Jun 2017  路  28Comments  路  Source: ocornut/imgui

@ocornut Do you think imgui will ever have a "No dependencies" version (basically without CRT linking)?

dropped

All 28 comments

I personally don't think it is really worth the extra effort of maintenance + impact on readability etc. and the kind of people who are into that are usually also into not touching anything C++ related.

That said, are there any specific function you are caring about?
You may be able to #include <imgui.cpp> from your code with a bunch of custom defines or locally defined symbols as a workaround.

I have nearly re-created everything without the need of CRT, however there are a few errors remaining such as:
"unresolved external symbol _Init_thread_epoch"

After extensive google searching, I could not find what generates that.
@ocornut do you have any idea?

I could go ahead and define that myself, but I have no idea what it does.

Really can't see why you need to remove the whole of the CRT, with modern compilers it can be quite hard. Don't know what the gain would be?

@paulsapps

  • not having to distribute or statically link the runtime and solve issues with it, especially when linking with 3rd party binary only libs
  • compile & link time
  • smaller executable

@nem0 is 100% right.

I've created my entire game without the usage of CRT, which was allot of work, but it works perfectly fine.
Now it's time to add a GUI and I really like ImGui the most.

I'd like to bet if you measure the changes its not worth it, probably saves 500kb of exe size on static link. For dynamic link all modern OS'es have the UCRT already..

3rd party things probably already use CRT, can't see why compile time would change, maybe link time but probably not by much.

  • 500kb can be a lot, in e.g. embedded.
  • UCRT - steam survey - ~50% do not have a "modern OS", in general population it's probably even more. You can't simply send your customer a single exe to run.
  • one 3rd party dll links crt statically, another one dynamically, another has different version of the runtime, ...

Anyway, this is a valid feature, although not valuable for most people.

If anyone can do this, I'd even be willing to pay.

What is CRT?

I think _Init_thread_epoch may be related to static variable initialization. I had another bug report related to a similar thing but with Clang, may investigate.!

@ocornut can you make like a test project for yourself without CRT so you can take a look?
I am very sure this will help a ton of users who want to use imgui.

UCRT is windows 7+ so your 50% stats are wrong FYI.

@paulsapps

The UCRT is now a Windows component, and ships as part of Windows 10

https://msdn.microsoft.com/en-us/library/abx4dbyh.aspx

Sorry being busy at the moment and when i'll get back on imgui I have other priorities, so can't prioritize that now :(

That symbol looks related to static variable initialization so if MSVC generates them it may have an option to not generate them. MS are probably not making your life easier with newer versions of MSVC.

(If you don't find the solution yoursef and want to contract-pay for it it's perhaps possible, tho If you made progress already it may be just a matter of fixing that thing)

@nem0 yes but:

https://support.microsoft.com/en-us/help/2999226/update-for-universal-c-runtime-in-windows

Microsoft Visual Studio 2015 creates a dependency on the Universal CRT when applications are built by using the Windows 10 Software Development Kit (SDK). You can install this update on earlier Windows operating systems to enable these applications to run correctly.

This update applies to the following operating systems:
Windows Server 2012 R2
Windows 8.1
Windows RT 8.1
Windows Server 2012
Windows 8
Windows RT
Windows Server 2008 R2 Service Pack 1 (SP1)
Windows 7 SP1
Windows Server 2008 Service Pack 2 (SP2)
Windows Vista SP2

I.e if the machine is patched (which most likely will be, especially because of wanna cry SMB exploit) it has UCRT.

I.e if the machine is patched (which most likely will be

Yet. in real life I had a problem exactly with this. Thank god my client was benevolent at that time.

ouch, no wonder wanna cry encrypted so many machines

_Init_thread_epoch is for statics:

https://www.unknowncheats.me/forum/c-and-c/158088-thread-epoch.html

Seems the main use case of no CRT is for hacks xD.

To avoid it use compiler option: /Zc:threadSafeInit- to disable "magic statics". This will make init of statics not thread safe though.

Some docs here: https://github.com/Microsoft/cpp-docs/blob/master/docs/build/reference/zc-threadsafeinit-thread-safe-local-static-initialization.md

FYI the similar-but-unrelated-but-similar issue with Clang that someone else discussed with me was:

clang -std=c++11 *.cpp ../../imgui*.cpp ../libs/gl3w/GL/gl3w.cpp -o Test -isystem /usr/include/SDL2 -I"../../" -I"../libs/gl3w" -I"../libs/glfw/include" -I. -lSDL2 -lglfw -lm -lGL -ldl

Errors such as:

In function `ImDrawList::PathArcToFast(ImVec2 const&, float, int, int)': 
ImGuiTest.cpp:(.text+0x1529f): undefined reference to `__cxa_guard_acquire' ImGuiTest.cpp:(.text+0x15302): undefined reference to `__cxa_guard_release' 
ImGuiTest.cpp:(.text+0x153ad): undefined reference to `__cxa_guard_abort' /tmp/ImGuiTest-36f9b3.o: In function `__clang_call_terminate': 
ImGuiTest.cpp:(.text.__clang_call_terminate[__clang_call_terminate]+0x2): undefined reference to `__cxa_begin_catch' 
ImGuiTest.cpp:(.text.__clang_call_terminate[__clang_call_terminate]+0xb): undefined reference to `std::terminate()'
/tmp/ImGuiTest-36f9b3.o:(.eh_frame+0x63): undefined reference to `__gxx_personality_v0' clang: error: linker command failed with exit code 1 (use -v to see invocation)

Code

void ImDrawList::PathArcToFast(const ImVec2& centre, float radius, int amin, int amax)
{
    static ImVec2 circle_vtx[12];
    static bool circle_vtx_builds = false;
    const int circle_vtx_count = IM_ARRAYSIZE(circle_vtx);
    if (!circle_vtx_builds)
    {
        for (int i = 0; i < circle_vtx_count; i++)
        {
            const float a = ((float)i / (float)circle_vtx_count) * 2*IM_PI;
            circle_vtx[i].x = cosf(a);
            circle_vtx[i].y = sinf(a);
        }
        circle_vtx_builds = true;
    }

I haven't looked into that, but I presume that each compiler have some support for thread-friendly usage of static variables within functions, and probably those should be moved.

@paulsapps thanks a bunch! Seems these hackers are useful sometimes.

However now these are left:
https://pastebin.com/BTueEaEa

@ocornut the nice thing about clang is it tells you exactly where the issue is, msvc wants us to sweat.. :(

(I'm thinking ImVector class is causing the first 4 errors)

msvc wants us to sweat.. :(

You want yourself to sweat :) Honestly I think you are just creating your own problems when doing this, but if you are going to do it you'd have an easier time using older versions of Visual Studio?

@ocornut went back as far as VS 2008 and it generates the same errors.

I'm super surprised that those CRT dependencies wouldn't have moved since 2008.

If you solve the thing it would be useful to post a write-up (we could even make it a wiki entry?) for others who might be interested.

Clearly the compiler was designed for those standard libraries, so it looks like few of those left-overs errors are related to explicit functions that imgui uses, more like generic code the compiler would emit for any C++ program. For constructor/destructor we only use placement new/delete which in theory remove dependency on <new> or libc++ so I don't understand what are those references left and how to best tackle/implement them.

For these last ones you need to reimplement exception handling (oh hey you can't) or disable exception handling (your only option really). You also need your own global operator new/delete since they are part of the CRT too. Plus any other part of the CRT your app uses.

Also you need to disable compiler intrinsic functions.. because.. yup they are part of the CRT too. This will probably also make your app way slower. As will reimplementing new/delete with HeapAlloc/HeapFree.

Closing this as we agreed that it won't be actively pursued by imgui to support compiling with zero CRT lib.

If you manage to figure out ways forward feel free to post information as it may be useful to others.

This is a complete guide on how to compile without CRT and keep code fast with intrinsics. Both 32 bit code and x64. I followed the guide successfully for my own project with msvc2017 and everything works just fine without crt now. Guide - How to avoid C/C++ runtime on Windows

I didn't use imgui in this project though, so I don't know if there are any issues specifically related to imgui.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

KaungZawHtet picture KaungZawHtet  路  3Comments

NPatch picture NPatch  路  3Comments

ILoveImgui picture ILoveImgui  路  3Comments

the-lay picture the-lay  路  3Comments

bogdaNNNN1 picture bogdaNNNN1  路  3Comments