diff --git a/NT/tools/rntecl b/NT/tools/rntecl new file mode 100755 index 0000000000000000000000000000000000000000..a06562ac4eb4366830c3da135192725d8b74954a --- /dev/null +++ b/NT/tools/rntecl @@ -0,0 +1,319 @@ +#!/usr/local/bin/pike +// -*- Pike -*- + +// RNTECL, a front-end to Intel ECL with options similar to GCC +// Written by Fredrik Hubinette & Henrik Grubbstr�m. + +inherit "lib.pike"; + +// Verbose is default for now, this can be turned off one this +// frontend has been refined to where it does not require more +// debugging. + +int verbose=1; + +// Temporary variable +int linking_failed; + +// Files to remove upon exit +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); +} + + +int main(int argc, string *argv) +{ + string *ldopts=({"-INCREMENTAL:no"}); + string *cflags=({ + "-Wp64", + "-D__WIN32__", + "-D_WIN32", + "-D__NT__", +// "-D__STDC__", + "-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_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": // fixme +// ldopts+=({"export",option[1]+"_"}); + break; + + case "share": // fixme + switch(option[1]) + { + case "hare": + share=1; + target="dll"; + break; + + case "tatic": + /* Not yet implemented */ + break; + } + break; + + case "oper_pre": + cflags+=({ "-E" }); + target="-"; + break; + + case "oper_comp": + target="obj"; + cflags+=({ "-c" }); + break; + + case "debug": + cflags+=({ + "-Z7", + "-FR", +// "-Yd", + }); + 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": + // Avoid searching 'local' include dirs. + // This is not a very pretty solution. + if(sscanf(option[1],"/usr/include/%*s") || + sscanf(option[1],"/usr/local/%*s")) + break; + + cflags+=({"-I"+fixpath(option[1])}); + break; + + case "link": + // -lm and -lc are automatically handled ? + if(option[1]=="m" || option[1]=="c") break; + + // We optimiza a little, no need to bring in the same + // library many times in a row. +// if(cflags[-1]!=option[1]+".lib") +// if(search(cflags,option[1]+".lib")!=-1) + cflags-=({option[1]+".lib"}); + cflags+=({option[1]+".lib"}); + break; + + case "warn": + if(option[1]) + { + // This allows us to pass options to the linker + if(sscanf(option[1],"l,%s",string tmp)) + { + // This was done for my convenience, it can be taken + // out once smartlink has been fixed to not use absoute + // paths for the 'uname' binary. + if(sscanf(tmp,"-rpath%*s")) break; + + cflags+=({tmp}); + break; + } + } + + // More options should be recognized, options which are not + // recognized should generate warning/error messages. + 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; + } + } + + // Scan through the remaining arguments + argv=Getopt.get_args(argv); + cflags+=Array.map(argv[1..],fixpath); + + 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"}); +// cflags+=({"-MT" + (debug?"d":"") }); + wantfile=output+".exe"; + break; + + case "obj": + if(!output) + output=remove_ext(argv[1])+".o"; + cflags+=({"-Fo"+fixpath(output)}); + wantfile=output; + break; + + case "dll": + if(output) + cflags+=({"-Fe"+fixpath(output)}); + else + output=remove_ext(argv[1])+".dll"; + +// cflags+=({"-MD" + (debug?"d":"") }); + 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", +// "-PDB:NONE", + "-DEBUGTYPE:BOTH", + "-DEBUG", + }) + +ldopts; + } + } + + + int ret; + if(verbose && target!="-") + { + ret=do_cmd(cmd); + }else{ + int first_line=1; + // ecl.exe echoes the file name of the file we are compiling + // first, we need to get rid of that to make configure behave + 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(!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" + "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); +}