[CMake] Support cross-compiling with multi-stage builds
authorPetr Hosek <phosek@chromium.org>
Fri, 16 Nov 2018 04:46:48 +0000 (04:46 +0000)
committerPetr Hosek <phosek@chromium.org>
Fri, 16 Nov 2018 04:46:48 +0000 (04:46 +0000)
When using multi-stage builds, we would like support cross-compilation.
Example is 2-stage build when the first stage is compiled for host while
the second stage is compiled for the target.

Normally, the second stage would be also used for compiling runtimes,
but that's not possible when cross-compiling, so we use the first stage
compiler instead. However, we still want to use the second stage paths.
To do so, we set the -resource-dir of the first stage compiler to point
to the resource directory of the second stage.

We also need compiler tools that support the target architecture. These
tools are not guaranteed to be present on the host, but in case of
multi-stage build, we can build these tools in the first stage.

Differential Revision: https://reviews.llvm.org/D54461

llvm-svn: 347025

clang/CMakeLists.txt
llvm/cmake/modules/LLVMExternalProjectUtils.cmake

index 0a38688..1482b17 100644 (file)
@@ -599,8 +599,8 @@ if (CLANG_ENABLE_BOOTSTRAP)
       if(NOT BOOTSTRAP_LLVM_ENABLE_LLD AND LLVM_BINUTILS_INCDIR)
         add_dependencies(clang-bootstrap-deps LLVMgold)
       endif()
-      set(LTO_AR -DCMAKE_AR=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ar)
-      set(LTO_RANLIB -DCMAKE_RANLIB=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ranlib)
+      set(${CLANG_STAGE}_AR -DCMAKE_AR=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ar)
+      set(${CLANG_STAGE}_RANLIB -DCMAKE_RANLIB=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ranlib)
     endif()
   endif()
 
@@ -666,6 +666,26 @@ if (CLANG_ENABLE_BOOTSTRAP)
     -DCMAKE_ASM_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/${C_COMPILER}
     -DCMAKE_ASM_COMPILER_ID=Clang)
 
+  if(BOOTSTRAP_CMAKE_SYSTEM_NAME)
+    set(${CLANG_STAGE}_CONFIG -DLLVM_CONFIG_PATH=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-config)
+    set(${CLANG_STAGE}_TABLEGEN
+      -DLLVM_TABLEGEN=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-tblgen
+      -DCLANG_TABLEGEN=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang-tblgen)
+    if(BOOTSTRAP_CMAKE_SYSTEM_NAME STREQUAL "Linux")
+      if(BOOTSTRAP_LLVM_ENABLE_LLD)
+        set(${CLANG_STAGE}_LINKER -DCMAKE_LINKER=${LLVM_RUNTIME_OUTPUT_INTDIR}/ld.lld)
+      endif()
+      if(NOT BOOTSTRAP_LLVM_ENABLE_LTO)
+        add_dependencies(clang-bootstrap-deps llvm-ar llvm-ranlib)
+        set(${CLANG_STAGE}_AR -DCMAKE_AR=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ar)
+        set(${CLANG_STAGE}_RANLIB -DCMAKE_RANLIB=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-ranlib)
+      endif()
+      add_dependencies(clang-bootstrap-deps llvm-objcopy llvm-strip)
+      set(${CLANG_STAGE}_OBJCOPY -DCMAKE_OBJCOPY=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-objcopy)
+      set(${CLANG_STAGE}_STRIP -DCMAKE_STRIP=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-strip)
+    endif()
+  endif()
+
   if(BOOTSTRAP_LLVM_BUILD_INSTRUMENTED)
     add_dependencies(clang-bootstrap-deps llvm-profdata)
     set(PGO_OPT -DLLVM_PROFDATA=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-profdata)
@@ -734,7 +754,14 @@ if (CLANG_ENABLE_BOOTSTRAP)
                 ${PASSTHROUGH_VARIABLES}
                  -DCLANG_STAGE=${NEXT_CLANG_STAGE}
                 ${COMPILER_OPTIONS}
-                ${LTO_LIBRARY} ${LTO_AR} ${LTO_RANLIB} ${verbose} ${PGO_OPT}
+                ${${CLANG_STAGE}_CONFIG}
+                ${${CLANG_STAGE}_TABLEGEN}
+                ${LTO_LIBRARY} ${verbose} ${PGO_OPT}
+                ${${CLANG_STAGE}_LINKER}
+                ${${CLANG_STAGE}_AR}
+                ${${CLANG_STAGE}_RANLIB}
+                ${${CLANG_STAGE}_OBJCOPY}
+                ${${CLANG_STAGE}_STRIP}
     INSTALL_COMMAND ""
     STEP_TARGETS configure build
     USES_TERMINAL_CONFIGURE 1
index f736c39..4d26a30 100644 (file)
@@ -162,8 +162,35 @@ function(llvm_ExternalProject_Add name source_dir)
                       -DCMAKE_OBJDUMP=${CMAKE_OBJDUMP}
                       -DCMAKE_STRIP=${CMAKE_STRIP})
     set(llvm_config_path ${LLVM_CONFIG_PATH})
+
+    if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+      string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" CLANG_VERSION
+             ${PACKAGE_VERSION})
+      set(resource_dir "${LLVM_LIBRARY_DIR}/clang/${CLANG_VERSION}")
+      set(flag_types ASM C CXX MODULE_LINKER SHARED_LINKER EXE_LINKER)
+      foreach(type ${flag_types})
+        set(${type}_flag -DCMAKE_${type}_FLAGS=-resource-dir=${resource_dir})
+      endforeach()
+      string(REPLACE ";" "|" flag_string "${flag_types}")
+      foreach(arg ${ARG_CMAKE_ARGS})
+        if(arg MATCHES "^-DCMAKE_(${flag_string})_FLAGS")
+          foreach(type ${flag_types})
+            if(arg MATCHES "^-DCMAKE_${type}_FLAGS")
+              string(REGEX REPLACE "^-DCMAKE_${type}_FLAGS=(.*)$" "\\1" flag_value "${arg}")
+              set(${type}_flag "${${type}_flag} ${flag_value}")
+            endif()
+          endforeach()
+        else()
+          list(APPEND cmake_args ${arg})
+        endif()
+      endforeach()
+      foreach(type ${flag_types})
+        list(APPEND cmake_args ${${type}_flag})
+      endforeach()
+    endif()
   else()
     set(llvm_config_path "$<TARGET_FILE:llvm-config>")
+    set(cmake_args ${ARG_CMAKE_ARGS})
   endif()
 
   ExternalProject_Add(${name}
@@ -187,7 +214,7 @@ function(llvm_ExternalProject_Add name source_dir)
                -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
                -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}
                -DCMAKE_EXPORT_COMPILE_COMMANDS=1
-               ${ARG_CMAKE_ARGS}
+               ${cmake_args}
                ${PASSTHROUGH_VARIABLES}
     INSTALL_COMMAND ""
     STEP_TARGETS configure build