4469f31999-06-19Fredrik Hübinette (Hubbe) #!/usr/local/bin/pike // RNTCC, a front-end to MS VC++ with options similar to GCC // Written by Fredrik Hubinette. 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=0; // 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) {
94a4db2000-12-13Fredrik Hübinette (Hubbe) // werror("%O\n",argv);
7aeb532000-01-09Fredrik Hübinette (Hubbe)  string *ldopts=({"-INCREMENTAL:no"});
4469f31999-06-19Fredrik Hübinette (Hubbe)  string *cflags=({ "-Zm300", "-F8388608", "-Ge", "-D__WIN32__", "-D_WIN32", "-D__NT__",
11e4001999-07-15Fredrik Hübinette (Hubbe) // "-D__STDC__",
4469f31999-06-19Fredrik Hübinette (Hubbe)  "-nologo", }); string target="exe";
9ca9872000-12-19Fredrik Hübinette (Hubbe)  int debug,optimize,share,dynamic;
4469f31999-06-19Fredrik Hübinette (Hubbe)  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"}) }),
9ca9872000-12-19Fredrik Hübinette (Hubbe)  ({"dynamic",Getopt.HAS_ARG, ({"-r"}) }), ({"ignore",Getopt.HAS_ARG, ({"-R","-L"}) }),
4469f31999-06-19Fredrik Hübinette (Hubbe)  ({"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]) {
9ca9872000-12-19Fredrik Hübinette (Hubbe)  case "dynamic": dynamic++; ldopts+=({ "-DELAY:nobind", "-OPT:noref" // This might not be required }); break;
4469f31999-06-19Fredrik Hübinette (Hubbe)  case "verbose": verbose++;
0932de1999-08-06Fredrik Hübinette (Hubbe)  ldopts+=({"-VERBOSE:lib"});
4469f31999-06-19Fredrik Hübinette (Hubbe)  break; case "export": // fixme // ldopts+=({"export",option[1]+"_"}); break; case "share": // fixme
7aeb532000-01-09Fredrik Hübinette (Hubbe)  switch(option[1]) { case "hare":
6dc2772000-07-28Fredrik Hübinette (Hubbe)  case "hared":
7aeb532000-01-09Fredrik Hübinette (Hubbe)  share=1; target="dll"; break; case "tatic": /* Not yet implemented */ break; }
4469f31999-06-19Fredrik Hübinette (Hubbe)  break; case "oper_pre": cflags+=({ "-E" }); target="-"; break; case "oper_comp": target="obj"; cflags+=({ "-c" }); break; case "debug": cflags+=({ "-Z7", // "-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+=({"-Ob2gity","-GB"}); 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;
94a4db2000-12-13Fredrik Hübinette (Hubbe)  ldopts+=({tmp});
4469f31999-06-19Fredrik Hübinette (Hubbe)  break; } } // More options should be recognized, options which are not // recognized should generate warning/error messages. switch(option[1]) { case "all": cflags+=({"-W3"}); 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; } } // 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":
f9e4d81999-07-08Fredrik Hübinette (Hubbe)  if(!output) output=remove_ext(argv[1])+".o"; cflags+=({"-Fo"+fixpath(output)});
4469f31999-06-19Fredrik Hübinette (Hubbe)  wantfile=output; break; case "dll": if(output) cflags+=({"-Fe"+fixpath(output)}); else output=remove_ext(argv[1])+".dll";
6dc2772000-07-28Fredrik Hübinette (Hubbe)  cflags+=({"-MD" + (debug?"d":""), "-LD" + (debug?"d":"")});
4469f31999-06-19Fredrik Hübinette (Hubbe)  wantfile=output; break; case "-": } cflags+=({"-MT" + (debug?"d":"") }); if(output) rm(output); array(string) cmd=({"cl"})+cflags; switch(target) { case "exe": case "dll": if(debug) {
0932de1999-08-06Fredrik Hübinette (Hubbe)  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",
4469f31999-06-19Fredrik Hübinette (Hubbe) // "-PDB:NONE", "-DEBUGTYPE:BOTH", "-DEBUG",
0932de1999-08-06Fredrik Hübinette (Hubbe)  }) +ldopts;
4469f31999-06-19Fredrik Hübinette (Hubbe)  }
94a4db2000-12-13Fredrik Hübinette (Hubbe)  break; default: if(sizeof(ldopts)) cmd+=({"-link" }) +ldopts; break;
4469f31999-06-19Fredrik Hübinette (Hubbe)  }
0932de1999-08-06Fredrik Hübinette (Hubbe) 
4469f31999-06-19Fredrik Hübinette (Hubbe)  int ret; if(verbose && target!="-")
7f563a1999-11-24Fredrik Hübinette (Hubbe)  {
9ca9872000-12-19Fredrik Hübinette (Hubbe)  werror(" %s\n",cmd*" ");
4469f31999-06-19Fredrik Hübinette (Hubbe)  ret=do_cmd(cmd);
7f563a1999-11-24Fredrik Hübinette (Hubbe)  }else{ int first_line=1; // cl.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); }
4469f31999-06-19Fredrik Hübinette (Hubbe)  if(ret) { werror("CL returned error code %d.\n",ret); exit(ret); } if(wantfile) { if(!file_stat(wantfile)) {
7aeb532000-01-09Fredrik Hübinette (Hubbe)  werror("RNTCL: output file not generated (%s).\n",wantfile);
4469f31999-06-19Fredrik Hübinette (Hubbe)  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"
7eb6942000-11-30Fredrik Hübinette (Hubbe)  " argv[0]=getenv(\"NTDRIVE\")+fixpath(follow_symlinks(combine_path(getcwd(),argv[0]))+\".exe\");\n" " exit(silent_do_cmd(argv));\n"
4469f31999-06-19Fredrik Hübinette (Hubbe)  "}\n"); chmod(output,0755); } exit(ret); }