Hi Tomohiro, On Fri, 23 Jan 2026 12:28:51 +0000 kikairoya via Cygwin <[email protected]> wrote: > > 2026年1月22日 17:20:03 (+09:00) で、Takashi Yano via Cygwin さんが書きました: > > > > > > > If you are planning to provide a package built with compiler-rt, > > > especially > > > one that contains a DLL, I would say, "Please don't do that." It's very > > > different if someone decides to build their own application with > > > compiler-rt > > > and takes responsibility for doing so. Before providing such a package, > > > the > > > implementation of native TLS in cygwin1.dll is needed, as well as an > > > update > > > to the toolchains to use it (and, I guess, it is impossible to switch with > > > keeping ABI). That changes the fundamental design of the distribution. > > > > I attempted to build the entire compiler-rt (builtins) as a shared library, > > similar to the suggestions in: > > https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/builtins/emutls.c#L388-L389 > > , and could successfully solve the problem. > > Could you please try 21.1.4-2 (Test)? > > > > > I’m concerned this makes the situation worse than providing a static library. > I guess > that the upstream has never built it as a shared library. Consequently, that > configuration > appears to be largely untested. > And then, what is the benefit of "specifying -rtlib=compiler-rt makes us > cyggcc_s.dll free but > requires a dependency on cygclang_rt.builtins-21-x86_64.dll" ? Is there > another benefit?
I don't think I could get your point. The benefit of this test version is solving the broken thread local variable reference between dlls and executable, of course. > Furthermore, if you really intend to provide a DLL linked with compiler-rt, > the > DLL comes with limitations that are hard to notice. > (If this is not what you are planning, please feel free to ignore this.) > - Linking the DLL without -rtlib=compiler-rt breaks the EmuTLS functionality > silently. There is > no way to know that the linking needs compiler-rt except inspecting the DLL > with ldd or objdump. Why? If -rtlib=compiler-rt is not specified, the program uses libgcc_s which is a shared library. Therefore, emutls works as expected except for a bug in libstdc++: https://cygwin.com/pipermail/cygwin/2025-November/258943.html > - GCC doesn't support -rtlib=compiler-rt. That effectively enforces the use > of clang. > - A single module (EXE or DLL) can link against only one of the TLS > implementations, either the > one from libgcc_s or the one from compiler-rt. A TLS variable that relies > on the other > implementation would be broken (again, silently). These are not related to the aproach whether compiler-rt provides shared library or not, I think. Even if compiler-rt provides static library, above two problems still exist. > Of course that might not matter if EmuTLS is never used, however, I worry > about the > assumptions that are not enforced or validators automatically would be broken > silently. > > Therefore, my conclusion remains unchanged -- "Please don't do that." I have uploaded compiler-rt 21.1.4-3 (Test), where the shared library is used only for __emutls_get_address(), and programs that do not use emutls will be linked with compiler-rt statically. > Just to note, we're now focusing on compiler-rt because my original attention > is about > EmuTLS, but the same discussion is applicable to libc++. A DLL that exports > C++ interfaces > and linked to libc++ (if such a DLL were to be provided, would it be > cygLLVM-X.dll?) can't be > linked together with another libstdc++-ed C++ library (e.g., boost). No. cygLLVM-x.dll is a part of llvm package. The shared library in libc++ package is cygc++-1.dll. Anyway, I don't understand what is the problem in that case. $ clang++ -stdlib=libc++ -unwindlib=libunwind -rtlib=compiler-rt emutlstest.cc -o emudll.dll -DDLL=1 -shared && clang++ -stdlib=libstdc++ -unwindlib=libunwind -rtlib=compiler-rt emutlstest.cc -o emuexe.exe -DEXE=1 emudll.dll && ./emuexe.exe 1 0xa00000538 0xa00000538 1 0xa000268a8 0xa000268a8 $ clang++ -stdlib=libstdc++ -unwindlib=libunwind -rtlib=compiler-rt emutlstest.cc -o emudll.dll -DDLL=1 -shared && clang++ -stdlib=libc++ -unwindlib=libunwind -rtlib=compiler-rt emutlstest.cc -o emuexe.exe -DEXE=1 emudll.dll && ./emuexe.exe 1 0xa00000538 0xa00000538 1 0xa000109c8 0xa000109c8 $ clang++ -stdlib=libc++ -unwindlib=libgcc -rtlib=libgcc emutlstest.cc -o emudll.dll -DDLL=1 -shared && clang++ -stdlib=libstdc++ -unwindlib=libgcc -rtlib=libgcc emutlstest.cc -o emuexe.exe -DEXE=1 emudll.dll && ./emuexe.exe 1 0xa00000538 0xa00000538 1 0xa000269c8 0xa000269c8 $ clang++ -stdlib=libstdc++ -unwindlib=libgcc -rtlib=libgcc emutlstest.cc -o emudll.dll -DDLL=1 -shared && clang++ -stdlib=libc++ -unwindlib=libgcc -rtlib=libgcc emutlstest.cc -o emuexe.exe -DEXE=1 emudll.dll && ./emuexe.exe 1 0xa00000538 0xa00000538 1 0xa00010ae8 0xa00010ae8 Of course, the cases bellow do not work because executable and DLL call different __emutls_get_address(). $ clang++ -stdlib=libc++ -unwindlib=libunwind -rtlib=compiler-rt emutlstest.cc -o emudll.dll -DDLL=1 -shared && clang++ -stdlib=libc++ -unwindlib=libgcc -rtlib=libgcc emutlstest.cc -o emuexe.exe -DEXE=1 emudll.dll && ./emuexe.exe 0 0xa00000538 0xa00000558 0 0xa00010ba8 0xa00010c58 $ clang++ -stdlib=libc++ -unwindlib=libgcc -rtlib=libgcc emutlstest.cc -o emudll.dll -DDLL=1 -shared && clang++ -stdlib=libc++ -unwindlib=libunwind -rtlib=compiler-rt emutlstest.cc -o emuexe.exe -DEXE=1 emudll.dll && ./emuexe.exe 0 0xa00000538 0xa00000558 0 0xa00010b18 0xa00010c58 Furthermore, the following test case also works. $ cat hello.cc #include <iostream> #ifdef DLL void func() { std::cout << "Hello(dll)" << std::endl; } #endif #ifdef EXE extern void func(); int main() { std::cout << "Hello(main)" << std::endl; func(); return 0; } #endif $ clang++ -stdlib=libc++ -rtlib=compiler-rt -unwindlib=libunwind -DDLL hello.cc -shared -o hello.dll && clang++ -stdlib=libstdc++ -rtlib=libgcc -unwindlib=libgcc -DEXE hello.cc hello.dll -o hello.exe && ./hello.exe Hello(main) Hello(dll) $ clang++ -stdlib=libstdc++ -rtlib=libgcc -unwindlib=libgcc -DDLL hello.cc -shared -o hello.dll && clang++ -stdlib=libc++ -rtlib=compiler-rt -unwindlib=libunwind -DEXE hello.cc hello.dll -o hello.exe && ./hello.exe Hello(main) Hello(dll) -- Takashi Yano <[email protected]> -- Problem reports: https://cygwin.com/problems.html FAQ: https://cygwin.com/faq/ Documentation: https://cygwin.com/docs.html Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple

