unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
From: Pierre Langlois <pierre.langlois@gmx.com>
To: Julien Lepiller <julien@lepiller.eu>
Cc: 54239@debbugs.gnu.org
Subject: [bug#54239] [PATCH] gnu: Add cross-clang.
Date: Thu, 03 Mar 2022 20:51:01 +0000	[thread overview]
Message-ID: <87wnhapwsv.fsf@gmx.com> (raw)
In-Reply-To: <20220303170252.3caec0a6@tachikoma.lepiller.eu>


[-- Attachment #1.1: Type: text/plain, Size: 1760 bytes --]

Hi Julien,

Julien Lepiller <julien@lepiller.eu> writes:

> Hi Guix!
>
> This small patch series adds cross-clang, a cross-compiler version of
> clang. Clang doesn't really make a distinction between a native and a
> cross-build, it is already a cross-compiler, but this ensures that:
>
> 1. it actually works
> 2. it targets (%current-target-architecture) by default
>
> The rest of the series ensures that libcxx and libcxxabi can be
> cross-compiled with it.

That's really cool! Out of curiosity, what target are you interested in
that clang supports and GCC doesn't?  For instance I'm interested in
WebAssembly, and I've actually been contemplating how we could improve
support for cross-compilers based on Clang in Guix, to be able to
provide a working WebAssembly toolchain.

For context, such a toolchain will be needed to enable potential use of
WebAssembly in IceCat, for security purposes, see
https://hacks.mozilla.org/2021/12/webassembly-and-back-again-fine-grained-sandboxing-in-firefox-95/

I actually have a toolchain that works already, which targets the
wasm32-wasi-unknown triplet, but I wasn't convinced the way I did it was
the right way to go long term, so it needs more work.  I'm attaching the
patch in case there's anything useful to you in there already!

The approach I took was to create wrappers around clang/clang++ in order
to set the correct include paths, and then provide an isolated sysroot
for wasm32-wasi using union-build. This will work for IceCat, where
their should be a flag to pass a sysroot path, but we should be able to
do better in Guix.

I though I'd share in case that's helpful! I'll take a look at your
patches to see if I can build on top of them for a future WebAssembly
toolchain in Guix.

Thanks,
Pierre


[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 519 bytes --]

[-- Attachment #2: 0001-gnu-Add-wasm32-wasi-clang-toolchain.patch --]
[-- Type: text/x-patch, Size: 12743 bytes --]

From 7d3c2a54ad66d5c4b2aa96eb946537fac1a5ae75 Mon Sep 17 00:00:00 2001
From: Pierre Langlois <pierre.langlois@gmx.com>
Date: Sun, 16 Jan 2022 16:55:59 +0000
Subject: [PATCH] gnu: Add wasm32-wasi-clang-toolchain.

WIP
---
 gnu/local.mk          |   1 +
 gnu/packages/llvm.scm |   1 +
 gnu/packages/wasm.scm | 273 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 275 insertions(+)
 create mode 100644 gnu/packages/wasm.scm

diff --git a/gnu/local.mk b/gnu/local.mk
index b7339ff472..952786827f 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -603,6 +603,7 @@ GNU_SYSTEM_MODULES =				\
   %D%/packages/vpn.scm				\
   %D%/packages/vulkan.scm			\
   %D%/packages/w3m.scm				\
+  %D%/packages/wasm.scm			\
   %D%/packages/wdiff.scm			\
   %D%/packages/web.scm				\
   %D%/packages/web-browsers.scm			\
diff --git a/gnu/packages/llvm.scm b/gnu/packages/llvm.scm
index eb949bed1b..8821b2b6a7 100644
--- a/gnu/packages/llvm.scm
+++ b/gnu/packages/llvm.scm
@@ -74,6 +74,7 @@ (define-module (gnu packages llvm)
   #:use-module (srfi srfi-1)
   #:use-module (ice-9 match)
   #:export (make-lld-wrapper
+            clang-from-llvm
             system->llvm-target))
 
 (define* (system->llvm-target #:optional
diff --git a/gnu/packages/wasm.scm b/gnu/packages/wasm.scm
new file mode 100644
index 0000000000..f9f73505ef
--- /dev/null
+++ b/gnu/packages/wasm.scm
@@ -0,0 +1,273 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2021 Pierre Langlois <pierre.langlois@gmx.com>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix 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; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix 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 GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu packages wasm)
+  #:use-module (guix gexp)
+  #:use-module (guix packages)
+  #:use-module ((guix licenses) #:prefix license:)
+  #:use-module (guix download)
+  #:use-module (guix git-download)
+  #:use-module (guix utils)
+  #:use-module (guix build-system cmake)
+  #:use-module (guix build-system gnu)
+  #:use-module (guix build-system trivial)
+  #:use-module (gnu packages base)
+  #:use-module (gnu packages bash)
+  #:use-module (gnu packages compression)
+  #:use-module (gnu packages llvm)
+  #:use-module (gnu packages python))
+
+(define-public wasi-libc
+  (let ((commit "ad5133410f66b93a2381db5b542aad5e0964db96")
+        (revision "1"))
+    (package
+      (name "wasi-libc")
+      (version (git-version "0.1-alpha" revision commit))
+      (source (origin
+                (method git-fetch)
+                (uri (git-reference
+                      (url "https://github.com/WebAssembly/wasi-libc")
+                      (commit commit)
+                      (recursive? #t)))
+                (file-name (git-file-name name version))
+                (sha256
+                 (base32
+                  "146jamq2q24vxjfpcwlqj84wzc80cbpbg0ns2wimyvzbanah48j6"))))
+      (build-system gnu-build-system)
+      (native-inputs (list clang-13))
+      (arguments
+       (list #:tests? #f ;No test suite
+             #:phases
+             #~(modify-phases %standard-phases
+                 (delete 'configure)
+                 (add-before 'build 'set-sysroot-include
+                   (lambda _
+                     (setenv "C_INCLUDE_PATH"
+                             (string-append (getcwd) "/sysroot/include"))))
+                 (add-before 'install 'set-install-dir
+                   (lambda _
+                     (setenv "INSTALL_DIR"
+                             (string-append #$output "/wasm32-wasi")))))))
+      (home-page "https://wasi.dev")
+      (synopsis "WASI libc implementation for WebAssembly")
+      (description
+       "WASI Libc is a libc for WebAssembly programs built on top of WASI
+system calls.  It provides a wide array of POSIX-compatible C APIs, including
+support for standard I/O, file I/O, filesystem manipulation, memory
+management, time, string, environment variables, program startup, and many
+other APIs.")
+      (license (list
+                ;; For wasi-libc, with LLVM exceptions
+                license:asl2.0
+                ;; For malloc.c.
+                license:cc0
+                ;; For cloudlibc.
+                license:bsd-2
+                ;; For wasi-libc and musl-libc.
+                license:expat)))))
+
+(define-public wasm32-wasi-clang-runtime
+  (package (inherit clang-runtime-13)
+    (native-inputs
+     (list clang-13 wasi-libc))
+    (inputs (list llvm-13))
+    (arguments
+     (list
+      #:build-type "Release"
+      #:tests? #f
+      ;; Stripping binaries breaks wasm linking, resulting in the following
+      ;; error: "archive has no index; run ranlib to add one".
+      #:strip-binaries? #f
+      #:configure-flags
+      #~(list "-DCMAKE_C_COMPILER=clang"
+              "-DCMAKE_C_COMPILER_TARGET=wasm32-wasi"
+              (string-append
+               "-DCMAKE_SYSROOT=" #$wasi-libc "/wasm32-wasi")
+              (string-append
+               "-DCMAKE_C_FLAGS=-I " #$wasi-libc "/wasm32-wasi/include")
+
+              "-DCOMPILER_RT_OS_DIR=wasi"
+
+              "-DCOMPILER_RT_BAREMETAL_BUILD=On"
+              "-DCOMPILER_RT_DEFAULT_TARGET_ONLY=On"
+
+              ;; WASM only needs libclang_rt.builtins-wasm32.a from
+              ;; compiler-rt.
+              (string-append "../compiler-rt-"
+                             #$(package-version clang-runtime-13)
+                             ".src/lib/builtins"))))))
+
+;; FIXME: Ideally we wouldn't need to build a separate compiler because clang
+;; can support multiple targets at runtime.  However Guix patches the default
+;; clang with a specific clang-runtime package.  It would be good to improve
+;; upstream Guix's support for cross-compiling with clang.
+
+(define clang-from-llvm (@@ (gnu packages llvm) clang-from-llvm))
+
+(define-public wasm32-wasi-clang
+  (let ((base (clang-from-llvm llvm-13 wasm32-wasi-clang-runtime
+                               "1j8pr5kk8iqyb4jds3yl7c6x672617h4ngkpl4575j7mk4nrwykq")))
+    (package (inherit base)
+      (name "wasm32-wasi-clang")
+      (inputs
+       (modify-inputs (package-inputs base)
+         (prepend wasi-libc)))
+      (arguments
+       (substitute-keyword-arguments (package-arguments base)
+         ((#:configure-flags flags)
+          #~(list "-DCLANG_INCLUDE_TESTS=True"
+                  ;; Use a sane default include directory.
+                  (string-append "-DC_INCLUDE_DIRS="
+                                 #$wasi-libc
+                                 "/wasm32-wasi/include")))
+         ((#:phases phases)
+          `(modify-phases ,phases
+             (delete 'symlink-cfi_ignorelist))))))))
+
+(define-public wasm32-wasi-libcxx
+  (package
+    (name "wasm32-wasi-libcxx")
+    (version "13.0.0")
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/llvm/llvm-project")
+             (commit (string-append "llvmorg-" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "0cjl0vssi4y2g4nfr710fb6cdhxmn5r0vis15sf088zsc5zydfhw"))))
+    (build-system cmake-build-system)
+    (arguments
+     (list
+      #:configure-flags
+      #~(list (string-append "-S ../source/runtimes")
+
+              "-DLLVM_ENABLE_RUNTIMES=libcxx;libcxxabi"
+
+              (string-append
+               "-DCMAKE_SYSROOT=" #$wasi-libc "/wasm32-wasi")
+
+              (string-append
+               "-DCMAKE_INCLUDE_PATH=" #$wasi-libc "/wasm32-wasi/include")
+
+              (string-append
+               "-DCMAKE_STAGING_PREFIX=" #$output "/wasm32-wasi")
+
+              "-DCMAKE_C_COMPILER=clang"
+              "-DCMAKE_C_COMPILER_WORKS=ON"
+              "-DCMAKE_CXX_COMPILER=clang++"
+              "-DCMAKE_CXX_COMPILER_WORKS=ON"
+              "-DCMAKE_C_COMPILER_TARGET=wasm32-wasi"
+              "-DCMAKE_CXX_COMPILER_TARGET=wasm32-wasi"
+
+              "-DLIBCXX_LIBDIR_SUFFIX=/wasm32-wasi"
+
+              "-DLIBCXX_ENABLE_EXCEPTIONS=OFF"
+              "-DLIBCXX_ENABLE_SHARED=OFF"
+              "-DLIBCXX_ENABLE_THREADS=OFF"
+              "-DLIBCXX_ENABLE_FILESYSTEM=OFF"
+
+              "-DLIBCXXABI_LIBDIR_SUFFIX=/wasm32-wasi"
+
+              "-DLIBCXXABI_ENABLE_EXCEPTIONS=OFF"
+              "-DLIBCXXABI_ENABLE_SHARED=OFF"
+              "-DLIBCXXABI_ENABLE_THREADS=OFF"
+              "-DLIBCXXABI_ENABLE_FILESYSTEM=OFF")
+      #:tests? #f
+      #:phases
+      #~(modify-phases %standard-phases
+          (add-after 'set-paths 'adjust-CPLUS_INCLUDE_PATH
+            (lambda _
+              (setenv "CPLUS_INCLUDE_PATH"
+                      (string-append #$wasi-libc "/wasm32-wasi/include:"
+                                     (getenv "CPLUS_INCLUDE_PATH"))))))))
+    (native-inputs
+     (list wasm32-wasi-clang lld python))
+    (inputs
+     (list wasi-libc))
+    (home-page "https://libcxx.llvm.org")
+    (synopsis "C++ standard library, for WebAssembly")
+    (description
+     "This package provides an implementation of the C++ standard library for
+use with Clang, targeting C++11, C++14 and above.  This package targets
+WebAssembly with WASI.")
+    (license license:expat)))
+
+(define-public wasm32-wasi-clang-toolchain
+  (package
+    (name "wasm32-wasi-clang-toolchain")
+    (version (package-version wasm32-wasi-clang))
+    (source #f)
+    (build-system trivial-build-system)
+    (arguments
+     (list
+      #:builder
+      (with-imported-modules '((guix build union)
+                               (guix build utils))
+        #~(begin
+            (use-modules (guix build union)
+                         (guix build utils))
+            (union-build #$output
+                         (list #$wasm32-wasi-clang-runtime
+                               #$wasi-libc
+                               #$wasm32-wasi-libcxx))
+            (mkdir-p (string-append #$output "/bin"))
+
+            ;; We provide clang and clang++ via a wrapped program that sets
+            ;; include paths correctly so that it does not include paths from
+            ;; the host.
+
+            ;; FIXME: Review how we can provide better support for
+            ;; cross-compiling with clang in Guix, maybe adding support for
+            ;; the CROSS_C_INCLUDE_PATH and CROSS_CPLUS_INCLUDE_PATH
+            ;; environment variables like GCC.
+
+            (for-each
+             (lambda (bin)
+               (symlink (string-append #$wasm32-wasi-clang bin)
+                        (string-append #$output bin))
+               (wrap-program (string-append #$output bin)
+                 #:sh (string-append #$bash-minimal "/bin/bash")
+                 `("C_INCLUDE_PATH" ":" =
+                   (,(string-append #$output "/wasm32-wasi/include")))
+                 `("CPLUS_INCLUDE_PATH" ":" =
+                   ;; Make sure inclure/c++/v1 comes first for #include_next
+                   ;; to work.
+                   (,(string-append #$output "/wasm32-wasi/include/c++/v1")
+                    ,(string-append #$output "/wasm32-wasi/include")))))
+             '("/bin/clang" "/bin/clang++"))
+
+            (symlink (string-append #$lld "/bin/wasm-ld")
+                     (string-append #$output "/bin/wasm-ld"))))))
+    (inputs
+     (list bash-minimal
+           lld
+           wasm32-wasi-clang
+           wasm32-wasi-clang-runtime
+           wasi-libc
+           wasm32-wasi-libcxx))
+    (license (cons
+              (package-license wasm32-wasi-clang)
+              (package-license wasi-libc)))
+    (home-page "https://clang.llvm.org")
+    (synopsis "Complete Clang toolchain for C/C++ development, for WebAssembly.")
+    (description "This package provides a complete Clang toolchain for C/C++
+development targeting WebAssembly with WASI.  This includes Clang, as well as
+libc, libc++ and wasm-ld.")))
-- 
2.34.0


  parent reply	other threads:[~2022-03-03 21:24 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-03 16:02 [bug#54239] [PATCH] gnu: Add cross-clang Julien Lepiller
2022-03-03 16:07 ` [bug#54239] [PATCH 1/5] gnu: Add cross-llvm Julien Lepiller
2022-03-03 16:07   ` [bug#54239] [PATCH 2/5] gnu: Add cross-clang Julien Lepiller
2022-03-03 16:07   ` [bug#54239] [PATCH 3/5] gnu: libcxx: Allow cross-compilation Julien Lepiller
2022-03-03 16:07   ` [bug#54239] [PATCH 4/5] gnu: libcxxabi-6: " Julien Lepiller
2022-03-03 16:07   ` [bug#54239] [PATCH 5/5] gnu: Add libcxxabi-9 Julien Lepiller
2022-03-03 16:40 ` [bug#54239] [PATCH] gnu: Add cross-clang Maxime Devos
2022-03-03 18:35   ` Julien Lepiller
2022-03-03 18:59     ` Maxime Devos
2022-03-03 21:11       ` Julien Lepiller
2022-03-04 20:05     ` Maxime Devos
2022-03-03 20:51 ` Pierre Langlois [this message]
2022-03-03 21:20   ` Julien Lepiller
2022-03-04  9:59 ` [bug#54239] [PATCH v2 1/5] gnu: Add cross-llvm Julien Lepiller
2022-03-04  9:59   ` [bug#54239] [PATCH v2 2/5] gnu: Add cross-clang Julien Lepiller
2022-03-04 19:53     ` Maxime Devos
2022-03-04 19:54     ` Maxime Devos
2022-03-05  8:30       ` Julien Lepiller
2022-03-04 19:56     ` Maxime Devos
2022-03-04 20:00     ` Maxime Devos
2022-03-05 16:05     ` Pierre Langlois
2022-03-04  9:59   ` [bug#54239] [PATCH v2 3/5] gnu: libcxx: Allow cross-compilation Julien Lepiller
2022-03-04  9:59   ` [bug#54239] [PATCH v2 4/5] gnu: libcxxabi-6: " Julien Lepiller
2022-03-04  9:59   ` [bug#54239] [PATCH v2 5/5] gnu: Add libcxxabi-9 Julien Lepiller
2022-03-04 19:50     ` Maxime Devos
2022-05-21 13:41       ` [bug#54239] [PATCH] gnu: Add cross-clang Ludovic Courtès
2022-07-16 19:44         ` Julien Lepiller
2022-07-16 19:47           ` [bug#54239] [PATCH v3 01/10] guix: Add build-system transformation for target Julien Lepiller
2022-07-16 19:47             ` [bug#54239] [PATCH v3 02/10] gnu: clang-runtime: Fix cross-compilation Julien Lepiller
2022-07-16 19:48             ` [bug#54239] [PATCH v3 03/10] gnu: llvm-9: " Julien Lepiller
2022-07-16 19:48             ` [bug#54239] [PATCH v3 04/10] gnu: Add cross-llvm Julien Lepiller
2022-07-16 19:48             ` [bug#54239] [PATCH v3 05/10] gnu: Add cross-clang Julien Lepiller
2022-07-16 19:48             ` [bug#54239] [PATCH v3 06/10] gnu: libcxx: Allow cross-compilation Julien Lepiller
2022-07-16 19:48             ` [bug#54239] [PATCH v3 07/10] gnu: libcxxabi-6: " Julien Lepiller
2022-07-16 19:48             ` [bug#54239] [PATCH v3 08/10] gnu: Add libcxxabi-9 Julien Lepiller
2022-07-16 19:48             ` [bug#54239] [PATCH v3 09/10] gnu: Add libcxx-12 Julien Lepiller
2022-07-16 19:48             ` [bug#54239] [PATCH v3 10/10] gnu: Add libcxxabi-12 Julien Lepiller
2022-07-19 19:54           ` [bug#54239] [PATCH] gnu: Add cross-clang Maxime Devos
2022-07-19 20:42             ` Julien Lepiller
2022-03-04 19:34   ` [bug#54239] [PATCH v2 1/5] gnu: Add cross-llvm Pierre Langlois
2022-03-05  8:24     ` Julien Lepiller
2022-03-05 13:02       ` Pierre Langlois
2022-03-05 14:00   ` Pierre Langlois

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87wnhapwsv.fsf@gmx.com \
    --to=pierre.langlois@gmx.com \
    --cc=54239@debbugs.gnu.org \
    --cc=julien@lepiller.eu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).