1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
10 #include "wrapper.hxx"
12 #define WIN32_LEAN_AND_MEAN
18 string
getexe(string exename
, bool maybeempty
) {
21 _dupenv_s(&cmdbuf
,&cmdlen
,exename
.c_str());
26 cout
<< "Error " << exename
<< " not defined. Did you forget to source the environment?" << endl
;
29 string
command(cmdbuf
);
35 // Set-up library path
36 string libpath
="LIB=";
39 _dupenv_s(&libbuf
,&liblen
,"ILIB");
40 libpath
.append(libbuf
);
42 if(_putenv(libpath
.c_str())<0) {
43 cerr
<< "Error: could not export LIB" << endl
;
47 // Set-up include path
48 string includepath
="INCLUDE=.;";
51 _dupenv_s(&incbuf
,&inclen
,"SOLARINC");
52 string
inctmp(incbuf
);
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
);
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
;
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"))
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
) {
94 // TODO: handle more than just exe output
96 size_t dot
=(*i
).find_last_of(".");
97 if(!(*i
).compare(dot
+1,3,"obj") || !(*i
).compare(dot
+1,1,"o"))
102 else if(!(*i
).compare(dot
+1,3,"exe"))
107 else if(!(*i
).compare(dot
+1,3,"dll"))
108 { // apparently cl.exe has no flag for dll?
109 linkargs
.append(" -dll -out:");
114 cerr
<< "unknown -o argument - please adapt gcc-wrapper for \""
119 else if(*i
== "-g") {
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,"\\");
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")
153 args
.append(linkargs
);
157 int startprocess(string command
, string args
) {
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
;
178 si
.dwFlags
|= STARTF_USESTDHANDLES
;
179 si
.hStdOutput
=childout_write
;
180 si
.hStdError
=childout_write
;
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";
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
208 &pi
) // Process Information
210 cerr
<< "Error: could not create process" << endl
;
214 // if you don't close this the process will hang
215 CloseHandle(childout_write
);
217 // Get Process output
219 DWORD readlen
, writelen
, ret
;
220 HANDLE stdout_handle
=GetStdHandle(STD_OUTPUT_HANDLE
);
222 int success
=ReadFile(childout_read
,buffer
,BUFLEN
,&readlen
,NULL
);
223 // check if the child process has exited
224 if(GetLastError()==ERROR_BROKEN_PIPE
)
227 cerr
<< "Error: could not read from subprocess stdout" << endl
;
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
);
241 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */