Windows support in libobjc2

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Windows support in libobjc2

David Chisnall-7
Hello,

I have spent a little bit of time integrating some of the work done by the WinObjC team with libobjc2 and now have the relevant clang changes under review:

https://reviews.llvm.org/D50144

With this clang patch, it is now possible to build an objc.dll that supports the new ABI (with all of the introspection improvements and reduced binary size that this includes) as well as providing SEH-compatible exception support (so you can throw exceptions through MSVC-compiled C/C++ code and everything works).  I’ve tested with the runtime’s test suite on i386 and x64 Windows.  Incremental linking doesn’t work, but everything else does.  I have not tested with linkers other than Microsoft’s LINK.EXE, but compatible linkers ought to work.

Building on Windows is still a little bit painful, but I can provide binaries of clang and the runtime if anyone wants to test a bit more.  Is anyone using Windows and GNUstep?

David


_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Windows support in libobjc2

Ivan Vučica-2
I'm not actively using it, but as this holds my interest, I could give
it a shot.

Could you, along with clang and runtime binaries, provide build
instructions up to a trivial -base app?

Could you clarify what you mean by using with a different linker? I
generally just have clang pick a linker on other platform (as with
gcc); how does one tell clang which linker to use? I think I haven't
uninstalled it, so I think I have msvc set up, but it'd be nice to be
able to use a free toolchain.

Have you, before this, tried using libobjc2 with clang with mingw64 w/
msys, or with cygwin?
On Wed, Aug 1, 2018 at 5:39 PM David Chisnall <[hidden email]> wrote:

>
> Hello,
>
> I have spent a little bit of time integrating some of the work done by the WinObjC team with libobjc2 and now have the relevant clang changes under review:
>
> https://reviews.llvm.org/D50144
>
> With this clang patch, it is now possible to build an objc.dll that supports the new ABI (with all of the introspection improvements and reduced binary size that this includes) as well as providing SEH-compatible exception support (so you can throw exceptions through MSVC-compiled C/C++ code and everything works).  I’ve tested with the runtime’s test suite on i386 and x64 Windows.  Incremental linking doesn’t work, but everything else does.  I have not tested with linkers other than Microsoft’s LINK.EXE, but compatible linkers ought to work.
>
> Building on Windows is still a little bit painful, but I can provide binaries of clang and the runtime if anyone wants to test a bit more.  Is anyone using Windows and GNUstep?
>
> David
>
>
> _______________________________________________
> Discuss-gnustep mailing list
> [hidden email]
> https://lists.gnu.org/mailman/listinfo/discuss-gnustep

_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Windows support in libobjc2

David Chisnall-7
On 1 Aug 2018, at 21:43, Ivan Vučica <[hidden email]> wrote:
>
> I'm not actively using it, but as this holds my interest, I could give
> it a shot.

Great!

> Could you, along with clang and runtime binaries, provide build
> instructions up to a trivial -base app?

I haven’t actually tried to build GNUstep yet.  The runtime is built as a native Windows DLL with no external dependencies.  I believe it should work with the SEH versions of MinGW and with anything built with Visual Studio.  GCC gained SEH support around 4.9ish, so exceptions should interoperate with any C/C++/Objective-C/whatever code that is built with a vaguely recent GCC, clang, ICC, or MSVC with an MSVC-compatible target triple.

> Could you clarify what you mean by using with a different linker? I
> generally just have clang pick a linker on other platform (as with
> gcc); how does one tell clang which linker to use? I think I haven't
> uninstalled it, so I think I have msvc set up, but it'd be nice to be
> able to use a free toolchain.

The Windows builds of clang appear to default to invoking link.exe.  If you use -fuse-ld=lld, then I believe it will try to use lld-link.exe on Windows, which is the link.exe-compatible lld frontend.  I do not yet have a build of lld for Windows, so I haven’t tested it yet.  I’ve no idea how well BFD ld works (gold, as I recall, doesn’t support anything other than ELF).  From the lld web site, I believe that it supports all of the linker features that I use, so it should be possible to build with an entirely free toolchain (modulo the fact that you’re linking to a bunch of non-Free system libraries, running on a non-Free OS, using a non-Free windowing system, and so on).

> Have you, before this, tried using libobjc2 with clang with mingw64 w/
> msys, or with cygwin?

Before I started at MSR, the most recent version of Windows I’d used was Windows 2000.  I started working on libobjc2 after I stopped using Windows, so this is the first time that I’ve trued using both together.

David


_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Windows support in libobjc2

Paul Landers
In reply to this post by David Chisnall-7
Is anyone using Windows and GNUstep?

This is great! We at testplant use GNUstep on windows extensively. 

Have you, before this, tried using libobjc2 with clang with mingw64 w/
msys, or with cygwin?

Our current environment is msys2(mingw-w64) with some older versions of libobjc2 and clang. We are looking to update those versions soon though, and the clang patches should be very helpful!

Could you clarify what you mean by using with a different linker? 

I can’t recall too much about our environment, but I can say for all recent versions of the mingw version of clang, the clang linker still has not worked and it has used the gcc linker instead. I do not have Visual Studio (etc) installed. 


---
Paul Landers





_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Windows support in libobjc2

David Chisnall-7
On 2 Aug 2018, at 16:46, Paul Landers <[hidden email]> wrote:
>
>> Is anyone using Windows and GNUstep?
>
> This is great! We at testplant use GNUstep on windows extensively.

I’ll try to put some binaries online for people to test tomorrow.

>> Have you, before this, tried using libobjc2 with clang with mingw64 w/
>> msys, or with cygwin?
>
> Our current environment is msys2(mingw-w64) with some older versions of libobjc2 and clang. We are looking to update those versions soon though, and the clang patches should be very helpful!

I haven’t used MinGW for many years, but it looks as if they provide three different exception models:

- DWARF: Itanium-style unwinding.  The same thing that most *NIX platforms use.  Not interoperable with MSVC-built code or with exceptions thrown by system libraries.
- sjlj: GCC’s setjmp/longjmp EH support, intended for platforms where there’s no native EH support.  Doesn’t depend on a stack unwinder, but has a high cost for every @try block.  Not supported by clang.
- SEH: Windows Structured Exception Handling.  Low overhead, interoperates with Windows native libraries, but requires a recent GCC or an even more recent clang.

The Windows exception model is quite complicated, because it doesn’t unwind the stack until the exception is caught.  On most *NIX systems, there’s an iterative process that first scans the stack to see if there’s a handler, then pops each stack frame that has any cleanups off the stack and runs the cleanups from the next one on top.  On Windows, the stack remains intact and each frame provides ‘funclets’ that run on top of the stack with a pointer to the real stack frame.  This has some nice properties (it can easily be extended to support resumable exceptions and it is possible to throw an out-of-memory exception because, unlike the *NIX model, throwing an exception doesn’t allocate heap memory [though you can’t throw an out-of-stack-space exception, because it does allocate stack memory]).

The new code in libobjc2 supports SEH exceptions.  Most of this was contributed by the WinObjC team, I extended it to work with Win64 and added support for SEH to the assembly code paths, so you can (for example) throw an exception from a +initialize method and have it correctly propagated up to whatever sent the message that triggered the +initialize.

>> Could you clarify what you mean by using with a different linker?
>
> I can’t recall too much about our environment, but I can say for all recent versions of the mingw version of clang, the clang linker still has not worked and it has used the gcc linker instead. I do not have Visual Studio (etc) installed.

The main requirement from the linker is that it correctly sorts things in PE sections lexically by subsection[1].  I don’t know if GNU ld does, but I believe either Microsoft’s link.exe or LLVM’s lld will work.  If you can test with GNU ld, that would be helpful.

When building libobjc2, we also rely on the linker to figure out if we refer to __imp_objc_msgSend, but objc_msgSend is provided locally, that we actually mean the local version.  I think the GNU linker sulks about this, link.exe just tells you that you’re a numpty[2] and continues.  This is because clang doesn’t know whether you’re building the Objective-C runtime or not and so assumes that objc_msgSend and a bunch of other helper functions are dllimport (because in all code that isn’t an Objective-C runtime, they are).

