fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / solenv / gcc-wrappers / wrapper.cxx
blobe68603c14013fb7f51333661ce7acc9c0f222e6c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include "wrapper.hxx"
12 #define WIN32_LEAN_AND_MEAN
14 #include <windows.h>
16 #define BUFLEN 2048
18 string getexe(string exename, bool maybeempty) {
19 char* cmdbuf;
20 size_t cmdlen;
21 _dupenv_s(&cmdbuf,&cmdlen,exename.c_str());
22 if(!cmdbuf) {
23 if (maybeempty) {
24 return string();
26 cout << "Error " << exename << " not defined. Did you forget to source the environment?" << endl;
27 exit(1);
29 string command(cmdbuf);
30 free(cmdbuf);
31 return command;
34 void setupccenv() {
35 // Set-up library path
36 string libpath="LIB=";
37 char* libbuf;
38 size_t liblen;
39 _dupenv_s(&libbuf,&liblen,"ILIB");
40 libpath.append(libbuf);
41 free(libbuf);
42 if(_putenv(libpath.c_str())<0) {
43 cerr << "Error: could not export LIB" << endl;
44 exit(1);
47 // Set-up include path
48 string includepath="INCLUDE=.;";
49 char* incbuf;
50 size_t inclen;
51 _dupenv_s(&incbuf,&inclen,"SOLARINC");
52 string inctmp(incbuf);
53 free(incbuf);
55 // 3 = strlen(" -I")
56 for(size_t pos=0; pos != string::npos;) {
57 size_t endpos=inctmp.find(" -I",pos+3);
58 size_t len=endpos-pos-3;
59 if(endpos==string::npos)
60 includepath.append(inctmp,pos+3,endpos);
61 else if(len>0) {
62 includepath.append(inctmp,pos+3,len);
63 includepath.append(";");
65 pos=inctmp.find(" -I",pos+len);
67 if(_putenv(includepath.c_str())<0) {
68 cerr << "Error: could not export INCLUDE" << endl;
69 exit(1);
73 string processccargs(vector<string> rawargs) {
74 // suppress the msvc banner
75 string args=" -nologo";
76 // TODO: should these options be enabled globally?
77 args.append(" -EHsc");
78 const char *const pDebugRuntime(getenv("MSVC_USE_DEBUG_RUNTIME"));
79 if (pDebugRuntime && !strcmp(pDebugRuntime, "TRUE"))
80 args.append(" -MDd");
81 else
82 args.append(" -MD");
83 args.append(" -Gy");
84 args.append(" -Zc:wchar_t-");
85 args.append(" -Ob1 -Oxs -Oy-");
87 // apparently these must be at the end
88 // otherwise configure tests may fail
89 string linkargs(" -link");
91 for(vector<string>::iterator i = rawargs.begin(); i != rawargs.end(); ++i) {
92 args.append(" ");
93 if(*i == "-o") {
94 // TODO: handle more than just exe output
95 ++i;
96 size_t dot=(*i).find_last_of(".");
97 if(!(*i).compare(dot+1,3,"obj") || !(*i).compare(dot+1,1,"o"))
99 args.append("-Fo");
100 args.append(*i);
102 else if(!(*i).compare(dot+1,3,"exe"))
104 args.append("-Fe");
105 args.append(*i);
107 else if(!(*i).compare(dot+1,3,"dll"))
108 { // apparently cl.exe has no flag for dll?
109 linkargs.append(" -dll -out:");
110 linkargs.append(*i);
112 else
114 cerr << "unknown -o argument - please adapt gcc-wrapper for \""
115 << (*i) << "\"";
116 exit(1);
119 else if(*i == "-g") {
120 args.append("-Zi");
121 args.append(" -FS");
123 else if(!(*i).compare(0,2,"-D")) {
124 // need to re-escape strings for preprocessor
125 for(size_t pos=(*i).find("\"",0); pos!=string::npos; pos=(*i).find("\"",pos)) {
126 (*i).replace(pos,0,"\\");
127 pos+=2;
129 args.append(*i);
131 else if(!(*i).compare(0,2,"-L")) {
132 linkargs.append(" -LIBPATH:"+(*i).substr(2));
134 else if(!(*i).compare(0,2,"-l")) {
135 linkargs.append(" "+(*i).substr(2)+".lib");
137 else if(!(*i).compare(0,5,"-def:") || !(*i).compare(0,5,"/def:")) {
138 // why are we invoked with /def:? cl.exe should handle plain
139 // "foo.def" by itself
140 linkargs.append(" " + *i);
142 else if(!(*i).compare(0,12,"-fvisibility")) {
143 //TODO: drop other gcc-specific options
145 else if(!(*i).compare(0,4,"-Wl,")) {
146 //TODO: drop other gcc-specific options
148 else if(*i == "-Werror")
149 args.append("-WX");
150 else
151 args.append(*i);
153 args.append(linkargs);
154 return args;
157 int startprocess(string command, string args) {
158 STARTUPINFO si;
159 PROCESS_INFORMATION pi;
160 SECURITY_ATTRIBUTES sa;
162 HANDLE childout_read;
163 HANDLE childout_write;
165 memset(&sa,0,sizeof(sa));
166 memset(&si,0,sizeof(si));
167 memset(&pi,0,sizeof(pi));
169 sa.nLength=sizeof(sa);
170 sa.bInheritHandle=TRUE;
172 if(!CreatePipe(&childout_read,&childout_write,&sa,0)) {
173 cerr << "Error: could not create stdout pipe" << endl;
174 exit(1);
177 si.cb=sizeof(si);
178 si.dwFlags |= STARTF_USESTDHANDLES;
179 si.hStdOutput=childout_write;
180 si.hStdError=childout_write;
182 // support ccache
183 size_t pos=command.find("ccache ");
184 if(pos != string::npos) {
185 args.insert(0,"cl.exe");
186 command=command.substr(0,pos+strlen("ccache"))+".exe";
189 if (args[0] != ' ')
191 args.insert(0, " "); // lpCommandLine *must* start with space!
194 //cerr << "CMD= " << command << " " << args << endl;
196 // Commandline may be modified by CreateProcess
197 char* cmdline=_strdup(args.c_str());
199 if(!CreateProcess(command.c_str(), // Process Name
200 cmdline, // Command Line
201 NULL, // Process Handle not Inheritable
202 NULL, // Thread Handle not Inheritable
203 TRUE, // Handles are Inherited
204 0, // No creation flags
205 NULL, // Environment for process
206 NULL, // Use same starting directory
207 &si, // Startup Info
208 &pi) // Process Information
210 cerr << "Error: could not create process" << endl;
211 exit(1);
214 // if you don't close this the process will hang
215 CloseHandle(childout_write);
217 // Get Process output
218 char buffer[BUFLEN];
219 DWORD readlen, writelen, ret;
220 HANDLE stdout_handle=GetStdHandle(STD_OUTPUT_HANDLE);
221 while(true) {
222 int success=ReadFile(childout_read,buffer,BUFLEN,&readlen,NULL);
223 // check if the child process has exited
224 if(GetLastError()==ERROR_BROKEN_PIPE)
225 break;
226 if(!success) {
227 cerr << "Error: could not read from subprocess stdout" << endl;
228 exit(1);
230 if(readlen!=0) {
231 WriteFile(stdout_handle,buffer,readlen,&writelen,NULL);
234 WaitForSingleObject(pi.hProcess, INFINITE);
235 GetExitCodeProcess(pi.hProcess, &ret);
236 CloseHandle(pi.hThread);
237 CloseHandle(pi.hProcess);
238 return int(ret);
241 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */