Skip to content

Commit 55445ca

Browse files
X547davidkarolybrad0
committed
[Driver] Implement ToolChain on Haiku
Co-authored-by: David Karoly <[email protected]> Co-authored-by: Brad Smith <[email protected]>
1 parent 74338bf commit 55445ca

File tree

14 files changed

+187
-9
lines changed

14 files changed

+187
-9
lines changed

clang/lib/Driver/ToolChains/Gnu.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2224,6 +2224,12 @@ bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const {
22242224
void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
22252225
const llvm::Triple &TargetTriple, SmallVectorImpl<std::string> &Prefixes,
22262226
StringRef SysRoot) {
2227+
2228+
if (TargetTriple.isOSHaiku()) {
2229+
Prefixes.push_back(concat(SysRoot, "/boot/system/develop/tools"));
2230+
return;
2231+
}
2232+
22272233
if (TargetTriple.isOSSolaris()) {
22282234
// Solaris is a special case.
22292235
// The GCC installation is under

clang/lib/Driver/ToolChains/Haiku.cpp

Lines changed: 124 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,141 @@
99
#include "Haiku.h"
1010
#include "CommonArgs.h"
1111
#include "clang/Config/config.h"
12+
#include "clang/Driver/Compilation.h"
1213
#include "llvm/Support/Path.h"
1314

1415
using namespace clang::driver;
16+
using namespace clang::driver::tools;
1517
using namespace clang::driver::toolchains;
1618
using namespace clang;
1719
using namespace llvm::opt;
1820

21+
void haiku::Linker::ConstructJob(Compilation &C, const JobAction &JA,
22+
const InputInfo &Output,
23+
const InputInfoList &Inputs,
24+
const ArgList &Args,
25+
const char *LinkingOutput) const {
26+
const toolchains::Haiku &ToolChain =
27+
static_cast<const toolchains::Haiku &>(getToolChain());
28+
const Driver &D = ToolChain.getDriver();
29+
const llvm::Triple::ArchType Arch = ToolChain.getArch();
30+
const bool Static = Args.hasArg(options::OPT_static);
31+
const bool Shared = Args.hasArg(options::OPT_shared);
32+
ArgStringList CmdArgs;
33+
34+
// Silence warning for "clang -g foo.o -o foo"
35+
Args.ClaimAllArgs(options::OPT_g_Group);
36+
// and "clang -emit-llvm foo.o -o foo"
37+
Args.ClaimAllArgs(options::OPT_emit_llvm);
38+
// and for "clang -w foo.o -o foo". Other warning options are already
39+
// handled somewhere else.
40+
Args.ClaimAllArgs(options::OPT_w);
41+
42+
// Silence warning for "clang -pie foo.o -o foo"
43+
Args.ClaimAllArgs(options::OPT_pie);
44+
45+
if (!D.SysRoot.empty())
46+
CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
47+
48+
CmdArgs.push_back("--eh-frame-hdr");
49+
if (Static) {
50+
CmdArgs.push_back("-Bstatic");
51+
} else {
52+
if (Args.hasArg(options::OPT_rdynamic))
53+
CmdArgs.push_back("-export-dynamic");
54+
if (Shared)
55+
CmdArgs.push_back("-shared");
56+
CmdArgs.push_back("--enable-new-dtags");
57+
}
58+
59+
CmdArgs.push_back("-shared");
60+
61+
if (!Shared)
62+
CmdArgs.push_back("--no-undefined");
63+
64+
if (Arch == llvm::Triple::riscv64)
65+
CmdArgs.push_back("-X");
66+
67+
assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");
68+
if (Output.isFilename()) {
69+
CmdArgs.push_back("-o");
70+
CmdArgs.push_back(Output.getFilename());
71+
}
72+
73+
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
74+
options::OPT_r)) {
75+
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
76+
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbeginS.o")));
77+
if (!Shared)
78+
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("start_dyn.o")));
79+
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("init_term_dyn.o")));
80+
}
81+
82+
Args.AddAllArgs(CmdArgs,
83+
{options::OPT_L, options::OPT_T_Group, options::OPT_s,
84+
options::OPT_t, options::OPT_Z_Flag, options::OPT_r});
85+
ToolChain.AddFilePathLibArgs(Args, CmdArgs);
86+
87+
addLinkerCompressDebugSectionsOption(ToolChain, Args, CmdArgs);
88+
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
89+
90+
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
91+
options::OPT_r)) {
92+
// Use the static OpenMP runtime with -static-openmp
93+
bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Static;
94+
addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP);
95+
96+
if (D.CCCIsCXX() && ToolChain.ShouldLinkCXXStdlib(Args))
97+
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
98+
99+
CmdArgs.push_back("-lgcc");
100+
101+
CmdArgs.push_back("--push-state");
102+
CmdArgs.push_back("--as-needed");
103+
CmdArgs.push_back("-lgcc_s");
104+
CmdArgs.push_back("--no-as-needed");
105+
CmdArgs.push_back("--pop-state");
106+
107+
CmdArgs.push_back("-lroot");
108+
109+
CmdArgs.push_back("-lgcc");
110+
111+
CmdArgs.push_back("--push-state");
112+
CmdArgs.push_back("--as-needed");
113+
CmdArgs.push_back("-lgcc_s");
114+
CmdArgs.push_back("--no-as-needed");
115+
CmdArgs.push_back("--pop-state");
116+
}
117+
118+
// No need to do anything for pthreads. Claim argument to avoid warning.
119+
Args.claimAllArgs(options::OPT_pthread, options::OPT_pthreads);
120+
121+
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
122+
options::OPT_r)) {
123+
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o")));
124+
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
125+
}
126+
127+
ToolChain.addProfileRTLibs(Args, CmdArgs);
128+
129+
const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
130+
C.addCommand(std::make_unique<Command>(JA, *this,
131+
ResponseFileSupport::AtFileCurCP(),
132+
Exec, CmdArgs, Inputs, Output));
133+
}
134+
19135
/// Haiku - Haiku tool chain which can call as(1) and ld(1) directly.
20136

21137
Haiku::Haiku(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
22138
: Generic_ELF(D, Triple, Args) {
23139

140+
GCCInstallation.init(Triple, Args);
141+
24142
getFilePaths().push_back(concat(getDriver().SysRoot, "/boot/system/lib"));
25143
getFilePaths().push_back(concat(getDriver().SysRoot, "/boot/system/develop/lib"));
144+
145+
if (GCCInstallation.isValid())
146+
getFilePaths().push_back(GCCInstallation.getInstallPath().str());
26147
}
27148

28149
void Haiku::AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
@@ -128,8 +249,6 @@ void Haiku::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
128249
concat(getDriver().SysRoot, "/boot/system/develop/headers/c++/v1"));
129250
}
130251

131-
void Haiku::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
132-
llvm::opt::ArgStringList &CC1Args) const {
133-
addLibStdCXXIncludePaths(concat(getDriver().SysRoot, "/boot/system/develop/headers/c++"),
134-
getTriple().str(), "", DriverArgs, CC1Args);
135-
}
252+
Tool *Haiku::buildLinker() const { return new tools::haiku::Linker(*this); }
253+
254+
bool Haiku::HasNativeLLVMSupport() const { return true; }

clang/lib/Driver/ToolChains/Haiku.h

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,53 @@
1515

1616
namespace clang {
1717
namespace driver {
18+
namespace tools {
19+
20+
/// Directly call GNU Binutils assembler and linker
21+
namespace haiku {
22+
class LLVM_LIBRARY_VISIBILITY Linker final : public Tool {
23+
public:
24+
Linker(const ToolChain &TC) : Tool("haiku::Linker", "linker", TC) {}
25+
26+
bool hasIntegratedCPP() const override { return false; }
27+
bool isLinkJob() const override { return true; }
28+
29+
void ConstructJob(Compilation &C, const JobAction &JA,
30+
const InputInfo &Output, const InputInfoList &Inputs,
31+
const llvm::opt::ArgList &TCArgs,
32+
const char *LinkingOutput) const override;
33+
};
34+
} // end namespace haiku
35+
} // end namespace tools
36+
1837
namespace toolchains {
1938

2039
class LLVM_LIBRARY_VISIBILITY Haiku : public Generic_ELF {
2140
public:
2241
Haiku(const Driver &D, const llvm::Triple &Triple,
2342
const llvm::opt::ArgList &Args);
2443

44+
bool HasNativeLLVMSupport() const override;
45+
2546
bool IsMathErrnoDefault() const override { return false; }
2647
bool IsObjCNonFragileABIDefault() const override { return true; }
2748
bool isPICDefault() const override { return true; }
2849

50+
const char *getDefaultLinker() const override { return "ld.lld"; }
51+
2952
void AddClangSystemIncludeArgs(
3053
const llvm::opt::ArgList &DriverArgs,
3154
llvm::opt::ArgStringList &CC1Args) const override;
3255
void addLibCxxIncludePaths(
3356
const llvm::opt::ArgList &DriverArgs,
3457
llvm::opt::ArgStringList &CC1Args) const override;
35-
void addLibStdCxxIncludePaths(
36-
const llvm::opt::ArgList &DriverArgs,
37-
llvm::opt::ArgStringList &CC1Args) const override;
3858

3959
unsigned GetDefaultDwarfVersion() const override { return 4; }
4060

4161
bool GetDefaultStandaloneDebug() const override { return true; }
62+
63+
protected:
64+
Tool *buildLinker() const override;
4265
};
4366

4467
} // end namespace toolchains

clang/test/Driver/Inputs/haiku_x86_64_tree/boot/system/develop/lib/crti.o

Whitespace-only changes.

clang/test/Driver/Inputs/haiku_x86_64_tree/boot/system/develop/lib/crtn.o

Whitespace-only changes.

clang/test/Driver/Inputs/haiku_x86_64_tree/boot/system/develop/lib/init_term_dyn.o

Whitespace-only changes.

clang/test/Driver/Inputs/haiku_x86_64_tree/boot/system/develop/lib/start_dyn.o

Whitespace-only changes.

clang/test/Driver/Inputs/haiku_x86_64_tree/boot/system/develop/tools/lib/gcc/x86_64-unknown-haiku/13.2.0/crtbegin.o

Whitespace-only changes.

clang/test/Driver/Inputs/haiku_x86_64_tree/boot/system/develop/tools/lib/gcc/x86_64-unknown-haiku/13.2.0/crtbeginS.o

Whitespace-only changes.

clang/test/Driver/Inputs/haiku_x86_64_tree/boot/system/develop/tools/lib/gcc/x86_64-unknown-haiku/13.2.0/crtend.o

Whitespace-only changes.

clang/test/Driver/Inputs/haiku_x86_64_tree/boot/system/develop/tools/lib/gcc/x86_64-unknown-haiku/13.2.0/crtendS.o

Whitespace-only changes.

clang/test/Driver/Inputs/haiku_x86_64_tree/boot/system/develop/tools/lib/gcc/x86_64-unknown-haiku/13.2.0/include/c++/.keep

Whitespace-only changes.

clang/test/Driver/haiku.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,32 @@
3636
// CHECK-C-HEADER-PATH: "-internal-isystem" "/boot/system/develop/headers/gnu"
3737
// CHECK-C-HEADER-PATH: "-internal-isystem" "/boot/system/develop/headers/posix"
3838
// CHECK-C-HEADER-PATH: "-internal-isystem" "/boot/system/develop/headers"
39+
40+
// Check x86_64-unknown-haiku, X86_64
41+
// RUN: %clang -### %s 2>&1 --target=x86_64-unknown-haiku \
42+
// RUN: --gcc-toolchain="" \
43+
// RUN: --sysroot=%S/Inputs/haiku_x86_64_tree \
44+
// RUN: | FileCheck --check-prefix=CHECK-LD-X86_64 %s
45+
// CHECK-LD-X86_64: "-cc1" "-triple" "x86_64-unknown-haiku"
46+
// CHECK-LD-X86_64-SAME: "-isysroot" "[[SYSROOT:[^"]+]]"
47+
// CHECK-LD-X86_64: "{{.*}}ld{{(.exe)?}}"
48+
// CHECK-LD-X86_64-SAME: "--no-undefined"
49+
// CHECK-LD-X86_64-SAME: "[[SYSROOT]]/boot/system/develop/lib/crti.o"
50+
// CHECK-LD-X86_64-SAME: {{^}} "[[SYSROOT]]/boot/system/develop/tools/lib/gcc/x86_64-unknown-haiku/13.2.0/crtbeginS.o"
51+
// CHECK-LD-X86_64-SAME: {{^}} "[[SYSROOT]]/boot/system/develop/lib/start_dyn.o"
52+
// CHECK-LD-X86_64-SAME: {{^}} "[[SYSROOT]]/boot/system/develop/lib/init_term_dyn.o"
53+
// CHECK-LD-X86_64-SAME: "-lgcc" "--push-state" "--as-needed" "-lgcc_s" "--no-as-needed" "--pop-state"
54+
// CHECK-LD-X86_64-SAME: {{^}} "-lroot"
55+
// CHECK-LD-X86_64-SAME: {{^}} "-lgcc" "--push-state" "--as-needed" "-lgcc_s" "--no-as-needed" "--pop-state"
56+
// CHECK-LD-X86_64-SAME: {{^}} "[[SYSROOT]]/boot/system/develop/tools/lib/gcc/x86_64-unknown-haiku/13.2.0/crtendS.o"
57+
// CHECK-LD-X86_64-SAME: {{^}} "[[SYSROOT]]/boot/system/develop/lib/crtn.o"
58+
59+
// Check the right flags are present with -shared
60+
// RUN: %clang -### %s -shared 2>&1 --target=x86_64-unknown-haiku \
61+
// RUN: --gcc-toolchain="" \
62+
// RUN: --sysroot=%S/Inputs/haiku_x86_64_tree \
63+
// RUN: | FileCheck --check-prefix=CHECK-X86_64-SHARED %s
64+
// CHECK-X86_64-SHARED: "-cc1" "-triple" "x86_64-unknown-haiku"
65+
// CHECK-X86_64-SHARED-SAME: "-isysroot" "[[SYSROOT:[^"]+]]"
66+
// CHECK-X86_64-SHARED: "{{.*}}ld{{(.exe)?}}"
67+
// CHECK-X86_64-SHARED-NOT: "[[SYSROOT]]/boot/system/develop/lib/start_dyn.o"

clang/test/Driver/haiku.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
// RUN: %clangxx --target=x86_64-unknown-haiku --stdlib=libstdc++ -### %s 2>&1 \
33
// RUN: --sysroot=%S/Inputs/haiku_x86_64_tree \
44
// RUN: | FileCheck --check-prefix=CHECK-LIBSTDCXX-HEADER-PATH %s
5-
// CHECK-LIBSTDCXX-HEADER-PATH: "-internal-isystem" "[[SYSROOT:[^"]+]]/boot/system/develop/headers/c++"
5+
// CHECK-LIBSTDCXX-HEADER-PATH: "-internal-isystem" "[[SYSROOT:[^"]+]]/boot/system/develop/tools/lib/gcc/x86_64-unknown-haiku/13.2.0/../../../gcc/x86_64-unknown-haiku/13.2.0/include/c++/"
6+
// CHECK-LIBSTDCXX-HEADER-PATH-SAME: "-internal-isystem" "[[SYSROOT:[^"]+]]/boot/system/develop/tools/lib/gcc/x86_64-unknown-haiku/13.2.0/../../../gcc/x86_64-unknown-haiku/13.2.0/include/c++//backward"
67

78
// Check the C++ header path (when using libc++)
89
// RUN: %clangxx --target=x86_64-unknown-haiku --stdlib=libc++ -### %s 2>&1 \

0 commit comments

Comments
 (0)