Sorry everyone, looks like my earlier draft got sent out prematurely...

> Am 29.01.2021 um 17:28 schrieb David Chisnall <gnus...@theravensnest.org>:
> 
> ld -r is pretty flaky everywhere.  LLD wasn't going to implement it at all 
> and GNUstep was one of only two consumers so I think it's fair to say that 
> it's pretty likely that it will continue to be intermittently broken by 
> various linker versions.  I personally like the concept but it's probably 
> better to not depend on it anywhere.

Yeah, hopefully this change will resolve these issues once and for all.

That being said, Richard raised one *potential* issue with this change on 
GitHub, which is that it increases the length of the command that the linker is 
being called with, as now all subproject object files are passed directly to 
the linker. Hopefully OS command line limits are large enough these days so 
that this won’t be an issue in practice, but I’d still encourage everyone to 
try building their projects with the "clang-msvc-support" branch of tools-make.


>> - Building
>> Building with this setup requires using a standard (non-MinGW) Clang that 
>> e.g. comes with Visual Studio or is available as pre-built binary from the 
>> LLVM website, and requires passing a host to configure like 
>> --host=x86_64-pc-windows. Invoking `clang -v` should show a target like 
>> "x86_64-pc-windows-msvc". It *might* be that using a MinGW Clang works too 
>> when invoked with --target x86_64-pc-windows-msvc, but I haven’t tried that.
> 
> The easiest way of installing clang on Windows is via Chocolatey: just run 
> `choco install llvm` once it's installed.  Choco is also the easiest way of 
> installing cmake and Ninja for building the runtime.

Thanks, good to know!


>> The build is best done in an MSYS2 shell that does not have any additional 
>> *-devel packages installed that might get picked up by configure. 
>> Alternatively --disable-xxx flags can be used to prevent these dependencies 
>> to be picked up.
> 
> Have you tried with the bash.exe in C:\Windows\System32?

I briefly tried building in WSL today, and the main difference to using an 
MSYS2 shell is that Autoconf will consider it cross-compiling. This means that 
some config checks will not be run (because Autoconf will think that it can’t 
run the binaries), and we would need to provide a cross.config file with 
pre-determined results of these config files instead (just like when 
cross-compiling e.g. for Android). This is obviously more fragile.

But this kind of illustrates what I consider the biggest challenge with this 
setup: the need to install and jump between different shells in order to build 
the whole system (i.e. CMD for libobjc2, libdispatch, and probably others; 
Bash/MSYS2 for GNUstep).

I’m not sure if there’s an elegant solution to this. My current line of 
thinking is to create a project like tools-android (tools-windows?) with Batch 
+ Bash scripts to build all dependencies and GNUstep in their respective 
environments.


> Is the -fuse-ld=lld line required?  You get LLD installed when you install 
> clang, so it's not very important, but the runtime and its tests, at least, 
> also work with LINK.EXE (though you may have to disable incremental linking 
> if it's on by default).

I did:

>> I tried using the MS linker (link.exe), but while that seems to generally 
>> work fine linking ObjC files, it throws up at some configure tests 
>> (specifically when testing "whether objc really works"). Using LLD works 
>> though, so one must run Make configure with LDFLAGS="-fuse-ld=lld".

This is reproducible simply by compiling config/config.objc.m from libs-base:

$ clang -o conftest.exe config/config.objc.m -I/c/GNUstep/x64/include 
-L/c/GNUstep/x64/lib -fobjc-runtime=gnustep-2.0 -lobjc
LINK : conftest.exe not found or not built by the last incremental link; 
performing full link
conftest-b38f3b.o : warning LNK4078: multiple '.CRT' sections found with 
different attributes (40400040)
libcmt.lib(initializers.obj) : warning LNK4254: section '.CRT' (C0000040) 
merged into '.rdata' (40000040) with different attributes

$ ./conftest.exe
Segmentation fault

$ lldb conftest.exe
(lldb) r
Process 165928 stopped
* thread #1, stop reason = Exception 0xc0000005 encountered at address 
0x7ffce04d1048: Access violation reading location 0x00000000
    frame #0: 0x00007ffce04d1048 objc.dll`objc_msgSend + 40
objc.dll`objc_msgSend:
->  0x7ffce04d1048 <+40>: movl   (%r10), %r11d
    0x7ffce04d104b <+43>: cmpl   $0x8, %r11d
    0x7ffce04d104f <+47>: je     0x7ffce04d1063            ; <+67>
    0x7ffce04d1051 <+49>: cmpl   $0x0, %r11d

Let me know if I should open an issue for this somewhere, or if there’s 
something in config.objc.m that we should change to fix this.


>> For pthreads I have built http://www.sourceware.org/pthreads-win32/ 
>> <http://www.sourceware.org/pthreads-win32/> from source by invoking "nmake 
>> clean VC" in a VS native tools command prompt, and manually copied the 
>> headers (pthread.h, sched.h, semaphore.h), pthreadVC2.lib (renamed to 
>> pthread.lib), and phtreadVC2.dll.
> 
> At some point it would be nice to lose this dependency.  I don't know how 
> much the attitude to C++ in GNUstep has changed recently, but C++11 now has a 
> nice set of threading abstractions that provide everything that NSThread, 
> NSLock and friends need.  If we use those instead of pthreads then we'd have 
> something that worked on any platform with a C++11 implementation (Linux, 
> Windows, Fuschia, Haiku, and so on).

That’d be nice! I would personally be completely open to using C++ in GNUstep, 
and that sounds to me like a much better solution than implementing NSThread 
and NSLock with native Windows APIs, although that’s of course also an option.

I’d appreciate any thoughts on this from others what they think about C++ in 
GNUstep to replace specific APIs like pthreads? I guess this could be guarded 
with a config check so that a pure-C version would still be available using 
pthreads.


>> - NSFileManager support
>> NSFileManager is currently non-functional with this setup due to dirent.h 
>> missing (MinGW has it, but Windows doesn’t).
>> I found this MIT-licensed header-only implementation – would that be ok to 
>> add to the project?
>> https://github.com/win32ports/dirent_h/blob/master/dirent.h 
>> <https://github.com/win32ports/dirent_h/blob/master/dirent.h>
> 
> I think that looks easier than using Win32 ABIs directly.

Agreed. I’ll give it a go.


>> - Autoconf GNUC / GCC / Clang detection
>> When targeting the MSVC ABI, Clang does not define `__GNUC__`, which causes 
>> Autoconf to not define $GCC (i.e. "checking whether we are using the GNU C 
>> compiler" will be NO). I thus removed $GCC as a pre-requisite in 
>> GS_CHECK_CC_IS_CLANG(), so that Clang is still correctly detected in this 
>> setup.
> 
> I *believe* this is controlled by either a gnu dialect (e.g. -std=gnu11 for 
> C) or -fgnu-extensions.  That said, I'm not sure if you can #include Windows 
> headers with gnu extensions enabled.

Yeah I tried with -fgnuc-version=xxx, but then Windows headers didn’t work.


>> - Debug/Release CRT
>> Just a heads up that on Windows the C runtime libraries (CRT) come in two 
>> versions for debug and release builds (e.g. msvcrt and msvcrtd). The 
>> libraries that are used seem to have to match between all DLLs – e.g. 
>> building libobjc2 for debug will cause all sorts of crashes when Base is 
>> build for release, e.g. when freeing memory allocated by libobjc2 in Base.
> 
> Fun.

Indeed. My plan is to link against debug libraries when building with "make 
debug=yes".


>>      lld-link: error: relocation against symbol in discarded section: 
>> __start_.objcrt$SEL
>>      >>> referenced by C:\msys64\tmp\conftest-78a937.o:(.objc_init)
>> This is reproducible when building a file that calls ObjC runtime functions 
>> but doesn’t actually contain any ObjC code. Not sure if that’s expected 
>> behavior or bug.
> 
> I think this is a bug, probably a clang bug (and probably my fault)

Should I open an LLVM issue for this?


> Awesome work, and it makes me much happier than trying to support MinGW.

Thank you, glad you like it! This is also exciting to us because it should e.g. 
allow us to use recent Windows technologies like the C++/WinRT language 
projection from ObjC++ which are not compatible with MinGW.

That being said, I would still very much like to get libobjc2 working with 
MinGW as well, as it would allow people currently using GNUstep with GCC in a 
MinGW environment to switch to Clang/libobjc2, should result in a more 
streamlined setup experience with all dependencies being available via MinGW 
packages and everything being built in one shell, and allow for existing 
MinGW-based software to be used.

I’ll try to get you those instructions for building LLVM with the MinGW patches 
in the next couple weeks.


> We have given up supporting MinGW for snmalloc and I am considering 
> optionally supporting snmalloc for Objective-C object allocations since it is 
> much faster than the system malloc on most platforms and is particularly good 
> for fixed-size allocations as are common in Objective-C.  It would be a shame 
> for this to be an everywhere-except-Windows thing.

That looks really great! Would be interesting to see some performance stats of 
this for ObjC specifically if you have that.


Frederik



Reply via email to