static TString EmitExports(const std::vector<TString> &escaped_args) { auto uuid_lib_file = TempFile::Create(TEXT(".lib"), true); auto uuid_exp_file = uuid_lib_file; uuid_exp_file.replace(uuid_exp_file.length() - 4, 4, TEXT(".exp")); TempFile::AutoDeleteFile(uuid_exp_file); // Call link.exe -lib -def <rest of linker arguments> -out:<uuid_lib_file> auto linker_exe = LocateMSVCLinker(); auto linker_exe_esc = QuoteSpaces(linker_exe.data()); std::vector<const _TCHAR*> export_args; export_args.push_back(linker_exe_esc.data()); export_args.push_back(TEXT("-lib")); export_args.push_back(TEXT("-def")); // If the original includes "/DEF" or "-DEF", it should override this one // FIXME: this passes many link.exe args to lib.exe which generates warnings for (auto &escaped_arg : escaped_args) export_args.push_back(escaped_arg.data()); TString out_arg(TEXT("-out:")); out_arg += uuid_lib_file; export_args.push_back(out_arg.data()); export_args.push_back(NULL); //PrintArgs(export_args); auto errnum = _tspawnvp(_P_WAIT, linker_exe.data(), export_args.data()); if (errnum) { perror("LinkWrapper:EmitExports"); exit(errnum); } // Convert the exports file to the trampoline object file auto exports_obj_file = TempFile::Create(TEXT(".obj"), true); bool converted = ConvertExports(uuid_exp_file.data(), exports_obj_file.data()); return converted ? exports_obj_file : TString(); }
int main(int argc, char* argv[]) { try { TCLAP::CmdLine cmd("Command description message", ' ', "0.2"); TCLAP::SwitchArg lex_switch("l", "lex", "Process up to the Lexer phase"); TCLAP::SwitchArg parse_switch("p", "parse", "Process up to the Parser phase"); TCLAP::SwitchArg sem_switch("s", "sem", "Process up to the Semantic Analyser phase"); TCLAP::SwitchArg tup_switch("t", "tup", "Process up to the Tuple phase"); TCLAP::SwitchArg compile_switch("c", "compile", "Process all phases and compile (default)", true); TCLAP::SwitchArg quiet_switch("q", "quiet", "Only display error messages (default)", true); TCLAP::SwitchArg verbose_switch("v", "verbose", "Display all Trace messages"); TCLAP::ValueArg< std::string > out_arg("o", "out", "Output file (default -out=STDOUT)", false, "out", "string"); TCLAP::ValueArg< std::string > err_arg("e", "err", "Error file (default -err=STDOUT)", false, "err", "string"); TCLAP::UnlabeledMultiArg<std::string> input_args("input", "Input files", true, "string"); std::vector<TCLAP::Arg*> args; args.push_back(&lex_switch); args.push_back(&parse_switch); args.push_back(&sem_switch); args.push_back(&tup_switch); args.push_back(&compile_switch); cmd.xorAdd(args); cmd.add(quiet_switch); cmd.add(verbose_switch); cmd.add(out_arg); cmd.add(err_arg); cmd.add(input_args); cmd.parse(argc, argv); std::vector< std::string > inputFiles = input_args.getValue(); if (inputFiles.size() == 0) { fprintf(stderr, "No input files. Please specify 1 or more .cs13 files using -I <file>\n"); return -1; } Administrator *admin; std::string err = err_arg.getValue(); if (err.compare("err") != 0) { // Have to create the error file to be able to write to it std::ofstream filestream(err_arg.getValue()); if (!filestream) { fprintf(stderr, "Error creating %s\n", err_arg.getValue().c_str()); return -1; } filestream.clear(); filestream.close(); admin = new Administrator(inputFiles, err_arg.getValue()); } else { admin = new Administrator(inputFiles); } std::string out = out_arg.getValue(); if (out.compare("out") != 0) { admin->set_output_file(out_arg.getValue()); } if (verbose_switch.isSet()) { admin->ShowTrace(true); } if (lex_switch.isSet()) { admin->LexerPhase(); } else if (parse_switch.isSet()) { admin->ParserPhase(); } else if (sem_switch.getValue()) { admin->SemanticAnalysisPhase(); } else if (tup_switch.isSet()) { admin->TupleGenerationPhase(); } else { admin->Compile(); } } catch(TCLAP::ArgException &e) { fprintf(stderr, "error: %s for arg %s\n", e.error().c_str(), e.argId().c_str()); } return 0; }