/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include"wrapper.hxx"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define BUFLEN 2048
std::string getexe(std::string exename, bool maybeempty) { char* cmdbuf;
size_t cmdlen;
_dupenv_s(&cmdbuf,&cmdlen,exename.c_str()); if(!cmdbuf) { if (maybeempty) { return std::string();
}
std::cout << "Error " << exename << " not defined. Did you forget to source the environment?" << std::endl; exit(1);
}
std::string command(cmdbuf);
free(cmdbuf); return command;
}
// Instead of using synced PDB access (-FS), use individual PDB files based on output. // In fact, simply use -Z7, which doesn't use PDB files at all and writes all debug into the .obj file. constchar *const pEnvIndividualPDBs(getenv("MSVC_USE_INDIVIDUAL_PDBS")); constbool bIndividualPDBs = (pEnvIndividualPDBs && !strcmp(pEnvIndividualPDBs, "TRUE")); constchar *const pEnvEnableZ7Debug(getenv("ENABLE_Z7_DEBUG")); constbool bEnableZ7Debug = (pEnvEnableZ7Debug && !strcmp(pEnvEnableZ7Debug, "TRUE")) || bIndividualPDBs;
for(std::vector<std::string>::const_iterator i = rawargs.begin(); i != rawargs.end(); ++i) { if (env_prefix_next_arg)
{
env_prefix = *i;
env_prefix_next_arg = false; continue;
}
args.append(" "); if(*i == "-o") { // TODO: handle more than just exe output
++i;
size_t dot=(*i).find_last_of("."); if(!(*i).compare(dot+1,3,"obj") || !(*i).compare(dot+1,1,"o"))
{
args.append("-Fo");
args.append(*i);
} elseif(!(*i).compare(dot+1,3,"exe"))
{
args.append("-Fe");
args.append(*i);
} elseif(!(*i).compare(dot+1,3,"dll"))
{ // apparently cl.exe has no flag for dll?
linkargs.append(" -dll -out:");
linkargs.append(*i);
} elseif (dot == std::string::npos)
{
args.append("-Fe");
args.append(*i + ".exe");
} else
{
std::cerr << "unknown -o argument - please adapt gcc-wrapper for \""
<< (*i) << "\"" << std::endl; exit(1);
}
} elseif(*i == "-g" || !(*i).compare(0,5,"-ggdb")) { if(!bEnableZ7Debug)
{
args.append("-Zi");
args.append(" -FS");
} else
{ // ccache doesn't work with -Zi, the -link -debug for linking will create a final PDB
args.append("-Z7");
}
} elseif(!(*i).compare(0,2,"-D")) { // need to re-escape strings for preprocessor
std::string str = *i; for(size_t pos=str.find("\""); pos!=std::string::npos; pos=str.find("\"",pos)) {
str.replace(pos,0,"\\");
pos+=2;
}
args.append(str);
} elseif(!(*i).compare(0,2,"-L")) {
linkargs.append(" -LIBPATH:"+(*i).substr(2));
} elseif(!(*i).compare(0,2,"-l") && (*i).compare(0,5,"-link")) {
linkargs.append(" "+(*i).substr(2)+".lib");
} elseif(!(*i).compare(0,5,"-def:") || !(*i).compare(0,5,"/def:")) { // why are we invoked with /def:? cl.exe should handle plain // "foo.def" by itself
linkargs.append(" " + *i);
} elseif(!(*i).compare(0,12,"-fvisibility") || *i == "-fPIC") { //TODO: drop other gcc-specific options
} elseif(!(*i).compare(0,4,"-Wl,")) { //TODO: drop other gcc-specific options
} elseif(*i == "-c") {
args.append("-c"); // If -c is specified, there will be no linking anyway, // and passing -link with -c stops ccache from caching.
block_linkargs = true;
} elseif(*i == "-Werror")
args.append("-WX"); elseif (*i == "--wrapper-print-cmdline")
verbose = true; else
{
size_t pos = i->find("="); if (0 == i->compare(0, pos, "--wrapper-env-prefix"))
{ if (pos == std::string::npos)
env_prefix_next_arg = true; elseif (pos + 1 == i->length())
{ // bailout - missing arg
env_prefix_next_arg = true; break;
} else
env_prefix = i->substr(pos + 1);
} else
args.append(*i);
}
}
if (env_prefix_next_arg)
{
std::cerr << "wrapper-env-prefix needs an argument!" << std::endl; exit(1);
}
if(!block_linkargs) { // apparently these must be at the end // otherwise configure tests may fail // note: always use -debug so a PDB file is created
args.append(" -link -debug ");
args.append(linkargs);
}
// Commandline may be modified by CreateProcess char* cmdlineBuf=_strdup(cmdline.c_str());
if(!CreateProcess(nullptr, // Process Name
cmdlineBuf, // Command Line
nullptr, // Process Handle not Inheritable
nullptr, // Thread Handle not Inheritable TRUE, // Handles are Inherited
0, // No creation flags
nullptr, // Environment for process
nullptr, // Use same starting directory
&si, // Startup Info
&pi) // Process Information
) { autoconst e = GetLastError();
std::cerr << "Error: could not create process \"" << cmdlineBuf << "\": " << e << std::endl; exit(1);
}
// if you don't close this the process will hang
CloseHandle(childout_write);
// Get Process output char buffer[BUFLEN];
DWORD readlen, writelen, ret;
HANDLE stdout_handle=GetStdHandle(STD_OUTPUT_HANDLE); while(true) { int success=ReadFile(childout_read,buffer,BUFLEN,&readlen,nullptr); // check if the child process has exited if(GetLastError()==ERROR_BROKEN_PIPE) break; if(!success) {
std::cerr << "Error: could not read from subprocess stdout" << std::endl; exit(1);
} if(readlen!=0) {
WriteFile(stdout_handle,buffer,readlen,&writelen,nullptr);
}
}
WaitForSingleObject(pi.hProcess, INFINITE);
GetExitCodeProcess(pi.hProcess, &ret);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess); returnint(ret);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.