Skip to content

Commit

Permalink
PoCL: Bundle parts of the sysroot to make Clang work. (#9656)
Browse files Browse the repository at this point in the history
  • Loading branch information
maleadt authored Oct 21, 2024
1 parent 60702e9 commit 239c897
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 7 deletions.
42 changes: 35 additions & 7 deletions P/pocl/build_tarballs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ sources = [

#=
POCL wants to be linked against LLVM for run-time code generation, but also generates code
PoCL wants to be linked against LLVM for run-time code generation, but also generates code
at compile time using LLVM tools, so we need to carefully select which of the different
builds of LLVM we need:
Expand All @@ -48,18 +48,19 @@ atomic_patch -p1 $WORKSPACE/srcdir/patches/freebsd.patch
atomic_patch -p1 $WORKSPACE/srcdir/patches/distro-generic.patch
atomic_patch -p1 $WORKSPACE/srcdir/patches/env-override.patch
atomic_patch -p1 $WORKSPACE/srcdir/patches/env-override-ld.patch
atomic_patch -p1 $WORKSPACE/srcdir/patches/env-override-args.patch
# POCL wants a target sysroot for compiling the host kernellib (for `math.h` etc)
sysroot=/opt/${target}/${target}/sys-root/usr/include
sysroot=/opt/${target}/${target}/sys-root
if [[ "${target}" == *apple* ]]; then
# XXX: including the sysroot like this doesn't work on Apple, missing definitions like
# TARGET_OS_IPHONE. it seems like these headers should be included using -isysroot,
# but (a) that doesn't seem to work, and (b) isn't that already done by the cmake
# toolchain file? work around the issue by inserting an include for the missing
# definitions at the top of the headers included from POCL's kernel library.
sed -i '1s/^/#include <TargetConditionals.h>\n/' $sysroot/stdio.h
sed -i '1s/^/#include <TargetConditionals.h>\n/' $sysroot/usr/include/stdio.h
fi
sed -i "s|COMMENT \\"Building C to LLVM bitcode \${BC_FILE}\\"|\\"-I$sysroot\\"|" \
sed -i "s|COMMENT \\"Building C to LLVM bitcode \${BC_FILE}\\"|\\"-I$sysroot/usr/include\\"|" \
cmake/bitcode_rules.cmake
CMAKE_FLAGS=()
Expand Down Expand Up @@ -95,6 +96,29 @@ fi
cmake -B build -S . -GNinja ${CMAKE_FLAGS[@]}
ninja -C build -j ${nproc} install
# PoCL uses Clang, which relies on certain system libraries Clang_jll.jl doesn't provide
mkdir -p $prefix/share/lib
if [[ ${target} == *-linux-gnu-* ]]; then
if [[ "${nbits}" == 64 ]]; then
cp -a $sysroot/lib64/libc{.,-}* $prefix/share/lib
cp -a $sysroot/usr/lib64/libm.* $prefix/share/lib
ln -sf libm.so.6 $prefix/share/lib/libm.so
cp -a $sysroot/lib64/libm{.,-}* $prefix/share/lib
cp -a /opt/${target}/${target}/lib64/libgcc_s.* $prefix/share/lib
cp -a /opt/$target/lib/gcc/$target/*/*.{o,a} $prefix/share/lib
else
cp -a $sysroot/lib/libc{.,-}* $prefix/share/lib
cp -a $sysroot/usr/lib/libm.* $prefix/share/lib
ln -sf libm.so.6 $prefix/share/lib/libm.so
cp -a $sysroot/lib/libm{.,-}* $prefix/share/lib
cp -a /opt/${target}/${target}/lib/libgcc_s.* $prefix/share/lib
cp -a /opt/$target/lib/gcc/$target/*/*.{o,a} $prefix/share/lib
fi
elif [[ ${target} == *-linux-musl-* ]]; then
cp -a $sysroot/usr/lib/*.{o,a} $prefix/share/lib
cp -a /opt/$target/lib/gcc/$target/*/*.{o,a} $prefix/share/lib
fi
"""

# These are the platforms we will build for by default, unless further
Expand Down Expand Up @@ -206,9 +230,13 @@ init_block = raw"""
else
error("Unsupported platform")
end
ENV["POCL_PATH_LD"] =
generate_wrapper_script("lld", ld_path,
LLD_unified_jll.LIBPATH[], LLD_unified_jll.PATH[])
ld_wrapper = generate_wrapper_script("lld", ld_path,
LLD_unified_jll.LIBPATH[],
LLD_unified_jll.PATH[])
ENV["POCL_ARGS_CLANG"] = join([
"-fuse-ld=lld", "--ld-path=$ld_wrapper",
"-L" * joinpath(artifact_dir, "share", "lib")
], ";")
"""

# determine exactly which tarballs we should build
Expand Down
119 changes: 119 additions & 0 deletions P/pocl/bundled/patches/env-override-args.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
From 4663081155ce0af4ebacd5a3429eba9449f35b0f Mon Sep 17 00:00:00 2001
From: Tim Besard <tim.besard@gmail.com>
Date: Mon, 21 Oct 2024 09:40:13 +0200
Subject: [PATCH] Replace POCL_PATH_LD by a more generic POCL_ARGS_CLANG.

---
doc/sphinx/source/using.rst | 12 +++++++++++-
lib/CL/pocl_llvm_build.cc | 12 ++++++++----
lib/CL/pocl_runtime_config.c | 28 ++++++++++++++++++++++++++++
lib/CL/pocl_runtime_config.h | 3 +++
4 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/doc/sphinx/source/using.rst b/doc/sphinx/source/using.rst
index cdf9b5172..b366e611b 100644
--- a/doc/sphinx/source/using.rst
+++ b/doc/sphinx/source/using.rst
@@ -311,13 +311,23 @@ pocl.
The following variables are available:

* **POCL_PATH_CLANG** -- Path to the clang executable.
- * **POCL_PATH_LD** -- Path to the ld executable used by clang.
* **POCL_PATH_LLVM_LINK** -- Path to the llvm-link executable.
* **POCL_PATH_LLVM_OPT** -- Path to the llvm-opt executable.
* **POCL_PATH_LLVM_LLC** -- Path to the llc executable.
* **POCL_PATH_LLVM_SPIRV** -- Path to the llvm-spirv executable.
* **POCL_PATH_SPIRV_LINK** -- Path to the spirv-link executable.

+- **POCL_ARGS_XXX**
+
+ String. These variables can be used to pass additional arguments to executables
+ that pocl invokes during compilation, linking, etc. Multiple arguments can be
+ passed by separating them with a semicolon.
+
+ The following variables are available:
+
+ * **POCL_ARGS_CLANG** -- Additional arguments to pass to clang.
+
+
- **POCL_SIGFPE_HANDLER**

Defaults to 1. If set to 0, pocl will not install the SIGFPE handler.
diff --git a/lib/CL/pocl_llvm_build.cc b/lib/CL/pocl_llvm_build.cc
index b425d5edc..1892ab13d 100644
--- a/lib/CL/pocl_llvm_build.cc
+++ b/lib/CL/pocl_llvm_build.cc
@@ -1047,15 +1047,19 @@ int pocl_invoke_clang(cl_device_id Device, const char** Args) {
while (*ArgsEnd++ != nullptr) {}
llvm::SmallVector<const char*, 0> ArgsArray(Args, ArgsEnd);

- std::string LDPath;
- if (const char* LDOverride = pocl_get_path("LD", nullptr)) {
- LDPath = "--ld-path=" + std::string(LDOverride);
- ArgsArray.push_back(LDPath.c_str());
+ int NumExtraArgs;
+ const char *ExtraArgs = pocl_get_args("CLANG", &NumExtraArgs);
+ const char *ExtraArg = ExtraArgs;
+ for (int i = 0; i < NumExtraArgs; ++i) {
+ ArgsArray.push_back(ExtraArg);
+ ExtraArg += strlen(ExtraArg) + 1;
}

std::unique_ptr<clang::driver::Compilation> C(
TheDriver.BuildCompilation(ArgsArray));

+ free((void *)ExtraArgs);
+
if (C && !C->containsError()) {
SmallVector<std::pair<int, const clang::driver::Command *>, 4> FailingCommands;
return TheDriver.ExecuteCompilation(*C, FailingCommands);
diff --git a/lib/CL/pocl_runtime_config.c b/lib/CL/pocl_runtime_config.c
index 3f596549e..4a7e38b54 100644
--- a/lib/CL/pocl_runtime_config.c
+++ b/lib/CL/pocl_runtime_config.c
@@ -67,3 +67,31 @@ pocl_get_path (const char *name, const char *default_value)
snprintf (key, sizeof (key), "POCL_PATH_%s", name);
return pocl_get_string_option (key, default_value);
}
+
+/* Returns `n` null-terminated strings representing arguments
+ for an invocation. Can be set using the POCL_ARGS env vars.
+ If the env var is not set, returns NULL and sets `n` to zero. */
+char *
+pocl_get_args (const char *name, int *n)
+{
+ char key[256];
+ snprintf (key, sizeof (key), "POCL_ARGS_%s", name);
+ const char *val = getenv (key);
+ if (val == NULL)
+ {
+ *n = 0;
+ return NULL;
+ }
+
+ char *args = strdup (val);
+ *n = 1;
+ for (char *p = args; *p; ++p)
+ {
+ if (*p == ';')
+ {
+ *p = 0;
+ ++(*n);
+ }
+ }
+ return args;
+}
diff --git a/lib/CL/pocl_runtime_config.h b/lib/CL/pocl_runtime_config.h
index 3d58a7b9e..6dafd5340 100644
--- a/lib/CL/pocl_runtime_config.h
+++ b/lib/CL/pocl_runtime_config.h
@@ -43,6 +43,9 @@ const char* pocl_get_string_option(const char *key, const char *default_value);
POCL_EXPORT
const char *pocl_get_path (const char *name, const char *default_value);

+POCL_EXPORT
+char *pocl_get_args (const char *name, int *n);
+
#ifdef __cplusplus
}
#endif

0 comments on commit 239c897

Please sign in to comment.