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 if (libbuf
== nullptr) {
41 std::cerr
<< "No environment variable ILIB" << std::endl
;
42 std::exit(EXIT_FAILURE
);
44 libpath
.append(libbuf
);
46 if(_putenv(libpath
.c_str())<0) {
47 cerr
<< "Error: could not export LIB" << endl
;
51 // Set-up include path
52 string includepath
="INCLUDE=.";
55 _dupenv_s(&incbuf
,&inclen
,"SOLARINC");
56 if (incbuf
== nullptr) {
57 std::cerr
<< "No environment variable SOLARINC" << std::endl
;
58 std::exit(EXIT_FAILURE
);
60 string
inctmp(incbuf
);
64 for(size_t pos
=0,len
=0;pos
<inctmp
.length();) {
65 size_t endpos
=inctmp
.find(" -I",pos
+1);
66 if(endpos
==string::npos
)
67 endpos
=inctmp
.length();
70 while(len
>0&&inctmp
[pos
+len
-1]==' ')
74 includepath
.append(";");
75 includepath
.append(inctmp
,pos
+3,len
-3);
79 if(_putenv(includepath
.c_str())<0) {
80 cerr
<< "Error: could not export INCLUDE" << endl
;
85 string
processccargs(vector
<string
> rawargs
) {
86 // suppress the msvc banner
87 string args
=" -nologo";
88 // TODO: should these options be enabled globally?
89 args
.append(" -EHsc");
90 const char *const pDebugRuntime(getenv("MSVC_USE_DEBUG_RUNTIME"));
91 if (pDebugRuntime
&& !strcmp(pDebugRuntime
, "TRUE"))
96 args
.append(" -Ob1 -Oxs -Oy-");
98 // apparently these must be at the end
99 // otherwise configure tests may fail
100 // note: always use -debug so a PDB file is created
101 string
linkargs(" -link -debug");
103 for(vector
<string
>::iterator i
= rawargs
.begin(); i
!= rawargs
.end(); ++i
) {
106 // TODO: handle more than just exe output
108 size_t dot
=(*i
).find_last_of(".");
109 if(!(*i
).compare(dot
+1,3,"obj") || !(*i
).compare(dot
+1,1,"o"))
114 else if(!(*i
).compare(dot
+1,3,"exe"))
119 else if(!(*i
).compare(dot
+1,3,"dll"))
120 { // apparently cl.exe has no flag for dll?
121 linkargs
.append(" -dll -out:");
126 cerr
<< "unknown -o argument - please adapt gcc-wrapper for \""
131 else if(*i
== "-g" || !(*i
).compare(0,5,"-ggdb")) {
135 else if(!(*i
).compare(0,2,"-D")) {
136 // need to re-escape strings for preprocessor
137 for(size_t pos
=(*i
).find("\""); pos
!=string::npos
; pos
=(*i
).find("\"",pos
)) {
138 (*i
).replace(pos
,0,"\\");
143 else if(!(*i
).compare(0,2,"-L")) {
144 linkargs
.append(" -LIBPATH:"+(*i
).substr(2));
146 else if(!(*i
).compare(0,2,"-l") && (*i
).compare(0,5,"-link")) {
147 linkargs
.append(" "+(*i
).substr(2)+".lib");
149 else if(!(*i
).compare(0,5,"-def:") || !(*i
).compare(0,5,"/def:")) {
150 // why are we invoked with /def:? cl.exe should handle plain
151 // "foo.def" by itself
152 linkargs
.append(" " + *i
);
154 else if(!(*i
).compare(0,12,"-fvisibility") || *i
== "-fPIC") {
155 //TODO: drop other gcc-specific options
157 else if(!(*i
).compare(0,4,"-Wl,")) {
158 //TODO: drop other gcc-specific options
160 else if(*i
== "-Werror")
165 args
.append(linkargs
);
169 int startprocess(string command
, string args
) {
171 PROCESS_INFORMATION pi
;
172 SECURITY_ATTRIBUTES sa
;
174 HANDLE childout_read
;
175 HANDLE childout_write
;
177 memset(&sa
,0,sizeof(sa
));
178 memset(&si
,0,sizeof(si
));
179 memset(&pi
,0,sizeof(pi
));
181 sa
.nLength
=sizeof(sa
);
182 sa
.bInheritHandle
=TRUE
;
184 if(!CreatePipe(&childout_read
,&childout_write
,&sa
,0)) {
185 cerr
<< "Error: could not create stdout pipe" << endl
;
190 si
.dwFlags
|= STARTF_USESTDHANDLES
;
191 si
.hStdOutput
=childout_write
;
192 si
.hStdError
=childout_write
;
195 size_t pos
=command
.find("ccache ");
196 if(pos
!= string::npos
) {
197 args
.insert(0,"cl.exe");
198 command
=command
.substr(0,pos
+strlen("ccache"))+".exe";
201 auto cmdline
= "\"" + command
+ "\" " + args
;
203 //cerr << "CMD= " << command << " " << args << endl;
205 // Commandline may be modified by CreateProcess
206 char* cmdlineBuf
=_strdup(cmdline
.c_str());
208 if(!CreateProcess(nullptr, // Process Name
209 cmdlineBuf
, // Command Line
210 nullptr, // Process Handle not Inheritable
211 nullptr, // Thread Handle not Inheritable
212 TRUE
, // Handles are Inherited
213 0, // No creation flags
214 nullptr, // Environment for process
215 nullptr, // Use same starting directory
217 &pi
) // Process Information
219 cerr
<< "Error: could not create process" << endl
;
223 // if you don't close this the process will hang
224 CloseHandle(childout_write
);
226 // Get Process output
228 DWORD readlen
, writelen
, ret
;
229 HANDLE stdout_handle
=GetStdHandle(STD_OUTPUT_HANDLE
);
231 int success
=ReadFile(childout_read
,buffer
,BUFLEN
,&readlen
,nullptr);
232 // check if the child process has exited
233 if(GetLastError()==ERROR_BROKEN_PIPE
)
236 cerr
<< "Error: could not read from subprocess stdout" << endl
;
240 WriteFile(stdout_handle
,buffer
,readlen
,&writelen
,nullptr);
243 WaitForSingleObject(pi
.hProcess
, INFINITE
);
244 GetExitCodeProcess(pi
.hProcess
, &ret
);
245 CloseHandle(pi
.hThread
);
246 CloseHandle(pi
.hProcess
);
250 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */