#!/usr/local/bin/pike |
|
inherit "lib.pike"; |
|
int compile(string *sources, |
string dest, |
string errorfile, |
string *cflags) |
{ |
int ret; |
if(!dest) |
{ |
string tmp=reverse(sources[0]); |
sscanf(tmp,"%*s.%s",tmp); |
dest=reverse(tmp)+".o"; |
} |
|
sources=Array.map(sources,fixpath); |
if(lower_case(sources[0][strlen(sources[0])-3..])==".s") |
{ |
ret=do_cmd(({ "wasm", "-fe"+errorfile, "-fo"+dest,})+ sources ); |
}else{ |
ret=do_cmd(({ "wcc386" }) + cflags + ({"-fr"+errorfile, "-fo"+dest}) + sources ); |
} |
return ret; |
} |
|
string check_errorfile(string errorfile) |
{ |
object f=Stdio.File(); |
if(f->open(errorfile,"r")) |
{ |
string data; |
write(data=f->read()); |
f->close(); |
data=replace(data,"\r",""); |
rm(errorfile); |
foreach(data/"\n", string line) |
{ |
if(!strlen(line)) continue; |
if(search(line,"Warning")!=-1) continue; |
werror("Error in compilation detected. "+line+"\n"); |
exit(1); |
} |
} |
} |
|
int main(int argc, string *argv) |
{ |
string target; |
string operation="link"; |
string *cflags=({}); |
string *ldopts=({"OPTION","STACK=8m"}); |
string *libraries=({}); |
string *objects=({}); |
string *sources=({}); |
int debug,optimize; |
string output; |
int share=0; |
|
mixed *opts=Getopt.find_all_options(argv, ({ |
({"oper_pre",Getopt.NO_ARG, ({"-E"}) }), |
({"oper_comp",Getopt.NO_ARG, ({"-c"}) }), |
({"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"}) }), |
({"warn",Getopt.MAY_HAVE_ARG, ({"-W"}) }), |
({"define",Getopt.HAS_ARG, ({"-D"}) }), |
({"undefine",Getopt.HAS_ARG, ({"-U"})}), |
({"output",Getopt.HAS_ARG, ({"-o"}) }) |
})); |
foreach(opts, mixed *option) |
{ |
switch(option[0]) |
{ |
case "share": |
share=1; |
ldopts+=({"SYS","nt_dll"}); |
cflags+=({"-bd"}); |
break; |
|
case "oper_pre": operation="preprocess"; break; |
case "oper_comp": operation="compile"; break; |
case "debug": |
cflags+=({"-d2"}); |
ldopts+=({"DEBUG","WATCOM","ALL"}); |
debug=1; |
break; |
|
case "optimize": |
if(!option[1]) option[1]=1; |
switch(optimize=(int)option[1]) |
{ |
case 0: optimize=0; break; |
case 1: cflags+=({"-ox"}); break; |
case 2..: cflags+=({"-otexan"}); 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; |
|
libraries+=({"LIBRARY",option[1]}); |
break; |
|
case "warn": |
if(option[1] && sscanf(option[1],"l,%*s")) break; |
switch(option[1]) |
{ |
case "all": cflags+=({"-wx"}); break; |
default: cflags+=({"-w2"}); 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); |
foreach(argv[1..], string tmp) |
{ |
string ext; |
if(tmp[0]=='-') |
{ |
werror("Unrecognized option "+tmp+".\n"); |
exit(1); |
} |
sscanf(reverse(tmp),"%s.",ext); |
switch(ext) |
{ |
case "o": |
case "a": |
objects+=({tmp}); |
break; |
|
default: |
sources+=({tmp}); |
} |
} |
|
if(output) rm(output); |
|
string errorfile="TMP"+getpid()+".err"; |
rm(errorfile); |
|
cflags+=({"-bm","-zq","-hw","-sg"}); |
|
switch(operation) |
{ |
default: |
werror("Unknown operation "+operation+".\n"); |
exit(1); |
|
case "compile": |
compile(sources,output,errorfile,cflags); |
break; |
|
case "preprocess": |
{ |
int ret=silent_do_cmd( ({"wcc386","-p","-fr"+errorfile}) + cflags + Array.map(sources, fixpath)); |
break; |
} |
|
case "link": |
foreach(sources, string source) |
{ |
string obj=reverse(source); |
sscanf(obj,"%*s.%s",obj); |
obj=reverse(obj)+".obj"; |
|
compile( ({source}), obj, errorfile, cflags); |
objects+=({obj}); |
check_errorfile(errorfile); |
} |
|
string ldfile="TMP"+getpid()+".lk"; |
if(!output) output="a.out"; |
rm(ldfile); |
|
target=output; |
if(!share) target+=".exe"; |
|
Stdio.write_file(ldfile, |
"NAME "+target+" " +ldopts*" "+" "+ |
"FIL "+Array.map(objects,fixpath)*","+" "+ |
libraries*" "+" "); |
|
do_cmd( ({"wlink","@"+ldfile }), lambda(string data) |
{ |
if(search(data," W1008:")!=-1) |
exit(1); |
}); |
|
if(getenv("CLEANUP")!="no") |
rm(ldfile); |
} |
|
check_errorfile(errorfile); |
|
if(target) |
{ |
if(!file_stat(target)) |
{ |
werror("RNTCC: output file not generated.\n"); |
exit(1); |
} |
} |
|
if(operation == "link" && !share) |
{ |
rm(output); |
Stdio.write_file(output, |
"#!/usr/local/bin/pike\n" |
"inherit \""+find_lib_location()+"\";\n" |
"int main(int argc, string *argv) {\n" |
"argv[0]+=\".exe\";\n" |
"argv[0]=getenv(\"NTDRIVE\")+fixpath(combine_path(getcwd(),argv[0]));\n" |
" exit(silent_do_cmd(argv));\n" |
"}\n"); |
chmod(output,0755); |
} |
exit(0); |
} |
|