Skip to content

FreeBSD compatibility patch #4804

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

Merged
merged 40 commits into from
Jan 10, 2017
Merged

FreeBSD compatibility patch #4804

merged 40 commits into from
Jan 10, 2017

Conversation

kstaring
Copy link
Contributor

@kstaring kstaring commented Sep 15, 2016

This patch lets the current Swift 3 codebase compile on FreeBSD. The specific version tested with is FreeBSD 11-RELEASE.
The swift binary runs and perhaps more importantly, swiftc is able to at least compile simple programs-- more complicated code simply haven't been tested yet so more claims cannot be made.

  • some conditional clauses in glibc.modulemap.gyb to not include a number of headers in /usr/include which don't exist/aren't needed on FreeBSD
  • fix find_package for ICU to actually fill the variables which should be filled and include the find_package() in the stubs directory
  • use ld.gold (resides in binutils package) for linking due to the known ld relocation problem
  • add a #define to have stdio.h export getline() in swift-demangle (see COMPATIBILITY in the FreeBSD getline(3) man page)
  • don't link libdl on FreeBSD

This patch incoorporates some of @tinysun212 PR https://github.com/apple/swift/pull/3886/files#diff-99fd89ad44c4466de8ad6b8aab9c207d

add /usr/local/include to include path in stdlib/public/stubs
use FreeBSD procfs path to cmdline when building for FreeBSD
Things like: PthreadBarriers.swift:114:50: error: cannot convert value of type 'UnsafeMutablePointer<pthread_mutex_t>' (aka 'UnsafeMutablePointer<OpaquePointer>') to expected argument type 'UnsafeMutablePointer<pthread_mutex_t?>' (aka 'UnsafeMutablePointer<Optional<OpaquePointer>>')
on barrier.pointee.mutex . I need to do more research to understand this
@kstaring
Copy link
Contributor Author

@swift-ci Please smoke test

@gribozavr
Copy link
Contributor

conditionally disable pthread convenience wrappers since they didn't compile and aren't absolutely necessary to generate a running swift & swiftc

Note that these wrappers are necessary to build and run the testsuite, which is essential in declaring Swift actually working on the platform. Please add FIXMEs to these #ifs, these should be fixed before anyone starts using the port for anything real.

@gribozavr
Copy link
Contributor

include /usr/local/include in the /stdlib/public/stubs CMakeLists.txt , otherwise the headers under /usr/local/include/unicode cannot be found

Why isn't find_package(ICU) taking care of this? That would be the right way to fix it.

"fatal error: Unable to open interface to '/proc/self/cmdline'.\n");
"fatal error: Unable to open interface to '"
PROCFS_CMDLINE_PATH
"'.\n");
Copy link
Contributor

Choose a reason for hiding this comment

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

Changes to this file LGTM, feel free to submit as a separate PR if you would like them to be merged immediately.

@@ -14,6 +14,10 @@
//
//===----------------------------------------------------------------------===//

#if defined(__FreeBSD__)
#define _WITH_GETLINE
#endif
Copy link
Contributor

Choose a reason for hiding this comment

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

Changes to this file LGTM, feel free to submit as a separate PR if you would like them to be merged immediately.

Copy link
Member

Choose a reason for hiding this comment

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

This particular bit LGTM too.

@@ -35,6 +37,7 @@ module SwiftGlibc [system] {
header "${GLIBC_INCLUDE_PATH}/complex.h"
export *
}
% if CMAKE_SDK != "FREEBSD":
Copy link
Contributor

@gribozavr gribozavr Sep 17, 2016

Choose a reason for hiding this comment

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

I don't see a matching %end being added, is this intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not intentional, fixed in a subsequent commit, thanks!

@kstaring
Copy link
Contributor Author

@gribozavr : thanks for your feedback, I'll take your suggestions into account in the coming days!

@lin7sh
Copy link

lin7sh commented Sep 17, 2016

great work! Freebsd RC3 just release yesterday. Does your patch work on it too?

@kstaring
Copy link
Contributor Author

kstaring commented Sep 18, 2016

Indeed, the patch appears to work on RC3 as well; same provisions apply though: the bare swift(c) compiles and runs.
The prerequisites are: cmake ninja icu libxml2 sqlite3 swig python27 pkgconf py27-sphinx

@gribozavr
Copy link
Contributor

@swift-ci Please test

@jrose-apple
Copy link
Contributor

Tagging @dcci and @landonf, who did much of the initial FreeBSD work.

@tinysun212 tinysun212 mentioned this pull request Oct 4, 2016
1 task
@@ -58,6 +58,11 @@ extern "C" char ** _swift_stdlib_getUnsafeArgvArgc(int *outArgLen) {
return *_NSGetArgv();
}
#elif defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__)
#if defined(__FreeBSD__)
Copy link
Contributor

Choose a reason for hiding this comment

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

Since /proc is optional and not mounted by default, I'd recommend using sysctl(3) here. The MIB you want is { CTL_KERN, KERN_PROC, KERN_PROC_ARGS, getpid() }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great pointer, thanks! I was never quite happy with requiring /proc to be mounted.. Hope commit ede70f2 is a better FreeBSD fit.

@jrose-apple
Copy link
Contributor

I'm happy to take FreeBSD 12 patches later, just to get this in. We normally prefer small positive changes over big merges anyway. (40 commits is already much bigger than we'd like, even if most of them are edits and merges.)

@llvm-beanz
Copy link
Contributor

In any case, since gold doesn't automatically link to libc, it makes sense to link to libc explicitly. Relying on libgcc_s to pull in libc sound weird to me.

@myfreeweb, I would not expect the linker to ever implicitly add anything. Linkers can follow library dependencies of static archives in some (but not all) situations. I would however expect the clang driver to add libc to most linker invocations. Is your build invoking the linker directly or via clang?

@valpackett
Copy link

@llvm-beanz I just built it using the build script

@llvm-beanz
Copy link
Contributor

@myfreeweb I think it is probable that the issue you're seeing with libc missing in the linker options is either a bug in swift's driver or a bug in clang's. It would be great if you could capture the command in the swift build that is generating the error, so that we can attempt to reproduce.

@nether-cat
Copy link

nether-cat commented Jan 10, 2017

I just finished a build successfully using the build script on FreeBSD 11.0-RELEASE. However I had to use swift/utils/update-checkout --tag swift-DEVELOPMENT-SNAPSHOT-2016-11-15-a and then merge this pull request to get a working result. I'm using this build-script command:

$ swift/utils/build-script --no-swift-stdlib-assertions --release -- --install-swift --install-prefix=/usr/local '--swift-install-components=autolink-driver;compiler;clang-builtin-headers;stdlib;sdk-overlay;dev' --build-swift-static-stdlib=1 --build-swift-static-sdk-overlay --install-destdir=$HOME/swift-dist --reconfigure

My previous builds (using the same build-script invocation) with the current master and this pull request merged finished without any build errors, too – but then I could neither run the Swift REPL nor build any working executables using swiftc. I got these errors:

$ swift
<unknown>:0: error: could not load the swift standard library
$ swiftc hello.swift -o hello
$ ./hello
/root/swift-dist/usr/local/lib/swift/freebsd/libswiftCore.so: Undefined symbol "__gnustep_objcxx_personality_v0"

Did I miss something? I feel like I actually did right, because the build-script invocation produced a working result in the same environment using that development snapshot. Any ideas?

EDIT: I have also attached a system call trace from $ truss -o truss.txt swift -> truss.txt

@slavapestov
Copy link
Contributor

@jrose-apple Do you think it would be better to squash the commits?

@slavapestov slavapestov self-assigned this Jan 10, 2017
@slavapestov
Copy link
Contributor

@swift-ci Please smoke test and merge

@swift-ci swift-ci merged commit 294359b into swiftlang:master Jan 10, 2017
@jrose-apple
Copy link
Contributor

For the record: I do like tidy histories and meaningful commits even on merge branches, but I do see that they're an extra hoop for contributors to jump through, so I mostly haven't been pushing it on PR reviews. If we were using rebase-and-merge it would be a different story.

@kstaring
Copy link
Contributor Author

Thanks for the merge!!
@jrose-apple noted, and thanks for your patience. This was a very 'my-first-pull-request' experience for me ;-)

@jrose-apple
Copy link
Contributor

I'm sorry your first pull request took months to settle and merge! You're doing good work; glad to have you contributing.

@lin7sh
Copy link

lin7sh commented Jan 10, 2017

@kstaring congrats! Is there any documentation for build instruction on Freebsd and maybe a package(there is swift 2 on freshport already)

@lin7sh
Copy link

lin7sh commented Jan 10, 2017

build fail on my freebsd 11
$ utils/build-script -r -t
clang: error: invalid linker name in argument '-fuse-ld=gold'
[24/66] Building C object src/CMakeFiles/libcmark_static.dir/blocks.c.o
ninja: build stopped: subcommand failed.

uname -r
11.0-RELEASE-p2

@valpackett
Copy link

@mko-io do you have gold installed? It's in the binutils package

@nether-cat
Copy link

nether-cat commented Jan 11, 2017

I just finished another build with the current master branch and got the same issues when executing:

$ swift
<unknown>:0: error: could not load the swift standard library
$ swiftc hello.swift -o hello
$ ./hello
/root/swift-dist/usr/local/lib/swift/freebsd/libswiftCore.so: Undefined symbol "__gnustep_objcxx_personality_v0"

