Closed steffengy closed 7 years ago
@steffengy
Is a windows implementation planned?
Yes, but I hope someone knowing Windows will take care of it.
- emulating the required linux APIs ("mapping" to the windows equivalents at runtime or at a later stage of the project during compilation)
I think emulating one OS in another, while possible, is too ambitious. virtual
uses direct syscalls wherever possible, because I have no intents to rewrite parts of libc
or the Linux kernel from scratch ;-)
- implementing it natively (as the linux implementation, proxying WINAPI calls, this seems to require quite much work?)
IIUC, this is probably the better way.
Couple of notes.
There's a set of platform/architecture neutral VM opcodes, their respective implementations and there's a platform/achitecture specific set. The later set can be tailored using build tags or using the foo_os_arch.go
naming scheme. The later option is already in use where amd64
and 386
architectures differ on Linux, so I guess it's easiest to stick with that.
Assuming sqlite
is the motivation, I suggest to start the approach like this, because ccir
consults virtual
when compiling C to recognize functions implemented by the VM itself, aka "builtins":
gcc
on a Windows box.ccir
, go to its libc
directory, enter go generate
. See what happens and provide feedback so I can make any necessary changes.sqlite-amalgamation-3180000.zip
to $GOPATH/src/sqlite.org/sqlite-amalgamation-3180000
so ccir
tests can find the sources.go test
. That will fail, but the failures will tell exactly which "syscalls" sqlite
needs on Windows.ccir
and virtual
tests pass on Windows, enter the sqlite
directory, try issuing go generate
and, if that works, go test
.Easy, isn't it? ;-)
Thanks for the valuable input!
Assuming sqlite is the motivation
Assumed correctly ;)
Install ccir, go to its libc directory, enter go generate. See what happens and provide feedback so I can make any necessary changes.
go generate:
..\..\virtual\stdio.go:17:2: no buildable Go source files in gopath\src\github.com\cznic\ccir\libc\errno
..\..\virtual\pthread.go:12:2: no buildable Go source files in gopath\src\github.com\cznic\ccir\libc\pthread
..\..\virtual\stdio.go:18:2: no buildable Go source files in gopath\src\github.com\cznic\ccir\libc\stdio
..\..\virtual\unistd.go:14:2: no buildable Go source files in gopath\src\github.com\cznic\ccir\libc\unistd
Which is so far expected. Should virtual really depend on pthreads for windows? (That seems quite linux-specific [isn't used by sqlite on windows], even though there are pthread-shims for windows)
That's a rather unfortunate dependency chain we've got here. generator.go
in ccir/libc
must import ccir
, which imports virtual
which imports things under ccir/libc
which exactly generator.go
should generate ;-)
The proper solution is not clear to me immediately, IIRC, the virtual.IsBuiltin
function is the only thing ccir
, modulo its tests, needs from virtual
.
Let's do the "improper" way: Copy the ccir/libc/errno/errno_linux_yyy.go
file to ccir/libc/errno/errno_windows_yyy.go
, where yyy
is your GOARCH. That will make the constants in that package probably wrong, but I believe it should not matter for now as generator.go
generates it's stuff using gcc
's headers.
Of course, you need to repeat the step above for any and all other directories missing Windows specific files. Commit to some temp branch before running go generate
again because those files will get overwritten once generator.go
builds and attempts to do its job. After that you should have the correct values there. Or no values[0] where the source thing does not exist on Windows (like pthread.h
). This situation will indicate where a file in virtual
will later[1] need to be specialized (like virtual/pthread.go
-> virtual/pthread_linux.go
, for example).
[0]: Such instances would be probable removed completely later on - once they get no more imported on Windows.
[1]: Maybe this will be necessary before ccir/libc/generator
can build, I'm not sure, but it seems you're soon going to know ;-)
@cznic
I created the necessary _windows_amd64
files, now go generate
results in:
..\..\virtual\cpu.go:1747: c.lstat64 undefined (type *cpu has no field or method lstat64)
..\..\virtual\cpu.go:1749: c.stat64 undefined (type *cpu has no field or method stat64)
..\..\virtual\cpu.go:1755: c.open64 undefined (type *cpu has no field or method open64)
..\..\virtual\cpu.go:1757: c.fcntl undefined (type *cpu has no field or method fcntl)
..\..\virtual\cpu.go:1759: c.fstat64 undefined (type *cpu has no field or method fstat64)
..\..\virtual\sys_mman.go:28: undefined: syscall.SYS_MMAP
..\..\virtual\sys_mman.go:28: not enough arguments in call to syscall.Syscall6
have (<T>, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr)
want (uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr)
..\..\virtual\sys_mman.go:39: undefined: syscall.SYS_MUNMAP
..\..\virtual\sys_mman.go:39: not enough arguments in call to syscall.Syscall
have (<T>, uintptr, uintptr, number)
want (uintptr, uintptr, uintptr, uintptr, uintptr)
..\..\virtual\sys_time.go:24: undefined: syscall.SYS_GETTIMEOFDAY
..\..\virtual\sys_time.go:24: too many errors
I have a feeling that quite much more in virtual currently depends on linux.
I have a feeling that quite much more in virtual currently depends on linux.
You're right and it's my fault. IMD, free time is most precious and I thought about porting, but that's about it, sorry.
But please don't give up! We can make it, I'm sure ;-)
I'll create ccir
and virtual
branches for the Windows port, send you a collaborator's invite and will try to fix the trouble in the parts I am able to do so. The above quoted errors seem to be well in that category. IOW, I'll prepare any stubs needed for you to fill in the implementation any time later.
After you accept the invitations, if you decide to do so, please push to the respective branches the non-building versions you have now and I'll try to do what I can. Please be patient, I cannot really test my part, I don't have any Windows box at hand now, not even a virtualized one, so it will probably take more than one round to get it building at least.
@steffengy Branches are ready, invitations sent.
@cznic Thanks for getting me started, I committed my local CCIR changes (which consist of only copying the _linux_amd64.go
files to _windows_amd64
as discussed above), for virtual there aren't any changes yet.
Thanks! I'm on it.
@steffengy
jnml@4670:~/src/github.com/cznic/ccir/libc$ GOOS=windows go build generator.go
jnml@4670:~/src/github.com/cznic/ccir/libc$ file generator.exe
generator.exe: PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows
jnml@4670:~/src/github.com/cznic/ccir/libc$
Seems okay here, but I cannot of course execute it. Please try it on Windows.
@cznic
go build generator.go
works.
go generate
returns:
22:48:34.707583 generator.go:951: exit status 1
exit status 1
libc.go:1: running "go": exit status 1
After applying https://github.com/cznic/cc/pull/60 locally:
23:11:45.068749 generator.go:826: m:\mingw\x86_64-w64-mingw32\include\crtdefs.h:35:44: unexpected identifier size_t, expected one of ['(', ')', ',', ':', ';', '=', '[', '{', _Bool, _Complex, _Noreturn, _Static_assert, asm, auto, char, const, double, enum, extern, float, inline, int, long, register, restrict, short, signed, static, struct, typedef, typedefname, typeof, union, unsigned, void, volatile]
m:\mingw\x86_64-w64-mingw32\include\vadefs.h:35:2: error: "VARARGS not implemented for this compiler"
exit status 1
libc.go:2: running "go": exit status 1
(This is using Nuwen 14.1 (GCC 6.3, Mingw) but also happens with TDM-GCC 5.3)
~If I understand correctly VARARGS aren't supported by
cznic/cc yet?~
Seems like cznic/cc isn't able to parse crtdefs.h:35 which is:
__MINGW_EXTENSION typedef unsigned __int64 size_t;
Not sure if the VARARGS error is related to that or some other problem:
#ifndef _VA_LIST_DEFINED /* if stdargs.h didn't define it */
#define _VA_LIST_DEFINED
#if defined(__GNUC__)
typedef __gnuc_va_list va_list;
#elif defined(_MSC_VER)
typedef char * va_list;
#elif !defined(__WIDL__)
#error VARARGS not implemented for this compiler
#endif
#endif /* _VA_LIST_DEFINED */
Might also be something going wrong with defines/preprocessing
If I understand correctly VARARGS aren't supported by cznic/cc yet?
No, varargs should work just fine.
jnml@4670:~/src/github.com/cznic/cc$ git branch
issue51
issue57
issue59
issue60
issue62
issue67
issue67-debug
issue67-wips
issue91
* master
jnml@4670:~/src/github.com/cznic/cc$ git log -1
commit d5c3a9df03dc0d4053f7d1ba6f4e4622d6d645dc
Author: Jan Mercl <0xjnml@gmail.com>
Date: Wed Apr 12 01:05:53 2017 +0200
Fix anonymous struct/union members flattening.
jnml@4670:~/src/github.com/cznic/cc$ grep -ni varargs *
cc.go:419:// See https://gcc.gnu.org/onlinedocs/gccint/Varargs.html
grep: testdata: je adresářem
jnml@4670:~/src/github.com/cznic/cc$
The above and what you sent seems to indicate the error message "VARARGS not implemented for this compiler"
probably comes from an #error
directive. Why? Good question I don't have an answer for ATM.
Can you please take a look at m:\mingw\x86_64-w64-mingw32\include\vadefs.h:35:2
and around to look what the surround (guess) #if
or #ifdef
condition is? I will meanwhile try to google the file as well. Thank you.
@cznic Already updated the message, seems like you were too fast :)
Looking here I think we probaly need #define _MSC_VER somenumber
on Windows platform. This is due to a hack where I remove any GNUC|GCC
#define
from the set of predefined macros. It's necessary because otherwise GNU libc wants very GCC specific things.
Looking here I think we probaly need #define _MSC_VER somenumber on Windows platform.
Hopefully that won't pull in anything too MSVC C++ specific, but I also do not see what else would help here.
23:11:45.068749 generator.go:826: m:\mingw\x86_64-w64-mingw32\include\crtdefs.h:35:44: unexpected identifier size_t, expected one of ['(', ')', ',', ':', ';', '=', '[', '{', _Bool, _Complex, _Noreturn, _Static_assert, asm, auto, char, const, double, enum, extern, float, inline, int, long, register, restrict, short, signed, static, struct, typedef, typedefname, typeof, union, unsigned, void, volatile]
Seems like cznic/cc isn't able to parsecrtdefs.h:35
which is:__MINGW_EXTENSION typedef unsigned __int64 size_t;
That part is a bug (or not implemented), I guess?
I hoped for GCC on Windows to also use its own (GNU libc) headers, but it doesn't seem to be the case. It took a bit of tweaking to make it all work with the GNU libc headers...
That part is a bug (or not implemented), I guess?
I think this can be resolved by adding
#define __MINGW_EXTENSION
to builtin.h
(in ccir/libc
).
I added the following as a test to ccir/libc/builtin.h
:
#define _MSC_VER
#define __MINGW_EXTENSION
This didn't change any of the error messages, which is strange, since atleast the VARARGS error should surely disappear. Do I need to follow some additional steps that these changes are applied?
This didn't change any of the error messages, which is strange, since atleast the VARARGS error should surely disappear.
Very strange, I must be missing something.
Not really related to the above, but maybe __int64
is not defined to be a type and it neeeds to be added to builtin.h
on Windows?
#define _MSC_VER
is possibly not enough, try giving it a non zero value, like in #define _MSC_VER 1
, for example.
Also tried that, adding some random stuff like abc
to builtin.h
which should be syntactically invalid on it's own
also doesn't result in any change of the errors (which it surely should).
So I guess it doesn't actually look at this file?
I'll try to add a cpp hook to ccir/libc/generator.go
, it may help in debugging the issue.
Option added, please pull and try go run generator.go -cpp
instead of go generate
and redirect stderr output to some log file to inspect. You can also attach it here at issue comments for me to have a look, I think it's possible.
Done:
# 22 "predefined.h"
typedef char *__builtin_va_list;
# 548 "mingw\\x86_64-w64-mingw32\\include\\_mingw.h"
const char *__mingw_get_crt_info (void);
# 35 "mingw\\x86_64-w64-mingw32\\include\\crtdefs.h"
typedef unsigned __int64 size_t;
00:00:39.304571 generator.go:847: mingw\x86_64-w64-mingw32\include\crtdefs.h:35:44: unexpected identifier size_t, expected one of ['(', ')', ',', ':', ';', '=', '[', '{', _Bool, _Complex, _Noreturn, _Static_assert, asm, auto, char, const, double, enum, extern, float, inline, int, long, register, restrict, short, signed, static, struct, typedef, typedefname, typeof, union, unsigned, void, volatile]
mingw\x86_64-w64-mingw32\include\vadefs.h:35:2: error: "VARARGS not implemented for this compiler"
exit status 1
EDIT: seems like builtin.h is indeed somehow not applied.
adding _MSVC_VER
to predefined.h
makes the VARARGS error disappear.
# 35 "m:\\mingw\\x86_64-w64-mingw32\\include\\crtdefs.h"
typedef unsigned __int64 size_t;
00:00:39.304571 generator.go:847: mingw\x86_64-w64-mingw32\include\crtdefs.h:35:44: unexpected identifier size_t, expected one of ['(', ')', ',', ':', ';', '=', '[', '{', _Bool, _Complex, _Noreturn, _Static_assert, asm, auto, char, const, double, enum, extern, float, inline, int, long, register, restrict, short, signed, static, struct, typedef, typedefname, typeof, union, unsigned, void, volatile]
The line with the crtdefs.h:35:44
error seems to have only 32 characters, why is the error column 44? Do you have any idea?
Anyway, please look into the log, if __int64
is typedef
ed or #define
d any place before usage here. Thanks.
edit: typos
EDIT: seems like builtin.h is indeed somehow not applied.
Have no idea why, it's imported quite directly.
The crtdefs.h:35:44 seems to have only 32 characters, why the error column is 44?
"__MINGW_EXTENSION typedef unsigned __int64 size_t;".length == 50
Anyway, please look into the log, if __int64 is typedefed or #defined any place before usage here.
With the following in predefined.h
#define _MSC_VER 1
#define __MINGW_EXTENSION 1
the (entire) log is:
# 25 "predefined.h"
typedef char *__builtin_va_list;
# 33 "m:\\mingw\\x86_64-w64-mingw32\\include\\vadefs.h"
typedef char * va_list;
# 548 "m:\\mingw\\x86_64-w64-mingw32\\include\\_mingw.h"
const char *__mingw_get_crt_info (void);
# 35 "m:\\mingw\\x86_64-w64-mingw32\\include\\crtdefs.h"
typedef unsigned __int64 size_t;
00:12:16.470538 generator.go:847: m:\mingw\x86_64-w64-mingw32\include\crtdefs.h:35:44: unexpected identifier size_t, expected one of ['(', ')', ',', ':', ';', '=', '[', '{', _Bool, _Complex, _Noreturn, _Static_assert, asm, auto, char, const, double, enum, extern, float, inline, int, long, register, restrict, short, signed, static, struct, typedef, typedefname, typeof, union, unsigned, void, volatile]
exit status 1
Adding e.g. #define __int64 int
[which isn't quite right but fine to track this compiler issue here]
to also predefined.h (definitely also not working in builtin.h)
seems to do it and gives me another error (the next one):
ctype_windows_amd64.h:10:23: unexpected identifier __ptlocinfo, expected one of ['(', ')', ',', ':', ';', '=', '[', '{', _Bool, _Complex, _Noreturn, _Static_assert, asm, auto, char, const, double, enum, extern, float, inline, int, long, register, restrict, short, signed, static, struct, typedef, typedefname, typeof, union, unsigned, void, volatile]
My comment about <builtin.h>
was misleading, sorry, that's used in a later stage.
I think your experiments are correct, we have to, guarded by some #ifdef
s, add some #define
s to predefine.h
.
Sorry, it's few weeks I've been into these places and got meanwhile focused elsewhere...
ctype_windows_amd64.h:10:23: unexpected identifier __ptlocinfo, expected one of ['(', ')', ',', ':', ';', '=', '[', '{', _Bool, _Complex, _Noreturn, _Static_assert, asm, auto, char, const, double, enum, extern, float, inline, int, long, register, restrict, short, signed, static, struct, typedef, typedefname, typeof, union, unsigned, void, volatile]
Such implementation defined things, note the two leading underscores, are why we are slurping the predefined macros from cpp -dM
. What does that, if I recall the command correctly, shows?
BTW, have I told you how much I dislike C after doing this project? ;-)
Haha you probably now know several more edge cases than before :)
cpp -dM
doesn't appear to do anything.
Maybe __ptlocinfo
comes from mingw-w64-headers/crt/ctype.h ?
Haha you probably now know several more edge cases than before :)
Always look on the bright side ;-)
cpp -dM doesn't appear to do anything.
Yeah, on Linux it should be $ cpp -dM /dev/null
, please try (guessed) c:\> cpp -dM NUL
or something like that... We rely on the system CC predefines a lot.
Maybe __ptlocinfo comes from mingw-w64-headers/crt/ctype.h ?
If only I had any idea what it stands for. Some 'pointer to location info'?
Or 'thread local info' maybe?
Since it's quite big not directly here (cpp -dM NUL
works):
https://gist.github.com/steffengy/690934e545549c280efa6731ac4550eb
pthreadlocinfo "points" to threadlocaleinfostruct
.
Since it's quite big not directly here (cpp -dM NUL works): https://gist.github.com/steffengy/690934e545549c280efa6731ac4550eb
Thanks. The output of cpp -dM
seems okay. That's all I know.
We're now in the Windows/C land and there's not much left what I can help you with. Not that I don't want to, I just don't know enough about Windows (and the GCC implementation on that platform).
Please try to investigate further. Don't hesitate to ask for any help I can provide you with. (That means mostly the Go side, unfortunately.) We can always ask other/more experts if necessary. Last, but not least, it's getting a bit late at night here and I should probably get some sleep.
My wish for this weekend is to try and start coding ccgo
. FYI: The ccir/libc
.h and .go stuff will be used by it as well, meaning this work of your's is not going to be wasted.
Also, please add yourself to the CONTRIBUTORS and/or AUTHORS files in both ccir
and virtual
so we do not forget to do that later before merging the issue1
branches to master
.
Yeah I'll try to look into that stuff once I got proper defines for __int64 and will update here once there are some exciting news.
The windows land itself is often quite annoying, MSVC even more but MINGW is IMHO not better buf (except for interoperability) worse.
Also signing out for today.
Regarding unexpected identifier __ptlocinfo
for extern pthreadlocinfo __ptlocinfo;
seems like that it's actually because of pthreadlocalinfo
not being recognized.
#define pthreadlocinfo struct threadlocaleinfostruct
"fixes" the compilation,
while using the equivalent typedef doesn't work.prebuild.h
but it doesn't appear so)From my point this seems like a bug, where typedefs are not semantically recognized for such cases?
From my point this seems like a bug, where typedefs are not semantically recognized for such cases?
Of course it can be a bug. If you can create a simple reproduction case, which some other C compiler accepts, please fill a cc
issue, thank you.
@cznic LIBC builds now for mingw64 :)
Happy for feedback, especially regarding the workaround + adding of types here: https://github.com/cznic/ccir/commit/c77c34348497f3d1b39778e50a099d6b66eaf18e#diff-c0cbe5fc2255f37eda2c46a58fd84141R930
One issue seems to be:
string_windows_amd64.h:23:100: unexpected ',', expected declarator or optional init declarator list or one of ['(', '*', ';', identifier]
references cznic/cc#94
This seems to be caused because it's a struct-redefinition of pthreadlocinfo
using multiple declarators.
(It is included in most .h files, maybe moving to builtin.h and removing it from builder.go works, but I don't see how that could work)
Any idea how to fix that?
Assuming "LIBC builds" means that running go generate
in ccir/libc
works without errors, I'm not sure from where or at which step the error in the header file is reported. Is that when go test
is invoked in ccir
? Please clarify.
Also, please keep pushing your intermediate local changes of the issue1
branches so I can early test for potential breakages of the Linux version. Don't worry about size of the commits or proper commit messages if you think the later merge to master branch will be squashed.
In any case, it seems your porting effort is making great progress already!
I will get to look cznic/cc#94 in a couple of hours, I hope.
Assuming "LIBC builds" means that running go generate in ccir/libc works without errors, I'm not sure from where or at which step the error in the header file is reported. Is that when go test is invoked in ccir? Please clarify.
Sorry, yeah that happens when I run go test
when for example a GCC-torture test relies on string.h and stdlib.h, which both contain a definition of pthreadlocinfo
, which fails because of cznic/cc#94.
I'm currently also trying to find out what's going on there, but still having a hard time finding the relevant place in the parser.
Wow! Do some tests already pass? You're light years ahead compared to what I thought is possible only yesterday ;-)
--- FAIL: TestTCC (0.65s)
all_test.go:359: ..\cc\testdata\tcc-0.9.26\tests\tests2\22_floating_point.c: FAIL
cc.Parse: gopath\src\github.com\cznic\ccir\libc\math_windows_amd64.h:23:100: unexpected ',', expected declarator or optional init declarator list or one of ['(', '*', ';', identifier]
all_test.go:368: 47/55 ok
all_test.go:370: failures: 8
--- FAIL: TestGCCExec (10.51s)
all_test.go:359: ..\cc\testdata\gcc-6.3.0\gcc\testsuite\gcc.c-torture\execute\20000910-2.c: FAIL
cc.Parse: gopath\src\github.com\cznic\ccir\libc\string_windows_amd64.h:23:100: unexpected ',', expected declarator or optional init declarator list or one of ['(', '*', ';', identifier]
all_test.go:368: 1222/1250 ok
all_test.go:370: failures: 28
--- FAIL: TestC4 (0.02s)
all_test.go:792: gopath\src\github.com\cznic\ccir\libc\stdlib_windows_amd64.h:23:100: unexpected ',', expected declarator or optional init declarator list or one of ['(', '*', ';', identifier]
--- FAIL: TestSqlite (0.06s)
all_test.go:792: gopath\src\github.com\cznic\ccir\libc\stdlib_windows_amd64.h:23:100: unexpected ',', expected declarator or optional init declarator list or one of ['(', '*', ';', identifier]
FAIL
exit status 1
FAIL github.com/cznic/ccir 11.312s
I guess that means some already pass ;-)
ir.LinkMain: ..\cc\testdata\tcc-0.9.26\tests\tests2\40_stdio.c:5:14: undefined fopen
# ccir.New
# [0]: *ir.FunctionDefinition {gopath\src\github.com\cznic\ccir\libc\builtin.h:38:15 __builtin_strlen func(*int8)uint64 ExternalLinkage } [__s]
0x00000 panic ; gopath\src\github.com\cznic\ccir\libc\builtin.h:38:15
# [1]: *ir.FunctionDefinition {gopath\src\github.com\cznic\ccir\libc\builtin.h:39:17 __builtin_bswap64 func(uint64)uint64 ExternalLinkage } [x]
0x00000 panic ; gopath\src\github.com\cznic\ccir\libc\builtin.h:39:17
What does output like that actually mean?
Seems like builtin.h comes into play now, but since stdio.h
for windows contains
those definitions I guess this is "one stage further" now?
EDIT: likely fopen should point to __builtin_fopen (which is in builtin.h)
Blind shot: https://github.com/cznic/virtual/commit/951399f7ea15f610de34277e3f938fd04d5aa676 Please try, thank you.
# ccir.New
# [0]: *ir.FunctionDefinition {gopath\src\github.com\cznic\ccir\libc\builtin.h:38:15 __builtin_strlen func(*int8)uint64 ExternalLinkage } [__s]
0x00000 panic ; gopath\src\github.com\cznic\ccir\libc\builtin.h:38:15
# [1]: *ir.FunctionDefinition {gopath\src\github.com\cznic\ccir\libc\builtin.h:39:17 __builtin_bswap64 func(uint64)uint64 ExternalLinkage } [x]
0x00000 panic ; gopath\src\github.com\cznic\ccir\libc\builtin.h:39:17
This lists/dumps the objects ir.LinkMain
was passed to aid in debugging linker failure.
@cznic It may've been blind but spot on :) Now I atleast know that for the future errors of this kind, I'll have to take a look at virtual.
EDIT: likely fopen should point to __builtin_fopen (which is in builtin.h)
That could be the proper solution. It depends on how GCC on Windows solves the 32/64 bit file sizes schizma of many libc functions. This solves it for Linux.
edit: fixed link
Now I atleast know that for the future errors of this kind, I'll have to take a look at virtual.
Yeah, you're now entering the real land-of-fun, aka the virtual
builtins B-)
FYI: Builtins are implemented as "abnormal" functions having a single panic
instruction. That's a pattern recognized in virtual.Load
and replaced by a call to the corresponding Go builtin. Like fopen64
you've just met.
GCC & TCC test suites now pass on windows. Now the real fun begins.
GCC & TCC test suites now pass on windows. Now the real fun begins.
Wonderful. Just fantastic!
Not sure if this is the right repository to place this issue, since it also affects
ccir
, but i feel it might belong a bit more here.Is a windows implementation planned?
I see two very different ways of implementing it:
Which of those (or maybe an other even better idea?) would you consider the favorable solution?
Other todos: