In dogfood parts 1-4,I was able to create a native llvm-project within the <arch>-<vendor>-linux-gnu environment with a clear dependency path:
- build a functional clang++
- build a functional compiler-rt (libclang_rt.builtins.a)
- build native libraries (libc++, libc++abi, libunwind)
- build native compiler-rt
in order to return to step 1 which this time builds a native clang.
Unfortunately this method consumes more resources (time and space) than it needs to, because each build installs to a staging area, sometimes installing over what came before. I do this because clang often looks for its resources relative to its own position. If anyone can show me how to avoid using a staging area (to achieve the same outcome) I would be grateful.
I am currently looking into the fact that:
- I can override the location of headerfiles and isystem files
- I can override the location of libc++
- If I specify the full path of clang then I can use a compiler flag -resource-path to point to the compiler-rt files. Then because this messes up everything else, I need to use the other two
Quite reasonably, I do not have access rights to make the code changes in order to use this technique. If someone could take a look and suggest changes or commit them I would be grateful:
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index dc9901010737..ab825cb9a66c 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -515,28 +515,33 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (IsIAMCU)
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
- else if (HasCRTBeginEndFiles) {
- std::string P;
- if (ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT &&
- !isAndroid) {
- std::string crtbegin = ToolChain.getCompilerRT(Args, "crtbegin",
- ToolChain::FT_Object);
- if (ToolChain.getVFS().exists(crtbegin))
- P = crtbegin;
- }
- if (P.empty()) {
+ else {
+ std::string path;
+ if (isAndroid) {
const char *crtbegin;
if (Args.hasArg(options::OPT_shared))
- crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o";
+ crtbegin = "crtbegin_so.o";
else if (IsStatic)
- crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o";
+ crtbegin = "crtbegin_static.o";
else if (IsPIE || IsStaticPIE)
- crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o";
+ crtbegin = "crtbegin_dynamic.o";
else
- crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o";
- P = ToolChain.GetFilePath(crtbegin);
+ crtbegin = "crtbegin_dynamic.o";
+ path = ToolChain.GetFilePath(crtbegin);
+ } else if (ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_Libgcc) {
+ const char *crtbegin;
+ if (Args.hasArg(options::OPT_shared))
+ crtbegin = "crtbeginS.o";
+ else if (IsStatic)
+ crtbegin = "crtbeginT.o";
+ else if (IsPIE || IsStaticPIE)
+ crtbegin = "crtbeginS.o";
+ else
+ crtbegin = "crtbegin.o";
+ path = ToolChain.GetFilePath(crtbegin);
}
- CmdArgs.push_back(Args.MakeArgString(P));
+ if (!path.empty())
+ CmdArgs.push_back(Args.MakeArgString(path));
}
// Add crtfastmath.o if available and fast math is enabled.
@@ -658,29 +663,32 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
if (!Args.hasArg(options::OPT_nostartfiles) && !IsIAMCU) {
- if (HasCRTBeginEndFiles) {
- std::string P;
- if (ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT &&
- !isAndroid) {
- std::string crtend = ToolChain.getCompilerRT(Args, "crtend",
- ToolChain::FT_Object);
- if (ToolChain.getVFS().exists(crtend))
- P = crtend;
- }
- if (P.empty()) {
- const char *crtend;
- if (Args.hasArg(options::OPT_shared))
- crtend = isAndroid ? "crtend_so.o" : "crtendS.o";
- else if (IsPIE || IsStaticPIE)
- crtend = isAndroid ? "crtend_android.o" : "crtendS.o";
- else
- crtend = isAndroid ? "crtend_android.o" : "crtend.o";
- P = ToolChain.GetFilePath(crtend);
- }
- CmdArgs.push_back(Args.MakeArgString(P));
+ std::string path;
+ if (isAndroid) {
+ const char *crtend;
+ if (Args.hasArg(options::OPT_shared))
+ crtend = "crtend_so.o";
+ else if (IsPIE || IsStaticPIE)
+ crtend = "crtend_android.o";
+ else
+ crtend = "crtend_android.o";
+ path = ToolChain.GetFilePath(crtend);
+ } else if (ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_Libgcc) {
+ const char *crtend;
+ if (Args.hasArg(options::OPT_shared))
+ crtend = "crtendS.o";
+ else if (IsPIE || IsStaticPIE)
+ crtend = "crtendS.o";
+ else
+ crtend = "crtend.o";
+ path = ToolChain.GetFilePath(crtend);
}
- if (!isAndroid)
- CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
+ if (!path.empty())
+ CmdArgs.push_back(Args.MakeArgString(path));
+ }
+
+ if (!isAndroid) {
+ CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
}
}
In the original code, if the crtbegin or crtend file found in getCompilerRT did not exist
then it would attempt to use the ones associated with libgcc which is a bug.
I first modified this code into 3 clear sections, but then realised that neither of these files are neccessary for compiler-rt and to fail a compile because clang cannot find two files that are not required was a bigger bug.
Also in the original code, a variable ‘HasCRTBeginEndFiles’ is used. This variable checks to see if the triple has an environment (presumably GNU) or if the vendor was MipsTechnologies. I presumed that if the environment was not GNU then the code was misplaced in this GNU driver.
diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake
index 8a6219568b3f..f9cff1f44027 100644
--- a/compiler-rt/cmake/base-config-ix.cmake
+++ b/compiler-rt/cmake/base-config-ix.cmake
@@ -32,20 +32,15 @@ set_property(
# Setting these variables from an LLVM build is sufficient that compiler-rt can
# construct the output paths, so it can behave as if it were in-tree here.
-if (LLVM_LIBRARY_OUTPUT_INTDIR AND LLVM_RUNTIME_OUTPUT_INTDIR AND PACKAGE_VERSION)
+if (LLVM_LIBRARY_OUTPUT_INTDIR AND LLVM_RUNTIME_OUTPUT_INTDIR AND CMAKE_C_COMPILER_VERSION)
set(LLVM_TREE_AVAILABLE On)
endif()
if (LLVM_TREE_AVAILABLE)
- # Compute the Clang version from the LLVM version.
- # FIXME: We should be able to reuse CLANG_VERSION variable calculated
- # in Clang cmake files, instead of copying the rules here.
- string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" CLANG_VERSION
- ${PACKAGE_VERSION})
# Setup the paths where compiler-rt runtimes and headers should be stored.
- set(COMPILER_RT_OUTPUT_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION})
+ set(COMPILER_RT_OUTPUT_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CMAKE_C_COMPILER_VERSION})
set(COMPILER_RT_EXEC_OUTPUT_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
- set(COMPILER_RT_INSTALL_PATH lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION})
+ set(COMPILER_RT_INSTALL_PATH lib${LLVM_LIBDIR_SUFFIX}/clang/${CMAKE_C_COMPILER_VERSION})
option(COMPILER_RT_INCLUDE_TESTS "Generate and build compiler-rt unit tests."
${LLVM_INCLUDE_TESTS})
option(COMPILER_RT_ENABLE_WERROR "Fail and stop if warning is triggered"
Here LLVM_TREE_AVAILABLE was failing because the PACKAGE_VERSION flag was unavailable. This caused the compiler-rt files to be stored in the wrong place. I replaced it with the more generally available CMAKE_C_COMPILER_VERSION to fix it.
I thought about replacing the word clang with CMAKE_COMPILER_ID just in case someone tried to use a different compiler but decided it could create problems beyond my understanding.
diff --git a/libcxx/cmake/config-ix.cmake b/libcxx/cmake/config-ix.cmake
index 209e6214a471..8a619b2647c1 100644
--- a/libcxx/cmake/config-ix.cmake
+++ b/libcxx/cmake/config-ix.cmake
@@ -125,5 +125,9 @@ else()
check_library_exists(m ccos "" LIBCXX_HAS_M_LIB)
check_library_exists(rt clock_gettime "" LIBCXX_HAS_RT_LIB)
set(LIBCXX_HAS_SYSTEM_LIB NO)
- check_library_exists(atomic __atomic_fetch_add_8 "" LIBCXX_HAS_ATOMIC_LIB)
+ if (LIBCXX_USE_COMPILER_RT)
+ set(LIBCXX_HAS_ATOMIC_LIB NO)
+ else()
+ check_library_exists(atomic __atomic_fetch_add_8 "" LIBCXX_HAS_ATOMIC_LIB)
+ endif()
endif()
Even if we are asking the to use compiler-rt, the code looks for the GNU Compiler Collection’s libatomic which is probably a bug.
I fixed it by making the check dependent on LIBCXX_USE_COMPILER_RT
I wan’t sure if this fix was also required for Fuchsia a few lines up.