As I mentioned before the tag swift-DEVELOPMENT-SNAPSHOT-2016-11-15-a gives me a somehow working result. So I went ahead and compared the working and the broken build in terms of occurences of the undefined symbol with $ grep -ri -l "__gnustep_objcxx_personality_v0" ./build

This produced an output which reveals differences.
That might explain why the one swift is working and the newer one is not:

./build/Ninja-ReleaseAssert+stdlib-Release/llvm-freebsd-x86_64/tools/clang/lib/CodeGen/CMakeFiles/clangCodeGen.dir/CGException.cpp.o
./build/Ninja-ReleaseAssert+stdlib-Release/llvm-freebsd-x86_64/lib/libclangCodeGen.a
./build/Ninja-ReleaseAssert+stdlib-Release/llvm-freebsd-x86_64/bin/clang-4.0
./build/Ninja-ReleaseAssert+stdlib-Release/llvm-freebsd-x86_64/bin/clang
./build/Ninja-ReleaseAssert+stdlib-Release/llvm-freebsd-x86_64/bin/clang++
./build/Ninja-ReleaseAssert+stdlib-Release/llvm-freebsd-x86_64/bin/clang-cl
./build/Ninja-ReleaseAssert+stdlib-Release/swift-freebsd-x86_64/bin/swift-ide-test
./build/Ninja-ReleaseAssert+stdlib-Release/swift-freebsd-x86_64/bin/swift
./build/Ninja-ReleaseAssert+stdlib-Release/swift-freebsd-x86_64/bin/swiftc
./build/Ninja-ReleaseAssert+stdlib-Release/swift-freebsd-x86_64/bin/swift-autolink-extract
./build/Ninja-ReleaseAssert+stdlib-Release/swift-freebsd-x86_64/bin/swift-format
./build/Ninja-ReleaseAssert+stdlib-Release/swift-freebsd-x86_64/bin/sil-opt
./build/Ninja-ReleaseAssert+stdlib-Release/swift-freebsd-x86_64/bin/swift-remoteast-test
./build/Ninja-ReleaseAssert+stdlib-Release/swift-freebsd-x86_64/bin/lldb-moduleimport-test
./build/Ninja-ReleaseAssert+stdlib-Release/swift-freebsd-x86_64/bin/sil-extract
./build/Ninja-ReleaseAssert+stdlib-Release/swift-freebsd-x86_64/bin/swift-llvm-opt
./build/Ninja-ReleaseAssert+stdlib-Release/swift-freebsd-x86_64/bin/swift-api-digester
./build/Ninja-ReleaseAssert+stdlib-Release__broken/llvm-freebsd-x86_64/tools/clang/lib/CodeGen/CMakeFiles/clangCodeGen.dir/CGException.cpp.o
./build/Ninja-ReleaseAssert+stdlib-Release__broken/llvm-freebsd-x86_64/lib/libclangCodeGen.a
./build/Ninja-ReleaseAssert+stdlib-Release__broken/llvm-freebsd-x86_64/bin/clang-4.0
./build/Ninja-ReleaseAssert+stdlib-Release__broken/llvm-freebsd-x86_64/bin/clang
./build/Ninja-ReleaseAssert+stdlib-Release__broken/llvm-freebsd-x86_64/bin/clang++
./build/Ninja-ReleaseAssert+stdlib-Release__broken/llvm-freebsd-x86_64/bin/clang-cl
./build/Ninja-ReleaseAssert+stdlib-Release__broken/swift-freebsd-x86_64/lib/swift_static/freebsd/x86_64/libswiftCore.a
./build/Ninja-ReleaseAssert+stdlib-Release__broken/swift-freebsd-x86_64/lib/swift_static/freebsd/libswiftCore.a
./build/Ninja-ReleaseAssert+stdlib-Release__broken/swift-freebsd-x86_64/lib/swift/freebsd/x86_64/libswiftCore.so
./build/Ninja-ReleaseAssert+stdlib-Release__broken/swift-freebsd-x86_64/lib/swift/freebsd/libswiftCore.so
./build/Ninja-ReleaseAssert+stdlib-Release__broken/swift-freebsd-x86_64/stdlib/public/runtime/CMakeFiles/swiftRuntime-freebsd-x86_64.dir/Reflection.mm.o
./build/Ninja-ReleaseAssert+stdlib-Release__broken/swift-freebsd-x86_64/bin/swift-ide-test
./build/Ninja-ReleaseAssert+stdlib-Release__broken/swift-freebsd-x86_64/bin/lldb-moduleimport-test
./build/Ninja-ReleaseAssert+stdlib-Release__broken/swift-freebsd-x86_64/bin/swift
./build/Ninja-ReleaseAssert+stdlib-Release__broken/swift-freebsd-x86_64/bin/swiftc
./build/Ninja-ReleaseAssert+stdlib-Release__broken/swift-freebsd-x86_64/bin/swift-format
./build/Ninja-ReleaseAssert+stdlib-Release__broken/swift-freebsd-x86_64/bin/swift-autolink-extract
./build/Ninja-ReleaseAssert+stdlib-Release__broken/swift-freebsd-x86_64/bin/sil-opt
./build/Ninja-ReleaseAssert+stdlib-Release__broken/swift-freebsd-x86_64/bin/swift-remoteast-test
./build/Ninja-ReleaseAssert+stdlib-Release__broken/swift-freebsd-x86_64/bin/sil-func-extractor
./build/Ninja-ReleaseAssert+stdlib-Release__broken/swift-freebsd-x86_64/bin/sil-passpipeline-dumper
./build/Ninja-ReleaseAssert+stdlib-Release__broken/swift-freebsd-x86_64/bin/sil-nm
./build/Ninja-ReleaseAssert+stdlib-Release__broken/swift-freebsd-x86_64/bin/swift-llvm-opt
./build/Ninja-ReleaseAssert+stdlib-Release__broken/swift-freebsd-x86_64/bin/swift-api-digester

