serene/nix/llvm.nix

361 lines
14 KiB
Nix

# Serene Programming Language
#
# Copyright (c) 2019-2023 Sameer Rahmani <lxsameer@gnu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
{ lib,
stdenv,
llvm_source,
utils,
cmake,
ninja,
libxml2,
python3,
fetchgit,
fetchurl,
# llvm_libcxx,
# llvm_compiler-rt,
# llvm_libcxxabi,
# llvm_libunwind,
zlib,
wrapCCWith,
runCommand,
overrideCC,
ccache ? null,
useCcache ? false,
url ? "https://github.com/llvm/llvm-project.git",
hash ? "sha256-8MEDLLhocshmxoEBRSKlJ/GzJ8nfuzQ8qn0X/vLA+ag=",
version ? "17.0.6",
ref ? "refs/tags/llvmorg-${version}"
}:
let
useLLVM = true;
ncpus = "32"; #builtins.getEnv "NIX_BUILD_CORES";
major = llvm_source.major;
target = stdenv.targetPlatform.config;
# We're going to build "include-what-you-use" with our llvm build
iwyu = stdenv.mkDerivation rec {
pname = "include-what-you-use";
version = "0.21";
src = builtins.fetchTarball {
url = "https://${pname}.org/downloads/${pname}-${version}.src.tar.gz";
sha256 = "14z2r95wbrqpany565zbp3apij54b28mjk4s83hkgsh31ym0zpnw";
};
# phases = [ "unpackPhase" "installPhase" ];
# installPhase = ''
# mkdir -p $out
# cp -rv $src $out
# '';
};
vanilla = stdenv.mkDerivation (final: rec{
inherit (llvm_source) version;
pname = "serene_llvm";
NIX_CFLAGS_COMPILE = [ "-v" ];
NIX_CXXFLAGS_COMPILE = [ "-v" ];
src = runCommand "${pname}-src-${version}" {} ''
mkdir -p "$out"
cp -r ${llvm_source}/cmake "$out"
cp -r ${llvm_source}/libcxxabi "$out"
cp -r ${llvm_source}/libcxx "$out/libcxx"
cp -r ${llvm_source}/llvm "$out"
cp -r ${llvm_source}/lld "$out"
cp -r ${llvm_source}/clang-tools-extra "$out"
cp -r ${llvm_source}/clang "$out"
cp -r ${llvm_source}/compiler-rt "$out"
cp -r ${llvm_source}/mlir "$out"
cp -r ${llvm_source}/bolt "$out"
cp -r ${llvm_source}/libunwind "$out"
cp -r ${llvm_source}/third-party "$out"
cp -r ${llvm_source}/utils "$out"
cp -r ${llvm_source}/runtimes "$out"
'';
sourceRoot = "${src.name}/llvm";
nativeBuildInputs = [ cmake ninja python3 zlib ];
buildInputs = [ libxml2 zlib ];
#NIX_CFLAGS_COMPILE = ["-fno-rtti"];
#ninjaFlags = [ "-v" ];
cmakeFlags' = [
# "-DLLVM_PARALLEL_COMPILE_JOBS=${ncpus}"
# "-DLLVM_PARALLEL_LINK_JOBS=1"
"-DLLVM_BUILD_EXAMPLES=ON"
"-DLLVM_TARGETS_TO_BUILD='X86'"
"-DCMAKE_BUILD_TYPE=Release"
"-DLLVM_ENABLE_ASSERTIONS=ON"
"-DLLVM_CCACHE_BUILD=OFF"
"-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
"-DLLVM_EXTERNAL_PROJECTS=iwyu"
"-DLLVM_EXTERNAL_IWYU_SOURCE_DIR=${iwyu.src}"
# No lldb? Yes, lldb links against liblldb.so and since we use
# -static with our executables that wouldn't be easy to handle
# and I'm lazy. We can just compile the lldb or any other debugger
# on the host
"-DLLVM_ENABLE_PROJECTS='clang;lld;mlir;clang-tools-extra'"
"-DLLVM_RUNTIME_TARGETS=${stdenv.hostPlatform.config}"
"-DLLVM_ENABLE_RUNTIMES='compiler-rt;libcxx;libcxxabi;libunwind'"
"-DLLVM_HOST_TRIPLE=${stdenv.hostPlatform.config}"
"-DLLVM_RUNTIME_TARGET=${stdenv.hostPlatform.config}"
"-DLLVM_BUILTIN_TARGETS=${stdenv.hostPlatform.config}"
# Serene uses static libs, so no shared lib
"-DLLVM_ENABLE_PIC=OFF"
"-DLLVM_BUILD_STATIC=OFF"
"-DLLVM_LINK_LLVM_DYLIB=off"
"-DLLVM_ENABLE_LIBXML2=OFF"
"-DLLVM_BUILD_DOCS=OFF"
"-DLLVM_ENABLE_SPHINX=OFF"
"-DSPHINX_OUTPUT_MAN=OFF"
"-DSPHINX_OUTPUT_HTML=OFF"
"-DCMAKE_POSITION_INDEPENDENT_CODE=ON"
"-DCLANG_DEFAULT_CXX_STDLIB=libc++"
#"-DCLANG_DEFAULT_LINKER=lld"
"-DCLANG_DEFAULT_OBJCOPY=llvm-objcopy"
"-DCLANG_DEFAULT_RTLIB=compiler-rt"
"-DCLANG_VENDOR_UTI=serene.toolchain"
"-DLLVM_ENABLE_LIBCXX=ON"
"-DLLVM_ENABLE_NEW_PASS_MANAGER=ON"
"-DLLVM_BUILD_TESTS=OFF"
"-DLLVM_ENABLE_ASSERTIONS=ON"
"-DLLVM_ENABLE_LIBXML2=OFF"
"-DLLVM_ENABLE_TERMINFO=OFF"
#"-DLLVM_ENABLE_ZLIB=FORCE_ON"
"-DLLVM_INCLUDE_BENCHMARKS=OFF"
"-DLLVM_INCLUDE_EXAMPLES=OFF"
"-DLLVM_INCLUDE_TESTS=OFF"
"-DLLVM_INCLUDE_GO_TESTS=OFF"
"-DLLVM_ENABLE_BINDINGS=OFF"
#"-DLLVM_TARGETS_TO_BUILD": "X86;AArch64;AMDGPU;ARM;RISCV;WebAssembly"
"-DLLVM_STATIC_LINK_CXX_STDLIB=OFF"
"-DPACKAGE_VENDOR=Serene"
"-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON"
"-DENABLE_X86_RELAX_RELOCATIONS=ON"
"-DBUILD_SHARED_LIBS=OFF"
"-DLIBUNWIND_ENABLE_SHARED=OFF"
"-DLIBUNWIND_ENABLE_STATIC=ON"
"-DCLANG_ENABLE_BOOTSTRAP=ON"
"-DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=ON"
"-DLIBCXXABI_ENABLE_SHARED=OFF"
"-DLIBCXX_ABI_VERSION=2"
"-DLLVM_HAVE_LIBXAR=0"
"-DLIBCLANG_BUILD_STATIC=ON"
"-DCOMPILER_RT_BUILD_BUILTINS=ON"
"-DCOMPILER_RT_USE_LIBCXX=ON"
"-DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY"
"-DLIBCLANG_BUILD_STATIC=ON"
"-DCMAKE_INSTALL_PREFIX=${placeholder "out"}"
"-DCOMPILER_RT_ENABLE_STATIC_UNWINDER=ON"
"-DSANITIZER_USE_STATIC_LLVM_UNWINDER=ON"
"-DSANITIZER_USE_STATIC_CXX_ABI=ON"
] ++ lib.optional (stdenv.hostPlatform.isMusl) [
"-DDLIBCXX_HAS_MUSL_LIBC=ON"
# ] ++ lib.optional (stdenv.hostPlatform.isStatic) [
# "-DLIBCLANG_BUILD_STATIC=ON"
] ++ lib.optional (useCcache) [
"-DLLVM_CCACHE_BUILD=ON"
];
builtinFlags = [
"-DBUILTINS_${target}_CMAKE_C_COMPILER_TARGET=${target}"
"-DBUILTINS_${target}_CMAKE_CXX_COMPILER_TARGET=${target}"
"-DBUILTINS_${target}_CMAKE_ASM_COMPILER_TARGET=${target}"
"-DBUILTINS_${target}_CMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY"
# "CMAKE_EXE_LINKER_FLAGS=--target=${target} {self.buildenv.get('LDFLAGS', '')}"
# "CMAKE_SHARED_LINKER_FLAGS=--target=${target} {self.buildenv.get('LDFLAGS', '')}"
"-DBUILTINS_${target}_CMAKE_INSTALL_RPATH=\$ORIGIN/../lib"
"-DBUILTINS_${target}_CMAKE_BUILD_WITH_INSTALL_RPATH=ON"
"-DBUILTINS_${target}_COMPILER_RT_BAREMETAL_BUILD=ON"
"-DBUILTINS_${target}_COMPILER_RT_DEFAULT_TARGET_ONLY=ON"
"-DBUILTINS_${target}_LIBUNWIND_ENABLE_SHARED=OFF"
"-DBUILTINS_${target}_LIBUNWIND_ENABLE_STATIC=ON"
"-DBUILTINS_${target}_LIBCXXABI_ENABLE_SHARED=OFF"
"-DBUILTINS_${target}_LIBCXX_ENABLE_SHARED=OFF"
"-DBUILTINS_${target}_COMPILER_RT_ENABLE_STATIC_UNWINDER=ON"
"-DBUILTINS_${target}_SANITIZER_USE_STATIC_LLVM_UNWINDER=ON"
"-DBUILTINS_${target}_SANITIZER_USE_STATIC_CXX_ABI=ON"
] ++ lib.optional (useLLVM) [
#"-DBUILTINS_${target}_LLVM_USE_LINKER=lld"
] ++ lib.optional (useCcache) [
"-DBUILTINS_${target}_LLVM_CCACHE_BUILD=ON"
];
runtimeFlags = [
"-DRUNTIMES_${target}_CMAKE_C_COMPILER_TARGET=${target}"
"-DRUNTIMES_${target}_CMAKE_CXX_COMPILER_TARGET=${target}"
"-DRUNTIMES_${target}_CMAKE_ASM_COMPILER_TARGET=${target}"
"-DRUNTIMES_${target}_CMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY"
"-DRUNTIMES_${target}_CMAKE_INSTALL_RPATH=\$ORIGIN/../lib"
"-DRUNTIMES_${target}_CMAKE_BUILD_WITH_INSTALL_RPATH=ON"
"-DRUNTIMES_${target}_CMAKE_POSITION_INDEPENDENT_CODE=ON"
"-DRUNTIMES_${target}_LLVM_USE_LTO=ON"
# Make sure we use libc++ from the tree instead from the system.
"-DRUNTIMES_${target}_LIBCXX_ENABLE_SHARED=OFF"
"-DRUNTIMES_${target}_SANITIZER_CXX_ABI=libc++"
"-DRUNTIMES_${target}_SANITIZER_CXX_ABI_INTREE=ON"
"-DRUNTIMES_${target}_LIBCXX_CXX_ABI=libcxxabi"
"-DRUNTIMES_${target}_LIBCXX_USE_COMPILER_RT=ON"
"-DRUNTIMES_${target}_LIBCXX_ENABLE_STATIC_ABI_LIBRARY=ON"
"-DRUNTIMES_${target}_LIBCXX_ABI_UNSTABLE=ON"
"-DRUNTIMES_${target}_LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY=OFF"
"-DRUNTIMES_${target}_LIBCXX_STATICALLY_LINK_ABI_IN_STATIC_LIBRARY=ON"
"-DRUNTIMES_${target}_LIBCXX_ABI_VERSION=2"
"-DRUNTIMES_${target}_LIBCXXABI_ENABLE_THREADS=ON"
"-DRUNTIMES_${target}_LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL=OFF"
"-DRUNTIMES_${target}_LIBCXXABI_USE_COMPILER_RT=ON"
"-DRUNTIMES_${target}_LIBCXXABI_USE_LLVM_UNWINDER=ON"
"-DRUNTIMES_${target}_LIBCXXABI_ENABLE_STATIC_UNWINDER=ON"
"-DRUNTIMES_${target}_LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_SHARED_LIBRARY=OFF"
"-DRUNTIMES_${target}_LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY=ON"
"-DRUNTIMES_${target}_LIBCXXABI_ENABLE_SHARED=OFF"
"-DRUNTIMES_${target}_LIBUNWIND_USE_COMPILER_RT=ON"
] ++ (lib.optional (useLLVM) [
#"-DRUNTIMES_${target}_LLVM_USE_LINKER=lld"
]) ++ lib.optional (useCcache) [
"-DRUNTIMES_${target}_LLVM_CCACHE_BUILD=ON"
] ++ (lib.optional (stdenv.hostPlatform.isMusl) [
# TODO: Check for more sanitizers that work with musl
"-DRUNTIMES_${target}_COMPILER_RT_SANITIZERS_TO_BUILD='asan;msan;tsan'"
"-DRUNTIMES_${target}_COMPILER_RT_USE_BUILTINS_LIBRARY=ON"
"-DRUNTIMES_${target}_COMPILER_RT_USE_LIBCXX=ON"
"-DRUNTIMES_${target}_COMPILER_RT_BUILD_SANITIZERS=ON"
# musl doesn't have -latomic
"-DRUNTIMES_${target}_LIBCXX_HAS_ATOMIC_LIB=OFF"
"-DRUNTIMES_${target}_LIBCXX_HAS_MUSL_LIBC=ON"
# For some reason this flag is not correctly set if we don't
# manually set it and some strange gnu only LDFLAGS are injected.
"-DRUNTIMES_${target}_COMPILER_RT_HAS_GNU_VERSION_SCRIPT_COMPAT=OFF"
# X-Ray doesn't seem to compiler with musl
"-DRUNTIMES_${target}_COMPILER_RT_BUILD_XRAY=OFF"
# Only build these if we enable sanitizers since they depend
# on the sanitizer common runtime
"-DRUNTIMES_${target}_COMPILER_RT_BUILD_MEMPROF=ON"
"-DRUNTIMES_${target}_COMPILER_RT_BUILD_LIBFUZZER=OFF"
"-DRUNTIMES_${target}_COMPILER_RT_BUILD_ORC=ON"
"-DRUNTIMES_${target}_LIBUNWIND_ENABLE_SHARED=OFF"
"-DRUNTIMES_${target}_LIBUNWIND_ENABLE_STATIC=ON"
"-DRUNTIMES_${target}_COMPILER_RT_ENABLE_STATIC_UNWINDER=ON"
"-DRUNTIMES_${target}_SANITIZER_USE_STATIC_LLVM_UNWINDER=ON"
"-DRUNTIMES_${target}_SANITIZER_USE_STATIC_CXX_ABI=ON"
]);
cmakeFlags = cmakeFlags' ++ builtinFlags ++ runtimeFlags;
ninjaFlags = [
#"install-clang"
"install-builtins"
"install-compiler-rt"
"install-runtimes"
"tools/iwyu/install"
];
meta = {
homepage = "https://llvm.org/";
description = "A collection of modular and reusable compiler and toolchain technologies";
longDescription = ''
The LLVM Project is a collection of modular and reusable compiler and
toolchain technologies. Despite its name, LLVM has little to do with
traditional virtual machines. The name "LLVM" itself is not an acronym; it
is the full name of the project.
LLVM began as a research project at the University of Illinois, with the
goal of providing a modern, SSA-based compilation strategy capable of
supporting both static and dynamic compilation of arbitrary programming
languages. Since then, LLVM has grown to be an umbrella project consisting
of a number of subprojects, many of which are being used in production by
a wide variety of commercial and open source projects as well as being
widely used in academic research. Code in the LLVM project is licensed
under the "Apache 2.0 License with LLVM exceptions".
'';
license = lib.licenses.ncsa;
# TODO: Add the maintainer
# maintainers = "Sameer Rahmani []";
# See llvm/cmake/config-ix.cmake.
platforms =
lib.platforms.aarch64 ++
lib.platforms.arm ++
lib.platforms.mips ++
lib.platforms.power ++
lib.platforms.s390x ++
lib.platforms.wasi ++
lib.platforms.x86 ++
lib.platforms.riscv ++
lib.platforms.m68k;
};
});
vanila.passthru = {
isLLVM = true;
# libc_bin = stdenv.cc.binutils.libc_bin;
# libc_dev = stdenv.cc.binutils.libc_dev;
cxxabi = vanila;
libc = stdenv.cc.libc;
};
tools = lib.makeExtensible (tools:
let
mkExtraBuildCommands0 = cc: ''
rsrc="$out/resource-root"
mkdir "$rsrc"
ln -s "${vanilla}/lib/clang/${major}/include" "$rsrc"
echo "-resource-dir=$rsrc" >> $out/nix-support/cc-cflags
'';
mkExtraBuildCommands = cc: mkExtraBuildCommands0 cc + ''
ln -s "${vanilla}/lib" "$rsrc/lib"
ln -s "${vanilla}/share" "$rsrc/share"
'';
bintools' = vanilla;
in {
clang = wrapCCWith rec {
cc = vanilla;
libcxx = vanilla;
libc = stdenv.cc.libc;
extraBuildCommands = mkExtraBuildCommands cc;
nixSupport.cc-cflags =
[ "-rtlib=compiler-rt"
"-lc++"
"-lc++abi"
"-Wno-unused-command-line-argument"
"-B${vanilla}/lib"
] ++ lib.optional (!stdenv.targetPlatform.isWasm) "--unwindlib=libunwind"
++ lib.optional (!stdenv.targetPlatform.isWasm && (useLLVM || false))
"-lunwind"
++ lib.optional stdenv.targetPlatform.isWasm "-fno-exceptions";
};
});
in vanilla