<div dir="ltr">We use standalone builds in Chrome OS to build libc++ for different ISA targets. One reason to do so is to cross-compile libc++ only for the target Chromebooks. <div>We do not want to cross-compile all of clang/llvm as they are not going to be shipped on device.<div><br></div><div>The cmake invocation roughly looks like:</div><div>cmake <monorepo-root>/libcxx -DLLVM_ENABLE_PROJECTS=libcxx -DCMAKE_INSTALL_PREFIX=/path/to/target_root/usr</div><div><br></div><div>Thanks,</div><div>Manoj</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Apr 8, 2020 at 4:12 PM Petr Hosek via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Thanks Shoaib for a great summary. To summarize this as an answer to Louis' questions:</div><div><br></div><div><div>1. What is a "Standalone build"? What does it enable that a normal monorepo build can't?</div><div><br></div><div>This means building any of the runtimes separately, where the runtime's CMakeLists.txt (e.g. path/to/my/llvm-project/libcxx/CMakeLists.txt) is the top-level one. The reason for using this variant is the ability to build individual runtimes without the rest of LLVM (e.g. building only libc++) which is not something that the monorepo build can do.</div><div><br></div><div>2. What is the "Runtimes" build? How does it work, what is it used for, and what does it expect from libc++/libc++abi/libunwind?</div><div><br></div><div>This means building runtimes with the just-built Clang. The reason why this is complicated is because at the point when you run CMake for runtimes (i.e. where path/to/my/llvm-project/llvm/runtimes/CMakeLists.txt is the top-level one), you may not have a fully working toolchain yet.</div><div><br></div><div>For example, in case of Fuchsia, our sysroot contains only libc, so when we're doing the runtimes build, and one of the runtimes tries to use check_cxx_compiler_flag, which behind the scenes tries to compile and link a small C++ binary, that check is going to fail not because the flag isn't supported, but because we don't have libc++ yet (that's what we're trying to build right now). So we need to be really careful and avoid introducing cycles e.g. where libc++ CMake build depends C++ standard library (even if that dependency is not explicit).</div><div><br></div><div>Note that this is going to become significantly easier after we upgrade CMake because 3.6 introduced <a href="https://cmake.org/cmake/help/v3.6/variable/CMAKE_TRY_COMPILE_TARGET_TYPE.html" target="_blank">https://cmake.org/cmake/help/v3.6/variable/CMAKE_TRY_COMPILE_TARGET_TYPE.html</a> which allows building static archives instead of executables when running check_* functions which can help and break these cycles.</div><div><br></div><div>3. Are there other "hidden" ways to build the runtime libraries?</div><div><br></div><div>Not "hidden", but there's the default way which most developers use where you use the same host compiler to build both Clang and your runtimes. I think this mode should go away because it's too fragile: it silently relies on your host compiler and the Clang you just built using the same ABI, which isn't guaranteed (unless you're using a multi-stage build) and I'm surprised we haven't yet seen issues due to this (or maybe we did and people just aren't aware of the problem).</div></div><div><br></div><div><div>(Why do we need HAVE_* flags?)</div><div><br></div><div>It's because in the runtimes build, there's no guarantee about the order in which runtimes are being built, so you cannot use e.g. <font face="monospace">if (TARGET cxxabi_shared)</font> from within libc++ build because you don't have any guarantee whether libc++abi has already been processed. So instead, runtimes build sets these flags for each runtime being built (that is each runtime specified in -DLLVM_ENABLE_RUNTIMES=) and you can at least check whether that runtime is being built at all (e.g. you can check from within libc++ whether libc++abi is also being built as part of the runtimes build).</div></div><div><br></div><div>There's more discussion related to this in <a href="https://reviews.llvm.org/D68833" target="_blank">https://reviews.llvm.org/D68833</a>, once we update CMake to >=3.11 we'll eliminate all HAVE_* variables and replace them with generator expressions which is a much better solution.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Apr 8, 2020 at 1:21 PM Shoaib Meenai <<a href="mailto:smeenai@fb.com" target="_blank">smeenai@fb.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div lang="EN-US">
<div>
<p class="MsoNormal">(CCing Chris and Petr, who’ve done the most work on the runtimes build)<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">At least for me on Linux, using LLVM_ENABLE_PROJECTS is actually the unusual way of building libc++; I use LLVM_ENABLE_RUNTIMES. The reason is, my host compiler is often gcc, but I want to build, test, and ship libc++ with the clang I just
built.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">The runtimes build is when you use LLVM_ENABLE_RUNTIMES. It sets up the build of all runtimes (compiler-rt, libc++, libc++abi, libunwind, etc.) as a CMake ExternalProject which depends on the build of clang and other toolchain tools. In
other words, if I run the following:<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">cmake -DLLVM_ENABLE_PROJECTS=clang -DLLVM_ENABLE_RUNTIMES='libcxx;libcxxabi' path/to/my/llvm-project/llvm<u></u><u></u></p>
<p class="MsoNormal">ninja cxx<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">The build system will automatically build clang and other toolchain tools (e.g. llvm-ar), run the ExternalProject configuration with e.g. CMAKE_C_COMPILER and CMAKE_CXX_COMPILER set to the just-built clang, and then build libc++ with that
configuration (so with the just-built clang). It’s a pretty convenient workflow for my setup. It also takes care of e.g. automatically rebuilding libc++ if you make changes to clang and then run `ninja cxx` again.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">As for why the runtimes build use the “standalone build” setup, it’s because there’s a separate CMake configuration happening for the runtimes in this setup (which is necessary in order to be able to configure them to use the just-built
toolchain), so e.g. clang isn’t available as an in-tree target. See <a href="https://reviews.llvm.org/D62410" target="_blank">
https://reviews.llvm.org/D62410</a> for more details. Your top-level CMakeLists.txt in the runtimes build is llvm/runtimes/CMakeLists.txt and not libcxx/CMakeLists.txt (as it would be in a fully standalone build), but it’s also not llvm/CMakeLists.txt (as it
would be with LLVM_ENABLE_PROJECTS).<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">At the CMake round table at the dev meeting last October, we’d discussed the runtimes builds, and Chris had advanced that there should be two supported ways to build the runtimes:<u></u><u></u></p>
<ol style="margin-top:0in" start="1" type="1">
<li style="margin-left:0in">If you’re building as part of the LLVM build and using LLVM_ENABLE_RUNTIMES<u></u><u></u></li><li style="margin-left:0in">If you’re building fully standalone (as in you’re pointing CMake to libc++’s source directory, so that your top-level CMakeLists is libcxx/CMakeLists.txt)<u></u><u></u></li></ol>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">I agree with that position. In particular, I think LLVM_ENABLE_PROJECTS is definitely the wrong thing to use for compiler-rt, which is strongly tied to your just-built compiler. I think it’s arguably the wrong thing to use for libc++/libc++abi/libunwind
as well, where you either want to use your just-built Clang (which LLVM_ENABLE_RUNTIMES was made for), or a different compiler (in which case you’d do a fully standalone build), but silently using your host compiler for them is probably not what you want.
(The LLVM_ENABLE_PROJECTS workflow for libc++/libc++abi/libunwind probably works out better on macOS, where your host compiler is a recent Clang anyway so the difference between it and a just-built Clang aren’t as marked, but I’ve had issues even on macOS
in the past where using the host compiler via LLVM_ENABLE_PROJECTS gave me weird libc++ test errors, and LLVM_ENABLE_RUNTIMES just worked.)<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">What do you think?<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div style="border-right:none;border-bottom:none;border-left:none;border-top:1pt solid rgb(181,196,223);padding:3pt 0in 0in">
<p class="MsoNormal" style="margin-left:0.5in"><b><span style="font-size:12pt;color:black">From:
</span></b><span style="font-size:12pt;color:black">llvm-dev <<a href="mailto:llvm-dev-bounces@lists.llvm.org" target="_blank">llvm-dev-bounces@lists.llvm.org</a>> on behalf of Louis Dionne via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
<b>Reply-To: </b>Louis Dionne <<a href="mailto:ldionne@apple.com" target="_blank">ldionne@apple.com</a>><br>
<b>Date: </b>Wednesday, April 8, 2020 at 8:46 AM<br>
<b>To: </b>Libc++ Dev <<a href="mailto:libcxx-dev@lists.llvm.org" target="_blank">libcxx-dev@lists.llvm.org</a>><br>
<b>Cc: </b>llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
<b>Subject: </b>[llvm-dev] Clarifying the supported ways to build libc++, libc++abi and libunwind<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in">[Cross-post to llvm-dev to make sure everybody relevant sees this]<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in">Hi,<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in">I'm currently trying to simplify the libc++/libc++abi/libunwind build systems and testing setup. In doing so, I am encountering issues related to "unusual" ways of building them. By unusual, I just mean "not the
usual monorepo build with LLVM_ENABLE_PROJECTS". I would like to pin down what the set of supported use cases for building the runtime libraries are. In particular, the world I would like to live in is one where the only way to build libc++/libc++abi/libunwind
is:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in"><span style="font-family:Monaco"> $ mkdir build</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in"><span style="font-family:Monaco"> $ cd build</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in"><span style="font-family:Monaco"> $ cmake <monorepo-root>/llvm -DLLVM_ENABLE_PROJECTS=libcxx;libcxxabi;libunwind <options></span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in"><span style="font-family:Monaco"> $ ninja -C build install-{cxx,cxxabi,unwind}</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in">The "runtimes" build would be built on top of this -- it would be just a driver for building these libraries using documented options against the just-built Clang. I think it already does so in essence, however
if I'm not mistaken it uses the "Standalone build" and it definitely sets some magic and undocumented CMake variables (like HAVE_LIBCXXABI) that we have to be really careful not to break.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in">So, to better understand what people use today, I have some questions. I know the answer to some of those, but I want to see what others have to say:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in">1. What is a "Standalone build"? What does it enable that a normal monorepo build can't?<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in">2. What is the "Runtimes" build? How does it work, what is it used for, and what does it expect from libc++/libc++abi/libunwind?<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in">3. Are there other "hidden" ways to build the runtime libraries?<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in">Cheers,<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in">Louis<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:0.5in"><u></u> <u></u></p>
</div>
</div>
</div>
</blockquote></div></div>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>