I work with Macintosh mini box, but I use Linux in the cloud. Therefore, I installed musl-cross gcc, and tested it with a small programa in C:
#include <stdio.h>
#include <stdlib.h>
int fib(int i) {
if (i<2) return i+1;
if (i<3) return fib(i-1)+fib(i-2);
return fib(i-3) + fib(i-2) + fib(i-2);
}
int main(int argc,char* argv[]){
int n=atoi(argv[1]);
printf("fib(%d)= %d\n", n, fib(n));
return 0;}
I compiled the above program thus:
/usr/local/Cellar/musl-cross/0.9.8/bin/x86_64-linux-musl-gcc -O2 -static cfib.c -o cfib.x
I moved it to the cloud:
› scp -P2222 cfib.x [email protected]:~/
I tested it in the cloud machine, and everything worked as expected:
[email protected] [~]# ./cfib.x 5
fib(5)= 13
Then I tried the cross compilation with Bigloo Scheme, Haskell and Rust without any problem at all. However, it did not work on Nim. Let us replace the Fibonacci application with a hello program:
import os, strutils
if paramCount() < 2:
echo "Usage: ", paramStr(0), " <votre nom>"
else: echo "Hello, ", paramStr(1)
I tried to compile the above program in different ways. I defined nim.cfg, using the following link as a model:
https://github.com/mratsim/Arraymancer/blob/master/nim.cfg
Here is my nim.cfg:
cincludes:"/usr/local/Cellar/musl-cross/0.9.8/libexec/x86_64-linux-musl/include"
amd64.linux.gcc.path:"/usr/local/Cellar/musl-cross/0.9.8/bin"
amd64.linux.gcc.exe:"/usr/local/Cellar/musl-cross/0.9.8/bin/x86_64-linux-musl-gcc"
#amd64.linux.gcc.linkerexe:"/usr/local/Cellar/musl-cross/0.9.8/bin/x86_64-linux-musl-gcc"
amd64.linux.gcc.options.always:"-static"
amd64.linux.gcc.linkerexe:"/usr/local/Cellar/musl-cross/0.9.8/libexec/x86_64-linux-musl/lib"
The static libraries are in the x86_64-linux-mus/lib directory. However, I tried both with the commented line and with the uncommented line for the linker. Besides this, here is my build.nims script:
#!/usr/bin/env -S nim --hints:off
mode = ScriptMode.Silent
if paramCount() > 1 and fileExists(paramStr(3) & ".nim"):
let
app = paramStr(3)
src = app & ".nim"
exe = "nim" & app & ".x "
c = "nim c --hints:off --os:linux --cpu:amd64 --nimcache:xx -d:release -o:"
cc= "--cc:gcc --passC:\"-static\" --passL:\"-static\" --app:staticlib "
exec c & exe & " "& cc & " " & src
echo c & exe & " "& cc & " " & src
else: echo "Usage: ./build.nims <app without extension>"
As you know, Skinner wrote a random algorithm based on the weather to feed his doves. After some time receiving meals an random intervals, the doves created a crazy ritual to receive food. Skinner concluded that they had invented a religion. I acted like Skinner's doves, which means that I tried everything. For instance, I compiled with --passC, without --passC, with --passL, without --passL, with --app, without --app, etc. When I send the program to the cloud, I get the following error message:
[email protected] [~]# ./nimhello.x edu
./nimhello.x: line 1: syntax error near unexpected token `newline'
./nimhello.x: line 1: `!<arch>'
As you know, Skinner invented a random algorithm based on the weather to feed his doves.
syntax error near unexpected token newline
I do know really nothing, but from that message my guess would be that the server tries to execute your uploaded file as a shell script. But I guess it should be executed as a binary. May it be necessary to mark it as executable, maybe setting an executable bit on that file or to copy it to a special folder for binaries?
Also note that google will point you to
https://gist.github.com/deef0000dragon1/2336e2404c468c3c59f1ef670745a920
Hi, Stefan.
Thank you for providing me the links, which indeed solved the problem. Below, I will describe the solution, in case someone else comes across the same problem.
1 -- I wanted to compile dynamic Internet pages running on a Linux server. My machine is a Macintosh mini box. I used homebrew to install the x86_64-linux-musl-gcc
2 -- Here is my nim.cfg:
amd64.linux.gcc.path:"/usr/local/Cellar/musl-cross/0.9.8/bin"
amd64.linux.gcc.exe:"x86_64-linux-musl-gcc"
amd64.linux.gcc.linkerexe:"x86_64-linux-musl-gcc"
3 -- Here is the build.nims that I use to compile the Internet page:
#!/usr/bin/env -S nim --hints:off
mode = ScriptMode.Silent
if paramCount() > 1 and fileExists(paramStr(3) & ".nim"):
let
app = paramStr(3)
src = app & ".nim"
exe = "nim" & app & ".x "
c = "nim c --nimcache:xx --os:linux --cpu:amd64 -d:danger -o:"
cc= " --passL:\"-static\""
exec c & exe & " " & cc & " " & src
echo c & exe & " " & cc & " " & src
else: echo "Usage: ./build.nims <app without extension>"
4 -- Here is the program I want to compile:
# File: recfib.nim
import os, strutils
proc fib(n: int): int =
if n<2: result= n+1
elif n<3: result= fib(n-1)+fib(n-2)
else: result= fib(n-3)+fib(n-2)+fib(n-2)
echo fib(paramStr(1).parseInt)
5 -- Here is the compilation:
~/nim/os› ./build.nims recfib
6 -- I send the code to my son's Internet server:
~/nim/os› scp -P2222 nimrecfib.x [email protected]:~/
7 -- I enter the server in the cloud and test the program:
~/nim/os› ssh -p2222 [email protected]
[email protected] [~]# time ./nimrecfib.x 40
267914296
real 0m0.011s
user 0m0.000s
sys 0m0.010s