Skip to content

[FreeBSD] Adding FreeBSD support #77836

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

michael-yuji
Copy link
Member

This commit adds required conditional compilation blocks to enable building and running
on FreeBSD (tested on x86_64 FreeBSD 14.1-RELEASE-p6).

Also implements FreeBSD synchronization shims using _umtx_op(2)

@michael-yuji michael-yuji requested a review from a team as a code owner November 25, 2024 22:53
@lin72h
Copy link

lin72h commented Nov 25, 2024

It's my early Christmas gift. Thanks for working on this.

@michael-yuji
Copy link
Member Author

It's my early Christmas gift. Thanks for working on this.

unfortunately this PR alone here is not enough. I do have patches to other swift components to get it fully working and going to PR them to coming weeks. But even with those, you'll need to have a functional swiftc (by bootstrapping a swift 5.8+) on FreeBSD to build them. personally I've done a multi-stages bootstrap until I now have a toolchain ready.

you also need a patch to the base libc++ to workaround this issue

@lin72h
Copy link

lin72h commented Nov 26, 2024

it's very impressive work especially the bootstrap part!

@@ -65,6 +65,7 @@ headers = [
'spawn.h',
'strings.h',
'sys/event.h',
'sys/extattr.h',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this header available universally? I think that this might need to be under a FreeBSD condition.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The gyb expands '${header}' to an include guarded by __has_include, which test if the header can be included. similarly, the Linux specific sys/inotify.h header is also in the list.

#if __has_include(<${header}>)
#include <${header}>
#endif

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, any headers added to this file are just ignored if they don't exist, as there are already some OpenBSD-specific headers.

Have you considered adding a FreeBSD overlay instead? You could take a look at the recent Musl, WASI, and Android overlays for examples.

I know that's more work, but the WASI one isn't so bad, and FreeBSD may not be either.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's definitely on my radar! I'm not sure yet if I have to bandwidth to include that change in this PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shoulda just called them all import C.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all the feedback! Sorry for the late reply I was extremely sick for the past 2 weeks.
I certainly agree FreeBSD shouldn't use Glibc. In fact I have been working on the overlay for quite a while now but never gotten into a state I'm perfectly happy about it. More specifically I'd love to follow the Darwin modulemap and make certain C headers replaceable by clang, however it doesn't seems to be possible without making changes to the FreeBSD source tree.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My plan is to put the overlay changes into a separate PR, due to size of diff is quite big and this is already a rather large PR (as you can imagine all instance of where import Glibc occurs needs to be patched).

I have a working implementation ready to go, either committing to this PR, or as a separate PR, depending on what will be more comfortable for you to review. Wdyt @al45tair @ian-twilightcoder @grynspan @finagolfin

This also helps keep my head sane as I've been to maintaining quite a few separate trees of all the swift sub-projects locally to implement various feature for FreeBSD and it's getting quite messy.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no opinion either way.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overlay PR created. #79261

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To rathole a bit, what does FreeBSD call its libc, if anything?

It doesn't have a separate name, t's just the FreeBSD libc.

@finagolfin
Copy link
Member

Nice, there is some work to get Swift 6 bootstrapping again, #77815, that you'll want to follow.

Pinging @mhjacobson and @3405691582, who added BSD support before and may be able to help review.

@3405691582
Copy link
Member

As a heads up, the code uses LLVM target triples and the build system has a few places where it assumes that the platform calls the architecture with the same name as LLVM does. This isn't a problem for FreeBSD on what LLVM calls x86_64, since they apparently both seem to use the same spelling, but for what LLVM calls aarch64, both OpenBSD and FreeBSD call it arm64. This causes headaches.

In the past, I've tried to keep some meaningful separation between platform spelling and LLVM spelling, but I'm reconsidering that in #77879. You probably won't need to do anything right now for this pr if you're just targeting x86_64, though, and what you have seems good to me, but keep this in mind if you're going to also be working on arm64.

@khng300
Copy link

khng300 commented Dec 1, 2024

As a heads up, the code uses LLVM target triples and the build system has a few places where it assumes that the platform calls the architecture with the same name as LLVM does. This isn't a problem for FreeBSD on what LLVM calls x86_64, since they apparently both seem to use the same spelling, but for what LLVM calls aarch64, both OpenBSD and FreeBSD call it arm64. This causes headaches.

In the past, I've tried to keep some meaningful separation between platform spelling and LLVM spelling, but I'm reconsidering that in #77879. You probably won't need to do anything right now for this pr if you're just targeting x86_64, though, and what you have seems good to me, but keep this in mind if you're going to also be working on arm64.

Which is not correct for the FreeBSD part. On FreeBSD itself, arm64 is the TARGET, meanwhile aarch64 is the TARGET_ARCH and MACHINE_ARCH. Below is what I got from a build of the FreeBSD tree on my side:

CMD cc -target aarch64-unknown-freebsd15.0 --sysroot=

For reference how we build the -target tuple in the tree:

Makefile.inc1:		MACHINE_ARCH=${TARGET_ARCH}
Makefile:	TARGET=${_TARGET} TARGET_ARCH=${_TARGET_ARCH} ${_MAKEARGS}
Makefile:_TARGET_ARCH=	${TARGET:S/arm64/aarch64/:S/riscv/riscv64/:S/arm/armv7/}
./Makefile.inc1:MACHINE_TRIPLE?=${MACHINE_ARCH:S/amd64/x86_64/}-${MACHINE_TRIPLE_ABI}-freebsd${OS_REVISION}

@QuietMisdreavus QuietMisdreavus removed their request for review December 2, 2024 17:47
@michael-yuji
Copy link
Member Author

@swift-ci please smoke test

@michael-yuji
Copy link
Member Author

@swift-ci please test

@jakepetroules
Copy link
Contributor

I'm considering this a blocker for swiftlang/swift-build#12 since that requires the header file providing access to the xattr functions to be in the modulemap in order to enable xattr support in Swift Build's filesystem implementation.

@jakepetroules
Copy link
Contributor

@swift-ci test

Copy link
Contributor

@egorzhdan egorzhdan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks amazing! I have just one comment about a C++ interop test.

michael-yuji and others added 4 commits March 14, 2025 02:15
This commit adds required conditional compilation blocks to enable bulding on
FreeBSD (tested on x86_64 FreeBSD 14.1-RELEASE-p6). Also implements FreeBSD
synchronization shims using `_umtx_op(2)`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this one correct? I recently was working to get 5.10 running on an ARM 64bit VPS FreeBSD 14 box, and I think I had to use arch(aarch64) here to get the compiling to succeed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naïve of me to say it, but I'd expect that if the Swift compiler accepts aarch64 then it would treat it as a synonym of arm64.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, they mean the same. IIRC clang uses aarch64 on FreeBSD. I am not sure why.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strictly speaking, AArch64 is the architecture's name according to Arm Holdings. 🤷 Apple's technically the odd one out, here.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we want to be using the name aarch64, not arm64. See another PR here which deals with this topic: #81662

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FreeBSD has separate notions of MACHINE and MACHINE_ARCH and we ended up with arm64 as the MACHINE and aarch64 as the MACHINE_ARCH. The code isn't going to need to check for both; if what it's fetching is the MACHINE_ARCH it will remain aarch64.

@@ -417,7 +417,7 @@ macro(configure_sdk_unix name architectures)
message(FATAL_ERROR "unknown arch for ${prefix}: ${arch}")
endif()
elseif("${prefix}" STREQUAL "FREEBSD")
if(NOT arch MATCHES "(arm64|x86_64)")
if(NOT arch MATCHES "(aarch64|arm64|x86_64)")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we even keep the arm64 string here? aarch64 seems to be the architecture name that we should be using for 64-bit ARM.

@CodingCarpincho
Copy link

@shahmishal Could you or someone else kick off the CI here so we can get Michael’s work merged?

@3405691582
Copy link
Member

@swift-ci please test.

@@ -422,7 +422,14 @@ class DerivativeFunctionTypeError
Kind kind;

/// The type and index of a differentiability parameter or result.
using TypeAndIndex = std::pair<Type, unsigned>;
/// std::pair does not have a trivial copy constructor on FreeBSD <= 14 for
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment implies that FreeBSD 15 changed libc++ ABI to support this, but that's not true, it still hasn't happened, and it's not clear if or when it will

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NB: Upstream libc++ still has the patch to break ABI and support this for FreeBSD >= 14 (not > 14 as this implies), but the vendored copy in FreeBSD used to build /usr/lib/libc++.so.1 is patched to keep the old ABI for all versions.

@@ -71,10 +71,17 @@ struct DifferentiationInvoker {

/// The parent `apply` instruction and the witness associated with the
/// `IndirectDifferentiation` case.
std::pair<ApplyInst *, SILDifferentiabilityWitness *>
indirectDifferentiation;
/// Note: This used to be a std::pair, but on FreeBSD <= 14, libc++ is
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As before

@@ -116,6 +116,8 @@ public typealias CLongDouble = Double
#elseif os(FreeBSD)
#if arch(x86_64) || arch(i386)
public typealias CLongDouble = Float80
#elseif arch(arm64)
public typealias CLongDouble = Double
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it Float128 (also for OpenBSD)? I note that there are various comments above about Float128 not being supported, so perhaps this should be omitted for arm64 on *BSD?

@@ -93,7 +93,8 @@ set(swift_runtime_backtracing_sources
Backtrace.cpp
BacktraceUtils.cpp
CrashHandlerMacOS.cpp
CrashHandlerLinux.cpp)
CrashHandlerLinux.cpp
)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably shouldn't be reformatted if you're not otherwise touching the file?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.