#!/usr/local/bin/pike |
|
|
|
|
|
|
|
inherit "lib.pike"; |
|
|
|
|
|
int verbose=1; |
|
|
int linking_failed; |
|
|
string *tmpfiles=({}); |
|
void exit(int code) |
{ |
if(getenv("CLEANUP")!="no") |
Array.map(tmpfiles,rm); |
|
predef::exit(code); |
} |
|
string get_ext(string file) |
{ |
sscanf(file=lower_case(reverse(file)),"%s.",file); |
return reverse(file); |
} |
|
string remove_ext(string file) |
{ |
sscanf(file=reverse(file),"%*s.%s",file,file); |
return reverse(file); |
} |
|
string o_to_obj(string fname) |
{ |
if (fname[sizeof(fname)-3..] == ".o") { |
return fname + "bj"; |
} |
return fname; |
} |
|
int main(int argc, string *argv) |
{ |
string *ldopts=({"-INCREMENTAL:no"}); |
string *cflags=({ |
"-Wp64", |
|
"-W3", |
"-D__WIN32__", |
"-D_WIN32", |
"-D__NT__", |
|
"-nologo", |
}); |
|
string target="exe"; |
int debug,optimize,share; |
string output, wantfile; |
|
mixed *opts=Getopt.find_all_options(argv, aggregate( |
({"oper_pre",Getopt.NO_ARG, ({"-E"}) }), |
({"oper_asm",Getopt.NO_ARG, ({"-S"}) }), |
({"oper_comp",Getopt.NO_ARG, ({"-c"}) }), |
({"verbose",Getopt.NO_ARG, ({"-v"}) }), |
({"debug",Getopt.MAY_HAVE_ARG, ({"-g"}) }), |
({"optimize",Getopt.MAY_HAVE_ARG, ({"-O"}) }), |
({"include",Getopt.HAS_ARG, ({"-I"}) }), |
({"link",Getopt.HAS_ARG, ({"-l"}) }), |
({"share",Getopt.MAY_HAVE_ARG, ({"-s"}) }), |
({"ignore",Getopt.MAY_HAVE_ARG, ({"-t"}) }), |
({"ignore",Getopt.HAS_ARG, ({"-R","-L","-r"}) }), |
({"warn",Getopt.MAY_HAVE_ARG, ({"-W"}) }), |
({"define",Getopt.HAS_ARG, ({"-D"}) }), |
({"undefine",Getopt.HAS_ARG, ({"-U"})}), |
({"output",Getopt.HAS_ARG, ({"-o"}) }), |
({"export",Getopt.HAS_ARG, ({"--export"}) }) |
)); |
foreach(opts, mixed *option) |
{ |
switch(option[0]) |
{ |
case "verbose": |
verbose++; |
ldopts+=({"-VERBOSE:lib"}); |
break; |
|
case "export": |
|
break; |
|
case "share": |
switch(option[1]) |
{ |
case "hare": |
share=1; |
target="dll"; |
break; |
|
case "tatic": |
|
break; |
} |
break; |
|
case "oper_pre": |
cflags+=({ "-E" }); |
target="-"; |
break; |
|
case "oper_asm": |
cflags+=({ "-S" }); |
target="asm"; |
break; |
|
case "oper_comp": |
target="obj"; |
cflags+=({ "-c" }); |
break; |
|
case "debug": |
cflags+=({ |
"-Z7", |
"-FR", |
|
}); |
debug=1; |
break; |
|
case "optimize": |
if(!option[1]) option[1]=1; |
switch(optimize=(int)option[1]) |
{ |
case 0: optimize=0; break; |
case 1: cflags+=({"-O1"}); break; |
case 2: cflags+=({"-O2"}); break; |
case 3..: |
break; |
} |
break; |
|
case "include": |
|
|
if(sscanf(option[1],"/usr/include/%*s") || |
sscanf(option[1],"/usr/local/%*s")) |
break; |
|
cflags+=({"-I"+fixpath(option[1])}); |
break; |
|
case "link": |
|
if(option[1]=="m" || option[1]=="c") break; |
|
|
|
|
|
cflags-=({option[1]+".lib"}); |
cflags+=({option[1]+".lib"}); |
break; |
|
case "warn": |
if(option[1]) |
{ |
|
if(sscanf(option[1],"l,%s",string tmp)) |
{ |
|
|
|
if(sscanf(tmp,"-rpath%*s")) break; |
|
cflags+=({tmp}); |
break; |
} |
} |
|
|
|
switch(option[1]) |
{ |
case "all": cflags+=({"-W4"}); break; |
default: cflags+=({"-W3"}); break; |
} |
break; |
|
case "define": cflags+=({"-D"+option[1]}); break; |
case "undefine": cflags+=({"-U"+option[1]}); break; |
case "output": |
output=option[1]; |
break; |
} |
} |
|
|
argv=Getopt.get_args(argv); |
cflags+=Array.map(Array.map(argv[1..],fixpath), o_to_obj); |
|
foreach(argv[1..], string tmp) |
{ |
if(tmp[0]=='-') |
{ |
werror("Unrecognized option "+tmp+".\n"); |
exit(1); |
} |
} |
|
switch(target) |
{ |
case "exe": |
if(!output) output="a.out"; |
cflags+=({"-Fe"+fixpath(output)+".exe"}); |
|
wantfile=output+".exe"; |
break; |
|
case "obj": |
if(!output) |
output=remove_ext(argv[1])+".o"; |
cflags+=({"-Fo"+fixpath(output+"bj")}); |
wantfile=output; |
break; |
|
case "asm": |
if(!output) |
output=remove_ext(argv[1])+".s"; |
cflags+=({"-Fa"+fixpath(output)}); |
wantfile=output; |
break; |
|
case "dll": |
if(output) |
cflags+=({"-Fe"+fixpath(output)}); |
else |
output=remove_ext(argv[1])+".dll"; |
|
|
wantfile=output; |
break; |
|
case "-": |
} |
|
|
cflags+=({"-MT" + (debug?"d":"") }); |
|
if(output) rm(output); |
|
array(string) cmd=({"ecl"})+cflags; |
|
switch(target) |
{ |
case "exe": |
case "dll": |
if(debug) |
{ |
array libs=({"libc.lib","libcd.lib", |
"libcmt.lib","libcmtd.lib", |
"msvcrt.lib","msvcrtd.lib"}); |
|
string lib=(debug?"libcmtd.lib":"libcmt.lib"); |
libs-=({ lib }); |
for(int e=0;e<sizeof(libs);e++) |
ldopts+=({"-nodefaultlib:"+libs[e]}); |
|
|
cmd+=({"-link", |
|
"-DEBUGTYPE:BOTH", |
"-DEBUG", |
}) |
+ldopts; |
} |
} |
|
|
int ret; |
if(verbose && target!="-") |
{ |
ret=do_cmd(cmd); |
}else{ |
int first_line=1; |
|
|
ret=silent_do_cmd(cmd, lambda(string line) |
{ |
if(first_line) |
{ |
array x=line/"\n"; |
if(sizeof(x)>1) |
{ |
line=x[1..]*"\n"; |
first_line=0; |
}else{ |
return; |
} |
} |
write(line); |
},1); |
} |
|
if(ret) |
{ |
werror("ECL returned error code %d.\n",ret); |
exit(ret); |
} |
|
if(wantfile) |
{ |
if (target == "obj") { |
if(!file_stat(wantfile+"bj")) |
{ |
werror("RNTECL: output file not generated (%s).\n", |
wantfile+"bj"); |
exit(1); |
} |
rm(wantfile); |
hardlink(wantfile+"bj", wantfile); |
} |
if(!file_stat(wantfile)) |
{ |
werror("RNTECL: output file not generated (%s).\n",wantfile); |
exit(1); |
} |
} |
|
if(target=="exe" && !share) |
{ |
rm(output); |
Stdio.write_file(output, |
"#!/usr/local/bin/pike\n" |
"inherit \""+find_lib_location()+"\";\n" |
"int main(int argc, string *argv) {\n" |
" if (lower_case(getenv(\"CROSSCOMPILING\")||\"no\") != \"no\")\n" |
" exit(1);\n" |
" argv[0]+=\".exe\";\n" |
" argv[0]=getenv(\"NTDRIVE\")+fixpath(combine_path(getcwd(),argv[0]));\n" |
" int ret=silent_do_cmd(argv);\n" |
" exit(ret);\n" |
"}\n"); |
chmod(output,0755); |
} |
|
exit(ret); |
} |
|
|