David

[1] On ELF platforms, we rely on GNU linker behaviour to emit magic __start_{section name} and __stop_{section name} symbols.  On PE/COFF, we emit everything in {section name}$m and then emit zero-sized {section name}$a and {section name}$z symbols to mark the beginning and end of the sections.  

[2] Not an actual error message.
_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Windows support in libobjc2

Andreas Fink-2
Hello all,
I'm rebuilding the latest version on libobj2 under debian8 and debian9 and I run into crashes of llvm. I have never seen this before with the same compiler. And its blocking the whole thing.

Anyhow having a clue on how to work around this?


It happens here:

Scanning dependencies of target ForwardDeclareProtocolAccess_legacy
[ 19%] Building C object Test/CMakeFiles/ForwardDeclareProtocolAccess_legacy.dir/ForwardDeclareProtocolAccess.m.o
[ 19%] Building C object Test/CMakeFiles/ForwardDeclareProtocolAccess_legacy.dir/ForwardDeclareProtocol.m.o
#0 0x0000564c7f0c57ca llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/usr/local/bin/clang-5.0+0x1dc07ca)
#1 0x0000564c7f0c38ee llvm::sys::RunSignalHandlers() (/usr/local/bin/clang-5.0+0x1dbe8ee)
#2 0x0000564c7f0c3a12 SignalHandler(int) (/usr/local/bin/clang-5.0+0x1dbea12)
#3 0x00007f8ccb4fe0c0 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x110c0)
#4 0x0000564c7f427a50 llvm::IRBuilder<llvm::ConstantFolder, clang::CodeGen::CGBuilderInserter>::CreateCast(llvm::Instruction::CastOps, llvm::Value*, llvm::Type*, llvm::Twine const&) [clone .constprop.407] (/usr/local/bin/clang-5.0+0x2122a50)
#5 0x0000564c7f4283b7 (anonymous namespace)::CGObjCGNU::GenerateProtocolRef(clang::CodeGen::CodeGenFunction&, clang::ObjCProtocolDecl const*) (/usr/local/bin/clang-5.0+0x21233b7)
#6 0x0000564c7f413b9e (anonymous namespace)::ScalarExprEmitter::Visit(clang::Expr*) (/usr/local/bin/clang-5.0+0x210eb9e)
#7 0x0000564c7f414c30 clang::CodeGen::CodeGenFunction::EmitScalarExpr(clang::Expr const*, bool) (/usr/local/bin/clang-5.0+0x210fc30)
#8 0x0000564c7f297495 clang::CodeGen::CodeGenFunction::EmitReturnStmt(clang::ReturnStmt const&) (/usr/local/bin/clang-5.0+0x1f92495)
#9 0x0000564c7f29946f clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) (/usr/local/bin/clang-5.0+0x1f9446f)
#10 0x0000564c7f2c64d8 clang::CodeGen::CodeGenFunction::EmitFunctionBody(clang::CodeGen::FunctionArgList&, clang::Stmt const*) (/usr/local/bin/clang-5.0+0x1fc14d8)
#11 0x0000564c7f2cda85 clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) (/usr/local/bin/clang-5.0+0x1fc8a85)
#12 0x0000564c7f2e6e35 clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/usr/local/bin/clang-5.0+0x1fe1e35)
#13 0x0000564c7f2f7299 clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/usr/local/bin/clang-5.0+0x1ff2299)
#14 0x0000564c7f2f8218 clang::CodeGen::CodeGenModule::EmitGlobal(clang::GlobalDecl) (/usr/local/bin/clang-5.0+0x1ff3218)
#15 0x0000564c7f2f8859 clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) [clone .part.5457] (/usr/local/bin/clang-5.0+0x1ff3859)
#16 0x0000564c7f8df3c3 (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef) (/usr/local/bin/clang-5.0+0x25da3c3)
#17 0x0000564c7f8d60d2 clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) (/usr/local/bin/clang-5.0+0x25d10d2)
#18 0x0000564c7fc5bfd6 clang::ParseAST(clang::Sema&, bool, bool) (/usr/local/bin/clang-5.0+0x2956fd6)
#19 0x0000564c7f8dd151 clang::CodeGenAction::ExecuteAction() (/usr/local/bin/clang-5.0+0x25d8151)
#20 0x0000564c7f5db016 clang::FrontendAction::Execute() (/usr/local/bin/clang-5.0+0x22d6016)
#21 0x0000564c7f5aa7f6 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/usr/local/bin/clang-5.0+0x22a57f6)
#22 0x0000564c7f66c13b clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/usr/local/bin/clang-5.0+0x236713b)
#23 0x0000564c7dcdf3b8 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/usr/local/bin/clang-5.0+0x9da3b8)
#24 0x0000564c7dc64af3 main (/usr/local/bin/clang-5.0+0x95faf3)
#25 0x00007f8cca0812e1 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202e1)
#26 0x0000564c7dcdce2a _start (/usr/local/bin/clang-5.0+0x9d7e2a)
Stack dump:
0. Program arguments: /usr/local/bin/clang-5.0 -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ForwardDeclareProtocol.m -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debug-info-kind=limited -dwarf-version=4 -debugger-tuning=gdb -coverage-notes-file /Users/afink/development/gnustep/libobjc2/Build/Test/CMakeFiles/ForwardDeclareProtocolAccess_legacy.dir/ForwardDeclareProtocol.m.gcno -resource-dir /usr/local/lib/clang/5.0.0 -D GC_DEBUG -D GNUSTEP -D NO_LEGACY -D OLDABI_COMPAT=1 -D TYPE_DEPENDENT_DISPATCH -I /Users/afink/development/gnustep/libobjc2 -U NDEBUG -internal-isystem /usr/local/include -internal-isystem /usr/local/lib/clang/5.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -fdebug-compilation-dir /Users/afink/development/gnustep/libobjc2/Build/Test -ferror-limit 19 -fmessage-length 172 -fobjc-runtime=gnustep-1.7 -fobjc-dispatch-method=non-legacy -fobjc-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -fexceptions -fobjc-exceptions -fblocks -o CMakeFiles/ForwardDeclareProtocolAccess_legacy.dir/ForwardDeclareProtocol.m.o -x objective-c /Users/afink/development/gnustep/libobjc2/Test/ForwardDeclareProtocol.m
1. <eof> parser at end of file
2. /Users/afink/development/gnustep/libobjc2/Test/ForwardDeclareProtocol.m:4:11: LLVM IR generation of declaration 'getProtocol'
3. /Users/afink/development/gnustep/libobjc2/Test/ForwardDeclareProtocol.m:4:11: Generating code for declaration 'getProtocol'
clang-5.0: error: unable to execute command: Segmentation fault
clang-5.0: error: clang frontend command failed due to signal (use -v to see invocation)
clang version 5.0.0 (tags/RELEASE_500/final 320467)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/local/bin
clang-5.0: note: diagnostic msg: PLEASE submit a bug report to http://llvm.org/bugs/ and include the crash backtrace, preprocessed source, and associated run script.
clang-5.0: note: diagnostic msg:
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang-5.0: note: diagnostic msg: /tmp/ForwardDeclareProtocol-e5f47b.m
clang-5.0: note: diagnostic msg: /tmp/ForwardDeclareProtocol-e5f47b.sh
clang-5.0: note: diagnostic msg:

********************
Test/CMakeFiles/ForwardDeclareProtocolAccess_legacy.dir/build.make:86: recipe for target 'Test/CMakeFiles/ForwardDeclareProtocolAccess_legacy.dir/ForwardDeclareProtocol.m.o' failed
make[2]: *** [Test/CMakeFiles/ForwardDeclareProtocolAccess_legacy.dir/ForwardDeclareProtocol.m.o] Error 254
CMakeFiles/Makefile2:670: recipe for target 'Test/CMakeFiles/ForwardDeclareProtocolAccess_legacy.dir/all' failed
make[1]: *** [Test/CMakeFiles/ForwardDeclareProtocolAccess_legacy.dir/all] Error 2
Makefile:162: recipe for target 'all' failed
make: *** [all] Error 2

_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep