Source: ldc Version: 1:1.30.0-1 Severity: wishlist Tags: ftbf, patch User: debian-riscv@lists.debian.org Usertags: riscv64 X-Debbugs-Cc: debian-riscv@lists.debian.org Dear Maintainer, Now ldc does not support riscv64 either upstream or Debian. Fortunately, The Arch linux has porting the riscv64 support[0] for ldc. And I try to build ldc on Debian riscv64 arch with their patch. Despite the twists and turns of the process, in the end the build was successfully. I also got the support from upstream[1]. The patch attached is to add support for riscv64 on Debian. I have tested it on my riscv machines. The mirror issue in the patch here is I have to disable check D_COMPILER_FLAGS from CMake. I am not sure if this is the inappropriate DADDITIONAL_DEFAULT_LDC_SWITCHES flag I added in the d/rules. Anyway, it works. The next version of ldc from upstream will have better support for riscv64 as upstream said. I think this is good start to add support riscv64 build about D language packages if apply the change on Debian. Please let me know if there is any issues. [0]: https://github.com/felixonmars/archriscv-packages/blob/master/ldc/riscv64.patch [1]: https://github.com/ldc-developers/ldc/issues/4046 -- Regards, -- Bo YU
diff -Nru ldc-1.30.0/debian/control ldc-1.30.0/debian/control
--- ldc-1.30.0/debian/control 2022-08-13 00:42:49.000000000 +0800
+++ ldc-1.30.0/debian/control 2022-08-13 02:28:55.000000000 +0800
@@ -26,7 +26,7 @@
Vcs-Browser: https://salsa.debian.org/d-team/ldc
Package: ldc
-Architecture: amd64 arm64 armhf i386
+Architecture: amd64 arm64 armhf i386 riscv64
Provides: d-compiler,
d-v2-compiler
Depends: libphobos2-ldc-shared-dev (= ${binary:Version}),
@@ -41,7 +41,7 @@
Package: libphobos2-ldc-shared100
Section: libs
-Architecture: amd64 arm64 armhf i386
+Architecture: amd64 arm64 armhf i386 riscv64
Multi-Arch: same
Depends: ${misc:Depends},
${shlibs:Depends}
@@ -56,7 +56,7 @@
Package: libphobos2-ldc-shared-dev
Section: libdevel
-Architecture: amd64 arm64 armhf i386
+Architecture: amd64 arm64 armhf i386 riscv64
Depends: libphobos2-ldc-shared100 (= ${binary:Version}),
${misc:Depends},
${shlibs:Depends}
diff -Nru ldc-1.30.0/debian/patches/04_support-riscv64.patch ldc-1.30.0/debian/patches/04_support-riscv64.patch
--- ldc-1.30.0/debian/patches/04_support-riscv64.patch 1970-01-01 07:30:00.000000000 +0730
+++ ldc-1.30.0/debian/patches/04_support-riscv64.patch 2022-08-13 02:28:55.000000000 +0800
@@ -0,0 +1,578 @@
+refer to:
+https://patch-diff.githubusercontent.com/raw/ldc-developers/ldc/pull/4007.patch
+https://patch-diff.githubusercontent.com/raw/ldc-developers/druntime/pull/204.patch
+https://github.com/ldc-developers/phobos/pull/71.patch
+
+Help from:
+https://github.com/ldc-developers/ldc/issues/4046
+
+--- a/driver/tool.cpp
++++ b/driver/tool.cpp
+@@ -120,6 +120,11 @@
+ }
+ return;
+
++ case Triple::riscv64:
++ args.push_back("-march=rv64gc");
++ args.push_back("-mabi=lp64d");
++ return;
++
+ default:
+ break;
+ }
+--- /dev/null
++++ b/gen/abi-riscv64.cpp
+@@ -0,0 +1,234 @@
++//===-- gen/abi-riscv64.cpp - RISCV64 ABI description -----------*- C++ -*-===//
++//
++// LDC – the LLVM D compiler
++//
++// This file is distributed under the BSD-style LDC license. See the LICENSE
++// file for details.
++//
++//===----------------------------------------------------------------------===//
++
++#include "gen/abi.h"
++#include "gen/abi-generic.h"
++#include "gen/abi-riscv64.h"
++#include "gen/dvalue.h"
++#include "gen/irstate.h"
++#include "gen/llvmhelpers.h"
++#include "gen/tollvm.h"
++
++namespace {
++struct Integer2Rewrite : BaseBitcastABIRewrite {
++ LLType *type(Type *t) override {
++ return LLStructType::get(gIR->context(),
++ {DtoType(Type::tint64), DtoType(Type::tint64)});
++ }
++};
++
++struct FlattenedFields {
++ struct FlattenedField {
++ Type *ty = nullptr;
++ unsigned offset = 0;
++ };
++ FlattenedField fields[2];
++ int length = 0; // use -1 to represent "no need to rewrite" condition
++};
++
++FlattenedFields visitStructFields(Type *ty, unsigned baseOffset) {
++ // recursively visit a POD struct to flatten it
++ // FIXME: may cause low performance
++ // dmd may cache argtypes in some other architectures as a TypeTuple, but we
++ // need to additionally store field offsets to realign later
++ FlattenedFields result;
++ if (auto ts = ty->toBasetype()->isTypeStruct()) {
++ for (auto fi : ts->sym->fields) {
++ auto sub = visitStructFields(fi->type, baseOffset + fi->offset);
++ if (sub.length == -1 || result.length + sub.length > 2) {
++ result.length = -1;
++ return result;
++ }
++ for (unsigned i = 0; i < (unsigned)sub.length; ++i) {
++ result.fields[result.length++] = sub.fields[i];
++ }
++ }
++ return result;
++ }
++ switch (ty->toBasetype()->ty) {
++ case TY::Tcomplex32: // treat it as {float32, float32}
++ result.fields[0].ty = Type::tfloat32->pointerTo();
++ result.fields[1].ty = Type::tfloat32->pointerTo();
++ result.fields[0].offset = baseOffset;
++ result.fields[1].offset = baseOffset + 4;
++ result.length = 2;
++ break;
++ case TY::Tcomplex64: // treat it as {float64, float64}
++ result.fields[0].ty = Type::tfloat64->pointerTo();
++ result.fields[1].ty = Type::tfloat64->pointerTo();
++ result.fields[0].offset = baseOffset;
++ result.fields[1].offset = baseOffset + 8;
++ result.length = 2;
++ break;
++ default:
++ if (ty->toBasetype()->size() > 8) {
++ // field larger than XLEN and FLEN
++ result.length = -1;
++ break;
++ }
++ result.fields[0].ty = ty->toBasetype();
++ result.fields[0].offset = baseOffset;
++ result.length = 1;
++ break;
++ }
++ return result;
++}
++
++bool requireHardfloatRewrite(Type *ty) {
++ if (!ty->toBasetype()->isTypeStruct())
++ return false;
++ auto result = visitStructFields(ty, 0);
++ if (result.length <= 0)
++ return false;
++ if (result.length == 1)
++ return result.fields[0].ty->isfloating();
++ return result.fields[0].ty->isfloating() || result.fields[1].ty->isfloating();
++}
++
++struct HardfloatRewrite : ABIRewrite {
++ LLValue *put(DValue *dv, bool, bool) override {
++ // realign fields
++ // FIXME: no need to alloc an extra buffer in many conditions
++ const auto flat = visitStructFields(dv->type, 0);
++ LLType *asType = type(dv->type, flat);
++ const unsigned alignment = getABITypeAlign(asType);
++ assert(dv->isLVal());
++ LLValue *address = DtoLVal(dv);
++ LLValue *buffer =
++ DtoRawAlloca(asType, alignment, ".HardfloatRewrite_arg_storage");
++ for (unsigned i = 0; i < (unsigned)flat.length; ++i) {
++ DtoMemCpy(
++ DtoGEP(buffer, 0, i),
++ DtoGEP1(DtoBitCast(address, getVoidPtrType()), flat.fields[i].offset),
++ DtoConstSize_t(flat.fields[i].ty->size()));
++ }
++ return DtoLoad(buffer, ".HardfloatRewrite_arg");
++ }
++ LLValue *getLVal(Type *dty, LLValue *v) override {
++ // inverse operation of method "put"
++ const auto flat = visitStructFields(dty, 0);
++ LLType *asType = type(dty, flat);
++ const unsigned alignment = DtoAlignment(dty);
++ LLValue *buffer = DtoAllocaDump(v, asType, getABITypeAlign(asType),
++ ".HardfloatRewrite_param");
++ LLValue *ret = DtoRawAlloca(DtoType(dty), alignment,
++ ".HardfloatRewrite_param_storage");
++ for (unsigned i = 0; i < (unsigned)flat.length; ++i) {
++ DtoMemCpy(
++ DtoGEP1(DtoBitCast(ret, getVoidPtrType()), flat.fields[i].offset),
++ DtoGEP(buffer, 0, i), DtoConstSize_t(flat.fields[i].ty->size()));
++ }
++ return ret;
++ }
++ LLType *type(Type *ty, const FlattenedFields &flat) {
++ if (flat.length == 1) {
++ return LLStructType::get(gIR->context(), {DtoType(flat.fields[0].ty)},
++ false);
++ }
++ assert(flat.length == 2);
++ LLType *t[2];
++ for (unsigned i = 0; i < 2; ++i) {
++ t[i] = flat.fields[i].ty->isfloating()
++ ? DtoType(flat.fields[i].ty)
++ : LLIntegerType::get(gIR->context(),
++ flat.fields[i].ty->size() * 8);
++ }
++ return LLStructType::get(gIR->context(), {t[0], t[1]}, false);
++ }
++ LLType *type(Type *ty) override { return type(ty, visitStructFields(ty, 0)); }
++};
++} // anonymous namespace
++
++struct RISCV64TargetABI : TargetABI {
++private:
++ HardfloatRewrite hardfloatRewrite;
++ IndirectByvalRewrite indirectByvalRewrite;
++ Integer2Rewrite integer2Rewrite;
++ IntegerRewrite integerRewrite;
++
++public:
++ Type *vaListType() override {
++ // va_list is void*
++ return Type::tvoid->pointerTo();
++ }
++ bool returnInArg(TypeFunction *tf, bool) override {
++ if (tf->isref()) {
++ return false;
++ }
++ Type *rt = tf->next->toBasetype();
++ if (!rt->size())
++ return false;
++ if (!isPOD(rt))
++ return true;
++ return rt->size() > 16;
++ }
++ bool passByVal(TypeFunction *, Type *t) override {
++ if (!t->size())
++ return false;
++ if (t->toBasetype()->ty == TY::Tcomplex80) {
++ // rewrite it later to bypass the RVal problem
++ return false;
++ }
++ return t->size() > 16;
++ }
++ void rewriteFunctionType(IrFuncTy &fty) override {
++ if (!fty.ret->byref) {
++ if (!skipReturnValueRewrite(fty)) {
++ if (!fty.ret->byref && isPOD(fty.ret->type) &&
++ requireHardfloatRewrite(fty.ret->type)) {
++ // rewrite here because we should not apply this to variadic arguments
++ hardfloatRewrite.applyTo(*fty.ret);
++ } else {
++ rewriteArgument(fty, *fty.ret);
++ }
++ }
++ }
++
++ for (auto arg : fty.args) {
++ if (!arg->byref && isPOD(arg->type) &&
++ requireHardfloatRewrite(arg->type)) {
++ // rewrite here because we should not apply this to variadic arguments
++ hardfloatRewrite.applyTo(*arg);
++ } else {
++ rewriteArgument(fty, *arg);
++ }
++ }
++ }
++
++ void rewriteArgument(IrFuncTy &fty, IrFuncTyArg &arg) override {
++ if (arg.byref) {
++ return;
++ }
++
++ Type *ty = arg.type->toBasetype();
++ if (ty->ty == TY::Tcomplex80) {
++ // {real, real} should be passed in memory
++ indirectByvalRewrite.applyTo(arg);
++ return;
++ }
++
++ if (!isPOD(arg.type)) {
++ // non-PODs should be passed in memory
++ indirectByvalRewrite.applyTo(arg);
++ return;
++ }
++
++ if (isAggregate(ty) && ty->size() && ty->size() <= 16) {
++ if (ty->size() > 8 && DtoAlignment(ty) < 16) {
++ // pass the aggregate as {int64, int64} to avoid wrong alignment
++ integer2Rewrite.applyToIfNotObsolete(arg);
++ } else {
++ integerRewrite.applyToIfNotObsolete(arg);
++ }
++ }
++ }
++};
++
++// The public getter for abi.cpp
++TargetABI *getRISCV64TargetABI() { return new RISCV64TargetABI(); }
+--- /dev/null
++++ b/gen/abi-riscv64.h
+@@ -0,0 +1,18 @@
++//===-- gen/abi-riscv64.h - RISCV64 ABI description ------------*- C++ -*-===//
++//
++// LDC – the LLVM D compiler
++//
++// This file is distributed under the BSD-style LDC license. See the LICENSE
++// file for details.
++//
++//===----------------------------------------------------------------------===//
++//
++// The ABI implementation used for RISCV64 targets.
++//
++//===----------------------------------------------------------------------===//
++
++#pragma once
++
++struct TargetABI;
++
++TargetABI *getRISCV64TargetABI();
+--- a/gen/abi.cpp
++++ b/gen/abi.cpp
+@@ -17,6 +17,7 @@
+ #include "gen/abi-arm.h"
+ #include "gen/abi-generic.h"
+ #include "gen/abi-mips64.h"
++#include "gen/abi-riscv64.h"
+ #include "gen/abi-ppc.h"
+ #include "gen/abi-ppc64le.h"
+ #include "gen/abi-win64.h"
+@@ -275,6 +276,8 @@
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ return getMIPS64TargetABI(global.params.targetTriple->isArch64Bit());
++ case llvm::Triple::riscv64:
++ return getRISCV64TargetABI();
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ return getPPCTargetABI(global.params.targetTriple->isArch64Bit());
+--- a/runtime/druntime/src/core/stdc/stdarg.d
++++ b/runtime/druntime/src/core/stdc/stdarg.d
+@@ -47,6 +47,8 @@
+ version (MIPS64) version = MIPS_Any;
+ version (PPC) version = PPC_Any;
+ version (PPC64) version = PPC_Any;
++version (RISCV32) version = RISCV_Any;
++version (RISCV64) version = RISCV_Any;
+
+ version (GNU)
+ {
+@@ -130,6 +132,12 @@
+ {
+ alias va_list = core.internal.vararg.aarch64.va_list;
+ }
++else version (RISCV_Any)
++{
++ // The va_list type is void*, according to RISCV Calling Convention
++ // https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc
++ alias va_list = void*;
++}
+ else
+ {
+ alias va_list = char*; // incl. unknown platforms
+@@ -259,6 +267,19 @@
+ ap += T.sizeof.alignUp;
+ return *p;
+ }
++ else version (RISCV_Any)
++ {
++ static if (T.sizeof > (size_t.sizeof << 1))
++ auto p = *cast(T**) ap;
++ else
++ {
++ static if (T.alignof == (size_t.sizeof << 1))
++ ap = ap.alignUp!(size_t.sizeof << 1);
++ auto p = cast(T*) ap;
++ }
++ ap += T.sizeof.alignUp;
++ return *p;
++ }
+ else
+ static assert(0, "Unsupported platform");
+ }
+--- a/runtime/druntime/src/core/sys/linux/elf.d
++++ b/runtime/druntime/src/core/sys/linux/elf.d
+@@ -2531,3 +2531,66 @@
+ enum R_TILEGX_GNU_VTENTRY = 129;
+
+ enum R_TILEGX_NUM = 130;
++
++enum EF_RISCV_RVC = 0x0001;
++enum EF_RISCV_FLOAT_ABI = 0x0006;
++enum EF_RISCV_FLOAT_ABI_SOFT = 0x0000;
++enum EF_RISCV_FLOAT_ABI_SINGLE = 0x0002;
++enum EF_RISCV_FLOAT_ABI_DOUBLE = 0x0004;
++enum EF_RISCV_FLOAT_ABI_QUAD = 0x0006;
++enum R_RISCV_NONE = 0;
++enum R_RISCV_32 = 1;
++enum R_RISCV_64 = 2;
++enum R_RISCV_RELATIVE = 3;
++enum R_RISCV_COPY = 4;
++enum R_RISCV_JUMP_SLOT = 5;
++enum R_RISCV_TLS_DTPMOD32 = 6;
++enum R_RISCV_TLS_DTPMOD64 = 7;
++enum R_RISCV_TLS_DTPREL32 = 8;
++enum R_RISCV_TLS_DTPREL64 = 9;
++enum R_RISCV_TLS_TPREL32 = 10;
++enum R_RISCV_TLS_TPREL64 = 11;
++enum R_RISCV_BRANCH = 16;
++enum R_RISCV_JAL = 17;
++enum R_RISCV_CALL = 18;
++enum R_RISCV_CALL_PLT = 19;
++enum R_RISCV_GOT_HI20 = 20;
++enum R_RISCV_TLS_GOT_HI20 = 21;
++enum R_RISCV_TLS_GD_HI20 = 22;
++enum R_RISCV_PCREL_HI20 = 23;
++enum R_RISCV_PCREL_LO12_I = 24;
++enum R_RISCV_PCREL_LO12_S = 25;
++enum R_RISCV_HI20 = 26;
++enum R_RISCV_LO12_I = 27;
++enum R_RISCV_LO12_S = 28;
++enum R_RISCV_TPREL_HI20 = 29;
++enum R_RISCV_TPREL_LO12_I = 30;
++enum R_RISCV_TPREL_LO12_S = 31;
++enum R_RISCV_TPREL_ADD = 32;
++enum R_RISCV_ADD8 = 33;
++enum R_RISCV_ADD16 = 34;
++enum R_RISCV_ADD32 = 35;
++enum R_RISCV_ADD64 = 36;
++enum R_RISCV_SUB8 = 37;
++enum R_RISCV_SUB16 = 38;
++enum R_RISCV_SUB32 = 39;
++enum R_RISCV_SUB64 = 40;
++enum R_RISCV_GNU_VTINHERIT = 41;
++enum R_RISCV_GNU_VTENTRY = 42;
++enum R_RISCV_ALIGN = 43;
++enum R_RISCV_RVC_BRANCH = 44;
++enum R_RISCV_RVC_JUMP = 45;
++enum R_RISCV_RVC_LUI = 46;
++enum R_RISCV_GPREL_I = 47;
++enum R_RISCV_GPREL_S = 48;
++enum R_RISCV_TPREL_I = 49;
++enum R_RISCV_TPREL_S = 50;
++enum R_RISCV_RELAX = 51;
++enum R_RISCV_SUB6 = 52;
++enum R_RISCV_SET6 = 53;
++enum R_RISCV_SET8 = 54;
++enum R_RISCV_SET16 = 55;
++enum R_RISCV_SET32 = 56;
++enum R_RISCV_32_PCREL = 57;
++enum R_RISCV_IRELATIVE = 58;
++enum R_RISCV_NUM = 59;
+--- a/runtime/druntime/src/core/sys/posix/fcntl.d
++++ b/runtime/druntime/src/core/sys/posix/fcntl.d
+@@ -123,6 +123,12 @@
+ enum F_SETLK = 6;
+ enum F_SETLKW = 7;
+ }
++ else version (RISCV64)
++ {
++ enum F_GETLK = 5;
++ enum F_SETLK = 6;
++ enum F_SETLKW = 7;
++ }
+ else version (SystemZ)
+ {
+ static assert(off_t.sizeof == 8);
+--- a/runtime/druntime/src/core/thread/osthread.d
++++ b/runtime/druntime/src/core/thread/osthread.d
+@@ -37,6 +37,9 @@
+ version (PPC) version = PPC_Any;
+ version (PPC64) version = PPC_Any;
+
++ version (RISCV32) version = RISCV_Any;
++ version (RISCV64) version = RISCV_Any;
++
+ version (SupportSanitizers)
+ {
+ import ldc.sanitizers_optionally_linked;
+@@ -1568,6 +1571,27 @@
+ asm pure nothrow @nogc { (store ~ " $29, %0") : "=m" (sp); }
+ asm pure nothrow @nogc { ".set at"; }
+ }
++ else version (RISCV_Any)
++ {
++ version (RISCV32) enum store = "sw";
++ else version (RISCV64) enum store = "sd";
++ else static assert(0);
++
++ // Callee-save registers, according to RISCV Calling Convention
++ // https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc
++ size_t[24] regs = void;
++ static foreach (i; 0 .. 12)
++ {{
++ enum int j = i;
++ asm pure nothrow @nogc { (store ~ " s"~j.stringof~", %0") : "=m" (regs[i]); }
++ }}
++ static foreach (i; 0 .. 12)
++ {{
++ enum int j = i;
++ asm pure nothrow @nogc { ("f" ~ store ~ " fs"~j.stringof~", %0") : "=m" (regs[i + 12]); }
++ }}
++ asm pure nothrow @nogc { (store ~ " sp, %0") : "=m" (sp); }
++ }
+ else
+ {
+ static assert(false, "Architecture not supported.");
+--- a/runtime/druntime/src/core/vararg.d
++++ b/runtime/druntime/src/core/vararg.d
+@@ -28,6 +28,8 @@
+ version (MIPS64) version = MIPS_Any;
+ version (PPC) version = PPC_Any;
+ version (PPC64) version = PPC_Any;
++version (RISCV32) version = RISCV_Any;
++version (RISCV64) version = RISCV_Any;
+
+ version (ARM_Any)
+ {
+@@ -136,6 +138,21 @@
+ ap += tsize.alignUp;
+ parmn[0..tsize] = p[0..tsize];
+ }
++ else version (RISCV_Any)
++ {
++ const tsize = ti.tsize;
++ void* p;
++ if (tsize > (size_t.sizeof << 1))
++ p = *cast(void**) ap;
++ else
++ {
++ if (tsize == (size_t.sizeof << 1))
++ ap = ap.alignUp!(size_t.sizeof << 1);
++ p = cast(void*) ap;
++ }
++ ap += tsize.alignUp;
++ parmn[0..tsize] = p[0..tsize];
++ }
+ else
+ static assert(0, "Unsupported platform");
+ }
+--- a/runtime/druntime/src/rt/dwarfeh.d
++++ b/runtime/druntime/src/rt/dwarfeh.d
+@@ -84,6 +84,16 @@
+ enum eh_exception_regno = 4;
+ enum eh_selector_regno = 5;
+ }
++else version (RISCV64)
++{
++ enum eh_exception_regno = 10;
++ enum eh_selector_regno = 11;
++}
++else version (RISCV32)
++{
++ enum eh_exception_regno = 10;
++ enum eh_selector_regno = 11;
++}
+ else
+ {
+ static assert(0, "Unknown EH register numbers for this architecture");
+--- a/driver/targetmachine.cpp
++++ b/driver/targetmachine.cpp
+@@ -102,6 +102,8 @@
+ return "elfv1";
+ case llvm::Triple::ppc64le:
+ return "elfv2";
++ case llvm::Triple::riscv64:
++ return "lp64d";
+ default:
+ return "";
+ }
+@@ -418,6 +420,10 @@
+ features.push_back("+cx16");
+ }
+
++ if (triple.getArch() == llvm::Triple::riscv64 && !hasFeature("d")) {
++ features.push_back("+d");
++ }
++
+ // Handle cases where LLVM picks wrong default relocModel
+ if (!relocModel.hasValue()) {
+ if (triple.isOSDarwin()) {
+--- a/runtime/CMakeLists.txt
++++ b/runtime/CMakeLists.txt
+@@ -123,6 +123,9 @@
+ set(C_SYSTEM_LIBS m c)
+ elseif("${TARGET_SYSTEM}" MATCHES "Linux")
+ set(C_SYSTEM_LIBS m pthread rt dl z)
++ if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "riscv64")
++ set(C_SYSTEM_LIBS atomic)
++ endif()
+ else()
+ set(C_SYSTEM_LIBS m pthread z)
+ endif()
+@@ -348,8 +351,8 @@
+ )
+ endfunction()
+
+- set(target_arch "AArch64;AMDGPU;ARM;Mips;NVPTX;PowerPC;SystemZ;X86")
+- set(target_name "aarch64;amdgcn;arm;mips;nvvm;ppc;s390;x86")
++ set(target_arch "AArch64;AMDGPU;ARM;Mips;NVPTX;PowerPC;RISCV;SystemZ;X86")
++ set(target_name "aarch64;amdgcn;arm;mips;nvvm;ppc;riscv64;s390;x86")
+
+ foreach(target ${LLVM_TARGETS_TO_BUILD})
+ list(FIND target_arch ${target} idx)
+--- a/cmake/Modules/ExtractDMDSystemLinker.cmake
++++ b/cmake/Modules/ExtractDMDSystemLinker.cmake
+@@ -39,7 +39,10 @@
+ )
+
+ if(NOT "${result_code}" STREQUAL "0")
+- message(FATAL_ERROR "Failed to link empty D program using '${D_COMPILER} ${D_COMPILER_FLAGS} ${DFLAGS_BASE}':\n${stderr}")
++ elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "riscv64")
++ message("on riscv64 arch, not check the cmake result_code")
++ else()
++ message(FATAL_ERROR "Failed to link empty D program using '${D_COMPILER} ${D_COMPILER_FLAGS} ${DFLAGS_BASE}':\n${stderr}")
+ endif()
+
+ if("${D_COMPILER_ID}" STREQUAL "GDMD")
diff -Nru ldc-1.30.0/debian/patches/series ldc-1.30.0/debian/patches/series
--- ldc-1.30.0/debian/patches/series 2022-08-13 00:44:23.000000000 +0800
+++ ldc-1.30.0/debian/patches/series 2022-08-13 02:28:55.000000000 +0800
@@ -1,3 +1,4 @@
01_no-zlib-embed.patch
02_ldc_include_path.diff
03_ldc-no-default-rpath.patch
+04_support-riscv64.patch
diff -Nru ldc-1.30.0/debian/rules ldc-1.30.0/debian/rules
--- ldc-1.30.0/debian/rules 2022-08-13 00:36:13.000000000 +0800
+++ ldc-1.30.0/debian/rules 2022-08-13 02:28:55.000000000 +0800
@@ -7,9 +7,19 @@
CFLAGS += $(CPPFLAGS)
CXXFLAGS += $(CPPFLAGS)
+# Link with libatomic on riscv64 to get access to the __atomic_* functions
+ifeq ($(DEB_HOST_ARCH),riscv64)
+ export DEB_LDFLAGS_MAINT_APPEND += -Wl,--no-as-needed -latomic -Wl,--as-needed
+endif
+
+
LDC_BUILD_FLAGS = -DINCLUDE_INSTALL_DIR='/usr/lib/ldc/${DEB_HOST_MULTIARCH}/include/d' \
- -DLDC_DYNAMIC_COMPILE=OFF
-BOOTSTRAP_LDC_FLAGS = -DD_COMPILER=/usr/bin/gdmd -DBUILD_SHARED_LIBS=ON
+ -DLDC_DYNAMIC_COMPILE=OFF -DC_SYSTEM_LIBS='atomic;m;pthread;rt;dl;z'
+ -DADDITIONAL_DEFAULT_LDC_SWITCHES='"-platformlib=atomic,rt,dl,pthread,m"'
+
+BOOTSTRAP_LDC_FLAGS = -DD_COMPILER=/usr/bin/gdmd -DBUILD_SHARED_LIBS=ON \
+ -DC_SYSTEM_LIBS='atomic;m;pthread;rt;dl;z'
+ -DADDITIONAL_DEFAULT_LDC_SWITCHES='"-platformlib=atomic,rt,dl,pthread,m"'
ifeq ($(DEB_HOST_ARCH),armhf)
LDC_BUILD_FLAGS += -DD_COMPILER_FLAGS=-mattr=-neon
Attachment:
signature.asc
Description: PGP signature