diff --git a/flake.lock b/flake.lock index ba5e85f..144e324 100644 --- a/flake.lock +++ b/flake.lock @@ -5,11 +5,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1694529238, - "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", "owner": "numtide", "repo": "flake-utils", - "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", "type": "github" }, "original": { @@ -20,16 +20,18 @@ }, "nixpkgs": { "locked": { - "dirtyRev": "60a403eaffc56570ccc2fefebd1e09acd0ceab53-dirty", - "dirtyShortRev": "60a403eaffc5-dirty", - "lastModified": 1701178202, - "narHash": "sha256-WcFAx8yBoAGAUH6bCRJQWohtnzARZwpYh0H17LuAPZI=", - "type": "git", - "url": "file:///home/lxsameer/src/nixpkgs" + "lastModified": 1703110697, + "narHash": "sha256-n7/5rcNGo/JYaFpStPUo0SmiZmjVkRwZK0UwC9C8WkI=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "617e0a5cf51ae10bef08c9c110e98f5cac88de6d", + "type": "github" }, "original": { - "type": "git", - "url": "file:///home/lxsameer/src/nixpkgs" + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "617e0a5cf51ae10bef08c9c110e98f5cac88de6d", + "type": "github" } }, "root": { diff --git a/flake.nix b/flake.nix index dc60cbb..5312788 100644 --- a/flake.nix +++ b/flake.nix @@ -16,21 +16,22 @@ { description = "Serene programming language"; - inputs.nixpkgs.url = "/home/lxsameer/src/nixpkgs/"; + inputs.nixpkgs.url = "github:NixOS/nixpkgs/617e0a5cf51ae10bef08c9c110e98f5cac88de6d"; + #inputs.nixpkgs.url = "/home/lxsameer/src/nixpkgs/"; inputs.flake-utils.url = "github:numtide/flake-utils"; outputs = inputs@{ self, nixpkgs, flake-utils, ... }: flake-utils.lib.eachDefaultSystem (system: let zshDir = ./scripts/zsh; - llvm = { - url = "https://devheroes.codes/Serene/llvm-project.git"; - major = "16"; - version = "16.0.6"; - rev = "b2c0361bcc08afdf466a605a23924bcd64fa2b86"; - hash = "sha256-wUKHwWYYlKa0v5zEJXxndleYtK7wzJKi0vqr3lNkGMI="; - rev-version = "17-disable-shared-1"; - }; + # llvm = { + # url = "https://devheroes.codes/Serene/llvm-project.git"; + # major = "16"; + # version = "16.0.6"; + # rev = "b2c0361bcc08afdf466a605a23924bcd64fa2b86"; + # hash = "sha256-wUKHwWYYlKa0v5zEJXxndleYtK7wzJKi0vqr3lNkGMI="; + # rev-version = "17-disable-shared-1"; + # }; overlays = [ @@ -105,9 +106,9 @@ if system == "x86_64-linux" then import nixpkgs { inherit system overlays; - crossSystem = nixpkgs.lib.systems.examples.musl64 // { useLLVM = true; }; - config.replaceCrossStdenv = { buildPackages, baseStdenv }: - buildPackages.stdenvAdapters.overrideCC baseStdenv buildPackages.llvmPackages_16.clangUseLLVM; + crossSystem = nixpkgs.lib.systems.examples.musl64; #// { useLLVM = true; }; + # config.replaceCrossStdenv = { buildPackages, baseStdenv }: + # buildPackages.stdenvAdapters.overrideCC baseStdenv buildPackages.llvmPackages_17.clangUseLLVM; } else import nixpkgs { inherit system overlays; @@ -116,16 +117,42 @@ pkgs = get_pkgs system; - sereneLLVM = pkgs.callPackage ./nix/llvm.nix { - inherit (pkgs) lib stdenv cmake ninja ccache zlib libxml2 fetchgit; - }; + # # sereneLLVM = (pkgs.callPackage ./nix/llvm.nix { + # # inherit (pkgs) lib stdenv cmake ninja ccache zlib libxml2 fetchgit; + + # # }).llvm; + + # # stdenv = pkgs.stdenvAdapters.overrideCC pkgs.stdenv sereneLLVM; + # stdenv = pkgs.stdenv; + stdenv' = pkgs.stdenvAdapters.overrideCC pkgs.stdenv pkgs.llvmPackages_16.clangUseLLVM; + + utils = (pkgs.callPackage ./nix/utils.nix {}); + + llvm_source = pkgs.callPackage ./nix/llvm_source.nix {}; + + libunwind = (pkgs.callPackage ./nix/libunwind { + stdenv = stdenv'; + inherit llvm_source utils; + }); + + cxx-headers = (pkgs.callPackage ./nix/libcxx { + inherit llvm_source utils; + llvm_libunwind = libunwind; + llvm_libcxxabi = null; + headersOnly = true; + stdenv = stdenv'; + }); + + libcxxabi = (pkgs.callPackage ./nix/libcxxabi { + inherit llvm_source utils cxx-headers; + llvm_libunwind = libunwind; + stdenv = stdenv'; + }); + - stdenv = pkgs.stdenvAdapters.overrideCC pkgs.stdenv sereneLLVM; #with pkgs; native_build_inputs = let - - filterCmakeFlags = xs: builtins.filter (x: !(x == "-DCMAKE_CROSSCOMPILING=True" || pkgs.lib.hasPrefix "-DLLVM_TABLEGEN=" x)) xs; @@ -141,25 +168,25 @@ }); # iwyu = (pkgs.include-what-you-use.overrideAttrs (old: # let - # version = "0.20"; + # version = "0.21"; # in { # inherit version; # src = pkgs.fetchurl { # url = "${old.meta.homepage}/downloads/${old.pname}-${version}.src.tar.gz"; - # hash = "sha256-dfzh5khfKA+PE/TC0JCxHS/SECtQhXUHyEE6kZt6+Jk="; + # hash = "sha256-ajUZGf+JvafJXIlUcmAYaNs9qrlqlYs44DYokNWHYLY="; # }; - - - # })).override { - # llvmPackages = pkgs.__splicedPackages.llvmPackages_16;# .overrideAttrs (oldLLVM: { - # # cmakeFlags = builtins.trace ">> ${toString(filterCmakeFlags oldLLVM.cmakeFlags)}" filterCmakeFlags oldLLVM.cmakeFlags; - # # }); - # }; + # })) + # .override { + # llvmPackages = pkgs.__splicedPackages.llvmPackages_16;# .overrideAttrs (oldLLVM: { + # # cmakeFlags = builtins.trace ">> ${toString(filterCmakeFlags oldLLVM.cmakeFlags)}" filterCmakeFlags oldLLVM.cmakeFlags; + # # }); + # }; # mlir_16' = pkgs.mlir_16.overrideAttrs (old: { # }); - in builtins.trace ">> ${sereneLLVM}" (with pkgs; [ + # builtins.trace ">> ${sereneLLVM}" + in (with pkgs; [ cmake ninja ccache @@ -169,15 +196,17 @@ zsh-autocomplete zsh-syntax-highlighting python3 - sereneLLVM - # iwyu + #sereneLLVM + libunwind + libcxxabi + # mlir_17 ]); build_inputs = with pkgs; [ boehmgc # llvm_16 # llvm_16 - # mlir_16 + # mlir_17 gtest gmock @@ -187,7 +216,7 @@ in { inherit pkgs; - devShells.default = (pkgs.mkShell.override {inherit stdenv;}) { + devShells.default = (pkgs.mkShell.override { stdenv = stdenv';}) { nativeBuildInputs = native_build_inputs; buildInputs = build_inputs; shellHook = @@ -203,7 +232,11 @@ nativeBuildInputs = native_build_inputs; buildInputs = build_inputs; }; - packages.mlir = pkgs.mlir_16; + packages.mlir = pkgs.mlir_17; + packages.llvm_unwind = libunwind; + packages.llvm_libcxxabi = libcxxabi; + packages.llvm_cxx_headers = cxx-headers; + packages.llvm = pkgs.llvmPackages_16.llvm.override { stdenv = stdenv'; }; } ); } diff --git a/nix/libcxx/default.nix b/nix/libcxx/default.nix new file mode 100644 index 0000000..5c56384 --- /dev/null +++ b/nix/libcxx/default.nix @@ -0,0 +1,129 @@ +# Serene Programming Language +# +# Copyright (c) 2019-2023 Sameer Rahmani +# +# 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 . +{ lib, + stdenv, + runCommand, + cmake, + ninja, + python3, + fixDarwinDylibNames, + #cxxabi ? if stdenv.hostPlatform.isFreeBSD then libcxxrt else llvm_libcxxabi, + #libcxxrt, + llvm_libcxxabi, + llvm_libunwind, + llvm_source, + utils, + # If headersOnly is true, the resulting package would only include the headers. + # Use this to break the circular dependency between libcxx and libcxxabi. + # + # Some context: + # https://reviews.llvm.org/rG1687f2bbe2e2aaa092f942d4a97d41fad43eedfb + headersOnly ? false +}: +let + basename = "llvm_libcxx"; +in + +assert stdenv.isDarwin -> llvm_libcxxabi.libName == "c++abi"; + +stdenv.mkDerivation rec { + pname = basename + lib.optionalString headersOnly "-headers"; + inherit (llvm_source) version; + + src = runCommand "${pname}-src-${version}" {} '' + mkdir -p "$out" + cp -r ${llvm_source}/cmake "$out" + cp -r ${llvm_source}/libcxx "$out" + mkdir -p "$out/libcxxabi" + cp -r ${llvm_source}/libcxxabi/include "$out/libcxxabi" + mkdir -p "$out/llvm" + cp -r ${llvm_source}/llvm/cmake "$out/llvm" + cp -r ${llvm_source}/llvm/utils "$out/llvm" + cp -r ${llvm_source}/third-party "$out" + cp -r ${llvm_source}/runtimes "$out" + ''; + + sourceRoot = "${src.name}/runtimes"; + + outputs = [ "out" ] ++ lib.optional (!headersOnly) "dev"; + + prePatch = '' + cd ../libcxx + chmod -R u+w . + ''; + + patches = [ + ./gnu-install-dirs.patch + ]; + + postPatch = '' + cd ../runtimes + ''; + + preConfigure = lib.optionalString stdenv.hostPlatform.isMusl '' + patchShebangs utils/cat_files.py + ''; + + nativeBuildInputs = [ cmake ninja python3 ] + ++ lib.optional stdenv.isDarwin fixDarwinDylibNames; + + buildInputs = + lib.optionals (!headersOnly) [ llvm_libcxxabi ] + ++ lib.optionals (stdenv.hostPlatform.useLLVM or false && !stdenv.hostPlatform.isWasm) [ llvm_libunwind ]; + + cmakeFlags = let + # See: https://libcxx.llvm.org/BuildingLibcxx.html#cmdoption-arg-libcxx-cxx-abi-string + libcxx_cxx_abi_opt = { + "c++abi" = "system-libcxxabi"; + "cxxrt" = "libcxxrt"; + }.${llvm_libcxxabi.libName} or (throw "unknown cxxabi: ${llvm_libcxxabi.libName} (${llvm_libcxxabi.pname})"); + in [ + "-DLLVM_ENABLE_RUNTIMES=libcxx" + "-DLIBCXX_CXX_ABI=${if headersOnly then "none" else libcxx_cxx_abi_opt}" + "-DLIBCXX_ENABLE_SHARED=OFF" + ] ++ lib.optional (!headersOnly && llvm_libcxxabi.libName == "c++abi") + "-DLIBCXX_CXX_ABI_INCLUDE_PATHS=${llvm_libcxxabi.dev}/include/c++/v1" + ++ lib.optional (stdenv.hostPlatform.isMusl || stdenv.hostPlatform.isWasi) + "-DLIBCXX_HAS_MUSL_LIBC=1" + ++ lib.optionals (stdenv.hostPlatform.useLLVM or false) [ + "-DLIBCXX_USE_COMPILER_RT=ON" + # There's precedent for this in llvm-project/libcxx/cmake/caches. + # In a monorepo build you might do the following in the libcxxabi build: + # -DLLVM_ENABLE_PROJECTS=libcxxabi;libunwinder + # -DLIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY=On + # libcxx appears to require unwind and doesn't pull it in via other means. + "-DLIBCXX_ADDITIONAL_LIBRARIES=unwind" + ] ++ lib.optionals stdenv.hostPlatform.isWasm [ + "-DLIBCXX_ENABLE_THREADS=OFF" + "-DLIBCXX_ENABLE_FILESYSTEM=OFF" + "-DLIBCXX_ENABLE_EXCEPTIONS=OFF" + "-DUNIX=ON" # Required otherwise libc++ fails to detect the correct linker + ] ++ lib.optionals (headersOnly) [ + # If we're only building the headers we don't actually *need* a functioning + # C/C++ compiler: + "-DCMAKE_C_COMPILER_WORKS=ON" + "-DCMAKE_CXX_COMPILER_WORKS=ON" + ]; + + ninjaFlags = lib.optional headersOnly "generate-cxx-headers"; + installTargets = lib.optional headersOnly "install-cxx-headers"; + + passthru = { + isLLVM = true; + inherit llvm_libcxxabi; + }; + inherit (utils) meta; +} diff --git a/nix/libcxx/gnu-install-dirs.patch b/nix/libcxx/gnu-install-dirs.patch new file mode 100644 index 0000000..ceab7ac --- /dev/null +++ b/nix/libcxx/gnu-install-dirs.patch @@ -0,0 +1,22 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index b8ac536588d3..a2f4d7d5721b 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -401,7 +401,7 @@ if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) + set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1") + set(LIBCXX_GENERATED_MODULE_DIR "${LLVM_BINARY_DIR}/modules/c++/v1") + set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LLVM_BINARY_DIR}/include/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1") +- set(LIBCXX_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE STRING ++ set(LIBCXX_INSTALL_LIBRARY_DIR ${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE STRING + "Path where built libc++ libraries should be installed.") + set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "${CMAKE_INSTALL_INCLUDEDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1" CACHE STRING + "Path where target-specific libc++ headers should be installed.") +@@ -420,7 +420,7 @@ else() + set(LIBCXX_GENERATED_MODULE_DIR "${CMAKE_BINARY_DIR}/modules/c++/v1") + endif() + set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LIBCXX_GENERATED_INCLUDE_DIR}") +- set(LIBCXX_INSTALL_LIBRARY_DIR lib${LIBCXX_LIBDIR_SUFFIX} CACHE STRING ++ set(LIBCXX_INSTALL_LIBRARY_DIR ${CMAKE_INSTALL_LIBDIR}${LIBCXX_LIBDIR_SUFFIX} CACHE STRING + "Path where built libc++ libraries should be installed.") + set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "${LIBCXX_INSTALL_INCLUDE_DIR}" CACHE STRING + "Path where target-specific libc++ headers should be installed.") diff --git a/nix/libcxxabi/default.nix b/nix/libcxxabi/default.nix new file mode 100644 index 0000000..4b69cc4 --- /dev/null +++ b/nix/libcxxabi/default.nix @@ -0,0 +1,128 @@ +# Serene Programming Language +# +# Copyright (c) 2019-2023 Sameer Rahmani +# +# 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 . +{ + lib, + stdenv, + cmake, + ninja, + python3, + runCommand, + fetchpatch, + cxx-headers, + llvm_libunwind, + utils, + llvm_source, +}: + +stdenv.mkDerivation rec { + pname = "llvm_libcxxabi"; + inherit (llvm_source) version; + + src = runCommand "${pname}-src-${version}" {} '' + mkdir -p "$out" + cp -r ${llvm_source}/cmake "$out" + cp -r ${llvm_source}/libcxxabi "$out" + mkdir -p "$out/libcxx/src" + cp -r ${llvm_source}/libcxx/cmake "$out/libcxx" + cp -r ${llvm_source}/libcxx/include "$out/libcxx" + cp -r ${llvm_source}/libcxx/src/include "$out/libcxx/src" + mkdir -p "$out/llvm" + cp -r ${llvm_source}/llvm/cmake "$out/llvm" + cp -r ${llvm_source}/llvm/utils "$out/llvm" + cp -r ${llvm_source}/runtimes "$out" + ''; + + sourceRoot = "${src.name}/runtimes"; + + outputs = [ "out" "dev" ]; + + postUnpack = lib.optionalString stdenv.isDarwin '' + export TRIPLE=x86_64-apple-darwin + ''; + + prePatch = '' + cd ../libcxxabi + chmod -R u+w . + ''; + + patches = [ + ./gnu-install-dirs.patch + # Patch to allow libcxxabi standalone installation + # `LIBCXXABI_LIBCXX_INCLUDES` is not doing anything in the + # vanilla source from the llvm-project, and it will be removed + # in the future. + ./standalone.patch + #./test.patch + ]; + + postPatch = '' + cd ../runtimes + ''; + + nativeBuildInputs = [ cmake ninja python3 ]; + buildInputs = [ llvm_libunwind ]; + + ninjaFlags = [ "-v" ]; + cmakeFlags = [ + "-DLLVM_ENABLE_RUNTIMES=libcxxabi" + "-DLIBCXXABI_LIBCXX_INCLUDES=${cxx-headers}/include/c++/v1" + + # `libcxxabi`'s build does not need a toolchain with a c++ stdlib attached + # (we specify the headers it should use explicitly above). + # + # CMake however checks for this anyways; this flag tells it not to. See: + # https://github.com/llvm/llvm-project/blob/4bd3f3759259548e159aeba5c76efb9a0864e6fa/llvm/runtimes/CMakeLists.txt#L243 + "-DCMAKE_CXX_COMPILER_WORKS=ON" + ] ++ lib.optionals (stdenv.hostPlatform.useLLVM or false && !stdenv.hostPlatform.isWasm) [ + "-DLLVM_ENABLE_LIBCXX=ON" + "-DLIBCXXABI_USE_LLVM_UNWINDER=ON" + # libcxxabi's CMake looks as though it treats -nostdlib++ as implying -nostdlib, + # but that does not appear to be the case for example when building + # pkgsLLVM.libcxxabi (which uses clangNoCompilerRtWithLibc). + "-DCMAKE_EXE_LINKER_FLAGS=-nostdlib" + "-DCMAKE_SHARED_LINKER_FLAGS=-nostdlib" + ] ++ lib.optionals stdenv.hostPlatform.isWasm [ + "-DCMAKE_C_COMPILER_WORKS=ON" + "-DCMAKE_CXX_COMPILER_WORKS=ON" + "-DLIBCXXABI_ENABLE_THREADS=OFF" + "-DLIBCXXABI_ENABLE_EXCEPTIONS=OFF" + "-DUNIX=ON" # Required otherwise libc++ fails to detect the correct linker + + # We care only about the static libcxxabi + "-DLIBCXXABI_ENABLE_SHARED=OFF" + ]; + + preInstall = lib.optionalString stdenv.isDarwin '' + for file in lib/*.dylib; do + # this should be done in CMake, but having trouble figuring out + # the magic combination of necessary CMake variables + # if you fancy a try, take a look at + # https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/RPATH-handling + install_name_tool -id $out/$file $file + done + ''; + + postInstall = '' + mkdir -p "$dev/include" + install -m 644 ../../libcxxabi/include/${if stdenv.isDarwin then "*" else "cxxabi.h"} "$dev/include" + ''; + + passthru = { + libName = "c++abi"; + }; + + inherit (utils) meta; +} diff --git a/nix/libcxxabi/gnu-install-dirs.patch b/nix/libcxxabi/gnu-install-dirs.patch new file mode 100644 index 0000000..a547297 --- /dev/null +++ b/nix/libcxxabi/gnu-install-dirs.patch @@ -0,0 +1,44 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index f380fe6b6b92..40ed4793dafb 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -188,7 +188,7 @@ set(LIBCXXABI_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE STRING + if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) + set(LIBCXXABI_HEADER_DIR ${LLVM_BINARY_DIR}) + set(LIBCXXABI_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) +- set(LIBCXXABI_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE STRING ++ set(LIBCXXABI_INSTALL_LIBRARY_DIR ${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE STRING + "Path where built libc++abi libraries should be installed.") + if(LIBCXX_LIBDIR_SUBDIR) + string(APPEND LIBCXXABI_LIBRARY_DIR /${LIBCXXABI_LIBDIR_SUBDIR}) +@@ -202,7 +202,7 @@ else() + set(LIBCXXABI_HEADER_DIR ${CMAKE_BINARY_DIR}) + set(LIBCXXABI_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXXABI_LIBDIR_SUFFIX}) + endif() +- set(LIBCXXABI_INSTALL_LIBRARY_DIR lib${LIBCXXABI_LIBDIR_SUFFIX} CACHE STRING ++ set(LIBCXXABI_INSTALL_LIBRARY_DIR ${CMAKE_INSTALL_LIBDIR}${LIBCXXABI_LIBDIR_SUFFIX} CACHE STRING + "Path where built libc++abi libraries should be installed.") + endif() + +diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt +index 0d861cff980c..6a2a2b14fafd 100644 +--- a/test/CMakeLists.txt ++++ b/test/CMakeLists.txt +@@ -17,9 +17,14 @@ else() + set(LIBCXXABI_TEST_DEPS cxxabi_static) + endif() + +-list(APPEND LIBCXXABI_TEST_DEPS cxx) +-if (LIBCXXABI_USE_LLVM_UNWINDER AND TARGET unwind) +- list(APPEND LIBCXXABI_TEST_DEPS unwind) ++if(libcxx IN_LIST LLVM_ENABLE_RUNTIMES) ++ list(APPEND LIBCXXABI_TEST_DEPS cxx) ++endif() ++ ++if(libunwind IN_LIST LLVM_ENABLE_RUNTIMES) ++ if (LIBCXXABI_USE_LLVM_UNWINDER AND TARGET unwind) ++ list(APPEND LIBCXXABI_TEST_DEPS unwind) ++ endif() + endif() + + set(AUTO_GEN_COMMENT "## Autogenerated by libcxxabi configuration.\n# Do not edit!") diff --git a/nix/libcxxabi/standalone.patch b/nix/libcxxabi/standalone.patch new file mode 100644 index 0000000..9c82e9f --- /dev/null +++ b/nix/libcxxabi/standalone.patch @@ -0,0 +1,24 @@ +diff --git a/CMakeLists.txt b/libcxxabi/CMakeLists.txt +index f380fe6b6b92..60fca2687be0 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -132,10 +132,17 @@ if (NOT LIBCXXABI_ENABLE_SHARED AND NOT LIBCXXABI_ENABLE_STATIC) + message(FATAL_ERROR "libc++abi must be built as either a shared or static library.") + endif() + +-# TODO: Remove this, which shouldn't be necessary since we know we're being built +-# side-by-side with libc++. + set(LIBCXXABI_LIBCXX_INCLUDES "" CACHE PATH + "Specify path to libc++ includes.") ++if (NOT libcxx IN_LIST LLVM_ENABLE_RUNTIMES) ++ if (NOT IS_DIRECTORY ${LIBCXXABI_LIBCXX_INCLUDES}) ++ message(FATAL_ERROR ++ "LIBCXXABI_LIBCXX_INCLUDES=${LIBCXXABI_LIBCXX_INCLUDES} is not a valid directory. " ++ "Please provide the path to where the libc++ headers have been installed.") ++ endif() ++ add_library(cxx-headers INTERFACE) ++ target_include_directories(cxx-headers INTERFACE "${LIBCXXABI_LIBCXX_INCLUDES}") ++endif() + + set(LIBCXXABI_HERMETIC_STATIC_LIBRARY_DEFAULT OFF) + if (WIN32) diff --git a/nix/libunwind/default.nix b/nix/libunwind/default.nix new file mode 100644 index 0000000..64b2ba6 --- /dev/null +++ b/nix/libunwind/default.nix @@ -0,0 +1,69 @@ +# Serene Programming Language +# +# Copyright (c) 2019-2023 Sameer Rahmani +# +# 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 . +{ lib, + stdenv, + cmake, + ninja, + python3, + utils, + runCommand, + llvm_source, +}: +stdenv.mkDerivation rec{ + pname = "llvm_libunwind"; + inherit (llvm_source) version; + + src = runCommand "${pname}-src-${version}" {} '' + mkdir -p "$out" + cp -r ${llvm_source}/cmake "$out" + cp -r ${llvm_source}/libunwind "$out" + mkdir -p "$out/libcxx" + cp -r ${llvm_source}/libcxx/cmake "$out/libcxx" + cp -r ${llvm_source}/libcxx/utils "$out/libcxx" + mkdir -p "$out/llvm" + cp -r ${llvm_source}/llvm/cmake "$out/llvm" + cp -r ${llvm_source}/llvm/utils "$out/llvm" + cp -r ${llvm_source}/runtimes "$out" + ''; + + sourceRoot = "${src.name}/runtimes"; + + prePatch = '' + cd ../libunwind + chmod -R u+w . + ''; + + patches = [ + ./gnu-install-dirs.patch + ]; + + postPatch = '' + cd ../runtimes + ''; + + outputs = [ "out" "dev" ]; + + nativeBuildInputs = [ cmake ninja python3 ]; + + cmakeFlags = [ + "-DLLVM_ENABLE_RUNTIMES=libunwind" + "-DLIBUNWIND_ENABLE_SHARED=OFF" + "-DLIBUNWIND_ENABLE_CROSS_UNWINDING=ON" + "-DLIBUNWIND_USE_COMPILER_RT=ON" + ]; + + inherit (utils) meta; +} diff --git a/nix/libunwind/gnu-install-dirs.patch b/nix/libunwind/gnu-install-dirs.patch new file mode 100644 index 0000000..9410517 --- /dev/null +++ b/nix/libunwind/gnu-install-dirs.patch @@ -0,0 +1,21 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 5a06805f05f1..86a50329e6a8 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -117,7 +117,7 @@ set(LIBUNWIND_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH + + if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) + set(LIBUNWIND_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) +- set(LIBUNWIND_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH ++ set(LIBUNWIND_INSTALL_LIBRARY_DIR ${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH + "Path where built libunwind libraries should be installed.") + if(LIBCXX_LIBDIR_SUBDIR) + string(APPEND LIBUNWIND_LIBRARY_DIR /${LIBUNWIND_LIBDIR_SUBDIR}) +@@ -129,6 +129,6 @@ else() + else() + set(LIBUNWIND_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBUNWIND_LIBDIR_SUFFIX}) + endif() +- set(LIBUNWIND_INSTALL_LIBRARY_DIR lib${LIBUNWIND_LIBDIR_SUFFIX} CACHE PATH ++ set(LIBUNWIND_INSTALL_LIBRARY_DIR ${CMAKE_INSTALL_LIBDIR}${LIBUNWIND_LIBDIR_SUFFIX} CACHE PATH + "Path where built libunwind libraries should be installed.") + endif() diff --git a/nix/llvm.nix b/nix/llvm.nix index 44b1c73..d96828a 100644 --- a/nix/llvm.nix +++ b/nix/llvm.nix @@ -20,7 +20,10 @@ libxml2, python3, fetchgit, + fetchurl, zlib, + wrapCCWith, + overrideCC, ccache ? null, useCcache ? false, url ? "https://github.com/llvm/llvm-project.git", @@ -30,103 +33,212 @@ }: let ncpus = builtins.getEnv "NIX_BUILD_CORES"; -in builtins.trace ">>> ${toString ncpus}" stdenv.mkDerivation rec { - inherit version; - pname = "serene_llvm"; + major = lib.versions.major version; + target = stdenv.targetPlatform.config; - src = fetchgit { - inherit url hash; - rev = ref; + # 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 + # ''; }; - sourceRoot = "${src.name}/llvm"; + vanilla = builtins.trace ">.> " (stdenv.mkDerivation rec{ + inherit version; + pname = "serene_llvm"; - nativeBuildInputs = [ cmake ninja python3 zlib ]; - buildInputs = [ libxml2 zlib ]; + src = fetchgit { + inherit url hash; + rev = ref; + }; - 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" + sourceRoot = "${src.name}/llvm"; - # 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='compiler-rt;libcxx;libcxxabi;libunwind'" - "-DLLVM_HOST_TRIPLE=${stdenv.hostPlatform.config}" - "-DLLVM_RUNTIME_TARGET=${stdenv.hostPlatform.config}" - # Serene uses static libs, so no shared lib - "-DLLVM_ENABLE_PIC=OFF" - #"-DLLVM_BUILD_STATIC=ON" - "-DLLVM_LINK_LLVM_DYLIB=off" + nativeBuildInputs = [ cmake ninja python3 zlib ]; + buildInputs = [ libxml2 zlib ]; - "-DLLVM_ENABLE_LIBXML2=OFF" - "-DLLVM_BUILD_DOCS=OFF" - "-DLLVM_ENABLE_SPHINX=OFF" - "-DSPHINX_OUTPUT_MAN=OFF" - "-DSPHINX_OUTPUT_HTML=OFF" + #NIX_CFLAGS_COMPILE = ["-fno-rtti"]; + #ninjaFlags = [ "-v" ]; - "-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" + 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_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_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=ON" + "-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=ON" - "-DPACKAGE_VENDOR=Serene" - "-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON" - "-DENABLE_X86_RELAX_RELOCATIONS=ON" - "-DBUILD_SHARED_LIBS=OFF" - "-DCLANG_ENABLE_BOOTSTRAP=ON" - "-DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=ON" - "-DLIBCXXABI_ENABLE_SHARED=OFF" - "-DLIBCXX_ABI_VERSION=2" + "-DLLVM_STATIC_LINK_CXX_STDLIB=ON" + "-DPACKAGE_VENDOR=Serene" + "-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON" + "-DENABLE_X86_RELAX_RELOCATIONS=ON" + "-DBUILD_SHARED_LIBS=OFF" + "-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"}" - - "-DLIBCLANG_BUILD_STATIC=ON" - - "-DCMAKE_INSTALL_PREFIX=${placeholder "out"}" - "-DCMAKE_INSTALL_BINDIR=${placeholder "out"}/bin" - "-DCMAKE_INSTALL_INCLUDEDIR=${placeholder "out"}/include" - "-DCMAKE_INSTALL_LIBDIR=${placeholder "out"}/lib" - "-DCMAKE_INSTALL_LIBEXECDIR=${placeholder "out"}/libexec" - ] ++ lib.optional stdenv.hostPlatform.isMusl [ + ] ++ 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" - ]; + # ] ++ lib.optional (stdenv.hostPlatform.isStatic) [ + # "-DLIBCLANG_BUILD_STATIC=ON" + ] ++ lib.optional (useCcache) [ + "-DLLVM_CCACHE_BUILD=ON" + ]; - meta = { - homepage = "https://llvm.org/"; - description = "A collection of modular and reusable compiler and toolchain technologies"; - longDescription = '' + 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" + ] ++ lib.optional (stdenv.hostPlatform.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}_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=ON" + "-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=ON" + "-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 (stdenv.hostPlatform.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=ON" + "-DRUNTIMES_${target}_COMPILER_RT_BUILD_ORC=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 @@ -140,24 +252,61 @@ in builtins.trace ">>> ${toString ncpus}" stdenv.mkDerivation rec { 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; + license = lib.licenses.ncsa; - # TODO: Add the maintainer - # maintainers = "Sameer Rahmani []"; + # 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; - }; + # 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; + }; + }); + + 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; + extraPackages = [ + vanilla + ]; + extraBuildCommands = mkExtraBuildCommands cc; + nixSupport.cc-cflags = + [ "-rtlib=compiler-rt" + "-Wno-unused-command-line-argument" + "-B${vanilla}/lib" + ] ++ lib.optional (!stdenv.targetPlatform.isWasm) "--unwindlib=libunwind" + ++ lib.optional (!stdenv.targetPlatform.isWasm && stdenv.targetPlatform.useLLVM or false) + "-lunwind" + ++ lib.optional stdenv.targetPlatform.isWasm "-fno-exceptions"; + }; + }); +in { + inherit (tools) clang; + llvm = vanilla; + stdenv = overrideCC stdenv tools.clang; } - # -DCMAKE_C_COMPILER=clang \ # If you have clang installed already - # -DCMAKE_CXX_COMPILER=clang++ \ # If you have clang installed already - # -DLLVM_ENABLE_LLD=ON diff --git a/nix/llvm_source.nix b/nix/llvm_source.nix new file mode 100644 index 0000000..c42020b --- /dev/null +++ b/nix/llvm_source.nix @@ -0,0 +1,39 @@ +# Serene Programming Language +# +# Copyright (c) 2019-2023 Sameer Rahmani +# +# 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 . +{ + stdenv, + fetchgit, + url ? "https://github.com/llvm/llvm-project.git", + hash ? "sha256-8MEDLLhocshmxoEBRSKlJ/GzJ8nfuzQ8qn0X/vLA+ag=", + version ? "17.0.6", + ref ? "refs/tags/llvmorg-${version}" +}: +stdenv.mkDerivation rec{ + pname = "llvm_source"; + inherit version; + + src = fetchgit { + inherit url hash; + rev = ref; + }; + unpackPhase = "true"; + + phases = [ "unpackPhase" "installPhase" ]; + installPhase = '' + mkdir -p "$out" + cp -rv "$src"/* "$out/" + ''; +} diff --git a/nix/utils.nix b/nix/utils.nix index c79efe2..2c32419 100644 --- a/nix/utils.nix +++ b/nix/utils.nix @@ -15,5 +15,192 @@ # along with this program. If not, see . { lib }: { + cmakeFlags = stdenv: [ + "-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}" + #"-DCMAKE_INSTALL_PREFIX=${placeholder "out"}" + + + # 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=ON" + "-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=ON" + "-DPACKAGE_VENDOR=Serene" + "-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON" + "-DENABLE_X86_RELAX_RELOCATIONS=ON" + "-DBUILD_SHARED_LIBS=OFF" + "-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" + + + ] ++ lib.optional (stdenv.hostPlatform.isMusl) [ + "-DDLIBCXX_HAS_MUSL_LIBC=ON" + # ] ++ lib.optional (stdenv.hostPlatform.isStatic) [ + # "-DLIBCLANG_BUILD_STATIC=ON" + ]; + + builtinFlags = stdenv: + let + target = stdenv.targetPlatform.config; + in [ + "-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" + ] ++ lib.optional (stdenv.hostPlatform.useLLVM) [ + "-DBUILTINS_${target}_LLVM_USE_LINKER=lld" + ]; + + runtimeFlags = stdenv: + let + target = stdenv.targetPlatform.config; + in [ + "-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}_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=ON" + "-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=ON" + "-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 (stdenv.hostPlatform.useLLVM) [ + "-DRUNTIMES_${target}_LLVM_USE_LINKER=lld" + ]) ++ (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=ON" + "-DRUNTIMES_${target}_COMPILER_RT_BUILD_ORC=ON" + ]); + + 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; + }; }