Index: llvm/utils/gn/.gitignore =================================================================== --- llvm/utils/gn/.gitignore +++ llvm/utils/gn/.gitignore @@ -1 +1,2 @@ bin +sysroot Index: llvm/utils/gn/build/BUILD.gn =================================================================== --- llvm/utils/gn/build/BUILD.gn +++ llvm/utils/gn/build/BUILD.gn @@ -11,6 +11,24 @@ # out/gn/bin/llvm-undname ...` # to generate a HTML report for the binaries passed in the last line. llvm_build_instrumented_coverage = false + + # If set, puts relative paths in debug info. + # Makes the build output independent of the build directory, but makes + # most debuggers harder to use. See "Getting to local determinism" and + # "Getting debuggers to work well with locally deterministic builds" in + # http://blog.llvm.org/2019/11/deterministic-builds-with-clang-and-lld.html + # for more information. + use_deterministic_relative_paths_in_debug_info = false + + # If set, uses a sysroot for finding headers. + # To have a deterministic, machine-independent path to the sysroot on + # compile commands, the path for the sysroot is always + # llvm/utils/gn/sysroot/linux/{x64,arm,arm64,...} (linux), + # llvm/utils/gn/sysroot/mac (mac), + # llvm/utils/gn/sysroot/win/sdk/{include,lib} and + # llvm/utils/gn/sysroot/win/msvc/{include,lib} (win). See + # docs/deterministic.md for ways to set up these directories. + use_sysroot = false } assert(!llvm_build_instrumented_coverage || is_clang, @@ -27,7 +45,7 @@ cflags = target_flags ldflags = target_flags + target_ldflags - if (host_os == "mac" && clang_base_path != "") { + if (host_os == "mac" && clang_base_path != "" && !use_sysroot) { cflags += [ "-isysroot", mac_sdk_path, @@ -167,6 +185,85 @@ ] ldflags += [ "-fprofile-instr-generate" ] } + + # Deterministic build setup, see + # http://blog.llvm.org/2019/11/deterministic-builds-with-clang-and-lld.html + if (current_os == "win") { + ldflags += [ "/pdbaltpath:%_PDB%" ] + } + if (is_clang) { + cflags += [ + "-no-canonical-prefixes", + "-Werror=date-time", + ] + if (current_os == "win") { + cflags += [ + "-fmsc-version=1916", + "/X", + ] + } + if (current_os == "win" && use_lld) { + cflags += [ "/Brepro" ] + ldflags += [ + "/Brepro", + "/lldignoreenv", + ] + } + if (use_deterministic_relative_paths_in_debug_info) { + cflags += [ + "-fdebug-compilation-dir", + ".", + ] + } + } + if (use_sysroot) { + if (current_os == "linux") { + sysroot = "//llvm/utils/gn/sysroot/linux" + if (current_cpu == "x64") { + sysroot += "/x64" + } else { + assert(false, "don't know how to use linux sysroot for " + current_cpu) + } + cflags += [ "--sysroot=" + rebase_path(sysroot, root_build_dir) ] + } else if (current_os == "mac") { + cflags += [ + "-isysroot", + rebase_path("//llvm/utils/gn/sysroot/mac", root_build_dir), + ] + } else if (current_os == "win") { + # Headers. + assert(is_clang, "use_sysroot only works with clang-cl on Windows") + sdk_inc = "//llvm/utils/gn/sysroot/win/sdk/include" + cflags += [ + "-imsvc" + + rebase_path("//llvm/utils/gn/sysroot/win/msvc/include", + root_build_dir), + "-imsvc" + rebase_path(sdk_inc + "/shared", root_build_dir), + "-imsvc" + rebase_path(sdk_inc + "/ucrt", root_build_dir), + "-imsvc" + rebase_path(sdk_inc + "/um", root_build_dir), + "-imsvc" + rebase_path(sdk_inc + "/winrt", root_build_dir), + ] + + # Libraries. + sdk_lib = "//llvm/utils/gn/sysroot/win/sdk/lib" + msvc_lib = "//llvm/utils/gn/sysroot/win/msvc/lib" + if (current_cpu == "x64") { + arch = "/x64" + } else { + assert(false, "don't know how to use win sysroot for " + current_cpu) + } + ldflags += [ + "/libpath:" + rebase_path(msvc_lib + arch , root_build_dir), + "/libpath:" + rebase_path(sdk_lib + "/shared" + arch, root_build_dir), + "/libpath:" + rebase_path(sdk_lib + "/ucrt" + arch, root_build_dir), + "/libpath:" + rebase_path(sdk_lib + "/um" + arch, root_build_dir), + # XXX why do i need winrt in include but not in lib? + ] + } else { + # FIXME: android? + assert(false, "don't know how to use sysroot for " + current_os) + } + } } config("no_exceptions") { Index: llvm/utils/gn/build/libs/xml/BUILD.gn =================================================================== --- llvm/utils/gn/build/libs/xml/BUILD.gn +++ llvm/utils/gn/build/libs/xml/BUILD.gn @@ -5,8 +5,10 @@ visibility = [ ":xml" ] libs = [ "xml2" ] if (host_os == "mac") { + # FIXME: sysroot include_dirs = [ "$mac_sdk_path/usr/include/libxml2" ] } else { + # FIXME: sysroot include_dirs = [ "/usr/include/libxml2" ] } } Index: llvm/utils/gn/build/toolchain/BUILD.gn =================================================================== --- llvm/utils/gn/build/toolchain/BUILD.gn +++ llvm/utils/gn/build/toolchain/BUILD.gn @@ -39,7 +39,7 @@ tool("alink") { if (current_os == "mac") { - command = "libtool -static -no_warning_for_no_symbols {{arflags}} -o {{output}} {{inputs}}" + command = "libtool -D -static -no_warning_for_no_symbols {{arflags}} -o {{output}} {{inputs}}" } else { # Remove the output file first so that ar doesn't try to modify the # existing file. Index: llvm/utils/gn/docs/deterministic.md =================================================================== --- /dev/null +++ llvm/utils/gn/docs/deterministic.md @@ -0,0 +1,92 @@ +Deterministic builds with LLVM's GN build +========================================= + +Summary: Use the following args.gn, and create a bunch of symlinks so that +the relative compiler path and the default relative symlink paths work. + + clang_base_path = "../../llvm/utils/gn/toolchain/win" + use_deterministic_relative_paths_in_debug_info = true + use_sysroot = true + +It is possible to produce [universally deterministic][1] builds of LLVM +with the GN build. It requires some configuration though. + +1. Make debug info use relative paths by setting + `use_deterministic_relative_paths_in_debug_info = true` in your `args.gn` + file. With this set, current debuggers need minor configuration to keep + working. See "Getting to local determinism" and "Getting debuggers to work + well with locally deterministic builds" in the [deterministic builds][1] + documentation for details. + +2. Make the build use a sysroot for headers by setting `use_sysroot = true` + in your `args.gn` file. You need to create a symlink to your sysroot + at a fixed location for things to work. + + FIXME: Add scripts to make this less of a drag to set up. + + FIXME: This points to the chromium sysroots as examples for now. + + FIXME: The chromium debian sid sysroot does not contain ICU headers, + which libxml2 depends on by default. + + * Linux: `ln -s .../real/path/to/sysroot llvm/utils/gn/sysroot/linux/x64` + + $ mkdir -p llvm/utils/gn/sysroot/linux + $ ln -s $PWD/../chrome/src/build/linux/debian_sid_amd64-sysroot \ + llvm/utils/gn/sysroot/linux/x64 + + * Mac: `ln -s .../real/path/to/mac/sdk llvm/utils/gn/sysroot/mac`. You could + use `ln -s $(xcrun -show-sdk-path) llvm/utils/gn/sysroot/mac`, but the + idea in using a sysroot is that you don't need to register your sdk of + choice with `xcrun`, so normally it'd just be a local directory + containing a fixed SDK. + + * Windows: + + >mkdir llvm\utils\gn\sysroot\win\sdk\include + + > set P=c:\src\chrome\src\third_party\depot_tools\win_toolchain\vs_files\8f58c55897a3282ed617055775a77ec3db771b88 + + >mklink /j llvm\utils\gn\sysroot\win\sdk\include\ucrt ^ + %P%\win_sdk\Include\10.0.18362.0\ucrt + >mklink /j llvm\utils\gn\sysroot\win\sdk\include\shared ^ + %P%\win_sdk\Include\10.0.18362.0\shared + >mklink /j llvm\utils\gn\sysroot\win\sdk\include\um ^ + %P%\win_sdk\Include\10.0.18362.0\um + >mklink /j llvm\utils\gn\sysroot\win\sdk\include\winrt ^ + %P%\win_sdk\Include\10.0.18362.0\winrt + + >mkdir llvm\utils\gn\sysroot\win\sdk\lib + >mklink /j llvm\utils\gn\sysroot\win\sdk\lib\ucrt ^ + %P%\win_sdk\Lib\10.0.18362.0\ucrt + >mklink /j llvm\utils\gn\sysroot\win\sdk\lib\shared ^ + %P%\win_sdk\Lib\10.0.18362.0\shared + >mklink /j llvm\utils\gn\sysroot\win\sdk\lib\um ^ + %P%\win_sdk\Lib\10.0.18362.0\um + >mklink /j llvm\utils\gn\sysroot\win\sdk\lib\winrt ^ + %P%\win_sdk\Lib\10.0.18362.0\winrt + + >mkdir llvm\utils\gn\sysroot\win\msvc + >mklink /j llvm\utils\gn\sysroot\win\msvc\include ^ + %P%\VC\Tools\MSVC\14.23.28105\include + >mklink /j llvm\utils\gn\sysroot\win\msvc\lib ^ + %P%\VC\Tools\MSVC\14.23.28105\lib + + +3. Use the same host compiler / linker. (FIXME: Bootstrap builds) + Use a relative path for this! Else the path to the host compiler won't + be directory-independent. + Use e.g. `clang_base_path = "../../llvm/utils/gn/toolchain/win"` + + >mklink /j llvm\utils\gn\toolchain\win ^ + "c:\src\chrome\src\third_party\llvm-build\Release+Asserts" + + $ mkdir llvm/utils/gn/toolchain + $ ln -s $PWD/../chrome/src/third_party/llvm-build/Release+Asserts \ + llvm/utils/gn/toolchain/linux + + +4. FIXME: The mac build still uses system ld64, which makes links + system-dependent. + +1: http://blog.llvm.org/2019/11/deterministic-builds-with-clang-and-lld.html Index: llvm/utils/gn/secondary/llvm/lib/DebugInfo/PDB/enable_dia.gni =================================================================== --- llvm/utils/gn/secondary/llvm/lib/DebugInfo/PDB/enable_dia.gni +++ llvm/utils/gn/secondary/llvm/lib/DebugInfo/PDB/enable_dia.gni @@ -2,5 +2,6 @@ # Whether to build code that requires the Microsoft DIA SDK. # If this is set, %INCLUDE% must contain ".../DIA SDK/include" # and %LIB% must contain ".../DIA SKD/lib/amd64". + # XXX use_sysroot llvm_enable_dia_sdk = false }