Building with mingw64 on Windows issue

Dear people of clang and llvm,

I’m completely new here. But I have some experience with C++, TDM-GCC, boost
and Qt.

Ok, my desire is to be able to build the LLVM/clang system with mingw64 on
Windows 7, 64bit. I’m currently stuck on an error that the shared library
c++abi cannot be found. Below is shown how I got there.

I wasn’t able to find build guidelines specific for mingw64. But left to my
own devices I believe I made some progress.

I downloaded MinGW-W64 GCC-8.1.0 from here:

There I selected: x86_64-win32-seh for download.

I got llvm and clang plus the llvm libc++ standard library and libc++abi as
suggested on the getting started webpage.

I put the mingw-w64 bin folder in my PATH.
gcc -dumpversion
shown 8.1.0

I already figured out a way to compile the thread_win32.cpp file located in
<llvm_path>/projects/libcxx/src/support/win32. With the following
adjustments (hacks) to CMakeLists.txt files.

In C:\dev\llvm\projects\libcxx\CMakeLists.txt
added section at line 65:
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
  set(LIBCXX_TARGETING_GNU ON)
  message(STATUS "Configuring for GNU")
else()
  set(LIBCXX_TARGETING_GNU OFF)
endif()

Then in C:\dev\llvm\projects\libcxx\lib\CMakeLists.txt
added section at line 132
if (LIBCXX_TARGETING_GNU)
  message( STATUS "GNU Configuration here" )
  add_compile_flags(-D_LIBCPP_HAS_THREAD_API_WIN32 -D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS
-D_WIN32_WINNT=0x0600)
endif()

My cmake command line is:
cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release ^
-DLLVM_PATH=C:\dev\llvm ^
-DLIBCXX_CXX_ABI=libcxxabi ^
-DLIBCXX_CXX_ABI_INCLUDE_PATHS=C:\dev\llvm\projects\libcxxabi\include ^
-S C:\dev\llvm\projects\libcxx -B
T:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\build >
cmake_result.txt 2>&1

cmake_result.txt is attached.

note: T: is some ramdrive disk made with the tool Arsenal-Image-Mounter.

Then:
mingw32-make --directory=T:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\build
-f Makefile cxx > build_result.txt 2>&1

build_result.txt also attached. Line 204 in that file is the error: "cannot
find –lc++abi".

I think somehow in the folder:
T:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\build\lib\abi
the Makefile is not processed.

In the non-abi folder:
T:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\build\lib\CMakeFiles I
can find a full folder cxx_objects.dir. So libc++ is compiled.

I’d love if some expert on the building process could help me out here. I
hope I’ve communicated all the relevant details for this issue.

Best regards,
Maarten Verhage

build_result.txt (22.6 KB)

cmake_result.txt (5.03 KB)

Hi Maarten,

Ok, my desire is to be able to build the LLVM/clang system with mingw64 on
Windows 7, 64bit. I’m currently stuck on an error that the shared library
c++abi cannot be found. Below is shown how I got there.

I wasn’t able to find build guidelines specific for mingw64. But left to my
own devices I believe I made some progress.

FWIW, I regularly compile libcxx/libcxxabi for mingw, mainly with clang as a cross compiler from linux though, but the same build process also mostly works on msys/mingw.

I don't build libcxx/libcxxabi as part of the main llvm build, but I build them standalone outside of this, when I have clang set up as a cross compiler (building them for a number of different architectures). Here's the script I use for building that: https://github.com/mstorsjo/llvm-mingw/blob/master/build-libcxx.sh

I'm told it's supposed to be possible to cross-build the runtime libraries inside of the llvm tree with the newly built clang as cross compiler, but I haven't tried to figure out how to make this work for my setup yet.

I downloaded MinGW-W64 GCC-8.1.0 from here:
MinGW-w64 - for 32 and 64 bit Windows - Browse /Toolchains targetting Win32/Personal Builds/mingw-builds/8.1.0/threads-win32 at SourceForge.net

There I selected: x86_64-win32-seh for download.

I got llvm and clang plus the llvm libc++ standard library and libc++abi as
suggested on the getting started webpage.

I put the mingw-w64 bin folder in my PATH.
gcc -dumpversion
shown 8.1.0

I already figured out a way to compile the thread_win32.cpp file located in
<llvm_path>/projects/libcxx/src/support/win32. With the following
adjustments (hacks) to CMakeLists.txt files.

In C:\dev\llvm\projects\libcxx\CMakeLists.txt
added section at line 65:
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(LIBCXX_TARGETING_GNU ON)
message(STATUS "Configuring for GNU")
else()
set(LIBCXX_TARGETING_GNU OFF)
endif()

Then in C:\dev\llvm\projects\libcxx\lib\CMakeLists.txt
added section at line 132
if (LIBCXX_TARGETING_GNU)
message( STATUS "GNU Configuration here" )
add_compile_flags(-D_LIBCPP_HAS_THREAD_API_WIN32 -D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS
-D_WIN32_WINNT=0x0600)
endif()

