File 0000-invoke-lld-llvm15.patch of Package zig
From: Soc Virnyl Estela <socvirnyl.estela@gmail.com>
Date: Fri, 18 Nov 2022 14:09:02 PST
Based on Aaron Puchert's <aaronpuchert@alice-dsl.net> patch.
diff -bur zig-0.10.0.orig/CMakeLists.txt zig-0.10.0/CMakeLists.txt
--- zig-0.10.0.orig/CMakeLists.txt 2022-11-17 19:51:09.821938555 +0800
+++ zig-0.10.0/CMakeLists.txt 2022-11-18 13:06:07.734666684 +0800
@@ -137,7 +137,7 @@
find_package(llvm 15)
find_package(clang 15)
-find_package(lld 15)
+# find_package(lld 15)
if(ZIG_STATIC_ZLIB)
list(REMOVE_ITEM LLVM_LIBRARIES "-lz")
@@ -173,7 +173,7 @@
endforeach(CONFIG_TYPE CMAKE_CONFIGURATION_TYPES)
include_directories(${LLVM_INCLUDE_DIRS})
-include_directories(${LLD_INCLUDE_DIRS})
+# include_directories(${LLD_INCLUDE_DIRS})
include_directories(${CLANG_INCLUDE_DIRS})
# No patches have been applied to SoftFloat-3e
@@ -954,7 +954,7 @@
target_link_libraries(zigcpp LINK_PUBLIC
${CLANG_LIBRARIES}
- ${LLD_LIBRARIES}
+ # ${LLD_LIBRARIES}
${LLVM_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
)
diff -bur zig-0.10.0.orig/src/zig_llvm.cpp zig-0.10.0/src/zig_llvm.cpp
--- zig-0.10.0.orig/src/zig_llvm.cpp 2022-11-17 19:51:11.149937665 +0800
+++ zig-0.10.0/src/zig_llvm.cpp 2022-11-18 13:43:03.820487759 +0800
@@ -65,7 +65,8 @@
#include <llvm/Transforms/Utils/CanonicalizeAliases.h>
#include <llvm/Transforms/Utils/NameAnonGlobals.h>
-#include <lld/Common/Driver.h>
+// Commented out because openSUSE does not ship static libraries for LLD
+// #include <lld/Common/Driver.h>
#if __GNUC__ >= 9
#pragma GCC diagnostic pop
@@ -73,10 +74,96 @@
#include <new>
+#include <poll.h>
#include <stdlib.h>
+#include <spawn.h>
+#include <sys/wait.h>
+#include <unistd.h>
using namespace llvm;
+namespace {
+
+class Pipe {
+public:
+ Pipe(llvm::raw_ostream *output) : output(output) {}
+ ~Pipe() {
+ if (fd[0] != -1) close(fd[0]);
+ if (fd[1] != -1) close(fd[1]);
+ }
+ bool open() { return pipe(fd) == 0; }
+ int getRead() const { return fd[0]; }
+ int getWrite() const { return fd[1]; }
+ void closeWrite() { close(fd[1]); fd[1] = -1; }
+ void flush() const {
+ constexpr size_t size = 1024;
+ char buf[size];
+ ssize_t ret;
+ do {
+ ret = read(getRead(), buf, size);
+ if (ret > 0 && output)
+ output->write(buf, ret);
+ } while (ret == size || (ret == -1 && errno == EINTR));
+ }
+
+private:
+ int fd[2] = {-1, -1};
+ llvm::raw_ostream *output;
+};
+
+} // anonymous namespace
+
+static bool InvokeLld(const char *variant, llvm::ArrayRef<const char *> args,
+ llvm::raw_ostream &stdoutOS,
+ llvm::raw_ostream &stderrOS, bool disableOutput)
+{
+ Pipe outPipe(disableOutput ? nullptr : &stdoutOS),
+ errPipe(disableOutput ? nullptr : &stderrOS);
+ if (!outPipe.open())
+ return false;
+ if (!errPipe.open())
+ return false;
+
+ posix_spawn_file_actions_t actions;
+ posix_spawn_file_actions_init(&actions);
+ posix_spawn_file_actions_adddup2(&actions, outPipe.getWrite(), STDOUT_FILENO);
+ posix_spawn_file_actions_adddup2(&actions, errPipe.getWrite(), STDERR_FILENO);
+
+ // We need the command as argument, and end with nullptr.
+ SmallVector<char*, 32> arguments{const_cast<char*>(variant)};
+ for (size_t arg = 1; arg != args.size(); ++arg)
+ arguments.push_back(const_cast<char*>(args[arg]));
+ arguments.push_back(nullptr);
+
+ pid_t pid;
+ if (posix_spawnp(&pid, variant, &actions, nullptr, arguments.data(), environ) != 0)
+ return false;
+ posix_spawn_file_actions_destroy(&actions);
+ outPipe.closeWrite();
+ errPipe.closeWrite();
+
+ // Wait for child to finish and flush pipes.
+ sigset_t signals, old;
+ sigemptyset(&signals);
+ sigaddset(&signals, SIGCHLD);
+ pthread_sigmask(SIG_BLOCK, &signals, &old);
+ pollfd pollfds[2] = {{outPipe.getRead(), POLLIN}, {errPipe.getRead(), POLLIN}};
+ int wstatus;
+ do {
+ poll(pollfds, 2, -1);
+ if (pollfds[0].revents & POLLIN)
+ outPipe.flush();
+ if (pollfds[1].revents & POLLIN)
+ errPipe.flush();
+ } while (waitpid(pid, &wstatus, WNOHANG) == 0);
+ pthread_sigmask(SIG_SETMASK, &old, nullptr);
+
+ outPipe.flush();
+ errPipe.flush();
+
+ return WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 0;
+}
+
void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R) {
initializeLoopStrengthReducePass(*unwrap(R));
}
@@ -1347,18 +1434,15 @@ bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size
}
bool ZigLLDLinkCOFF(int argc, const char **argv, bool can_exit_early, bool disable_output) {
- std::vector<const char *> args(argv, argv + argc);
- return lld::coff::link(args, llvm::outs(), llvm::errs(), can_exit_early, disable_output);
+ return InvokeLld("lld-link", llvm::ArrayRef<const char *>(argv, argc), llvm::outs(), llvm::errs(), disable_output);
}
bool ZigLLDLinkELF(int argc, const char **argv, bool can_exit_early, bool disable_output) {
- std::vector<const char *> args(argv, argv + argc);
- return lld::elf::link(args, llvm::outs(), llvm::errs(), can_exit_early, disable_output);
+ return InvokeLld("ld.lld", llvm::ArrayRef<const char *>(argv, argc), llvm::outs(), llvm::errs(), disable_output);
}
bool ZigLLDLinkWasm(int argc, const char **argv, bool can_exit_early, bool disable_output) {
- std::vector<const char *> args(argv, argv + argc);
- return lld::wasm::link(args, llvm::outs(), llvm::errs(), can_exit_early, disable_output);
+ return InvokeLld("wasm-ld", llvm::ArrayRef<const char *>(argv, argc), llvm::outs(), llvm::errs(), disable_output);
}
inline LLVMAttributeRef wrap(Attribute Attr) {