Skip to content

Fix build on FreeBSD #38335

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL Windows AND NOT CMAKE_HOST_SYSTEM_NAME STREQUA
set(SWIFT_USE_LINKER_default "lld")
elseif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
set(SWIFT_USE_LINKER_default "")
elseif(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
set(SWIFT_USE_LINKER_default "")
else()
set(SWIFT_USE_LINKER_default "gold")
endif()
Expand Down
4 changes: 2 additions & 2 deletions cmake/modules/SwiftConfigureSDK.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -347,11 +347,11 @@ macro(configure_sdk_unix name architectures)
message(FATAL_ERROR "unsupported arch for FreeBSD: ${arch}")
endif()

if(CMAKE_HOST_SYSTEM_NAME NOT STREQUAL FreeBSD)
if(NOT CMAKE_HOST_SYSTEM_NAME STREQUAL FreeBSD)
message(WARNING "CMAKE_SYSTEM_VERSION will not match target")
endif()

string(REPLACE "[-].*" "" freebsd_system_version ${CMAKE_SYSTEM_VERSION})
string(REGEX REPLACE "[-].*" "" freebsd_system_version ${CMAKE_SYSTEM_VERSION})
message(STATUS "FreeBSD Version: ${freebsd_system_version}")

set(SWIFT_SDK_FREEBSD_ARCH_x86_64_TRIPLE "x86_64-unknown-freebsd${freebsd_system_version}")
Expand Down
9 changes: 8 additions & 1 deletion include/swift/AST/AutoDiff.h
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,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 for ABI reasons,
/// so we have to define our own type here instead
struct TypeAndIndex {
Type first;
unsigned second;

TypeAndIndex(Type type, unsigned index) : first(type), second(index) {}
};

private:
union Value {
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/PlatformKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ AVAILABILITY_PLATFORM(watchOSApplicationExtension, "application extensions for w
AVAILABILITY_PLATFORM(macOSApplicationExtension, "application extensions for macOS")
AVAILABILITY_PLATFORM(macCatalyst, "Mac Catalyst")
AVAILABILITY_PLATFORM(macCatalystApplicationExtension, "application extensions for Mac Catalyst")
AVAILABILITY_PLATFORM(FreeBSD, "FreeBSD")
AVAILABILITY_PLATFORM(OpenBSD, "OpenBSD")
AVAILABILITY_PLATFORM(Windows, "Windows")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,15 @@ 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 std::pair can't be
Copy link

Choose a reason for hiding this comment

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

I believe, this is not FreeBSD specifics, but a libc++ one. Change the comment accordingly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

FreeBSD specifically disables the copy constructor by setting _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR to preserve ABI. It is not a general limitation of libc++.

/// used here, because it does not have a trivial copy constructor.
struct IndirectDifferentiation {
ApplyInst *applyInst;
SILDifferentiabilityWitness *witness;
};
IndirectDifferentiation indirectDifferentiation;

Value(ApplyInst *applyInst, SILDifferentiabilityWitness *witness)
: indirectDifferentiation({applyInst, witness}) {}

Expand Down Expand Up @@ -111,7 +118,8 @@ struct DifferentiationInvoker {
std::pair<ApplyInst *, SILDifferentiabilityWitness *>
getIndirectDifferentiation() const {
assert(kind == Kind::IndirectDifferentiation);
return value.indirectDifferentiation;
return std::make_pair(value.indirectDifferentiation.applyInst,
value.indirectDifferentiation.witness);
}

SILDifferentiabilityWitness *getSILDifferentiabilityWitnessInvoker() const {
Expand Down
2 changes: 2 additions & 0 deletions lib/AST/PlatformKind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ static bool isPlatformActiveForTarget(PlatformKind Platform,
return Target.isWatchOS();
case PlatformKind::OpenBSD:
return Target.isOSOpenBSD();
case PlatformKind::FreeBSD:
return Target.isOSFreeBSD();
case PlatformKind::Windows:
return Target.isOSWindows();
case PlatformKind::none:
Expand Down
8 changes: 5 additions & 3 deletions lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5489,7 +5489,8 @@ AnyFunctionType::getAutoDiffDerivativeFunctionLinearMapType(
if (!resultTan) {
return llvm::make_error<DerivativeFunctionTypeError>(
this, DerivativeFunctionTypeError::Kind::NonDifferentiableResult,
std::make_pair(originalResultType, /*index*/ 0));
DerivativeFunctionTypeError::TypeAndIndex(
originalResultType, /*index*/ 0));
}
auto resultTanType = resultTan->getType();

Expand Down Expand Up @@ -5522,7 +5523,8 @@ AnyFunctionType::getAutoDiffDerivativeFunctionLinearMapType(
this,
DerivativeFunctionTypeError::Kind::
NonDifferentiableDifferentiabilityParameter,
std::make_pair(paramType, i));
DerivativeFunctionTypeError::TypeAndIndex(
paramType, 0));
}
differentialParams.push_back(AnyFunctionType::Param(
paramTan->getType(), Identifier(), diffParam.getParameterFlags()));
Expand Down Expand Up @@ -5563,7 +5565,7 @@ AnyFunctionType::getAutoDiffDerivativeFunctionLinearMapType(
this,
DerivativeFunctionTypeError::Kind::
NonDifferentiableDifferentiabilityParameter,
std::make_pair(paramType, i));
DerivativeFunctionTypeError::TypeAndIndex(paramType, i));
}
if (diffParam.isInOut()) {
hasInoutDiffParameter = true;
Expand Down
15 changes: 13 additions & 2 deletions lib/ClangImporter/ClangImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ importer::getNormalInvocationArguments(
// using Glibc or a libc that respects that flag. This will cause some
// source breakage however (specifically with strerror_r()) on Linux
// without a workaround.
if (triple.isOSFuchsia() || triple.isAndroid()) {
if (triple.isOSFuchsia() || triple.isAndroid() || triple.isOSFreeBSD()) {
// Many of the modern libc features are hidden behind feature macros like
// _GNU_SOURCE or _XOPEN_SOURCE.
invocationArgStrs.insert(invocationArgStrs.end(), {
Expand Down Expand Up @@ -658,7 +658,7 @@ importer::getNormalInvocationArguments(
}
}

if (searchPathOpts.SDKPath.empty()) {
if (searchPathOpts.SDKPath.empty() && !triple.isOSFreeBSD()) {
Copy link
Member

Choose a reason for hiding this comment

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

Why special case this for FreeBSD, not working?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it excludes all system headers, causing e.g. the Glibc module to not work. I am unsure why this works on Linux, but not FreeBSD.

Copy link
Member

Choose a reason for hiding this comment

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

You could try adding the ClangImporter flags -Xfrontend -dump-clang-diagnostics -Xcc -v after removing this special case to dump what it's seeing and compare with linux, as I did with SR-14796.

invocationArgStrs.push_back("-Xclang");
invocationArgStrs.push_back("-nostdsysteminc");
} else {
Expand Down Expand Up @@ -2069,6 +2069,10 @@ PlatformAvailability::PlatformAvailability(const LangOptions &langOpts)
deprecatedAsUnavailableMessage = "";
break;

case PlatformKind::FreeBSD:
deprecatedAsUnavailableMessage = "";
break;

case PlatformKind::Windows:
deprecatedAsUnavailableMessage = "";
break;
Expand Down Expand Up @@ -2108,6 +2112,9 @@ bool PlatformAvailability::isPlatformRelevant(StringRef name) const {
case PlatformKind::OpenBSD:
return name == "openbsd";

case PlatformKind::FreeBSD:
return name == "freebsd";

case PlatformKind::Windows:
return name == "windows";

Expand Down Expand Up @@ -2175,6 +2182,10 @@ bool PlatformAvailability::treatDeprecatedAsUnavailable(
// No deprecation filter on OpenBSD
return false;

case PlatformKind::FreeBSD:
// No deprecation filter on FreeBSD
return false;

case PlatformKind::Windows:
// No deprecation filter on Windows
return false;
Expand Down
2 changes: 1 addition & 1 deletion lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ Driver::buildToolChain(const llvm::opt::InputArgList &ArgList) {
return std::make_unique<toolchains::Android>(*this, target);
return std::make_unique<toolchains::GenericUnix>(*this, target);
case llvm::Triple::FreeBSD:
return std::make_unique<toolchains::GenericUnix>(*this, target);
return std::make_unique<toolchains::FreeBSD>(*this, target);
case llvm::Triple::OpenBSD:
return std::make_unique<toolchains::OpenBSD>(*this, target);
case llvm::Triple::Win32:
Expand Down
10 changes: 10 additions & 0 deletions lib/Driver/ToolChains.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,16 @@ class LLVM_LIBRARY_VISIBILITY OpenBSD : public GenericUnix {
~OpenBSD() = default;
};

class LLVM_LIBRARY_VISIBILITY FreeBSD : public GenericUnix {
protected:
std::string getDefaultLinker() const override;

public:
FreeBSD(const Driver &D, const llvm::Triple &Triple)
: GenericUnix(D, Triple) {}
~FreeBSD() = default;
};

} // end namespace toolchains
} // end namespace driver
} // end namespace swift
Expand Down
4 changes: 4 additions & 0 deletions lib/Driver/UnixToolChains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,3 +410,7 @@ std::string toolchains::Cygwin::getDefaultLinker() const {
std::string toolchains::OpenBSD::getDefaultLinker() const {
return "lld";
}

std::string toolchains::FreeBSD::getDefaultLinker() const {
return "lld";
}
2 changes: 2 additions & 0 deletions lib/Frontend/Frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,8 @@ static bool shouldImportConcurrencyByDefault(const llvm::Triple &target) {
#if SWIFT_IMPLICIT_CONCURRENCY_IMPORT
if (target.isOSOpenBSD())
return true;
if (target.isOSFreeBSD())
return true;
#endif
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Option/SanitizerOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ OptionSet<SanitizerKind> swift::parseSanitizerArgValues(
}

// Check that we're one of the known supported targets for sanitizers.
if (!(Triple.isOSDarwin() || Triple.isOSLinux() || Triple.isOSWindows())) {
if (!(Triple.isOSDarwin() || Triple.isOSLinux() || Triple.isOSWindows() || Triple.isOSFreeBSD())) {
SmallString<128> b;
Diags.diagnose(SourceLoc(), diag::error_unsupported_opt_for_target,
(A->getOption().getPrefixedName() +
Expand Down
3 changes: 3 additions & 0 deletions lib/PrintAsObjC/DeclAndTypePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -875,6 +875,9 @@ class DeclAndTypePrinter::Implementation
case PlatformKind::watchOSApplicationExtension:
plat = "watchos_app_extension";
break;
case PlatformKind::FreeBSD:
plat = "freebsd";
break;
case PlatformKind::OpenBSD:
plat = "openbsd";
break;
Expand Down
2 changes: 2 additions & 0 deletions lib/SymbolGraphGen/AvailabilityMixin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ StringRef getDomain(const AvailableAttr &AvAttr) {
return { "tvOSAppExtension" };
case swift::PlatformKind::watchOSApplicationExtension:
return { "watchOSAppExtension" };
case swift::PlatformKind::FreeBSD:
return { "FreeBSD" };
case swift::PlatformKind::OpenBSD:
return { "OpenBSD" };
case swift::PlatformKind::Windows:
Expand Down
2 changes: 2 additions & 0 deletions lib/TBDGen/TBDGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ getLinkerPlatformId(OriginallyDefinedInAttr::ActiveVersion Ver) {
switch(Ver.Platform) {
case swift::PlatformKind::none:
llvm_unreachable("cannot find platform kind");
case swift::PlatformKind::FreeBSD:
llvm_unreachable("not used for this platform");
case swift::PlatformKind::OpenBSD:
llvm_unreachable("not used for this platform");
case swift::PlatformKind::Windows:
Expand Down
8 changes: 8 additions & 0 deletions stdlib/cmake/modules/AddSwiftStdlib.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,10 @@ function(_add_target_variant_c_compile_flags)
endif()
endif()

if("${CFLAGS_SDK}" STREQUAL "FREEBSD")
list(APPEND result "-D_GNU_SOURCE")
endif()

if("${CFLAGS_SDK}" STREQUAL "WASI")
list(APPEND result "-D_WASI_EMULATED_MMAN")
endif()
Expand Down Expand Up @@ -976,6 +980,10 @@ function(_add_swift_target_library_single target name)
set_target_properties("${target}"
PROPERTIES
INSTALL_RPATH "$ORIGIN")
elseif("${SWIFTLIB_SINGLE_SDK}" STREQUAL "FREEBSD")
set_target_properties("${target}"
PROPERTIES
INSTALL_RPATH "$ORIGIN")
elseif("${SWIFTLIB_SINGLE_SDK}" STREQUAL "CYGWIN")
set_target_properties("${target}"
PROPERTIES
Expand Down
2 changes: 1 addition & 1 deletion stdlib/private/OSLog/OSLogFloatFormatting.swift
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ extension OSLogFloatFormatting {
// fprintf formatters promote Float to Double
case is Float.Type: return ""
case is Double.Type: return ""
#if !os(Windows) && (arch(i386) || arch(x86_64))
#if !(os(Windows) || os(FreeBSD)) && (arch(i386) || arch(x86_64))
// fprintf formatters use L for Float80
case is Float80.Type: return "L"
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public func getFloat32(_ x: Float32) -> Float32 { return _opaqueIdentity(x) }
@inline(never)
public func getFloat64(_ x: Float64) -> Float64 { return _opaqueIdentity(x) }

#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
#if !(os(Windows) || os(Android) || os(FreeBSD)) && (arch(i386) || arch(x86_64))
@inline(never)
public func getFloat80(_ x: Float80) -> Float80 { return _opaqueIdentity(x) }
#endif
Expand Down
2 changes: 1 addition & 1 deletion stdlib/private/StdlibUnittest/SymbolLookup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#error("Unsupported platform")
#endif

#if canImport(Darwin) || os(OpenBSD)
#if canImport(Darwin) || os(FreeBSD) || os(OpenBSD)
let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: -2)
#elseif os(Linux)
let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def Availability(bits):
}%

% if bits == 80:
#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
#if !(os(Windows) || os(Android) || os(FreeBSD)) && (arch(i386) || arch(x86_64))
% end
% if bits == 16:
#if !os(macOS) && !(os(iOS) && targetEnvironment(macCatalyst))
Expand Down
4 changes: 2 additions & 2 deletions stdlib/public/Differentiation/TgmathDerivatives.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func _${derivative_kind}Trunc<T: FloatingPoint & Differentiable> (
% linear_map_kind = 'differential' if derivative_kind == 'jvp' else 'pullback'
% for T in ['Float', 'Double', 'Float80']:
% if T == 'Float80':
#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
#if !(os(Windows) || os(Android) || os(FreeBSD)) && (arch(i386) || arch(x86_64))
% end
@inlinable
@derivative(of: exp)
Expand Down Expand Up @@ -276,7 +276,7 @@ func _${derivative_kind}Erfc(_ x: ${T}) -> (value: ${T}, ${linear_map_kind}: (${
// Binary functions
%for T in ['Float', 'Float80']:
% if T == 'Float80':
#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
#if !(os(Windows) || os(Android) || os(FreeBSD)) && (arch(i386) || arch(x86_64))
% end
@inlinable
@derivative(of: pow)
Expand Down
18 changes: 12 additions & 6 deletions stdlib/public/Platform/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ foreach(sdk ${SWIFT_SDKS})
set(glibc_modulemap_source "bionic.modulemap.gyb")
elseif(${sdk} STREQUAL OPENBSD)
set(glibc_modulemap_source "libc-openbsd.modulemap.gyb")
elseif(${sdk} STREQUAL FREEBSD)
set(glibc_modulemap_source "libc-freebsd.modulemap.gyb")
else()
set(glibc_modulemap_source "glibc.modulemap.gyb")
endif()
Expand Down Expand Up @@ -119,12 +121,16 @@ foreach(sdk ${SWIFT_SDKS})
list(APPEND glibc_modulemap_target_list ${copy_glibc_modulemap_static})
endif()

set(glibc_header_out "${module_dir}/SwiftGlibc.h")
handle_gyb_source_single(glibc_header_target
SOURCE "SwiftGlibc.h.gyb"
OUTPUT "${glibc_header_out}"
FLAGS "-DCMAKE_SDK=${sdk}")
list(APPEND glibc_modulemap_target_list ${glibc_header_target})
# FreeBSD uses a different module map that does not use this header,
# so we don't generate it
Copy link
Member

Choose a reason for hiding this comment

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

Have you tried using this "Glibc" header instead on FreeBSD? I have it almost working for Android, #35707, so I think it should work for the BSDs too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried, but ran into a lot of missing functions. I did not have time to figure out what the problem is, yet, but I will take a look. Thanks for the link. I would like to land this first, though.

if(NOT ${sdk} STREQUAL FREEBSD)
set(glibc_header_out "${module_dir}/SwiftGlibc.h")
handle_gyb_source_single(glibc_header_target
SOURCE "SwiftGlibc.h.gyb"
OUTPUT "${glibc_header_out}"
FLAGS "-DCMAKE_SDK=${sdk}")
list(APPEND glibc_modulemap_target_list ${glibc_header_target})
endif()

# If this SDK is a target for a non-native host, except if it's for Android
# with its own native sysroot, create a native modulemap without a sysroot
Expand Down
2 changes: 1 addition & 1 deletion stdlib/public/Platform/Glibc.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public let FLT_RADIX = Double.radix

%for type, prefix in [('Float', 'FLT'), ('Double', 'DBL'), ('Float80', 'LDBL')]:
% if type == "Float80":
#if !os(Android) && (arch(i386) || arch(x86_64))
#if !(os(Android) || os(FreeBSD)) && (arch(i386) || arch(x86_64))
% end
// Where does the 1 come from? C counts the usually-implicit leading
// significand bit, but Swift does not. Neither is really right or wrong.
Expand Down
Loading