As you can see in the diff libSwiftCore now references the undefined symbol and didn't before:

+libswiftCore.a
+libswiftCore.so
+Reflection.mm.o
+sil-func-extractor
+sil-passpipeline-dumper
+sil-nm
-sil-extract

I understand that the symbol refers to an exception handling personality function. But I can't figure out, what is wrong with my environment in FreeBSD 11.0-RELEASE – why the symbol cannot be resolved – despite the whole build process being successful. Any ideas @kstaring @myfreeweb ?

EDIT: I finally managed to produce a working Swift standard library now. Therefore I had to link the core standard library with gnustep's libobjc2, which I installed with pkg install libobjc2 – The errors mentioned above are now gone, but having done these steps doesn't feel right. Shouldn't the whole build process generate a runtime that also provides the exception handling personality?

@lin7sh
Copy link

lin7sh commented Jan 11, 2017

@myfreeweb Thank you. I'll try it again

@kstaring
Copy link
Contributor Author

The required packages are cmake ninja icu libxml2 sqlite3 swig python27 pkgconf py27-sphinx e2fsprogs-libuuid

I'll install a clean jail tomorrow and will see if I get a port ready to submit. I'm bound to run into the trouble nether-cat encountered that way, I suppose. Any packages I forgot to mention will become clear that way as well.

@lin7sh
Copy link

lin7sh commented Jan 12, 2017

@kstaring awesome!!

@kstaring
Copy link
Contributor Author

kstaring commented Jan 12, 2017

From a clean FreeBSD 11.0-RELEASE build, the following packages are required to build and run swiftc, as well as executables compiled with said swiftc. Git, python, cmake, ninja, pkgconf and bash are obviously only necessary to build swift itself.
git python cmake ninja bash binutils pkgconf icu e2fsprogs-libuuid libobjc2

I can confirm that a fresh build of swiftc produces binaries with the undefined symbol __gnustep_objcxx_personality_v0 . It can be solved with a little workaround, and that's why libobjc2 is included in the list of packages to install: add "-L/usr/local/lib -lobjc" to the compiler flags fixes the undefined symbol problem (also described by @nether-cat ).

% swiftc -o hello hello.swift 
% ./hello 
/home/.../src/swift/build/Ninja-ReleaseAssert/swift-freebsd-x86_64/lib/swift/freebsd/libswiftCore.so: Undefined symbol "__gnustep_objcxx_personality_v0"
% swiftc -o hello -L/usr/local/lib -lobjc hello.swift
% ./hello
hello world

The cause lies with llvm's CGException.cpp. I didn't expect a regression this quickly ;-) I'll try to make a port out of this and include a fix, to be included in a new PR as well. Will keep you posted!

I didn't encounter other reported problems yet. To be thorough; it sometimes helps to completely remove the build directory before building once more. At times some bizarre problems surface which can be solved by simply starting over..

@kstaring kstaring deleted the master branch January 12, 2017 15:52
@jrose-apple
Copy link
Contributor

Oof. We really shouldn't be linking libobjc on FreeBSD. The exception personality function comes from a C++ stdlib, not an ObjC one.

@kstaring kstaring restored the master branch January 12, 2017 21:53
@nether-cat
Copy link

I have submitted an issue here: https://bugs.swift.org/browse/SR-3635 – I will also keep trying to find the reason for __gnustep_objcxx_personality_v0 being used on FreeBSD. 👀

@lin7sh
Copy link

lin7sh commented Feb 8, 2017

Friendly check any update on this? I'm trying to follow the issue submitted by @nether-cat https://bugs.swift.org/browse/SR-3635, the status is unsolved, does it mean it's been working on or unsolvable?

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

Successfully merging this pull request may close these issues.