Hello everyone, first time post here. I was wondering whether there is any interest in getting Nim to run under Cygwin? A lot of people use this environment and I know that I for one would appreciate something better than C.
There is a particular program (mintty, its terminal emulator) that I am considering doing some hacking on. Mintty is a little unusual in that it uses both Windows API calls and POSIX api calls (via Cygwin1.dll) extensively. Working on it (well, rewriting it in Nim!) therefore seems best done in the Cygwin environment. To that end I have spent some time trying to get Nim to work in Cygwin, with some success. I now have a sort-of working Nim compiler but I need some assistance.
I tried to do a bootstrapped install from source. Here is what happened:
$ cd ~
$ git clone git://github.com/Araq/Nim.git
$ cd Nim
$ git clone --depth 1 git://github.com/nim-lang/csources
$ cd csources
$ sh build.sh
Error: unknown operating system: cygwin_nt-6.3-wow
$ vim build.sh # set uos="linux" just before the case at line 51
$ sh build.sh
c_code/2_1/stdlib_memfiles.c, MAP_POPULATE is undefined (Linuxism, see http://linux.die.net/man/2/mmap)
$ vim build.sh
Add "-D MAP_POPULATE=0" to the end of COMP_FLAGS. This seems safe based on the usages of this symbol and what it means.
$ cd ..
$ bin/nim c koch # This succeeds.
$ ./koch boot -d:release --parallelBuild:1
compiler/nimcache/stdlib_memfiles.c:190:32: error: ‘MAP_POPULATE’ undeclared (first use in this function)
LOC59 = (NI32)(MAP_PRIVATE | MAP_POPULATE);
Couldn't see how to pass a symbol to GCC via koch, so...
$ vim ~/Nim/config/nim.cfg
Added line 148:
gcc.options.always %= " -D MAP_POPULATE=0"
$ ./koch boot -d:release --parallelBuild:1
Success! But get warning about unequal executables.
So there were two problems here. I "fixed" the unrecognized OS problem by just forcing Linux and seeing what happens :-) I think the problem with MAP_POPULATE is that this is a Linuxism, not necessarily supported on other unices. Based on the usage in the files that were reporting the error, and the semantics mentioned on the web page above, I think it is a read-ahead optimisation, so not having it does not change program behaviour.
At this point I have a working Nim compiler, I can compile "hello world" and even link to cygwin1.dll and call functions like getpid(), but there are some gotchas.
1. I cannot compile any nim code in a folder EXCEPT the folder (or subfolder) where the nim.exe was installed, i.e. ~/Nim/bin. It complains
"cannot create directory: /c/Users/Phil/foo/nimcache".
This is very odd, I thought it was related to permissions, but I have chmod ugo+rwx the directory and it still doesn't work.
2. I can't compile nimble. After cloning, I get:
nimcache/stdlib_asyncdispatch.c:26:23: fatal error: sys/epoll.h: No such file or directory
Which is unfortunately true, Cygwin does not have this. I think it is another Linuxism. Cygwin does have poll.h.
Comments Welcome
Would welcome advice on the best way to fix the above errors I encountered. In particular, I was wondering if forcing uos=linux caused the later problems with MAP_POPULATE and sys/epoll.h? Are there some Linuxisms in the standard library that need alternative implementations?
I am a C# programmer by trade so I don't really know much about unix systems programming, but I am willing to pitch in with testing and patches where I can.
Afraid I don't understand your instructions at all. I think I setup platform.nim correctly, and added a line to the top of installer.ini, but "koch csource" now fails with
Hint: modules [Processing]
Hint: nodejs [Processing]
Hint: operation successful (83374 lines compiled; 4.337 sec total; 179.183MB; Debug Build) [SuccessX]
nim compile -f --symbolfiles:off --compileonly --gen_mapping --cc:gcc --skipUserCfg --os:cygwin --cpu:i386 compiler/nim.nim
command line(1, 1) Error: unknown OS: 'cygwin'
Error: call to nim compiler failed
Error: execution of an external program failed
FAILURE
I note that Andreas recently added support for a new VxWorks platform himself....I think without much more detailed instructions this will have to remain in the "too hard" bucket for me.
$ cat stevensiewchanges.txt --- build.sh.steven.backup.20150515 2015-05-15 14:33:58.334121400 +1000 +++ build.sh 2015-05-15 14:34:35.685856200 +1000 @@ -28,7 +28,7 @@ CC="gcc" LINKER="gcc" -COMP_FLAGS="-w -O3 -fno-strict-aliasing$extraBuildArgs" +COMP_FLAGS="-w -O3 -fno-strict-aliasing$extraBuildArgs -D MAP_POPULATE=0" LINK_FLAGS="" # platform detection ucpu=`uname -m` @@ -49,6 +49,10 @@ uos=`echo $uos | tr "[:upper:]" "[:lower:]"` case $uos in + *cygwin* ) + myos="linux" + LINK_FLAGS="$LINK_FLAGS -ldl -lm" + ;; *linux* ) myos="linux" LINK_FLAGS="$LINK_FLAGS -ldl -lm" --- nim.cfg.steven.backup.20150515 2015-05-15 14:37:07.333019400 +1000 +++ nim.cfg 2015-05-15 11:31:58.591190500 +1000 @@ -108,7 +108,7 @@ gcc.options.always = "-w" gcc.cpp.options.always = "-w -fpermissive" @else: - gcc.options.always = "-w" + gcc.options.always = "-w -D MAP_POPULATE=0" gcc.cpp.options.always = "-w -fpermissive" @end
Araq: You can also just use Nim on Windows properly, the async stuff uses the Win API directly.
That won't help if you need to work within Cygwin, e.g. because you use libraries that depend on Cygwin's POSIX layer.