Forcing the win32 thread api probably is good; I do the same, to avoid preferring winpthreads if they happen to be available. Is there any case where using winpthreads over the native win32 threads actually would be beneficial though, should we change the priority order there to avoid having to force it here?.

Forcing -D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS isn't ideal if you want to be able to build libcxx as a DLL as well.

Adding -D_WIN32_WINNT=0x0600 sounds sensible to me.

My cmake command line is:
cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release ^
-DLLVM_PATH=C:\dev\llvm ^
-DLIBCXX_CXX_ABI=libcxxabi ^
-DLIBCXX_CXX_ABI_INCLUDE_PATHS=C:\dev\llvm\projects\libcxxabi\include ^
-S C:\dev\llvm\projects\libcxx -B
T:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\build >
cmake_result.txt 2>&1

cmake_result.txt is attached.

note: T: is some ramdrive disk made with the tool Arsenal-Image-Mounter.

Then:
mingw32-make --directory=T:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\build
-f Makefile cxx > build_result.txt 2>&1

build_result.txt also attached. Line 204 in that file is the error: "cannot
find –lc++abi".

I think somehow in the folder:
T:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\build\lib\abi
the Makefile is not processed.

In the non-abi folder:
T:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\build\lib\CMakeFiles I
can find a full folder cxx_objects.dir. So libc++ is compiled.

I’d love if some expert on the building process could help me out here. I
hope I’ve communicated all the relevant details for this issue.

In my builds, there's quite a bit of fiddling between libcxxabi and libcxx to make them find each other, have a look at the script I linked earlier. It's not exactly very clean, but it works for me for now at least.

// Martin

Hi Martin,

Ok, my desire is to be able to build the LLVM/clang system with mingw64
on
Windows 7, 64bit. I’m currently stuck on an error that the shared library
c++abi cannot be found. Below is shown how I got there.

I wasn’t able to find build guidelines specific for mingw64. But left to
my
own devices I believe I made some progress.

FWIW, I regularly compile libcxx/libcxxabi for mingw, mainly with clang as
a cross compiler from linux though, but the same build process also mostly
works on msys/mingw.

I don't build libcxx/libcxxabi as part of the main llvm build, but I build
them standalone outside of this, when I have clang set up as a cross
compiler (building them for a number of different architectures). Here's
the script I use for building that:
https://github.com/mstorsjo/llvm-mingw/blob/master/build-libcxx.sh

I'm told it's supposed to be possible to cross-build the runtime libraries
inside of the llvm tree with the newly built clang as cross compiler, but
I haven't tried to figure out how to make this work for my setup yet.

Thanks for sharing your advice as well as that build script. I’m able to
copy-and-paste the relevant portions to make progress in building llvm/clang
in the windows command prompt.

First I tried to build llvm with clang in the tools folder but with an empty
projects folder. This failed because mingw64 gcc-8.1.0 doesn’t have support
for std::mutex. But libcxx does contain std::mutex so I decided to get
libcxx to build before this. As libcxx needs to link against libcxxabi I
decided to build libcxxabi first.

I realized the hacks I had in the CMakeLists.txt files could be eliminated
by specifying the defines on the command line of the cmake call.

I’m doing a single library at once. So first a cmake call to generate the
Mingw makefile for libcxxabi, then the mingw call to build the Makefile for
libcxxabi.

Ok specifically:
cmake -G "MinGW Makefiles" ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_SYSTEM_NAME=Windows ^
-DLIBCXXABI_ENABLE_SHARED=OFF ^
-DLIBCXXABI_LIBCXX_INCLUDES=..\..\llvm\projects\libcxx\include ^
-DLIBCXXABI_ENABLE_EXCEPTIONS=ON ^
-DCMAKE_CXX_FLAGS="-D_LIBCPP_BUILDING_LIBRARY -U_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS
-D_LIBCPP_HAS_THREAD_API_WIN32" ^
-S..\..\llvm\projects\libcxxabi ^
-BT:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\build\libcxxabi >
libcxxabi_cmake_result.txt 2>&1

I’m getting:
“CMake Warning at cmake/Modules/HandleOutOfTreeLLVM.cmake:57 (message):
  UNSUPPORTED LIBCXXABI CONFIGURATION DETECTED: llvm-config not found and
  LLVM_PATH not defined.

  Reconfigure with -DLLVM_CONFIG_PATH=path/to/llvm-config or
  -DLLVM_PATH=path/to/llvm-source-root.
Call Stack (most recent call first):
  cmake/Modules/HandleOutOfTreeLLVM.cmake:81 (find_llvm_parts)
  cmake/Modules/HandleOutOfTreeLLVM.cmake:140 (configure_out_of_tree_llvm)
  CMakeLists.txt:29 (include)”

Is this something I can tolerate? Your script shows neither of these
defines. So I assume you also have these warnings.

Then:
mingw32-make ^
--directory=T:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\build\libcxxabi
-f Makefile > libcxxabi_build_result.txt 2>&1

A bunch of warnings like:
warning: unknown conversion type character 'L' in format [-Wformat=]

worrisome?

But I do get the libc++abi.a library out of it.

So continuing with libcxx:
cmake -G "MinGW Makefiles" ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_SYSTEM_NAME=Windows ^
-DLIBCXX_HAS_WIN32_THREAD_API=ON ^
-DLIBCXX_ENABLE_SHARED=ON ^
-DLIBCXX_ENABLE_STATIC=OFF ^
-DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=TRUE ^
-DLIBCXX_ENABLE_EXCEPTIONS=ON ^
-DLIBCXX_CXX_ABI=libcxxabi ^
-DLIBCXX_CXX_ABI_INCLUDE_PATHS=..\..\llvm\projects\libcxxabi\include ^
-DLIBCXX_CXX_ABI_LIBRARY_PATH=T:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\build\libcxxabi\lib
^
-DCMAKE_CXX_FLAGS="-D_LIBCPP_BUILDING_LIBRARY -D_WIN32_WINNT=0x0600" ^
-S..\..\llvm\projects\libcxx ^
-BT:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\build\libcxx >
libcxx_cmake_result.txt 2>&1

Get the same warning about llvm-config not found.

Then:
mingw32-make ^
--directory=T:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\build\libcxx
^
-f Makefile > libcxx_build_result.txt 2>&1

The good news is that libc++.dll.a library is build. But right after that:
[ 95%] Linking CXX shared library libc++.dll fails. This is followed by a
couple of errors like:
undefined reference to `__imp___cxa_decrement_exception_refcount'

all following errors are exception related.

however looking in the cxxabi_objects.dir folder of libcxxabi I do see the
file cxa_exception.cpp.obj

Did I missed some crucial define somewhere? You know even when I look at the
official documentation on:
https://libcxx.llvm.org/docs/BuildingLibcxx.html
, it is hard for me to judge whether a define is needed for my goals.

In general my objective with clang is to be able to use the Windows API
functionality that mingw64 provides while having clang as the compiler. I
believe there needs to be a further step to build the mingw provided win32
code with clang is it?

Still any suggestions to make progress building clang are welcome!

Thanks I appreciate.
Maarten

In my builds, there's quite a bit of fiddling between libcxxabi and libcxx
to make them find each other, have a look at the script I linked earlier.
It's not exactly very clean, but it works for me for now at least.

// Martin

Well as for this world citizen (me) your script looks great! :slight_smile:

libcxxabi_build_result.txt (11.8 KB)

libcxxabi_cmake_result.txt (8.49 KB)

libcxx_cmake_result.txt (5.44 KB)

libcxx_build_result.txt (40.2 KB)

Hi Maarten,

Hi Martin,

Ok, my desire is to be able to build the LLVM/clang system with mingw64
on
Windows 7, 64bit.

Btw, if your intent with this is just to have a setup of LLVM/clang with mingw64 headers/libs, you can download the prebuilt toolchains from https://github.com/mstorsjo/llvm-mingw/releases. If the intent is to be able to build it all from scratch yourself, let's keep digging.

I’m currently stuck on an error that the shared library
c++abi cannot be found. Below is shown how I got there.
I wasn’t able to find build guidelines specific for mingw64. But left to
my
own devices I believe I made some progress.

FWIW, I regularly compile libcxx/libcxxabi for mingw, mainly with clang as
a cross compiler from linux though, but the same build process also mostly
works on msys/mingw.

I don't build libcxx/libcxxabi as part of the main llvm build, but I build
them standalone outside of this, when I have clang set up as a cross
compiler (building them for a number of different architectures). Here's
the script I use for building that:
https://github.com/mstorsjo/llvm-mingw/blob/master/build-libcxx.sh

I'm told it's supposed to be possible to cross-build the runtime libraries
inside of the llvm tree with the newly built clang as cross compiler, but
I haven't tried to figure out how to make this work for my setup yet.

Thanks for sharing your advice as well as that build script. I’m able to
copy-and-paste the relevant portions to make progress in building llvm/clang
in the windows command prompt.

First I tried to build llvm with clang in the tools folder but with an empty
projects folder. This failed because mingw64 gcc-8.1.0 doesn’t have support
for std::mutex. But libcxx does contain std::mutex so I decided to get
libcxx to build before this. As libcxx needs to link against libcxxabi I
decided to build libcxxabi first.

Ah, I see.

So in this case, you're intending to amend your mingw64 gcc-8.1.0 with libcxx in order to be able to build LLVM.

I'm not sure if anybody else actually has tested libcxx on windows with gcc. (In practice it probably shouldn't be impossible to fix in case it doesn't work though, I think.)

The common remedy to this would be to use a gcc/libstdc++ setup that uses winpthreads as threading backend for libstdc++.With such a gcc/libstdc++, it's rather straightforward to build llvm+clang. Based on quotes, it looks like you're using an installer from MinGW-w64 - for 32 and 64 bit Windows - Browse /Toolchains targetting Win32/Personal Builds/mingw-builds at SourceForge.net somewhere. If you pick threads-posix instead of threads-win32 you should be all set.

(However, winpthreads has got one rather annoying bug wrt pthread_cond_signal/broadcast which makes lld hang very often if built on top of libstdc++/winpthreads, see MinGW-w64 - for 32 and 64 bit Windows / Bugs / #774 winpthreads can deadlock if pthread_cond_signal is called outside of the mutex lock. It's easy to work around by tweaking lib/Support/Parallel.cpp and lib/Support/ThreadPool.cpp by moving all notify/notify_all calls into the corresponding lock scopes.)

My prebuilt toolchains are cross compiled from linux, with clang/libcxx though.

Also just FWIW, as far as I know, adding libcxx to llvm/projects won't make it automatically be used for building llvm itself. According to my understanding, it just builds libcxx using the same compiler as you build llvm and/or compiles it using the newly built clang as a runtime library for your target environment. But as I don't use that setup myself I'm not familiar with all the possibilities of hooking it all up in one cmake setup.

I realized the hacks I had in the CMakeLists.txt files could be eliminated
by specifying the defines on the command line of the cmake call.

I’m doing a single library at once. So first a cmake call to generate the
Mingw makefile for libcxxabi, then the mingw call to build the Makefile for
libcxxabi.

Ok specifically:
cmake -G "MinGW Makefiles" ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_SYSTEM_NAME=Windows ^
-DLIBCXXABI_ENABLE_SHARED=OFF ^
-DLIBCXXABI_LIBCXX_INCLUDES=..\..\llvm\projects\libcxx\include ^
-DLIBCXXABI_ENABLE_EXCEPTIONS=ON ^
-DCMAKE_CXX_FLAGS="-D_LIBCPP_BUILDING_LIBRARY -U_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS
-D_LIBCPP_HAS_THREAD_API_WIN32" ^
-S..\..\llvm\projects\libcxxabi ^
-BT:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\build\libcxxabi >
libcxxabi_cmake_result.txt 2>&1
I’m getting:
“CMake Warning at cmake/Modules/HandleOutOfTreeLLVM.cmake:57 (message):
UNSUPPORTED LIBCXXABI CONFIGURATION DETECTED: llvm-config not found and
LLVM_PATH not defined.

Reconfigure with -DLLVM_CONFIG_PATH=path/to/llvm-config or
-DLLVM_PATH=path/to/llvm-source-root.
Call Stack (most recent call first):
cmake/Modules/HandleOutOfTreeLLVM.cmake:81 (find_llvm_parts)
cmake/Modules/HandleOutOfTreeLLVM.cmake:140 (configure_out_of_tree_llvm)
CMakeLists.txt:29 (include)”

Is this something I can tolerate? Your script shows neither of these
defines. So I assume you also have these warnings.

Yes, I get these warnings as well.

In my setups, I first build llvm+clang, then use that newly built clang to crosscompile libcxx to my target environment. If I installed everything of llvm I don't get this warning, but if I stripped down the llvm installation to the bare essentials of what I use, I get the warning.

Then:
mingw32-make ^
--directory=T:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\build\libcxxabi
-f Makefile > libcxxabi_build_result.txt 2>&1

A bunch of warnings like:
warning: unknown conversion type character 'L' in format [-Wformat=]

worrisome?

Not sure - I haven't see that; that sounds like a difference caused by building it with gcc instead of clang.

But I do get the libc++abi.a library out of it.

So continuing with libcxx:
cmake -G "MinGW Makefiles" ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_SYSTEM_NAME=Windows ^
-DLIBCXX_HAS_WIN32_THREAD_API=ON ^
-DLIBCXX_ENABLE_SHARED=ON ^
-DLIBCXX_ENABLE_STATIC=OFF ^
-DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=TRUE ^
-DLIBCXX_ENABLE_EXCEPTIONS=ON ^
-DLIBCXX_CXX_ABI=libcxxabi ^
-DLIBCXX_CXX_ABI_INCLUDE_PATHS=..\..\llvm\projects\libcxxabi\include ^
-DLIBCXX_CXX_ABI_LIBRARY_PATH=T:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\build\libcxxabi\lib
^
-DCMAKE_CXX_FLAGS="-D_LIBCPP_BUILDING_LIBRARY -D_WIN32_WINNT=0x0600" ^
-S..\..\llvm\projects\libcxx ^
-BT:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\build\libcxx >
libcxx_cmake_result.txt 2>&1

Get the same warning about llvm-config not found.

Then:
mingw32-make ^
--directory=T:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\build\libcxx
^
-f Makefile > libcxx_build_result.txt 2>&1

The good news is that libc++.dll.a library is build.

I presume you mean libc++.a?

But right after that:
[ 95%] Linking CXX shared library libc++.dll fails. This is followed by a
couple of errors like:
undefined reference to `__imp___cxa_decrement_exception_refcount'

all following errors are exception related.

however looking in the cxxabi_objects.dir folder of libcxxabi I do see the
file cxa_exception.cpp.obj

Did I missed some crucial define somewhere?

Building a shared libcxx+libcxxabi is a pretty seriously hacky endaveour right now, while a static one isn't all that bad.

See https://github.com/mstorsjo/llvm-mingw/commit/957c34372c1ce8765b1184d3ff7160f7642a2de9?w=1 for what I did when I enabled building a shared version of it in my setups some time ago.

I don't build shared+static in one go but I build them separately, since I tweak a bunch of flags differently for both cases.

Since libcxxabi and libcxx have some amount of circular dependencies, I build libcxxabi statically when linking a shared libc++.dll. And to make dllexports work properly, I override the visibility flags, to have libcxx parts included in libcxxabi be built as if we were building libcxx, and enable dllexport in libcxxabi even if building a static library (as it will be be part of the final libc++.dll). And then to top it all off, I link libc++.dll with -Wl,--export-all-symbols. Not very pretty, but it seems to work for me so far.

Unfortunately I can't really give any more specific advice; if you want to dig deeper, my suggestion would be to try building things with my build scripts (works on linux and should mostly work now in msys now as well) and try to look at how the corresponding details ended up being handled there.

You know even when I look at the
official documentation on:
https://libcxx.llvm.org/docs/BuildingLibcxx.html
, it is hard for me to judge whether a define is needed for my goals.

That documentation only covers the case when you build libcxx for use with MSVC (not on top of libcxxabi but on top of the MSVC C++ base runtime functions); if you don't use a premade/pretested setup like mine, expect quite some amount of fiddling.

In general my objective with clang is to be able to use the Windows API
functionality that mingw64 provides while having clang as the compiler. I
believe there needs to be a further step to build the mingw provided win32
code with clang is it?

No, not at all. You can use clang itself just fine standalone on top of an existing mingw/gcc installation just fine in general, using the existing mingw runtime files and import libraries, and linking with GNU binutils ld (modulo minor bugs, like 23872 – MinGW Binaries can be built with misaligned relocation information).

The next step towards a full llvm environment is to replace GNU ld with lld. Up until a few months ago, this required you to rebuild all of the mingw runtime object files (due to an incompatibility wrt constructor invoking) and import libraries with llvm-dlltool (as lld didn't support the GNU import library format), but nowadays lld should work just fine even on top of a normal mingw installation, at least in the cases I've tested.

But if your end target just is to be able to compile with clang, I'd recommend either just downloading my prebuilt toolchains, or install clang within an msys2/mingw64 environment - it should install just fine there and run with the rest of the msys2/mingw64 environment.

// Martin

Hi Martin,

Thanks a lot for your advice. I really appreciate that you specifically
address the situation that I was describing in your post. I don't see that
very often on forums. Sorry for the delay in my reply. I was busy with
another project.

Hi Maarten,

Hi Martin,

Ok, my desire is to be able to build the LLVM/clang system with mingw64
on
Windows 7, 64bit.

Btw, if your intent with this is just to have a setup of LLVM/clang with
mingw64 headers/libs, you can download the prebuilt toolchains from
https://github.com/mstorsjo/llvm-mingw/releases. If the intent is to be
able to build it all from scratch yourself, let's keep digging.

Yes, I would like to go for the digging approach :slight_smile:

I’m currently stuck on an error that the shared library
c++abi cannot be found. Below is shown how I got there.
I wasn’t able to find build guidelines specific for mingw64. But left
to
my
own devices I believe I made some progress.

FWIW, I regularly compile libcxx/libcxxabi for mingw, mainly with clang
as
a cross compiler from linux though, but the same build process also
mostly
works on msys/mingw.

I don't build libcxx/libcxxabi as part of the main llvm build, but I
build
them standalone outside of this, when I have clang set up as a cross
compiler (building them for a number of different architectures). Here's
the script I use for building that:
https://github.com/mstorsjo/llvm-mingw/blob/master/build-libcxx.sh

I'm told it's supposed to be possible to cross-build the runtime
libraries
inside of the llvm tree with the newly built clang as cross compiler,
but
I haven't tried to figure out how to make this work for my setup yet.

Thanks for sharing your advice as well as that build script. I’m able to
copy-and-paste the relevant portions to make progress in building
llvm/clang
in the windows command prompt.

First I tried to build llvm with clang in the tools folder but with an
empty
projects folder. This failed because mingw64 gcc-8.1.0 doesn’t have
support
for std::mutex. But libcxx does contain std::mutex so I decided to get
libcxx to build before this. As libcxx needs to link against libcxxabi I
decided to build libcxxabi first.

Ah, I see.

So in this case, you're intending to amend your mingw64 gcc-8.1.0 with
libcxx in order to be able to build LLVM.

I'm not sure if anybody else actually has tested libcxx on windows with
gcc. (In practice it probably shouldn't be impossible to fix in case it
doesn't work though, I think.)

The common remedy to this would be to use a gcc/libstdc++ setup that uses
winpthreads as threading backend for libstdc++.With such a gcc/libstdc++,
it's rather straightforward to build llvm+clang. Based on quotes, it looks
like you're using an installer from
MinGW-w64 - for 32 and 64 bit Windows - Browse /Toolchains targetting Win32/Personal Builds/mingw-builds at SourceForge.net
somewhere. If you pick threads-posix instead of threads-win32 you should
be all set.

Yes, good idea. Going for x86_64-8.1.0-release-posix-seh-rt_v6-rev0! Also I
did realize I made a mistake in my windows command prompt script. The reason
it wasn't able to find std::mutex was that I didn't specify the include
folders for the gcc includes. The header file mutex certainly is present in
the mingw64 folder tree. It is also present in the win32 threads variant so
I might try that too, when I see the posix variant is building LLVM/clang
correctly.

Currently I'm just going for builing LLVM/clang with an empty projects
folder.

set
gcc_include_path=../../x86_64-8.1.0-release-posix-seh-rt_v6-rev0/mingw64\lib\gcc\x86_64-w64-mingw32\8.1.0\include
cmake -G "MinGW Makefiles" ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_SYSTEM_NAME=Windows ^
-DCMAKE_CXX_FLAGS="-I%gcc_include_path% -I%gcc_include_path%\c++ -D_WIN32_WINNT=0x0600"
^
-S C:\dev\llvm -B T:\x86_64-8.1.0-release-posix-seh-rt_v6-rev0\mingw64\build
> cmake_result.txt 2>&1
pause

Then:
mingw32-make --directory=T:\x86_64-8.1.0-release-posix-seh-rt_v6-rev0\mingw64\build
-f Makefile > build_result.txt 2>&1
pause

It builds a fair bit more. I wasn't sure if previous attempts did make the
folder: T:\x86_64-8.1.0-release-posix-seh-rt_v6-rev0\mingw64\build\NATIVE.
But at least this is what I see now.

But as I'm now stuck at:
No rule to make target 'NATIVE/bin/llvm-tblgen', needed by
'include/llvm/IR/Attributes.inc.tmp'. Stop.

seen on the end of the build_result.txt file. I find it hard to decide what
I could try next. The reason is that I'm missing a bit of a "build
rationale". With that I mean some documentation that explains in general
terms how the building process is designed. In it I hope to learn the reason
for the NATIVE folder, what it contains and what llvm-tblgen.exe is designed
to do. With that understanding I'm able to make an educated guess to try to
set a define that might solve the specific issue I'm facing now with that
"No rule to make target "

Would there be some documentation on that topic on the internet or are you
willing to explain this to me? I'd love to learn.

Best regards,
Maarten Verhage

build_result.txt (66.9 KB)

cmake_result.txt (13 KB)

Hi Maarten,

Yes, good idea. Going for x86_64-8.1.0-release-posix-seh-rt_v6-rev0! Also I
did realize I made a mistake in my windows command prompt script. The reason
it wasn't able to find std::mutex was that I didn't specify the include
folders for the gcc includes. The header file mutex certainly is present in
the mingw64 folder tree. It is also present in the win32 threads variant so
I might try that too, when I see the posix variant is building LLVM/clang
correctly.

That's rather strange. Normally you don't need to manually specify the include directories but they are implicit when you invoke GCC, but they are implicifly found when you invoke the compiler. I'm fairly sure the prebuilt GCC versions from mingw installers work that way.

Currently I'm just going for builing LLVM/clang with an empty projects
folder.

set
gcc_include_path=../../x86_64-8.1.0-release-posix-seh-rt_v6-rev0/mingw64\lib\gcc\x86_64-w64-mingw32\8.1.0\include
cmake -G "MinGW Makefiles" ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_SYSTEM_NAME=Windows ^

I'm not sure if CMAKE_SYSTEM_NAME is necessary, and/or if it does any harm to specify it when it's not needed.

-DCMAKE_CXX_FLAGS="-I%gcc_include_path% -I%gcc_include_path%\c++ -D_WIN32_WINNT=0x0600"
^
-S C:\dev\llvm -B T:\x86_64-8.1.0-release-posix-seh-rt_v6-rev0\mingw64\build
> cmake_result.txt 2>&1
pause

Then:
mingw32-make --directory=T:\x86_64-8.1.0-release-posix-seh-rt_v6-rev0\mingw64\build
-f Makefile > build_result.txt 2>&1
pause

It builds a fair bit more. I wasn't sure if previous attempts did make the
folder: T:\x86_64-8.1.0-release-posix-seh-rt_v6-rev0\mingw64\build\NATIVE.
But at least this is what I see now.

But as I'm now stuck at:
No rule to make target 'NATIVE/bin/llvm-tblgen', needed by
'include/llvm/IR/Attributes.inc.tmp'. Stop.

seen on the end of the build_result.txt file. I find it hard to decide what
I could try next. The reason is that I'm missing a bit of a "build
rationale". With that I mean some documentation that explains in general
terms how the building process is designed. In it I hope to learn the reason
for the NATIVE folder, what it contains and what llvm-tblgen.exe is designed
to do. With that understanding I'm able to make an educated guess to try to
set a define that might solve the specific issue I'm facing now with that
"No rule to make target "

Would there be some documentation on that topic on the internet or are you
willing to explain this to me? I'd love to learn.

If you haven't read Building LLVM with CMake — LLVM 16.0.0git documentation yet, that's recommended. (I don't remmeber if you've mentioned that you've read it or not.)

The NATIVE directory indicates that cmake thinks that you are cross compiling. It might be linked to you specifying CMAKE_SYSTEM_NAME even though it's redundant.

llvm-tblgen is a tool that reads .td files and generates code (.h/.cpp) out of it. So normally when you compile llvm, the build system first compiles llvm-tblgen and a few other tools, then uses llvm-tblgen to generate even more source files to compile. When cross compiling, one first has to build a native version of llvm-tblgen in order to be able to run it during the build on the build machine, even if the llvm build itself is supposed to be for another architecture/os.

(Even further away from your actual topic; CMake is supposed to handle building this automatically when cross compiling, but it doesn't really work for me in the cases where I've cross compiled LLVM, so for those cases I first build the tools in a non-cross llvm build directory, and point the cross build to the existing tools.)

I'm successfully building llvm with mingw/gcc within msys, with a cmake invocation like this:

cmake -G "MSYS Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/foo

If buidling within msys, make sure to pick the mingw-w64-x86_64-cmake package instead of the one for building things that target msys itself.

I haven't tested building outside of msys in a plain cmd with mingw32-make though, but nothing of the errors you've shown so far indicate that as a problem yet.

// Martin

Hi Martin,

Ok, good progress now. Your suggestion to remove the
DCMAKE_SYSTEM_NAME=Windows line did it. Now I don't have that NATIVE folder
and neither that "No rule to make target" error. Thank a lot for that. I
could have spend hours and a lot of frustration until I finally try to
remove that line.

Now it seems to build to the end. about 4GB on the T: drive. A lib folder
full of LLVM and clang libraries.And a bin folder full of executables.

In the process there are some warnings like:
1)
C:\dev\llvm\lib\IR\Core.cpp: In function 'void
LLVMContextSetDiagnosticHandler(LLVMContextRef, LLVMDiagnosticHandler,
void*)':
C:\dev\llvm\lib\IR\Core.cpp:91:18: warning: cast between incompatible
function types from 'LLVMDiagnosticHandler' {aka 'void
(*)(LLVMOpaqueDiagnosticInfo*, void*)'} to
'llvm::DiagnosticHandler::DiagnosticHandlerTy' {aka 'void (*)(const
llvm::DiagnosticInfo&, void*)'} [-Wcast-function-type]
           Handler),

2)
C:/dev/llvm/include/llvm/ADT/StringRef.h:302:37: warning: 'void*
memchr(const void*, int, size_t)' specified size 18446744073709551615
exceeds maximum object size 9223372036854775807 [-Wstringop-overflow=]

3)
C:\dev\llvm\tools\clang\tools\c-index-test\c-index-test.c:1018:62: warning:
unknown conversion type character 'l' in format [-Wformat=]
               printf(" [Template arg %d: kind: %d, intval: %lld]",

For the last one I thought I needed to set CMAKE_C_FLAGS to -std=c99 but
when building again I do get the same warnings on that c file.

I realize building took some time so I set LLVM_TARGETS_TO_BUILD just to X86
and on the mingw32-make invocation to -j4 for the 4 cores I have.

Hi Maarten,

Yes, good idea. Going for x86_64-8.1.0-release-posix-seh-rt_v6-rev0! Also
I
did realize I made a mistake in my windows command prompt script. The
reason
it wasn't able to find std::mutex was that I didn't specify the include
folders for the gcc includes. The header file mutex certainly is present
in
the mingw64 folder tree. It is also present in the win32 threads variant
so
I might try that too, when I see the posix variant is building LLVM/clang
correctly.

That's rather strange. Normally you don't need to manually specify the
include directories but they are implicit when you invoke GCC, but they
are implicifly found when you invoke the compiler. I'm fairly sure the
prebuilt GCC versions from mingw installers work that way.

You're right. I figured the specification of the include folders are
redundant. There is another reason why in the mingw win32 threads variant
there is an issue about utilizing the header mutex. But in the posix variant
it just builds w/o that specification. However I'm a bit curious how cmake
is able to find the header files within the mingw source tree.

As my goal is to have an LLVM/clang toolchain with standard Windows API
threads what would be the next step for me?
Or do I need to do some tests to see if my clang toolchain is stable?

Also I'm not quite sure at which moment I need to have which toolchain bin
folder in my PATH environment variable. My guess is to take the mingw64 bin
folder out of my path, set the bin folder of LLVM there and build libcxxabi
with clang and have D_LIBCPP_BUILDING_LIBRARY and
_LIBCPP_HAS_THREAD_API_WIN32 be set. Should the library be placed in the
build lib folder along with the libclangxxx.a and libLLVMxxx.a files?

Thanks a lot you're really helping me.

Best regards,
Maarten

Hi Martin,

Ok, good progress now. Your suggestion to remove the
DCMAKE_SYSTEM_NAME=Windows line did it. Now I don't have that NATIVE folder
and neither that "No rule to make target" error. Thank a lot for that. I
could have spend hours and a lot of frustration until I finally try to
remove that line.

Now it seems to build to the end. about 4GB on the T: drive. A lib folder
full of LLVM and clang libraries.And a bin folder full of executables.

In the process there are some warnings like:
1)
C:\dev\llvm\lib\IR\Core.cpp: In function 'void
LLVMContextSetDiagnosticHandler(LLVMContextRef, LLVMDiagnosticHandler,
void*)':
C:\dev\llvm\lib\IR\Core.cpp:91:18: warning: cast between incompatible
function types from 'LLVMDiagnosticHandler' {aka 'void
(*)(LLVMOpaqueDiagnosticInfo*, void*)'} to
'llvm::DiagnosticHandler::DiagnosticHandlerTy' {aka 'void (*)(const
llvm::DiagnosticInfo&, void*)'} [-Wcast-function-type]
          Handler),

2)
C:/dev/llvm/include/llvm/ADT/StringRef.h:302:37: warning: 'void*
memchr(const void*, int, size_t)' specified size 18446744073709551615
exceeds maximum object size 9223372036854775807 [-Wstringop-overflow=]

3)
C:\dev\llvm\tools\clang\tools\c-index-test\c-index-test.c:1018:62: warning:
unknown conversion type character 'l' in format [-Wformat=]
              printf(" [Template arg %d: kind: %d, intval: %lld]",

For the last one I thought I needed to set CMAKE_C_FLAGS to -std=c99 but
when building again I do get the same warnings on that c file.

These warnings generally are harmless.

The third one stems from the fact that the common mingw setups target msvcrt.dll, which doesn't support formats like %lld to printf. To get support for that, build with -D__USE_MINGW_ANSI_STDIO=1. But I don't think there should be any cases like that in the core parts of llvm/clang where it really matters though; this file sounds like a very fringe detail.

I realize building took some time so I set LLVM_TARGETS_TO_BUILD just to X86
and on the mingw32-make invocation to -j4 for the 4 cores I have.

Hi Maarten,

Yes, good idea. Going for x86_64-8.1.0-release-posix-seh-rt_v6-rev0! Also
I
did realize I made a mistake in my windows command prompt script. The
reason
it wasn't able to find std::mutex was that I didn't specify the include
folders for the gcc includes. The header file mutex certainly is present
in
the mingw64 folder tree. It is also present in the win32 threads variant
so
I might try that too, when I see the posix variant is building LLVM/clang
correctly.

That's rather strange. Normally you don't need to manually specify the
include directories but they are implicit when you invoke GCC, but they
are implicifly found when you invoke the compiler. I'm fairly sure the
prebuilt GCC versions from mingw installers work that way.

You're right. I figured the specification of the include folders are
redundant. There is another reason why in the mingw win32 threads variant
there is an issue about utilizing the header mutex. But in the posix variant
it just builds w/o that specification. However I'm a bit curious how cmake
is able to find the header files within the mingw source tree.

cmake doesn't manually look for headers, but cmake calls the compiler to detect headers, so as long as the compiler finds them, the build system tests should pass just fine.

As my goal is to have an LLVM/clang toolchain with standard Windows API
threads what would be the next step for me?
Or do I need to do some tests to see if my clang toolchain is stable?

You can run tests if you want to, but that requires a bit more infrastructure (it requires python).

Also I'm not quite sure at which moment I need to have which toolchain bin
folder in my PATH environment variable. My guess is to take the mingw64 bin
folder out of my path, set the bin folder of LLVM there and build libcxxabi
with clang and have D_LIBCPP_BUILDING_LIBRARY and
_LIBCPP_HAS_THREAD_API_WIN32 be set. Should the library be placed in the
build lib folder along with the libclangxxx.a and libLLVMxxx.a files?

What you have so far is the plain compiler, which can work with any mingw sysroot. If you just call this clang instance, it can try to detect a mingw sysroot (by e.g. looking for a matching gcc in your path, and picking the sysroot next to it) and find the one you most probably intended to be used.

Or call it with "clang -target x86_64-w64-mingw32 --sysroot=/path/to/sysroot" in order to avoid heuristics. Add "-v" to any clang invocation in order to get clear indications about what it does and what the heuristics ended up with.

This should work just fine with your existing mingw sysroot, no need to remove gcc from your path or so, as long as you invoke the compiler as "clang" and not "gcc" of course.

If you want to, you can build libcxxabi and libcxx (and libunwind, and compiler_rt, or try to make it work with the existing libgcc from your existing setup), install it on top of the existing sysroot, and call clang with -stdlib=libc++ to make it use that instead of libstdc++.

Now if you need llvm itself to run on top of libc++ instead of libstdc++, then you need to rebuild all of llvm again with this toolchain.

For the exact details on how to build and install libcxxabi/libcxx, have a look at the build-libcxx.sh script in my github repo - it's easier to read it from there than to verbally describe the process.

// Martin