8
#include <sys/cygwin.h>
12
#ifdef CCP_POSIX_TO_WIN_A
13
#define NEW_CYGPATH_INTERFACE
16
#ifdef NEW_CYGPATH_INTERFACE
17
#define GET_WIN32_SIZE(Posix) \
18
cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_ABSOLUTE, (Posix), NULL, 0)
19
#define CONVERT_TO_WIN32(Posix,Win32,Size) \
20
cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_ABSOLUTE, (Posix), \
23
#define GET_WIN32_SIZE(Posix) PATH_MAX
24
#define CONVERT_TO_WIN32(Posix,Win32,Size) \
25
((cygwin32_conv_to_full_win32_path((Posix),(Win32)) >= 0) ? 0 : -1)
28
/*#define HARDDEBUG 1*/
31
#define DEBUGF(X) printf X
33
#define DEBUGF(X) /* noop */
37
char *add_to(char *src,char *add) {
38
int len = strlen(src)+strlen(add)+1;
41
if (strlen(src) == 0) {
51
void maybe_cleanup(void)
55
if (*tmpobjdir == '\0') {
58
if (!(dir = opendir(tmpobjdir))) {
61
while((dent = readdir(dir)) != NULL) {
62
char *fullname = add_to("",tmpobjdir);
63
fullname = add_to(fullname,"/");
64
fullname = add_to(fullname,dent->d_name);
77
fprintf(stderr,"%s\n",str);
83
char **add_to_src(char **srcarr, char *add)
87
srcarr = malloc(sizeof(char *)*2);
88
srcarr[0]=malloc(strlen(add)+1);
89
strcpy(srcarr[0],add);
92
for(num = 0; srcarr[num] != NULL; ++num)
95
srcarr = realloc(srcarr,sizeof(char *)*(num+1));
96
srcarr[num-1] = malloc(strlen(add)+1);
97
strcpy(srcarr[num-1],add);
105
char *object_name(char *source) {
106
char *tmp = add_to("",source);
107
int j = strlen(tmp)-2;
111
while(j>0 && tmp[j] != '.') {
122
char *exe_name(char *source) {
123
char *tmp = add_to("",source);
124
int j = strlen(tmp)-2;
128
while(j>0 && tmp[j] != '.') {
135
return add_to(tmp,"exe");
138
char *dyn_get_short(char *longp)
142
size = GetShortPathName(longp,NULL,0);
146
shortp = malloc(size);
147
if (GetShortPathName(longp,shortp,size) != size - 1) {
154
char *do_cyp(char *posix)
158
size = GET_WIN32_SIZE(posix);
161
fprintf(stderr,"Could not cygpath %s, errno = %d\n",
164
win32 = (char *) malloc (size);
165
if (CONVERT_TO_WIN32(posix,
167
fprintf(stderr,"Could not cygpath %s, errno = %d\n",
170
char *w32_short = dyn_get_short(win32);
171
DEBUGF(("win32 = %s, w32_short = %s\n",win32, (w32_short == NULL) ? "NULL" : w32_short));
172
if (w32_short == NULL) {
173
char *rest = malloc(size);
174
char *first = malloc(size);
176
int y = strlen(win32) - 1;
178
while (w32_short == NULL) {
179
while ( y > 0 && first[y] != '\\') {
180
rest[x++] = first[y--];
183
rest[x++] = first[y];
188
w32_short = dyn_get_short(first);
189
DEBUGF(("first = %s, w32_short = %s\n",first, (w32_short == NULL) ? "NULL" : w32_short));
191
if (w32_short != NULL) {
192
y = strlen(w32_short);
193
w32_short = realloc(w32_short,y+1+x);
196
w32_short[y++] = rest[--x];
200
w32_short = malloc(strlen(win32)+1);
201
strcpy(w32_short,win32); /* last resort */
224
void save_args(int argc, char **argv)
227
for(i = 0; i < argc; ++i) {
228
save = add_to(save,argv[i]);
229
save = add_to(save," ");
233
char *progname="cc_wrap";
235
int my_create_pipe(HANDLE *read_p, HANDLE *write_p)
237
char name_buff[1000];
238
SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
239
static int counter = 0;
243
sprintf(name_buff,"\\\\.\\pipe\\%s_%d_%d",progname,getpid(),counter);
244
sa.bInheritHandle = FALSE;
245
if ((*read_p = CreateNamedPipe(name_buff,
246
PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
247
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
252
&sa)) == INVALID_HANDLE_VALUE ||
256
sa.bInheritHandle = TRUE;
257
if ((*write_p = CreateFile(name_buff,
262
FILE_ATTRIBUTE_NORMAL,
263
NULL)) == INVALID_HANDLE_VALUE ||
265
CloseHandle(*read_p);
271
void forwardenv(void)
273
char *(envs[]) = {"LIB","INCLUDE","LIBPATH", "LD_SH_DEBUG_LOG", NULL};
276
char *val = getenv(*p);
278
SetEnvironmentVariable(*p,val);
284
HANDLE do_run(char *commandline, HANDLE *out, HANDLE *err)
287
HANDLE write_pipe_stdout = NULL, read_pipe_stdout = NULL;
288
HANDLE write_pipe_stderr = NULL, read_pipe_stderr = NULL;
289
SECURITY_ATTRIBUTES pipe_security;
290
SECURITY_ATTRIBUTES attr;
291
PROCESS_INFORMATION info;
293
memset(&start,0,sizeof(start));
294
memset(&pipe_security,0,sizeof(pipe_security));
295
memset(&attr,0,sizeof(attr));
296
memset(&info,0,sizeof(info));
298
pipe_security.nLength = sizeof(pipe_security);
299
pipe_security.lpSecurityDescriptor = NULL;
300
pipe_security.bInheritHandle = TRUE;
302
if(!my_create_pipe(&read_pipe_stdout,&write_pipe_stdout)){
303
error("Could not create stdout pipes!");
305
if(!my_create_pipe(&read_pipe_stderr,&write_pipe_stderr)){
306
error("Could not create stderr pipes!");
308
start.cb = sizeof (start);
309
start.dwFlags = STARTF_USESHOWWINDOW;
310
start.wShowWindow = SW_HIDE;
311
start.hStdOutput = write_pipe_stdout;
312
start.hStdError = write_pipe_stderr;
313
start.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
314
start.dwFlags |= STARTF_USESTDHANDLES;
316
attr.nLength = sizeof(attr);
317
attr.lpSecurityDescriptor = NULL;
318
attr.bInheritHandle = TRUE;
319
forwardenv(); /* Cygwin and windows environment variables... sigh... */
320
if(!CreateProcess(NULL,
325
CREATE_DEFAULT_ERROR_MODE,
330
fprintf(stderr,"Could not run %s, last error: %d\n",commandline,GetLastError());
331
error("Could not create process");
333
*out = read_pipe_stdout;
334
*err = read_pipe_stderr;
335
CloseHandle(write_pipe_stdout);
336
CloseHandle(write_pipe_stderr);
337
return info.hProcess;
339
#define HANDLE_STDOUT 0
340
#define HANDLE_STDERR 1
341
#define HANDLE_PROC 2
347
int handle_overlapped(HANDLE fd, OVERLAPPED *ovp, char *buffer,
348
int bufflen, int get_old, FILE *whereto, int *skip)
353
DEBUGF(("In handle_overlapped(%d,0x%08x,0x%08x,%d,%d), prefix = %s\n",
354
fd,ovp,buffer,bufflen,get_old,prefix));
355
/* h�mta resultat av gamla f�rst */
357
res = GetOverlappedResult(fd,ovp,&read,TRUE);
358
DEBUGF(("read = %d, res = %d, GetLastError() = %d\n",read,res,GetLastError()));
364
while(*skip && *ptr != '\0') {
371
fprintf(whereto,"%s",ptr);
375
ResetEvent(ovp->hEvent);
378
res = ReadFile(fd,buffer,bufflen-1,&read,ovp);
381
err = GetLastError();
382
if (err == ERROR_IO_PENDING) {
383
DEBUGF(("Error I/O Pending\n"));
386
DEBUGF(("ReadFileFailed for %s, %d\n",prefix,err));
391
while(*skip && *ptr != '\0') {
398
fprintf(whereto,"%s",ptr);
404
int run(char *commandline,int skipout,int skiperr)
407
HANDLE real_stdout,real_stderr;
408
OVERLAPPED ov_out,ov_err;
409
char outbuff[1024],errbuff[1024];
415
unsigned living_handles = 0x7;
417
harr[HANDLE_STDOUT] = CreateEvent(NULL,
419
FALSE, /*not signalled */
421
harr[HANDLE_STDERR] = CreateEvent(NULL,
423
FALSE,/*not signalled */
426
memset(&ov_out,0,sizeof(ov_out));
427
memset(&ov_err,0,sizeof(ov_err));
429
ov_out.hEvent = harr[HANDLE_STDOUT];
430
ov_err.hEvent = harr[HANDLE_STDERR];
432
harr[HANDLE_PROC] = do_run(commandline,&real_stdout,&real_stderr);
437
handle_overlapped(real_stdout,&ov_out,outbuff,1024,0,stdout,&skipout);
441
handle_overlapped(real_stderr,&ov_err,errbuff,1024,0,stderr,&skiperr);
446
if ((living_handles & (1U << i))) {
448
wait[nwait++] = harr[i];
452
ret = WaitForMultipleObjects(nwait,
456
DEBUGF(("Wait returned %d\n",ret));
458
if (ret == WAIT_FAILED) {
459
error("Wait failed");
462
ret -= WAIT_OBJECT_0;
467
DEBUGF(("Process died!\n"));
468
GetExitCodeProcess(harr[HANDLE_PROC],&exitcode);
469
if ((living_handles &= (~(1U<<HANDLE_PROC))) == 0) {
478
if (!handle_overlapped(real_stdout,&ov_out, outbuff,1024,1,stdout,&skipout)) {
479
if ((living_handles &= (~(1U<<HANDLE_STDOUT))) == 0) {
488
if (!handle_overlapped(real_stderr,&ov_err, errbuff,1024,1,stderr,&skiperr)){
489
if ((living_handles &= (~(1U<<HANDLE_STDERR))) == 0) {
495
error("Unexpected wait result");
499
CloseHandle(harr[HANDLE_PROC]);
500
CloseHandle(harr[HANDLE_STDOUT]);
501
CloseHandle(harr[HANDLE_STDERR]);
502
CloseHandle(real_stdout);
503
CloseHandle(real_stderr);
504
return (int) exitcode;
507
int main(int argc, char **argv)
516
char *common_cflags="-nologo -D__WIN32__ -DWIN32 -DWINDOWS -D_WIN32 -DNT -D_CRT_SECURE_NO_DEPRECATE";
518
char *debug_flags = "";
519
char *optimize_flags = "";
522
char **sources = NULL;
523
char *accum_objects = "";
527
int preprocessing = 0;
529
int optimized_build = 0;
533
save_args(argc,argv);
535
for(i = 1; i < argc; ++i) {
536
if (argv[i][0] == '-') {
537
char *opt = argv[i]+1;
540
if(strcmp(opt,"Wall")) {
545
if(strlen(opt) > 1) {
551
if(strlen(opt) > 1) {
553
cmd = add_to(cmd," ");
554
cmd = add_to(cmd,opt);
563
/* ignore what opt is requested, set hard */
564
optimize_flags = "-Ox -Zi";
573
if (strcmp(opt,"g") && strcmp(opt,"ggdb")) {
576
if (!optimized_build) {
581
linkcmd = add_to(linkcmd," -g");
587
if(!strcmp(opt,"mt") || !strcmp(opt,"MT")) {
589
} else if (!strcmp(opt,"md") || !strcmp(opt,"MD")) {
591
} else if (!strcmp(opt,"ml") || !strcmp(opt,"ML")) {
593
} else if (!strcmp(opt,"mdd") || !strcmp(opt,"MDd") ||
594
!strcmp(opt,"MDD")) {
596
} else if (!strcmp(opt,"mtd") || !strcmp(opt,"MTd") ||
597
!strcmp(opt,"MTD")) {
599
} else if (!strcmp(opt,"mld") || !strcmp(opt,"MLd") ||
600
!strcmp(opt,"MLD")) {
608
if (!strcmp(opt,"o")) {
611
error("-o without filename");
620
mpath = do_cyp(opt+1);
621
cmd = add_to(cmd," -I\"");
622
cmd = add_to(cmd,mpath);
623
cmd = add_to(cmd,"\"");
626
cmd = add_to(cmd," ");
627
cmd = add_to(cmd,opt);
631
cmd = add_to(cmd," -");
632
cmd = add_to(cmd,opt);
634
linkcmd = add_to(linkcmd," -");
635
linkcmd = add_to(linkcmd,opt);
645
if (x > 1 && s[x-1] == 'c' && s[x-2] == '.') {
647
sources = add_to_src(sources,s);
648
} else if (x > 3 && !strcmp(s + (x - 4),".cpp")) {
650
sources = add_to_src(sources,s);
651
} else if (x > 1 && s[x-1] == 'o' && s[x-2] == '.') {
652
linkcmd = add_to(linkcmd," ");
653
linkcmd = add_to(linkcmd,s);
655
/* Pass rest to linker */
656
linkcmd = add_to(linkcmd," ");
657
linkcmd = add_to(linkcmd,s);
660
if ((debuglog = getenv("CC_SH_DEBUG_LOG")) != NULL) {
661
debugfile = fopen(debuglog,"wb+");
663
fprintf(debugfile,"----------------\n");
669
tmpobjdir = add_to("","/tmp/tmpobj");
672
pid_t pid = getpid();
673
sprintf(pidstr,"%d",pid);
674
tmpobjdir = add_to(tmpobjdir,pidstr);
676
mkdir(tmpobjdir,0777);
677
if (sources != NULL) {
678
char *output_filename;
681
for (i=0;sources[i] != NULL; ++i) {
683
int x = strlen(outfile);
684
if (x > 1 && outfile[x-1] == 'o' && outfile[x-2] == '.') {
685
if (*outfile != '/') {
686
/* non absolute object */
688
error("Single object multiple sources");
690
output_filename = add_to("",outfile);
693
error("Single object multiple sources");
695
output_filename = do_cyp(outfile);
698
char *tmp = object_name(sources[i]);
700
/*fprintf(stderr,"sources[i] = %s\ntmp = %s\n",
703
if (!x || outfile[0] != '/') {
704
/* non absolute directory */
705
output_filename = add_to("",outfile);
707
output_filename = do_cyp(outfile);
709
/*fprintf(stderr,"output_filename = %s\n",output_filename);*/
710
if (*output_filename != '\0') {
711
output_filename = add_to(output_filename,"/");
713
output_filename = add_to(output_filename,tmp);
717
char *tmp = object_name(sources[i]);
718
output_filename = add_to("",tmpobjdir);
719
output_filename = add_to(output_filename,"/");
720
output_filename = add_to(output_filename,tmp);
721
accum_objects = add_to(accum_objects," ");
722
accum_objects = add_to(accum_objects,output_filename);
723
/* reform to dos path */
724
free(output_filename);
725
output_filename = do_cyp(tmpobjdir);
726
output_filename = add_to(output_filename,"/");
727
output_filename = add_to(output_filename,tmp);
729
mpath = do_cyp(sources[i]);
731
output_flag = add_to("","-E");
733
output_flag = add_to("","-c -Fo");
734
output_flag = add_to(output_flag,output_filename);
736
params = add_to("","cl.exe ");
737
params = add_to(params,common_cflags);
738
params = add_to(params," ");
739
params = add_to(params,md);
740
params = add_to(params," ");
741
params = add_to(params,debug_flags);
742
params = add_to(params," ");
743
params = add_to(params,optimize_flags);
744
params = add_to(params," ");
745
params = add_to(params,cmd);
746
params = add_to(params," ");
747
params = add_to(params,output_flag);
748
params = add_to(params," ");
749
params = add_to(params,mpath);
750
free(output_filename);
755
fprintf(debugfile,"%s\n",save);
756
fprintf(debugfile,"%s\n",params);
759
retval = run(params,0,1);
761
retval = run(params,1,0);
774
if (strlen(outfile) == 0) {
775
if (sources != NULL && sources[0] != NULL) {
776
char *tmp = exe_name(sources[0]);
777
out_spec = add_to("","-o ");
778
out_spec = add_to(out_spec,tmp);
781
out_spec = add_to("","");
784
out_spec = add_to("","-o ");
785
out_spec = add_to(out_spec,outfile);
787
if (!strcmp(md,"-ML")) {
789
} else if (!strcmp(md,"-MLd")) {
791
} else if (!strcmp(md,"-MD")) {
793
} else if (!strcmp(md,"-MDd")) {
795
} else if (!strcmp(md,"-MT")) {
797
} else if (!strcmp(md,"-MTd")) {
803
params = add_to("","bash ld.sh ");
805
params = add_to("","ld_wrap.exe ");
807
params = add_to(params,accum_objects);
808
params = add_to(params," ");
809
params = add_to(params,out_spec);
810
params = add_to(params," ");
811
params = add_to(params,linkcmd);
812
params = add_to(params," ");
813
params = add_to(params,stdlib);
817
fprintf(debugfile,"%s\n",params);
819
if (retval = run(params,0,0) != 0) {