winex11.drv: Map coordinates before calling send_mouse_input.
[wine/zf.git] / tools / makedep.c
blob8245a3242790c38691d9d504e7d948fb7f5d15c7
1 /*
2 * Generate include file dependencies
4 * Copyright 1996, 2013, 2020 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
23 #include <assert.h>
24 #include <ctype.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdarg.h>
30 #include <signal.h>
31 #include <string.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #ifdef HAVE_UNISTD_H
35 # include <unistd.h>
36 #endif
37 #if defined(_WIN32) && !defined(__CYGWIN__)
38 #include <direct.h>
39 #include <io.h>
40 #define mkdir(path,mode) mkdir(path)
41 #endif
42 #include "wine/list.h"
44 struct strarray
46 unsigned int count; /* strings in use */
47 unsigned int size; /* total allocated size */
48 const char **str;
51 enum incl_type
53 INCL_NORMAL, /* #include "foo.h" */
54 INCL_SYSTEM, /* #include <foo.h> */
55 INCL_IMPORT, /* idl import "foo.idl" */
56 INCL_IMPORTLIB, /* idl importlib "foo.tlb" */
57 INCL_CPP_QUOTE, /* idl cpp_quote("#include \"foo.h\"") */
58 INCL_CPP_QUOTE_SYSTEM /* idl cpp_quote("#include <foo.h>") */
61 struct dependency
63 int line; /* source line where this header is included */
64 enum incl_type type; /* type of include */
65 char *name; /* header name */
68 struct file
70 struct list entry;
71 char *name; /* full file name relative to cwd */
72 void *args; /* custom arguments for makefile rule */
73 unsigned int flags; /* flags (see below) */
74 unsigned int deps_count; /* files in use */
75 unsigned int deps_size; /* total allocated size */
76 struct dependency *deps; /* all header dependencies */
79 struct incl_file
81 struct list entry;
82 struct file *file;
83 char *name;
84 char *filename;
85 char *basename; /* base target name for generated files */
86 char *sourcename; /* source file name for generated headers */
87 struct incl_file *included_by; /* file that included this one */
88 int included_line; /* line where this file was included */
89 enum incl_type type; /* type of include */
90 int use_msvcrt; /* put msvcrt headers in the search path? */
91 struct incl_file *owner;
92 unsigned int files_count; /* files in use */
93 unsigned int files_size; /* total allocated size */
94 struct incl_file **files;
95 struct strarray dependencies; /* file dependencies */
98 #define FLAG_GENERATED 0x000001 /* generated file */
99 #define FLAG_INSTALL 0x000002 /* file to install */
100 #define FLAG_IDL_PROXY 0x000100 /* generates a proxy (_p.c) file */
101 #define FLAG_IDL_CLIENT 0x000200 /* generates a client (_c.c) file */
102 #define FLAG_IDL_SERVER 0x000400 /* generates a server (_s.c) file */
103 #define FLAG_IDL_IDENT 0x000800 /* generates an ident (_i.c) file */
104 #define FLAG_IDL_REGISTER 0x001000 /* generates a registration (_r.res) file */
105 #define FLAG_IDL_TYPELIB 0x002000 /* generates a typelib (.tlb) file */
106 #define FLAG_IDL_REGTYPELIB 0x004000 /* generates a registered typelib (_t.res) file */
107 #define FLAG_IDL_HEADER 0x008000 /* generates a header (.h) file */
108 #define FLAG_RC_PO 0x010000 /* rc file contains translations */
109 #define FLAG_C_IMPLIB 0x020000 /* file is part of an import library */
110 #define FLAG_C_UNIX 0x040000 /* file is part of a Unix library */
111 #define FLAG_SFD_FONTS 0x080000 /* sfd file generated bitmap fonts */
113 static const struct
115 unsigned int flag;
116 const char *ext;
117 } idl_outputs[] =
119 { FLAG_IDL_TYPELIB, ".tlb" },
120 { FLAG_IDL_REGTYPELIB, "_t.res" },
121 { FLAG_IDL_CLIENT, "_c.c" },
122 { FLAG_IDL_IDENT, "_i.c" },
123 { FLAG_IDL_PROXY, "_p.c" },
124 { FLAG_IDL_SERVER, "_s.c" },
125 { FLAG_IDL_REGISTER, "_r.res" },
126 { FLAG_IDL_HEADER, ".h" }
129 #define HASH_SIZE 997
131 static struct list files[HASH_SIZE];
133 static const struct strarray empty_strarray;
135 enum install_rules { INSTALL_LIB, INSTALL_DEV, NB_INSTALL_RULES };
137 /* variables common to all makefiles */
138 static struct strarray linguas;
139 static struct strarray dll_flags;
140 static struct strarray target_flags;
141 static struct strarray msvcrt_flags;
142 static struct strarray extra_cflags;
143 static struct strarray extra_cross_cflags;
144 static struct strarray cpp_flags;
145 static struct strarray lddll_flags;
146 static struct strarray libs;
147 static struct strarray enable_tests;
148 static struct strarray cmdline_vars;
149 static struct strarray subdirs;
150 static struct strarray disabled_dirs;
151 static struct strarray cross_import_libs;
152 static struct strarray delay_import_libs;
153 static struct strarray top_install_lib;
154 static struct strarray top_install_dev;
155 static const char *root_src_dir;
156 static const char *tools_dir;
157 static const char *tools_ext;
158 static const char *exe_ext;
159 static const char *dll_ext;
160 static const char *man_ext;
161 static const char *crosstarget;
162 static const char *crossdebug;
163 static const char *fontforge;
164 static const char *convert;
165 static const char *flex;
166 static const char *bison;
167 static const char *ar;
168 static const char *ranlib;
169 static const char *rsvg;
170 static const char *icotool;
171 static const char *dlltool;
172 static const char *msgfmt;
173 static const char *ln_s;
174 static const char *sed_cmd;
175 static const char *delay_load_flag;
177 struct makefile
179 /* values determined from input makefile */
180 struct strarray vars;
181 struct strarray include_paths;
182 struct strarray include_args;
183 struct strarray define_args;
184 struct strarray programs;
185 struct strarray scripts;
186 struct strarray imports;
187 struct strarray delayimports;
188 struct strarray extradllflags;
189 struct strarray install_lib;
190 struct strarray install_dev;
191 struct strarray extra_targets;
192 struct strarray extra_imports;
193 struct list sources;
194 struct list includes;
195 const char *src_dir;
196 const char *obj_dir;
197 const char *parent_dir;
198 const char *module;
199 const char *testdll;
200 const char *sharedlib;
201 const char *staticlib;
202 const char *staticimplib;
203 const char *importlib;
204 int disabled;
205 int use_msvcrt;
206 int is_cross;
207 int is_win16;
208 int is_exe;
210 /* values generated at output time */
211 struct strarray in_files;
212 struct strarray ok_files;
213 struct strarray pot_files;
214 struct strarray clean_files;
215 struct strarray distclean_files;
216 struct strarray uninstall_files;
217 struct strarray object_files;
218 struct strarray crossobj_files;
219 struct strarray unixobj_files;
220 struct strarray res_files;
221 struct strarray font_files;
222 struct strarray c2man_files;
223 struct strarray debug_files;
224 struct strarray dlldata_files;
225 struct strarray implib_objs;
226 struct strarray all_targets;
227 struct strarray phony_targets;
228 struct strarray dependencies;
229 struct strarray install_rules[NB_INSTALL_RULES];
232 static struct makefile *top_makefile;
233 static struct makefile **submakes;
235 static const char separator[] = "### Dependencies";
236 static const char *output_makefile_name = "Makefile";
237 static const char *input_file_name;
238 static const char *output_file_name;
239 static const char *temp_file_name;
240 static int relative_dir_mode;
241 static int silent_rules;
242 static int input_line;
243 static int output_column;
244 static FILE *output_file;
246 static const char Usage[] =
247 "Usage: makedep [options] [directories]\n"
248 "Options:\n"
249 " -R from to Compute the relative path between two directories\n"
250 " -S Generate Automake-style silent rules\n"
251 " -fxxx Store output in file 'xxx' (default: Makefile)\n";
254 #ifndef __GNUC__
255 #define __attribute__(x)
256 #endif
258 static void fatal_error( const char *msg, ... ) __attribute__ ((__format__ (__printf__, 1, 2)));
259 static void fatal_perror( const char *msg, ... ) __attribute__ ((__format__ (__printf__, 1, 2)));
260 static void output( const char *format, ... ) __attribute__ ((__format__ (__printf__, 1, 2)));
261 static char *strmake( const char* fmt, ... ) __attribute__ ((__format__ (__printf__, 1, 2)));
263 /*******************************************************************
264 * fatal_error
266 static void fatal_error( const char *msg, ... )
268 va_list valist;
269 va_start( valist, msg );
270 if (input_file_name)
272 fprintf( stderr, "%s:", input_file_name );
273 if (input_line) fprintf( stderr, "%d:", input_line );
274 fprintf( stderr, " error: " );
276 else fprintf( stderr, "makedep: error: " );
277 vfprintf( stderr, msg, valist );
278 va_end( valist );
279 exit(1);
283 /*******************************************************************
284 * fatal_perror
286 static void fatal_perror( const char *msg, ... )
288 va_list valist;
289 va_start( valist, msg );
290 if (input_file_name)
292 fprintf( stderr, "%s:", input_file_name );
293 if (input_line) fprintf( stderr, "%d:", input_line );
294 fprintf( stderr, " error: " );
296 else fprintf( stderr, "makedep: error: " );
297 vfprintf( stderr, msg, valist );
298 perror( " " );
299 va_end( valist );
300 exit(1);
304 /*******************************************************************
305 * cleanup_files
307 static void cleanup_files(void)
309 if (temp_file_name) unlink( temp_file_name );
310 if (output_file_name) unlink( output_file_name );
314 /*******************************************************************
315 * exit_on_signal
317 static void exit_on_signal( int sig )
319 exit( 1 ); /* this will call the atexit functions */
323 /*******************************************************************
324 * xmalloc
326 static void *xmalloc( size_t size )
328 void *res;
329 if (!(res = malloc (size ? size : 1)))
330 fatal_error( "Virtual memory exhausted.\n" );
331 return res;
335 /*******************************************************************
336 * xrealloc
338 static void *xrealloc (void *ptr, size_t size)
340 void *res;
341 assert( size );
342 if (!(res = realloc( ptr, size )))
343 fatal_error( "Virtual memory exhausted.\n" );
344 return res;
347 /*******************************************************************
348 * xstrdup
350 static char *xstrdup( const char *str )
352 char *res = strdup( str );
353 if (!res) fatal_error( "Virtual memory exhausted.\n" );
354 return res;
358 /*******************************************************************
359 * strmake
361 static char *strmake( const char* fmt, ... )
363 int n;
364 size_t size = 100;
365 va_list ap;
367 for (;;)
369 char *p = xmalloc (size);
370 va_start(ap, fmt);
371 n = vsnprintf (p, size, fmt, ap);
372 va_end(ap);
373 if (n == -1) size *= 2;
374 else if ((size_t)n >= size) size = n + 1;
375 else return xrealloc( p, n + 1 );
376 free(p);
381 /*******************************************************************
382 * strendswith
384 static int strendswith( const char* str, const char* end )
386 size_t l = strlen( str );
387 size_t m = strlen( end );
389 return l >= m && strcmp(str + l - m, end) == 0;
393 /*******************************************************************
394 * output
396 static void output( const char *format, ... )
398 int ret;
399 va_list valist;
401 va_start( valist, format );
402 ret = vfprintf( output_file, format, valist );
403 va_end( valist );
404 if (ret < 0) fatal_perror( "output" );
405 if (format[0] && format[strlen(format) - 1] == '\n') output_column = 0;
406 else output_column += ret;
410 /*******************************************************************
411 * strarray_add
413 static void strarray_add( struct strarray *array, const char *str )
415 if (array->count == array->size)
417 if (array->size) array->size *= 2;
418 else array->size = 16;
419 array->str = xrealloc( array->str, sizeof(array->str[0]) * array->size );
421 array->str[array->count++] = str;
425 /*******************************************************************
426 * strarray_addall
428 static void strarray_addall( struct strarray *array, struct strarray added )
430 unsigned int i;
432 for (i = 0; i < added.count; i++) strarray_add( array, added.str[i] );
436 /*******************************************************************
437 * strarray_exists
439 static int strarray_exists( const struct strarray *array, const char *str )
441 unsigned int i;
443 for (i = 0; i < array->count; i++) if (!strcmp( array->str[i], str )) return 1;
444 return 0;
448 /*******************************************************************
449 * strarray_add_uniq
451 static void strarray_add_uniq( struct strarray *array, const char *str )
453 if (!strarray_exists( array, str )) strarray_add( array, str );
457 /*******************************************************************
458 * strarray_addall_uniq
460 static void strarray_addall_uniq( struct strarray *array, struct strarray added )
462 unsigned int i;
464 for (i = 0; i < added.count; i++) strarray_add_uniq( array, added.str[i] );
468 /*******************************************************************
469 * strarray_get_value
471 * Find a value in a name/value pair string array.
473 static const char *strarray_get_value( const struct strarray *array, const char *name )
475 int pos, res, min = 0, max = array->count / 2 - 1;
477 while (min <= max)
479 pos = (min + max) / 2;
480 if (!(res = strcmp( array->str[pos * 2], name ))) return array->str[pos * 2 + 1];
481 if (res < 0) min = pos + 1;
482 else max = pos - 1;
484 return NULL;
488 /*******************************************************************
489 * strarray_set_value
491 * Define a value in a name/value pair string array.
493 static void strarray_set_value( struct strarray *array, const char *name, const char *value )
495 int i, pos, res, min = 0, max = array->count / 2 - 1;
497 while (min <= max)
499 pos = (min + max) / 2;
500 if (!(res = strcmp( array->str[pos * 2], name )))
502 /* redefining a variable replaces the previous value */
503 array->str[pos * 2 + 1] = value;
504 return;
506 if (res < 0) min = pos + 1;
507 else max = pos - 1;
509 strarray_add( array, NULL );
510 strarray_add( array, NULL );
511 for (i = array->count - 1; i > min * 2 + 1; i--) array->str[i] = array->str[i - 2];
512 array->str[min * 2] = name;
513 array->str[min * 2 + 1] = value;
517 /*******************************************************************
518 * strarray_set_qsort
520 static void strarray_qsort( struct strarray *array, int (*func)(const char **, const char **) )
522 if (array->count) qsort( array->str, array->count, sizeof(*array->str), (void *)func );
526 /*******************************************************************
527 * output_filename
529 static void output_filename( const char *name )
531 if (output_column + strlen(name) + 1 > 100)
533 output( " \\\n" );
534 output( " " );
536 else if (output_column) output( " " );
537 output( "%s", name );
541 /*******************************************************************
542 * output_filenames
544 static void output_filenames( struct strarray array )
546 unsigned int i;
548 for (i = 0; i < array.count; i++) output_filename( array.str[i] );
552 /*******************************************************************
553 * output_rm_filenames
555 static void output_rm_filenames( struct strarray array )
557 static const unsigned int max_cmdline = 30000; /* to be on the safe side */
558 unsigned int i, len;
560 if (!array.count) return;
561 output( "\trm -f" );
562 for (i = len = 0; i < array.count; i++)
564 if (len > max_cmdline)
566 output( "\n" );
567 output( "\trm -f" );
568 len = 0;
570 output_filename( array.str[i] );
571 len += strlen( array.str[i] ) + 1;
573 output( "\n" );
577 /*******************************************************************
578 * get_extension
580 static char *get_extension( char *filename )
582 char *ext = strrchr( filename, '.' );
583 if (ext && strchr( ext, '/' )) ext = NULL;
584 return ext;
588 /*******************************************************************
589 * get_base_name
591 static const char *get_base_name( const char *name )
593 char *base;
594 if (!strchr( name, '.' )) return name;
595 base = strdup( name );
596 *strrchr( base, '.' ) = 0;
597 return base;
601 /*******************************************************************
602 * replace_extension
604 static char *replace_extension( const char *name, const char *old_ext, const char *new_ext )
606 char *ret;
607 size_t name_len = strlen( name );
608 size_t ext_len = strlen( old_ext );
610 if (name_len >= ext_len && !strcmp( name + name_len - ext_len, old_ext )) name_len -= ext_len;
611 ret = xmalloc( name_len + strlen( new_ext ) + 1 );
612 memcpy( ret, name, name_len );
613 strcpy( ret + name_len, new_ext );
614 return ret;
618 /*******************************************************************
619 * replace_filename
621 static char *replace_filename( const char *path, const char *name )
623 const char *p;
624 char *ret;
625 size_t len;
627 if (!path) return xstrdup( name );
628 if (!(p = strrchr( path, '/' ))) return xstrdup( name );
629 len = p - path + 1;
630 ret = xmalloc( len + strlen( name ) + 1 );
631 memcpy( ret, path, len );
632 strcpy( ret + len, name );
633 return ret;
637 /*******************************************************************
638 * strarray_replace_extension
640 static struct strarray strarray_replace_extension( const struct strarray *array,
641 const char *old_ext, const char *new_ext )
643 unsigned int i;
644 struct strarray ret;
646 ret.count = ret.size = array->count;
647 ret.str = xmalloc( sizeof(ret.str[0]) * ret.size );
648 for (i = 0; i < array->count; i++) ret.str[i] = replace_extension( array->str[i], old_ext, new_ext );
649 return ret;
653 /*******************************************************************
654 * replace_substr
656 static char *replace_substr( const char *str, const char *start, size_t len, const char *replace )
658 size_t pos = start - str;
659 char *ret = xmalloc( pos + strlen(replace) + strlen(start + len) + 1 );
660 memcpy( ret, str, pos );
661 strcpy( ret + pos, replace );
662 strcat( ret + pos, start + len );
663 return ret;
667 /*******************************************************************
668 * get_relative_path
670 * Determine where the destination path is located relative to the 'from' path.
672 static char *get_relative_path( const char *from, const char *dest )
674 const char *start;
675 char *ret, *p;
676 unsigned int dotdots = 0;
678 /* a path of "." is equivalent to an empty path */
679 if (!strcmp( from, "." )) from = "";
681 for (;;)
683 while (*from == '/') from++;
684 while (*dest == '/') dest++;
685 start = dest; /* save start of next path element */
686 if (!*from) break;
688 while (*from && *from != '/' && *from == *dest) { from++; dest++; }
689 if ((!*from || *from == '/') && (!*dest || *dest == '/')) continue;
691 /* count remaining elements in 'from' */
694 dotdots++;
695 while (*from && *from != '/') from++;
696 while (*from == '/') from++;
698 while (*from);
699 break;
702 if (!start[0] && !dotdots) return NULL; /* empty path */
704 ret = xmalloc( 3 * dotdots + strlen( start ) + 1 );
705 for (p = ret; dotdots; dotdots--, p += 3) memcpy( p, "../", 3 );
707 if (start[0]) strcpy( p, start );
708 else p[-1] = 0; /* remove trailing slash */
709 return ret;
713 /*******************************************************************
714 * concat_paths
716 static char *concat_paths( const char *base, const char *path )
718 int i, len;
719 char *ret;
721 if (!base || !base[0]) return xstrdup( path && path[0] ? path : "." );
722 if (!path || !path[0]) return xstrdup( base );
723 if (path[0] == '/') return xstrdup( path );
725 len = strlen( base );
726 while (len && base[len - 1] == '/') len--;
727 while (len && !strncmp( path, "..", 2 ) && (!path[2] || path[2] == '/'))
729 for (i = len; i > 0; i--) if (base[i - 1] == '/') break;
730 if (i == len - 2 && !memcmp( base + i, "..", 2 )) break; /* we can't go up if we already have ".." */
731 if (i != len - 1 || base[i] != '.')
733 path += 2;
734 while (*path == '/') path++;
736 /* else ignore "." element */
737 while (i > 0 && base[i - 1] == '/') i--;
738 len = i;
740 if (!len && base[0] != '/') return xstrdup( path[0] ? path : "." );
741 ret = xmalloc( len + strlen( path ) + 2 );
742 memcpy( ret, base, len );
743 ret[len++] = '/';
744 strcpy( ret + len, path );
745 return ret;
749 /*******************************************************************
750 * obj_dir_path
752 static char *obj_dir_path( const struct makefile *make, const char *path )
754 return concat_paths( make->obj_dir, path );
758 /*******************************************************************
759 * src_dir_path
761 static char *src_dir_path( const struct makefile *make, const char *path )
763 if (make->src_dir) return concat_paths( make->src_dir, path );
764 return obj_dir_path( make, path );
768 /*******************************************************************
769 * root_src_dir_path
771 static char *root_src_dir_path( const char *path )
773 return concat_paths( root_src_dir, path );
777 /*******************************************************************
778 * tools_dir_path
780 static char *tools_dir_path( const struct makefile *make, const char *path )
782 if (tools_dir) return strmake( "%s/tools/%s", tools_dir, path );
783 return strmake( "tools/%s", path );
787 /*******************************************************************
788 * tools_path
790 static char *tools_path( const struct makefile *make, const char *name )
792 return strmake( "%s/%s%s", tools_dir_path( make, name ), name, tools_ext );
796 /*******************************************************************
797 * strarray_addall_path
799 static void strarray_addall_path( struct strarray *array, const char *dir, struct strarray added )
801 unsigned int i;
803 for (i = 0; i < added.count; i++) strarray_add( array, concat_paths( dir, added.str[i] ));
807 /*******************************************************************
808 * get_line
810 static char *get_line( FILE *file )
812 static char *buffer;
813 static size_t size;
815 if (!size)
817 size = 1024;
818 buffer = xmalloc( size );
820 if (!fgets( buffer, size, file )) return NULL;
821 input_line++;
823 for (;;)
825 char *p = buffer + strlen(buffer);
826 /* if line is larger than buffer, resize buffer */
827 while (p == buffer + size - 1 && p[-1] != '\n')
829 buffer = xrealloc( buffer, size * 2 );
830 if (!fgets( buffer + size - 1, size + 1, file )) break;
831 p = buffer + strlen(buffer);
832 size *= 2;
834 if (p > buffer && p[-1] == '\n')
836 *(--p) = 0;
837 if (p > buffer && p[-1] == '\r') *(--p) = 0;
838 if (p > buffer && p[-1] == '\\')
840 *(--p) = 0;
841 /* line ends in backslash, read continuation line */
842 if (!fgets( p, size - (p - buffer), file )) return buffer;
843 input_line++;
844 continue;
847 return buffer;
852 /*******************************************************************
853 * hash_filename
855 static unsigned int hash_filename( const char *name )
857 /* FNV-1 hash */
858 unsigned int ret = 2166136261u;
859 while (*name) ret = (ret * 16777619) ^ *name++;
860 return ret % HASH_SIZE;
864 /*******************************************************************
865 * add_file
867 static struct file *add_file( const char *name )
869 struct file *file = xmalloc( sizeof(*file) );
870 memset( file, 0, sizeof(*file) );
871 file->name = xstrdup( name );
872 return file;
876 /*******************************************************************
877 * add_dependency
879 static void add_dependency( struct file *file, const char *name, enum incl_type type )
881 /* enforce some rules for the Wine tree */
883 if (!memcmp( name, "../", 3 ))
884 fatal_error( "#include directive with relative path not allowed\n" );
886 if (!strcmp( name, "config.h" ))
888 if (strendswith( file->name, ".h" ))
889 fatal_error( "config.h must not be included by a header file\n" );
890 if (file->deps_count)
891 fatal_error( "config.h must be included before anything else\n" );
893 else if (!strcmp( name, "wine/port.h" ))
895 if (strendswith( file->name, ".h" ))
896 fatal_error( "wine/port.h must not be included by a header file\n" );
897 if (!file->deps_count) fatal_error( "config.h must be included before wine/port.h\n" );
898 if (file->deps_count > 1)
899 fatal_error( "wine/port.h must be included before everything except config.h\n" );
900 if (strcmp( file->deps[0].name, "config.h" ))
901 fatal_error( "config.h must be included before wine/port.h\n" );
904 if (file->deps_count >= file->deps_size)
906 file->deps_size *= 2;
907 if (file->deps_size < 16) file->deps_size = 16;
908 file->deps = xrealloc( file->deps, file->deps_size * sizeof(*file->deps) );
910 file->deps[file->deps_count].line = input_line;
911 file->deps[file->deps_count].type = type;
912 file->deps[file->deps_count].name = xstrdup( name );
913 file->deps_count++;
917 /*******************************************************************
918 * find_src_file
920 static struct incl_file *find_src_file( const struct makefile *make, const char *name )
922 struct incl_file *file;
924 LIST_FOR_EACH_ENTRY( file, &make->sources, struct incl_file, entry )
925 if (!strcmp( name, file->name )) return file;
926 return NULL;
929 /*******************************************************************
930 * find_include_file
932 static struct incl_file *find_include_file( const struct makefile *make, const char *name )
934 struct incl_file *file;
936 LIST_FOR_EACH_ENTRY( file, &make->includes, struct incl_file, entry )
937 if (!strcmp( name, file->name )) return file;
938 return NULL;
941 /*******************************************************************
942 * add_include
944 * Add an include file if it doesn't already exists.
946 static struct incl_file *add_include( struct makefile *make, struct incl_file *parent,
947 const char *name, int line, enum incl_type type )
949 struct incl_file *include;
951 if (parent->files_count >= parent->files_size)
953 parent->files_size *= 2;
954 if (parent->files_size < 16) parent->files_size = 16;
955 parent->files = xrealloc( parent->files, parent->files_size * sizeof(*parent->files) );
958 LIST_FOR_EACH_ENTRY( include, &make->includes, struct incl_file, entry )
959 if (!parent->use_msvcrt == !include->use_msvcrt && !strcmp( name, include->name ))
960 goto found;
962 include = xmalloc( sizeof(*include) );
963 memset( include, 0, sizeof(*include) );
964 include->name = xstrdup(name);
965 include->included_by = parent;
966 include->included_line = line;
967 include->type = type;
968 include->use_msvcrt = parent->use_msvcrt;
969 list_add_tail( &make->includes, &include->entry );
970 found:
971 parent->files[parent->files_count++] = include;
972 return include;
976 /*******************************************************************
977 * add_generated_source
979 * Add a generated source file to the list.
981 static struct incl_file *add_generated_source( struct makefile *make,
982 const char *name, const char *filename )
984 struct incl_file *file;
986 if ((file = find_src_file( make, name ))) return file; /* we already have it */
987 file = xmalloc( sizeof(*file) );
988 memset( file, 0, sizeof(*file) );
989 file->file = add_file( name );
990 file->name = xstrdup( name );
991 file->basename = xstrdup( filename ? filename : name );
992 file->filename = obj_dir_path( make, file->basename );
993 file->file->flags = FLAG_GENERATED;
994 file->use_msvcrt = make->use_msvcrt;
995 list_add_tail( &make->sources, &file->entry );
996 return file;
1000 /*******************************************************************
1001 * parse_include_directive
1003 static void parse_include_directive( struct file *source, char *str )
1005 char quote, *include, *p = str;
1007 while (*p && isspace(*p)) p++;
1008 if (*p != '\"' && *p != '<' ) return;
1009 quote = *p++;
1010 if (quote == '<') quote = '>';
1011 include = p;
1012 while (*p && (*p != quote)) p++;
1013 if (!*p) fatal_error( "malformed include directive '%s'\n", str );
1014 *p = 0;
1015 add_dependency( source, include, (quote == '>') ? INCL_SYSTEM : INCL_NORMAL );
1019 /*******************************************************************
1020 * parse_pragma_directive
1022 static void parse_pragma_directive( struct file *source, char *str )
1024 char *flag, *p = str;
1026 if (!isspace( *p )) return;
1027 while (*p && isspace(*p)) p++;
1028 p = strtok( p, " \t" );
1029 if (strcmp( p, "makedep" )) return;
1031 while ((flag = strtok( NULL, " \t" )))
1033 if (!strcmp( flag, "depend" ))
1035 while ((p = strtok( NULL, " \t" ))) add_dependency( source, p, INCL_NORMAL );
1036 return;
1038 else if (!strcmp( flag, "install" )) source->flags |= FLAG_INSTALL;
1040 if (strendswith( source->name, ".idl" ))
1042 if (!strcmp( flag, "header" )) source->flags |= FLAG_IDL_HEADER;
1043 else if (!strcmp( flag, "proxy" )) source->flags |= FLAG_IDL_PROXY;
1044 else if (!strcmp( flag, "client" )) source->flags |= FLAG_IDL_CLIENT;
1045 else if (!strcmp( flag, "server" )) source->flags |= FLAG_IDL_SERVER;
1046 else if (!strcmp( flag, "ident" )) source->flags |= FLAG_IDL_IDENT;
1047 else if (!strcmp( flag, "typelib" )) source->flags |= FLAG_IDL_TYPELIB;
1048 else if (!strcmp( flag, "register" )) source->flags |= FLAG_IDL_REGISTER;
1049 else if (!strcmp( flag, "regtypelib" )) source->flags |= FLAG_IDL_REGTYPELIB;
1051 else if (strendswith( source->name, ".rc" ))
1053 if (!strcmp( flag, "po" )) source->flags |= FLAG_RC_PO;
1055 else if (strendswith( source->name, ".sfd" ))
1057 if (!strcmp( flag, "font" ))
1059 struct strarray *array = source->args;
1061 if (!array)
1063 source->args = array = xmalloc( sizeof(*array) );
1064 *array = empty_strarray;
1065 source->flags |= FLAG_SFD_FONTS;
1067 strarray_add( array, xstrdup( strtok( NULL, "" )));
1068 return;
1071 else
1073 if (!strcmp( flag, "implib" )) source->flags |= FLAG_C_IMPLIB;
1074 if (!strcmp( flag, "unix" )) source->flags |= FLAG_C_UNIX;
1080 /*******************************************************************
1081 * parse_cpp_directive
1083 static void parse_cpp_directive( struct file *source, char *str )
1085 while (*str && isspace(*str)) str++;
1086 if (*str++ != '#') return;
1087 while (*str && isspace(*str)) str++;
1089 if (!strncmp( str, "include", 7 ))
1090 parse_include_directive( source, str + 7 );
1091 else if (!strncmp( str, "import", 6 ) && strendswith( source->name, ".m" ))
1092 parse_include_directive( source, str + 6 );
1093 else if (!strncmp( str, "pragma", 6 ))
1094 parse_pragma_directive( source, str + 6 );
1098 /*******************************************************************
1099 * parse_idl_file
1101 static void parse_idl_file( struct file *source, FILE *file )
1103 char *buffer, *include;
1105 input_line = 0;
1107 while ((buffer = get_line( file )))
1109 char quote;
1110 char *p = buffer;
1111 while (*p && isspace(*p)) p++;
1113 if (!strncmp( p, "importlib", 9 ))
1115 p += 9;
1116 while (*p && isspace(*p)) p++;
1117 if (*p++ != '(') continue;
1118 while (*p && isspace(*p)) p++;
1119 if (*p++ != '"') continue;
1120 include = p;
1121 while (*p && (*p != '"')) p++;
1122 if (!*p) fatal_error( "malformed importlib directive\n" );
1123 *p = 0;
1124 add_dependency( source, include, INCL_IMPORTLIB );
1125 continue;
1128 if (!strncmp( p, "import", 6 ))
1130 p += 6;
1131 while (*p && isspace(*p)) p++;
1132 if (*p != '"') continue;
1133 include = ++p;
1134 while (*p && (*p != '"')) p++;
1135 if (!*p) fatal_error( "malformed import directive\n" );
1136 *p = 0;
1137 add_dependency( source, include, INCL_IMPORT );
1138 continue;
1141 /* check for #include inside cpp_quote */
1142 if (!strncmp( p, "cpp_quote", 9 ))
1144 p += 9;
1145 while (*p && isspace(*p)) p++;
1146 if (*p++ != '(') continue;
1147 while (*p && isspace(*p)) p++;
1148 if (*p++ != '"') continue;
1149 if (*p++ != '#') continue;
1150 while (*p && isspace(*p)) p++;
1151 if (strncmp( p, "include", 7 )) continue;
1152 p += 7;
1153 while (*p && isspace(*p)) p++;
1154 if (*p == '\\' && p[1] == '"')
1156 p += 2;
1157 quote = '"';
1159 else
1161 if (*p++ != '<' ) continue;
1162 quote = '>';
1164 include = p;
1165 while (*p && (*p != quote)) p++;
1166 if (!*p || (quote == '"' && p[-1] != '\\'))
1167 fatal_error( "malformed #include directive inside cpp_quote\n" );
1168 if (quote == '"') p--; /* remove backslash */
1169 *p = 0;
1170 add_dependency( source, include, (quote == '>') ? INCL_CPP_QUOTE_SYSTEM : INCL_CPP_QUOTE );
1171 continue;
1174 parse_cpp_directive( source, p );
1178 /*******************************************************************
1179 * parse_c_file
1181 static void parse_c_file( struct file *source, FILE *file )
1183 char *buffer;
1185 input_line = 0;
1186 while ((buffer = get_line( file )))
1188 parse_cpp_directive( source, buffer );
1193 /*******************************************************************
1194 * parse_rc_file
1196 static void parse_rc_file( struct file *source, FILE *file )
1198 char *buffer, *include;
1200 input_line = 0;
1201 while ((buffer = get_line( file )))
1203 char quote;
1204 char *p = buffer;
1205 while (*p && isspace(*p)) p++;
1207 if (p[0] == '/' && p[1] == '*') /* check for magic makedep comment */
1209 p += 2;
1210 while (*p && isspace(*p)) p++;
1211 if (strncmp( p, "@makedep:", 9 )) continue;
1212 p += 9;
1213 while (*p && isspace(*p)) p++;
1214 quote = '"';
1215 if (*p == quote)
1217 include = ++p;
1218 while (*p && *p != quote) p++;
1220 else
1222 include = p;
1223 while (*p && !isspace(*p) && *p != '*') p++;
1225 if (!*p)
1226 fatal_error( "malformed makedep comment\n" );
1227 *p = 0;
1228 add_dependency( source, include, (quote == '>') ? INCL_SYSTEM : INCL_NORMAL );
1229 continue;
1232 parse_cpp_directive( source, buffer );
1237 /*******************************************************************
1238 * parse_in_file
1240 static void parse_in_file( struct file *source, FILE *file )
1242 char *p, *buffer;
1244 /* make sure it gets rebuilt when the version changes */
1245 add_dependency( source, "config.h", INCL_SYSTEM );
1247 if (!strendswith( source->name, ".man.in" )) return; /* not a man page */
1249 input_line = 0;
1250 while ((buffer = get_line( file )))
1252 if (strncmp( buffer, ".TH", 3 )) continue;
1253 if (!(p = strtok( buffer, " \t" ))) continue; /* .TH */
1254 if (!(p = strtok( NULL, " \t" ))) continue; /* program name */
1255 if (!(p = strtok( NULL, " \t" ))) continue; /* man section */
1256 source->args = xstrdup( p );
1257 return;
1262 /*******************************************************************
1263 * parse_sfd_file
1265 static void parse_sfd_file( struct file *source, FILE *file )
1267 char *p, *eol, *buffer;
1269 input_line = 0;
1270 while ((buffer = get_line( file )))
1272 if (strncmp( buffer, "UComments:", 10 )) continue;
1273 p = buffer + 10;
1274 while (*p == ' ') p++;
1275 if (p[0] == '"' && p[1] && buffer[strlen(buffer) - 1] == '"')
1277 p++;
1278 buffer[strlen(buffer) - 1] = 0;
1280 while ((eol = strstr( p, "+AAoA" )))
1282 *eol = 0;
1283 while (*p && isspace(*p)) p++;
1284 if (*p++ == '#')
1286 while (*p && isspace(*p)) p++;
1287 if (!strncmp( p, "pragma", 6 )) parse_pragma_directive( source, p + 6 );
1289 p = eol + 5;
1291 while (*p && isspace(*p)) p++;
1292 if (*p++ != '#') return;
1293 while (*p && isspace(*p)) p++;
1294 if (!strncmp( p, "pragma", 6 )) parse_pragma_directive( source, p + 6 );
1295 return;
1300 static const struct
1302 const char *ext;
1303 void (*parse)( struct file *file, FILE *f );
1304 } parse_functions[] =
1306 { ".c", parse_c_file },
1307 { ".h", parse_c_file },
1308 { ".inl", parse_c_file },
1309 { ".l", parse_c_file },
1310 { ".m", parse_c_file },
1311 { ".rh", parse_c_file },
1312 { ".x", parse_c_file },
1313 { ".y", parse_c_file },
1314 { ".idl", parse_idl_file },
1315 { ".rc", parse_rc_file },
1316 { ".in", parse_in_file },
1317 { ".sfd", parse_sfd_file }
1320 /*******************************************************************
1321 * load_file
1323 static struct file *load_file( const char *name )
1325 struct file *file;
1326 FILE *f;
1327 unsigned int i, hash = hash_filename( name );
1329 LIST_FOR_EACH_ENTRY( file, &files[hash], struct file, entry )
1330 if (!strcmp( name, file->name )) return file;
1332 if (!(f = fopen( name, "r" ))) return NULL;
1334 file = add_file( name );
1335 list_add_tail( &files[hash], &file->entry );
1336 input_file_name = file->name;
1337 input_line = 0;
1339 for (i = 0; i < sizeof(parse_functions) / sizeof(parse_functions[0]); i++)
1341 if (!strendswith( name, parse_functions[i].ext )) continue;
1342 parse_functions[i].parse( file, f );
1343 break;
1346 fclose( f );
1347 input_file_name = NULL;
1349 return file;
1353 /*******************************************************************
1354 * open_include_path_file
1356 * Open a file from a directory on the include path.
1358 static struct file *open_include_path_file( const struct makefile *make, const char *dir,
1359 const char *name, char **filename )
1361 char *src_path = concat_paths( dir, name );
1362 struct file *ret = load_file( src_path );
1364 if (ret) *filename = src_path;
1365 return ret;
1369 /*******************************************************************
1370 * open_file_same_dir
1372 * Open a file in the same directory as the parent.
1374 static struct file *open_file_same_dir( const struct incl_file *parent, const char *name, char **filename )
1376 char *src_path = replace_filename( parent->file->name, name );
1377 struct file *ret = load_file( src_path );
1379 if (ret) *filename = replace_filename( parent->filename, name );
1380 return ret;
1384 /*******************************************************************
1385 * open_local_file
1387 * Open a file in the source directory of the makefile.
1389 static struct file *open_local_file( const struct makefile *make, const char *path, char **filename )
1391 char *src_path = src_dir_path( make, path );
1392 struct file *ret = load_file( src_path );
1394 /* if not found, try parent dir */
1395 if (!ret && make->parent_dir)
1397 free( src_path );
1398 path = strmake( "%s/%s", make->parent_dir, path );
1399 src_path = src_dir_path( make, path );
1400 ret = load_file( src_path );
1403 if (ret) *filename = src_path;
1404 return ret;
1408 /*******************************************************************
1409 * open_global_file
1411 * Open a file in the top-level source directory.
1413 static struct file *open_global_file( const struct makefile *make, const char *path, char **filename )
1415 char *src_path = root_src_dir_path( path );
1416 struct file *ret = load_file( src_path );
1418 if (ret) *filename = src_path;
1419 return ret;
1423 /*******************************************************************
1424 * open_global_header
1426 * Open a file in the global include source directory.
1428 static struct file *open_global_header( const struct makefile *make, const char *path, char **filename )
1430 return open_global_file( make, strmake( "include/%s", path ), filename );
1434 /*******************************************************************
1435 * open_src_file
1437 static struct file *open_src_file( const struct makefile *make, struct incl_file *pFile )
1439 struct file *file = open_local_file( make, pFile->name, &pFile->filename );
1441 if (!file) fatal_perror( "open %s", pFile->name );
1442 return file;
1446 /*******************************************************************
1447 * open_include_file
1449 static struct file *open_include_file( const struct makefile *make, struct incl_file *pFile )
1451 struct file *file = NULL;
1452 char *filename;
1453 unsigned int i, len;
1455 errno = ENOENT;
1457 /* check for generated bison header */
1459 if (strendswith( pFile->name, ".tab.h" ) &&
1460 (file = open_local_file( make, replace_extension( pFile->name, ".tab.h", ".y" ), &filename )))
1462 pFile->sourcename = filename;
1463 pFile->filename = obj_dir_path( make, pFile->name );
1464 return file;
1467 /* check for corresponding idl file in source dir */
1469 if (strendswith( pFile->name, ".h" ) &&
1470 (file = open_local_file( make, replace_extension( pFile->name, ".h", ".idl" ), &filename )))
1472 pFile->sourcename = filename;
1473 pFile->filename = obj_dir_path( make, pFile->name );
1474 return file;
1477 /* check for corresponding tlb file in source dir */
1479 if (strendswith( pFile->name, ".tlb" ) &&
1480 (file = open_local_file( make, replace_extension( pFile->name, ".tlb", ".idl" ), &filename )))
1482 pFile->sourcename = filename;
1483 pFile->filename = obj_dir_path( make, pFile->name );
1484 return file;
1487 /* check for extra targets */
1488 if (strarray_exists( &make->extra_targets, pFile->name ))
1490 pFile->sourcename = src_dir_path( make, pFile->name );
1491 pFile->filename = obj_dir_path( make, pFile->name );
1492 return NULL;
1495 /* now try in source dir */
1496 if ((file = open_local_file( make, pFile->name, &pFile->filename ))) return file;
1498 /* check for corresponding idl file in global includes */
1500 if (strendswith( pFile->name, ".h" ) &&
1501 (file = open_global_header( make, replace_extension( pFile->name, ".h", ".idl" ), &filename )))
1503 pFile->sourcename = filename;
1504 pFile->filename = strmake( "include/%s", pFile->name );
1505 return file;
1508 /* check for corresponding .in file in global includes (for config.h.in) */
1510 if (strendswith( pFile->name, ".h" ) &&
1511 (file = open_global_header( make, replace_extension( pFile->name, ".h", ".h.in" ), &filename )))
1513 pFile->sourcename = filename;
1514 pFile->filename = strmake( "include/%s", pFile->name );
1515 return file;
1518 /* check for corresponding .x file in global includes */
1520 if (strendswith( pFile->name, "tmpl.h" ) &&
1521 (file = open_global_header( make, replace_extension( pFile->name, ".h", ".x" ), &filename )))
1523 pFile->sourcename = filename;
1524 pFile->filename = strmake( "include/%s", pFile->name );
1525 return file;
1528 /* check for corresponding .tlb file in global includes */
1530 if (strendswith( pFile->name, ".tlb" ) &&
1531 (file = open_global_header( make, replace_extension( pFile->name, ".tlb", ".idl" ), &filename )))
1533 pFile->sourcename = filename;
1534 pFile->filename = strmake( "include/%s", pFile->name );
1535 return file;
1538 /* check in global includes source dir */
1540 if ((file = open_global_header( make, pFile->name, &pFile->filename ))) return file;
1542 /* check in global msvcrt includes */
1543 if (pFile->use_msvcrt &&
1544 (file = open_global_header( make, strmake( "msvcrt/%s", pFile->name ), &pFile->filename )))
1545 return file;
1547 /* now search in include paths */
1548 for (i = 0; i < make->include_paths.count; i++)
1550 const char *dir = make->include_paths.str[i];
1552 if (root_src_dir)
1554 len = strlen( root_src_dir );
1555 if (!strncmp( dir, root_src_dir, len ) && (!dir[len] || dir[len] == '/'))
1557 while (dir[len] == '/') len++;
1558 file = open_global_file( make, concat_paths( dir + len, pFile->name ), &pFile->filename );
1559 if (file) return file;
1561 continue; /* ignore paths that don't point to the top source dir */
1563 if (*dir != '/')
1565 if ((file = open_include_path_file( make, dir, pFile->name, &pFile->filename )))
1566 return file;
1570 if (pFile->type == INCL_SYSTEM && pFile->use_msvcrt)
1572 if (!strcmp( pFile->name, "stdarg.h" )) return NULL;
1573 if (!strcmp( pFile->name, "x86intrin.h" )) return NULL;
1574 fprintf( stderr, "%s:%d: error: system header %s cannot be used with msvcrt\n",
1575 pFile->included_by->file->name, pFile->included_line, pFile->name );
1576 exit(1);
1579 if (pFile->type == INCL_SYSTEM) return NULL; /* ignore system files we cannot find */
1581 /* try in src file directory */
1582 if ((file = open_file_same_dir( pFile->included_by, pFile->name, &pFile->filename ))) return file;
1584 fprintf( stderr, "%s:%d: error: ", pFile->included_by->file->name, pFile->included_line );
1585 perror( pFile->name );
1586 pFile = pFile->included_by;
1587 while (pFile && pFile->included_by)
1589 const char *parent = pFile->included_by->sourcename;
1590 if (!parent) parent = pFile->included_by->file->name;
1591 fprintf( stderr, "%s:%d: note: %s was first included here\n",
1592 parent, pFile->included_line, pFile->name );
1593 pFile = pFile->included_by;
1595 exit(1);
1599 /*******************************************************************
1600 * add_all_includes
1602 static void add_all_includes( struct makefile *make, struct incl_file *parent, struct file *file )
1604 unsigned int i;
1606 parent->files_count = 0;
1607 parent->files_size = file->deps_count;
1608 parent->files = xmalloc( parent->files_size * sizeof(*parent->files) );
1609 for (i = 0; i < file->deps_count; i++)
1611 switch (file->deps[i].type)
1613 case INCL_NORMAL:
1614 case INCL_IMPORT:
1615 add_include( make, parent, file->deps[i].name, file->deps[i].line, INCL_NORMAL );
1616 break;
1617 case INCL_IMPORTLIB:
1618 add_include( make, parent, file->deps[i].name, file->deps[i].line, INCL_IMPORTLIB );
1619 break;
1620 case INCL_SYSTEM:
1621 add_include( make, parent, file->deps[i].name, file->deps[i].line, INCL_SYSTEM );
1622 break;
1623 case INCL_CPP_QUOTE:
1624 case INCL_CPP_QUOTE_SYSTEM:
1625 break;
1631 /*******************************************************************
1632 * parse_file
1634 static void parse_file( struct makefile *make, struct incl_file *source, int src )
1636 struct file *file = src ? open_src_file( make, source ) : open_include_file( make, source );
1638 if (!file) return;
1640 source->file = file;
1641 source->files_count = 0;
1642 source->files_size = file->deps_count;
1643 source->files = xmalloc( source->files_size * sizeof(*source->files) );
1644 if (file->flags & FLAG_C_UNIX) source->use_msvcrt = 0;
1645 else if (file->flags & FLAG_C_IMPLIB) source->use_msvcrt = 1;
1647 if (source->sourcename)
1649 if (strendswith( source->sourcename, ".idl" ))
1651 unsigned int i;
1653 if (strendswith( source->name, ".tlb" )) return; /* typelibs don't include anything */
1655 /* generated .h file always includes these */
1656 add_include( make, source, "rpc.h", 0, INCL_NORMAL );
1657 add_include( make, source, "rpcndr.h", 0, INCL_NORMAL );
1658 for (i = 0; i < file->deps_count; i++)
1660 switch (file->deps[i].type)
1662 case INCL_IMPORT:
1663 if (strendswith( file->deps[i].name, ".idl" ))
1664 add_include( make, source, replace_extension( file->deps[i].name, ".idl", ".h" ),
1665 file->deps[i].line, INCL_NORMAL );
1666 else
1667 add_include( make, source, file->deps[i].name, file->deps[i].line, INCL_NORMAL );
1668 break;
1669 case INCL_CPP_QUOTE:
1670 add_include( make, source, file->deps[i].name, file->deps[i].line, INCL_NORMAL );
1671 break;
1672 case INCL_CPP_QUOTE_SYSTEM:
1673 add_include( make, source, file->deps[i].name, file->deps[i].line, INCL_SYSTEM );
1674 break;
1675 case INCL_NORMAL:
1676 case INCL_SYSTEM:
1677 case INCL_IMPORTLIB:
1678 break;
1681 return;
1683 if (strendswith( source->sourcename, ".y" ))
1684 return; /* generated .tab.h doesn't include anything */
1687 add_all_includes( make, source, file );
1691 /*******************************************************************
1692 * add_src_file
1694 * Add a source file to the list.
1696 static struct incl_file *add_src_file( struct makefile *make, const char *name )
1698 struct incl_file *file;
1700 if ((file = find_src_file( make, name ))) return file; /* we already have it */
1701 file = xmalloc( sizeof(*file) );
1702 memset( file, 0, sizeof(*file) );
1703 file->name = xstrdup(name);
1704 file->use_msvcrt = make->use_msvcrt;
1705 list_add_tail( &make->sources, &file->entry );
1706 parse_file( make, file, 1 );
1707 return file;
1711 /*******************************************************************
1712 * open_input_makefile
1714 static FILE *open_input_makefile( const struct makefile *make )
1716 FILE *ret;
1718 if (make->obj_dir)
1719 input_file_name = root_src_dir_path( obj_dir_path( make, strmake( "%s.in", output_makefile_name )));
1720 else
1721 input_file_name = output_makefile_name; /* always use output name for main Makefile */
1723 input_line = 0;
1724 if (!(ret = fopen( input_file_name, "r" ))) fatal_perror( "open" );
1725 return ret;
1729 /*******************************************************************
1730 * get_make_variable
1732 static const char *get_make_variable( const struct makefile *make, const char *name )
1734 const char *ret;
1736 if ((ret = strarray_get_value( &cmdline_vars, name ))) return ret;
1737 if ((ret = strarray_get_value( &make->vars, name ))) return ret;
1738 if (top_makefile && (ret = strarray_get_value( &top_makefile->vars, name ))) return ret;
1739 return NULL;
1743 /*******************************************************************
1744 * get_expanded_make_variable
1746 static char *get_expanded_make_variable( const struct makefile *make, const char *name )
1748 const char *var;
1749 char *p, *end, *expand, *tmp;
1751 var = get_make_variable( make, name );
1752 if (!var) return NULL;
1754 p = expand = xstrdup( var );
1755 while ((p = strchr( p, '$' )))
1757 if (p[1] == '(')
1759 if (!(end = strchr( p + 2, ')' ))) fatal_error( "syntax error in '%s'\n", expand );
1760 *end++ = 0;
1761 if (strchr( p + 2, ':' )) fatal_error( "pattern replacement not supported for '%s'\n", p + 2 );
1762 var = get_make_variable( make, p + 2 );
1763 tmp = replace_substr( expand, p, end - p, var ? var : "" );
1764 /* switch to the new string */
1765 p = tmp + (p - expand);
1766 free( expand );
1767 expand = tmp;
1769 else if (p[1] == '{') /* don't expand ${} variables */
1771 if (!(end = strchr( p + 2, '}' ))) fatal_error( "syntax error in '%s'\n", expand );
1772 p = end + 1;
1774 else if (p[1] == '$')
1776 p += 2;
1778 else fatal_error( "syntax error in '%s'\n", expand );
1781 /* consider empty variables undefined */
1782 p = expand;
1783 while (*p && isspace(*p)) p++;
1784 if (*p) return expand;
1785 free( expand );
1786 return NULL;
1790 /*******************************************************************
1791 * get_expanded_make_var_array
1793 static struct strarray get_expanded_make_var_array( const struct makefile *make, const char *name )
1795 struct strarray ret = empty_strarray;
1796 char *value, *token;
1798 if ((value = get_expanded_make_variable( make, name )))
1799 for (token = strtok( value, " \t" ); token; token = strtok( NULL, " \t" ))
1800 strarray_add( &ret, token );
1801 return ret;
1805 /*******************************************************************
1806 * get_expanded_file_local_var
1808 static struct strarray get_expanded_file_local_var( const struct makefile *make, const char *file,
1809 const char *name )
1811 char *p, *var = strmake( "%s_%s", file, name );
1813 for (p = var; *p; p++) if (!isalnum( *p )) *p = '_';
1814 return get_expanded_make_var_array( make, var );
1818 /*******************************************************************
1819 * set_make_variable
1821 static int set_make_variable( struct strarray *array, const char *assignment )
1823 char *p, *name;
1825 p = name = xstrdup( assignment );
1826 while (isalnum(*p) || *p == '_') p++;
1827 if (name == p) return 0; /* not a variable */
1828 if (isspace(*p))
1830 *p++ = 0;
1831 while (isspace(*p)) p++;
1833 if (*p != '=') return 0; /* not an assignment */
1834 *p++ = 0;
1835 while (isspace(*p)) p++;
1837 strarray_set_value( array, name, p );
1838 return 1;
1842 /*******************************************************************
1843 * parse_makefile
1845 static struct makefile *parse_makefile( const char *path )
1847 char *buffer;
1848 FILE *file;
1849 struct makefile *make = xmalloc( sizeof(*make) );
1851 memset( make, 0, sizeof(*make) );
1852 make->obj_dir = path;
1853 if (root_src_dir) make->src_dir = root_src_dir_path( make->obj_dir );
1855 file = open_input_makefile( make );
1856 while ((buffer = get_line( file )))
1858 if (!strncmp( buffer, separator, strlen(separator) )) break;
1859 if (*buffer == '\t') continue; /* command */
1860 while (isspace( *buffer )) buffer++;
1861 if (*buffer == '#') continue; /* comment */
1862 set_make_variable( &make->vars, buffer );
1864 fclose( file );
1865 input_file_name = NULL;
1866 return make;
1870 /*******************************************************************
1871 * add_generated_sources
1873 static void add_generated_sources( struct makefile *make )
1875 unsigned int i;
1876 struct incl_file *source, *next, *file;
1877 struct strarray objs = get_expanded_make_var_array( make, "EXTRA_OBJS" );
1879 LIST_FOR_EACH_ENTRY_SAFE( source, next, &make->sources, struct incl_file, entry )
1881 if (source->file->flags & FLAG_IDL_CLIENT)
1883 file = add_generated_source( make, replace_extension( source->name, ".idl", "_c.c" ), NULL );
1884 add_dependency( file->file, replace_extension( source->name, ".idl", ".h" ), INCL_NORMAL );
1885 add_all_includes( make, file, file->file );
1887 if (source->file->flags & FLAG_IDL_SERVER)
1889 file = add_generated_source( make, replace_extension( source->name, ".idl", "_s.c" ), NULL );
1890 add_dependency( file->file, "wine/exception.h", INCL_NORMAL );
1891 add_dependency( file->file, replace_extension( source->name, ".idl", ".h" ), INCL_NORMAL );
1892 add_all_includes( make, file, file->file );
1894 if (source->file->flags & FLAG_IDL_IDENT)
1896 file = add_generated_source( make, replace_extension( source->name, ".idl", "_i.c" ), NULL );
1897 add_dependency( file->file, "rpc.h", INCL_NORMAL );
1898 add_dependency( file->file, "rpcndr.h", INCL_NORMAL );
1899 add_dependency( file->file, "guiddef.h", INCL_NORMAL );
1900 add_all_includes( make, file, file->file );
1902 if (source->file->flags & FLAG_IDL_PROXY)
1904 file = add_generated_source( make, "dlldata.o", "dlldata.c" );
1905 add_dependency( file->file, "objbase.h", INCL_NORMAL );
1906 add_dependency( file->file, "rpcproxy.h", INCL_NORMAL );
1907 add_all_includes( make, file, file->file );
1908 file = add_generated_source( make, replace_extension( source->name, ".idl", "_p.c" ), NULL );
1909 add_dependency( file->file, "objbase.h", INCL_NORMAL );
1910 add_dependency( file->file, "rpcproxy.h", INCL_NORMAL );
1911 add_dependency( file->file, "wine/exception.h", INCL_NORMAL );
1912 add_dependency( file->file, replace_extension( source->name, ".idl", ".h" ), INCL_NORMAL );
1913 add_all_includes( make, file, file->file );
1915 if (source->file->flags & FLAG_IDL_TYPELIB)
1917 add_generated_source( make, replace_extension( source->name, ".idl", ".tlb" ), NULL );
1919 if (source->file->flags & FLAG_IDL_REGTYPELIB)
1921 add_generated_source( make, replace_extension( source->name, ".idl", "_t.res" ), NULL );
1923 if (source->file->flags & FLAG_IDL_REGISTER)
1925 add_generated_source( make, replace_extension( source->name, ".idl", "_r.res" ), NULL );
1927 if (source->file->flags & FLAG_IDL_HEADER)
1929 add_generated_source( make, replace_extension( source->name, ".idl", ".h" ), NULL );
1931 if (!source->file->flags && strendswith( source->name, ".idl" ))
1933 add_generated_source( make, replace_extension( source->name, ".idl", ".h" ), NULL );
1935 if (strendswith( source->name, ".x" ))
1937 add_generated_source( make, replace_extension( source->name, ".x", ".h" ), NULL );
1939 if (strendswith( source->name, ".y" ))
1941 file = add_generated_source( make, replace_extension( source->name, ".y", ".tab.c" ), NULL );
1942 /* steal the includes list from the source file */
1943 file->files_count = source->files_count;
1944 file->files_size = source->files_size;
1945 file->files = source->files;
1946 source->files_count = source->files_size = 0;
1947 source->files = NULL;
1949 if (strendswith( source->name, ".l" ))
1951 file = add_generated_source( make, replace_extension( source->name, ".l", ".yy.c" ), NULL );
1952 /* steal the includes list from the source file */
1953 file->files_count = source->files_count;
1954 file->files_size = source->files_size;
1955 file->files = source->files;
1956 source->files_count = source->files_size = 0;
1957 source->files = NULL;
1959 if (source->file->flags & FLAG_C_IMPLIB)
1961 if (!make->staticimplib && make->importlib && *dll_ext)
1962 make->staticimplib = strmake( "lib%s.a", make->importlib );
1964 if (strendswith( source->name, ".po" ))
1966 if (!make->disabled)
1967 strarray_add_uniq( &linguas, replace_extension( source->name, ".po", "" ));
1969 if (strendswith( source->name, ".spec" ))
1971 char *obj = replace_extension( source->name, ".spec", "" );
1972 strarray_addall_uniq( &make->extra_imports,
1973 get_expanded_file_local_var( make, obj, "IMPORTS" ));
1976 if (make->testdll)
1978 file = add_generated_source( make, "testlist.o", "testlist.c" );
1979 add_dependency( file->file, "wine/test.h", INCL_NORMAL );
1980 add_all_includes( make, file, file->file );
1982 for (i = 0; i < objs.count; i++)
1984 /* default to .c for unknown extra object files */
1985 if (strendswith( objs.str[i], ".o" ))
1987 file = add_generated_source( make, objs.str[i], replace_extension( objs.str[i], ".o", ".c" ));
1988 if (make->module || make->staticlib) file->file->flags |= FLAG_C_UNIX;
1990 else if (strendswith( objs.str[i], ".res" ))
1991 add_generated_source( make, replace_extension( objs.str[i], ".res", ".rc" ), NULL );
1992 else
1993 add_generated_source( make, objs.str[i], NULL );
1998 /*******************************************************************
1999 * create_dir
2001 static void create_dir( const char *dir )
2003 char *p, *path;
2005 p = path = xstrdup( dir );
2006 while ((p = strchr( p, '/' )))
2008 *p = 0;
2009 if (mkdir( path, 0755 ) == -1 && errno != EEXIST) fatal_perror( "mkdir %s", path );
2010 *p++ = '/';
2011 while (*p == '/') p++;
2013 if (mkdir( path, 0755 ) == -1 && errno != EEXIST) fatal_perror( "mkdir %s", path );
2014 free( path );
2018 /*******************************************************************
2019 * create_file_directories
2021 * Create the base directories of all the files.
2023 static void create_file_directories( const struct makefile *make, struct strarray files )
2025 struct strarray subdirs = empty_strarray;
2026 unsigned int i;
2027 char *dir;
2029 for (i = 0; i < files.count; i++)
2031 if (!strchr( files.str[i], '/' )) continue;
2032 dir = obj_dir_path( make, files.str[i] );
2033 *strrchr( dir, '/' ) = 0;
2034 strarray_add_uniq( &subdirs, dir );
2037 for (i = 0; i < subdirs.count; i++) create_dir( subdirs.str[i] );
2041 /*******************************************************************
2042 * output_filenames_obj_dir
2044 static void output_filenames_obj_dir( const struct makefile *make, struct strarray array )
2046 unsigned int i;
2048 for (i = 0; i < array.count; i++) output_filename( obj_dir_path( make, array.str[i] ));
2052 /*******************************************************************
2053 * get_dependencies
2055 static void get_dependencies( struct incl_file *file, struct incl_file *source )
2057 unsigned int i;
2059 if (!file->filename) return;
2061 if (file != source)
2063 if (file->owner == source) return; /* already processed */
2064 if (file->type == INCL_IMPORTLIB &&
2065 !(source->file->flags & (FLAG_IDL_TYPELIB | FLAG_IDL_REGTYPELIB)))
2066 return; /* library is imported only when building a typelib */
2067 file->owner = source;
2068 strarray_add( &source->dependencies, file->filename );
2070 for (i = 0; i < file->files_count; i++) get_dependencies( file->files[i], source );
2074 /*******************************************************************
2075 * get_local_dependencies
2077 * Get the local dependencies of a given target.
2079 static struct strarray get_local_dependencies( const struct makefile *make, const char *name,
2080 struct strarray targets )
2082 unsigned int i;
2083 struct strarray deps = get_expanded_file_local_var( make, name, "DEPS" );
2085 for (i = 0; i < deps.count; i++)
2087 if (strarray_exists( &targets, deps.str[i] ))
2088 deps.str[i] = obj_dir_path( make, deps.str[i] );
2089 else
2090 deps.str[i] = src_dir_path( make, deps.str[i] );
2092 return deps;
2096 /*******************************************************************
2097 * get_static_lib
2099 * Check if makefile builds the named static library and return the full lib path.
2101 static const char *get_static_lib( const struct makefile *make, const char *name )
2103 if (!make->staticlib) return NULL;
2104 if (strncmp( make->staticlib, "lib", 3 )) return NULL;
2105 if (strncmp( make->staticlib + 3, name, strlen(name) )) return NULL;
2106 if (strcmp( make->staticlib + 3 + strlen(name), ".a" )) return NULL;
2107 return obj_dir_path( make, make->staticlib );
2111 /*******************************************************************
2112 * get_parent_makefile
2114 static struct makefile *get_parent_makefile( struct makefile *make )
2116 char *dir, *p;
2117 int i;
2119 if (!make->obj_dir) return NULL;
2120 dir = xstrdup( make->obj_dir );
2121 if (!(p = strrchr( dir, '/' ))) return NULL;
2122 *p = 0;
2123 for (i = 0; i < subdirs.count; i++)
2124 if (!strcmp( submakes[i]->obj_dir, dir )) return submakes[i];
2125 return NULL;
2129 /*******************************************************************
2130 * needs_cross_lib
2132 static int needs_cross_lib( const struct makefile *make )
2134 const char *name;
2135 if (!crosstarget) return 0;
2136 if (make->importlib) name = make->importlib;
2137 else if (make->staticlib)
2139 name = replace_extension( make->staticlib, ".a", "" );
2140 if (!strncmp( name, "lib", 3 )) name += 3;
2142 else return 0;
2143 if (strarray_exists( &cross_import_libs, name )) return 1;
2144 if (delay_load_flag && strarray_exists( &delay_import_libs, name )) return 1;
2145 return 0;
2149 /*******************************************************************
2150 * needs_delay_lib
2152 static int needs_delay_lib( const struct makefile *make )
2154 if (delay_load_flag) return 0;
2155 if (*dll_ext && !crosstarget) return 0;
2156 if (!make->importlib) return 0;
2157 return strarray_exists( &delay_import_libs, make->importlib );
2161 /*******************************************************************
2162 * needs_implib_symlink
2164 static int needs_implib_symlink( const struct makefile *make )
2166 if (!make->module) return 0;
2167 if (!make->importlib) return 0;
2168 if (make->is_win16 && make->disabled) return 0;
2169 if (strncmp( make->obj_dir, "dlls/", 5 )) return 0;
2170 if (!strcmp( make->module, make->importlib )) return 0;
2171 if (!strchr( make->importlib, '.' ) &&
2172 !strncmp( make->module, make->importlib, strlen( make->importlib )) &&
2173 !strcmp( make->module + strlen( make->importlib ), ".dll" ))
2174 return 0;
2175 return 1;
2179 /*******************************************************************
2180 * add_unix_libraries
2182 static struct strarray add_unix_libraries( const struct makefile *make, struct strarray *deps )
2184 struct strarray ret = empty_strarray;
2185 struct strarray all_libs = empty_strarray;
2186 unsigned int i, j;
2188 strarray_add( &all_libs, "-lwine_port" );
2189 strarray_addall( &all_libs, get_expanded_make_var_array( make, "EXTRALIBS" ));
2190 strarray_addall( &all_libs, libs );
2192 for (i = 0; i < all_libs.count; i++)
2194 const char *lib = NULL;
2196 if (!strncmp( all_libs.str[i], "-l", 2 ))
2198 const char *name = all_libs.str[i] + 2;
2200 for (j = 0; j < subdirs.count; j++)
2201 if ((lib = get_static_lib( submakes[j], name ))) break;
2204 if (lib)
2206 strarray_add( deps, lib );
2207 strarray_add( &ret, lib );
2209 else strarray_add( &ret, all_libs.str[i] );
2211 return ret;
2215 /*******************************************************************
2216 * add_import_libs
2218 static struct strarray add_import_libs( const struct makefile *make, struct strarray *deps,
2219 struct strarray imports, int delay, int is_unix )
2221 struct strarray ret = empty_strarray;
2222 unsigned int i, j;
2223 int is_cross = make->is_cross && !is_unix;
2225 for (i = 0; i < imports.count; i++)
2227 const char *name = get_base_name( imports.str[i] );
2228 const char *lib = NULL;
2230 for (j = 0; j < subdirs.count; j++)
2232 if (submakes[j]->importlib && !strcmp( submakes[j]->importlib, name ))
2234 if (is_cross || !*dll_ext || submakes[j]->staticimplib)
2235 lib = obj_dir_path( submakes[j], strmake( "lib%s.a", name ));
2236 else
2238 strarray_add( deps, strmake( "%s/lib%s.def", submakes[j]->obj_dir, name ));
2239 if (needs_implib_symlink( submakes[j] ))
2240 strarray_add( deps, strmake( "dlls/lib%s.def", name ));
2242 break;
2245 if ((lib = get_static_lib( submakes[j], name ))) break;
2248 if (lib)
2250 const char *ext = NULL;
2252 if (delay && !delay_load_flag && (is_cross || !*dll_ext)) ext = ".delay.a";
2253 else if (is_cross) ext = ".cross.a";
2254 if (ext) lib = replace_extension( lib, ".a", ext );
2255 strarray_add( deps, lib );
2256 strarray_add( &ret, lib );
2257 if (needs_implib_symlink( submakes[j] ))
2258 strarray_add( deps, strmake( "dlls/lib%s%s", name, ext ? ext : ".a" ));
2260 else strarray_add( &ret, strmake( "-l%s", name ));
2262 return ret;
2266 /*******************************************************************
2267 * get_default_imports
2269 static struct strarray get_default_imports( const struct makefile *make )
2271 struct strarray ret = empty_strarray;
2273 if (strarray_exists( &make->extradllflags, "-nodefaultlibs" )) return ret;
2274 strarray_add( &ret, "winecrt0" );
2275 if (make->is_win16) strarray_add( &ret, "kernel" );
2276 strarray_add( &ret, "kernel32" );
2277 strarray_add( &ret, "ntdll" );
2278 return ret;
2282 /*******************************************************************
2283 * is_crt_module
2285 static int is_crt_module( const char *file )
2287 return !strncmp( file, "msvcr", 5 ) || !strncmp( file, "ucrt", 4 ) || !strcmp( file, "crtdll.dll" );
2291 /*******************************************************************
2292 * add_crt_import
2294 static void add_crt_import( const struct makefile *make, struct strarray *imports, struct strarray *defs )
2296 unsigned int i;
2297 const char *crt_dll = NULL;
2299 for (i = 0; i < imports->count; i++)
2301 if (!is_crt_module( imports->str[i])) continue;
2302 if (crt_dll) fatal_error( "More than one C runtime DLL imported: %s and %s\n", crt_dll, imports->str[i] );
2303 crt_dll = imports->str[i];
2305 if (!crt_dll && !strarray_exists( &make->extradllflags, "-nodefaultlibs" ))
2307 if (make->module && is_crt_module( make->module ))
2309 crt_dll = make->module;
2311 else
2313 crt_dll = !make->testdll && !make->staticlib ? "ucrtbase" : "msvcrt";
2314 strarray_add( imports, crt_dll );
2318 if (!defs) return;
2319 if (crt_dll && !strncmp( crt_dll, "ucrt", 4 )) strarray_add( defs, "-D_UCRT" );
2320 else
2322 unsigned int version = 0;
2323 if (crt_dll) sscanf( crt_dll, "msvcr%u", &version );
2324 strarray_add( defs, strmake( "-D_MSVCR_VER=%u", version ));
2329 /*******************************************************************
2330 * add_install_rule
2332 static void add_install_rule( struct makefile *make, const char *target,
2333 const char *file, const char *dest )
2335 if (strarray_exists( &make->install_lib, target ) ||
2336 strarray_exists( &top_install_lib, make->obj_dir ) ||
2337 strarray_exists( &top_install_lib, obj_dir_path( make, target )))
2339 strarray_add( &make->install_rules[INSTALL_LIB], file );
2340 strarray_add( &make->install_rules[INSTALL_LIB], dest );
2342 else if (strarray_exists( &make->install_dev, target ) ||
2343 strarray_exists( &top_install_dev, make->obj_dir ) ||
2344 strarray_exists( &top_install_dev, obj_dir_path( make, target )))
2346 strarray_add( &make->install_rules[INSTALL_DEV], file );
2347 strarray_add( &make->install_rules[INSTALL_DEV], dest );
2352 /*******************************************************************
2353 * get_include_install_path
2355 * Determine the installation path for a given include file.
2357 static const char *get_include_install_path( const char *name )
2359 if (!strncmp( name, "wine/", 5 )) return name + 5;
2360 if (!strncmp( name, "msvcrt/", 7 )) return name;
2361 return strmake( "windows/%s", name );
2365 /*******************************************************************
2366 * get_shared_library_name
2368 * Determine possible names for a shared library with a version number.
2370 static struct strarray get_shared_lib_names( const char *libname )
2372 struct strarray ret = empty_strarray;
2373 const char *ext, *p;
2374 char *name, *first, *second;
2375 size_t len = 0;
2377 strarray_add( &ret, libname );
2379 for (p = libname; (p = strchr( p, '.' )); p++)
2380 if ((len = strspn( p + 1, "0123456789." ))) break;
2382 if (!len) return ret;
2383 ext = p + 1 + len;
2384 if (*ext && ext[-1] == '.') ext--;
2386 /* keep only the first group of digits */
2387 name = xstrdup( libname );
2388 first = name + (p - libname);
2389 if ((second = strchr( first + 1, '.' )))
2391 strcpy( second, ext );
2392 strarray_add( &ret, xstrdup( name ));
2394 return ret;
2398 /*******************************************************************
2399 * get_source_defines
2401 static struct strarray get_source_defines( struct makefile *make, struct incl_file *source,
2402 const char *obj )
2404 unsigned int i;
2405 struct strarray ret = empty_strarray;
2407 strarray_addall( &ret, make->include_args );
2408 if (source->use_msvcrt)
2409 strarray_add( &ret, strmake( "-I%s", root_src_dir_path( "include/msvcrt" )));
2410 for (i = 0; i < make->include_paths.count; i++)
2411 strarray_add( &ret, strmake( "-I%s", make->include_paths.str[i] ));
2412 strarray_addall( &ret, make->define_args );
2413 strarray_addall( &ret, get_expanded_file_local_var( make, obj, "EXTRADEFS" ));
2414 if ((source->file->flags & FLAG_C_UNIX) && *dll_ext) strarray_add( &ret, "-DWINE_UNIX_LIB" );
2415 return ret;
2419 /*******************************************************************
2420 * get_debug_file
2422 static const char *get_debug_file( struct makefile *make, const char *name )
2424 const char *debug_file = NULL;
2425 if (!make->is_cross || !crossdebug) return NULL;
2426 if (!strcmp( crossdebug, "pdb" )) debug_file = strmake( "%s.pdb", get_base_name( name ));
2427 else if(!strncmp( crossdebug, "split", 5 )) debug_file = strmake( "%s.debug", name );
2428 if (debug_file) strarray_add( &make->debug_files, debug_file );
2429 return debug_file;
2433 /*******************************************************************
2434 * cmd_prefix
2436 static const char *cmd_prefix( const char *cmd )
2438 if (!silent_rules) return "";
2439 return strmake( "$(quiet_%s)", cmd );
2443 /*******************************************************************
2444 * output_winegcc_command
2446 static void output_winegcc_command( struct makefile *make, int is_cross )
2448 output( "\t%s%s -o $@", cmd_prefix( "CCLD" ), tools_path( make, "winegcc" ));
2449 output_filename( "--wine-objdir ." );
2450 if (tools_dir)
2452 output_filename( "--winebuild" );
2453 output_filename( tools_path( make, "winebuild" ));
2455 if (is_cross)
2457 output_filename( "-b" );
2458 output_filename( crosstarget );
2459 output_filename( "--lib-suffix=.cross.a" );
2461 else
2463 output_filenames( target_flags );
2464 output_filenames( lddll_flags );
2469 /*******************************************************************
2470 * output_symlink_rule
2472 * Output a rule to create a symlink.
2474 static void output_symlink_rule( const char *src_name, const char *link_name, int create_dir )
2476 const char *name = strrchr( link_name, '/' );
2477 char *dir = NULL;
2479 if (name)
2481 dir = xstrdup( link_name );
2482 dir[name - link_name] = 0;
2485 output( "\t%s", cmd_prefix( "LN" ));
2486 if (create_dir && dir && *dir) output( "%s -d %s && ", root_src_dir_path( "tools/install-sh" ), dir );
2487 output( "rm -f %s && ", link_name );
2489 /* dest path with a directory needs special handling if ln -s isn't supported */
2490 if (dir && strcmp( ln_s, "ln -s" ))
2491 output( "cd %s && %s %s %s\n", *dir ? dir : "/", ln_s, src_name, name + 1 );
2492 else
2493 output( "%s %s %s\n", ln_s, src_name, link_name );
2495 free( dir );
2499 /*******************************************************************
2500 * output_srcdir_symlink
2502 * Output rule to create a symlink back to the source directory, for source files
2503 * that are needed at run-time.
2505 static void output_srcdir_symlink( struct makefile *make, const char *obj )
2507 char *src_file, *dst_file, *src_name;
2509 if (!make->src_dir) return;
2510 src_file = src_dir_path( make, obj );
2511 dst_file = obj_dir_path( make, obj );
2512 output( "%s: %s\n", dst_file, src_file );
2514 src_name = src_file;
2515 if (src_name[0] != '/' && make->obj_dir)
2516 src_name = concat_paths( get_relative_path( make->obj_dir, "" ), src_name );
2518 output_symlink_rule( src_name, dst_file, 0 );
2519 strarray_add( &make->all_targets, obj );
2523 /*******************************************************************
2524 * output_install_commands
2526 static void output_install_commands( struct makefile *make, struct strarray files )
2528 unsigned int i;
2529 char *install_sh = root_src_dir_path( "tools/install-sh" );
2531 for (i = 0; i < files.count; i += 2)
2533 const char *file = files.str[i];
2534 const char *dest = strmake( "$(DESTDIR)%s", files.str[i + 1] + 1 );
2536 switch (*files.str[i + 1])
2538 case 'c': /* cross-compiled program */
2539 output( "\tSTRIPPROG=%s-strip %s -m 644 $(INSTALL_PROGRAM_FLAGS) %s %s\n",
2540 crosstarget, install_sh, obj_dir_path( make, file ), dest );
2541 output( "\t%s --builtin %s\n", tools_path( make, "winebuild" ), dest );
2542 break;
2543 case 'd': /* data file */
2544 output( "\t%s -m 644 $(INSTALL_DATA_FLAGS) %s %s\n",
2545 install_sh, obj_dir_path( make, file ), dest );
2546 break;
2547 case 'D': /* data file in source dir */
2548 output( "\t%s -m 644 $(INSTALL_DATA_FLAGS) %s %s\n",
2549 install_sh, src_dir_path( make, file ), dest );
2550 break;
2551 case 'p': /* program file */
2552 output( "\tSTRIPPROG=\"$(STRIP)\" %s $(INSTALL_PROGRAM_FLAGS) %s %s\n",
2553 install_sh, obj_dir_path( make, file ), dest );
2554 break;
2555 case 's': /* script */
2556 output( "\t%s $(INSTALL_SCRIPT_FLAGS) %s %s\n",
2557 install_sh, obj_dir_path( make, file ), dest );
2558 break;
2559 case 'S': /* script in source dir */
2560 output( "\t%s $(INSTALL_SCRIPT_FLAGS) %s %s\n",
2561 install_sh, src_dir_path( make, file ), dest );
2562 break;
2563 case 't': /* script in tools dir */
2564 output( "\t%s $(INSTALL_SCRIPT_FLAGS) %s %s\n",
2565 install_sh, tools_dir_path( make, files.str[i] ), dest );
2566 break;
2567 case 'y': /* symlink */
2568 output_symlink_rule( files.str[i], dest, 1 );
2569 break;
2570 default:
2571 assert(0);
2573 strarray_add( &make->uninstall_files, dest );
2578 /*******************************************************************
2579 * output_install_rules
2581 * Rules are stored as a (file,dest) pair of values.
2582 * The first char of dest indicates the type of install.
2584 static void output_install_rules( struct makefile *make, enum install_rules rules, const char *target )
2586 unsigned int i;
2587 struct strarray files = make->install_rules[rules];
2588 struct strarray targets = empty_strarray;
2590 if (!files.count) return;
2592 for (i = 0; i < files.count; i += 2)
2594 const char *file = files.str[i];
2595 switch (*files.str[i + 1])
2597 case 'c': /* cross-compiled program */
2598 case 'd': /* data file */
2599 case 'p': /* program file */
2600 case 's': /* script */
2601 strarray_add_uniq( &targets, obj_dir_path( make, file ));
2602 break;
2603 case 't': /* script in tools dir */
2604 strarray_add_uniq( &targets, tools_dir_path( make, file ));
2605 break;
2609 output( "%s %s::", obj_dir_path( make, "install" ), obj_dir_path( make, target ));
2610 output_filenames( targets );
2611 output( "\n" );
2612 output_install_commands( make, files );
2613 strarray_add_uniq( &make->phony_targets, obj_dir_path( make, "install" ));
2614 strarray_add_uniq( &make->phony_targets, obj_dir_path( make, target ));
2618 static int cmp_string_length( const char **a, const char **b )
2620 int paths_a = 0, paths_b = 0;
2621 const char *p;
2623 for (p = *a; *p; p++) if (*p == '/') paths_a++;
2624 for (p = *b; *p; p++) if (*p == '/') paths_b++;
2625 if (paths_b != paths_a) return paths_b - paths_a;
2626 return strcmp( *a, *b );
2629 /*******************************************************************
2630 * output_uninstall_rules
2632 static void output_uninstall_rules( struct makefile *make )
2634 static const char *dirs_order[] =
2635 { "$(includedir)", "$(mandir)", "$(fontdir)", "$(datadir)", "$(dlldir)" };
2637 struct strarray uninstall_dirs = empty_strarray;
2638 unsigned int i, j;
2640 if (!make->uninstall_files.count) return;
2641 output( "uninstall::\n" );
2642 output_rm_filenames( make->uninstall_files );
2643 strarray_add_uniq( &make->phony_targets, "uninstall" );
2645 if (!subdirs.count) return;
2646 for (i = 0; i < make->uninstall_files.count; i++)
2648 char *dir = xstrdup( make->uninstall_files.str[i] );
2649 while (strchr( dir, '/' ))
2651 *strrchr( dir, '/' ) = 0;
2652 strarray_add_uniq( &uninstall_dirs, xstrdup(dir) );
2655 strarray_qsort( &uninstall_dirs, cmp_string_length );
2656 output( "\t-rmdir" );
2657 for (i = 0; i < sizeof(dirs_order)/sizeof(dirs_order[0]); i++)
2659 for (j = 0; j < uninstall_dirs.count; j++)
2661 if (!uninstall_dirs.str[j]) continue;
2662 if (strncmp( uninstall_dirs.str[j] + strlen("$(DESTDIR)"), dirs_order[i], strlen(dirs_order[i]) ))
2663 continue;
2664 output_filename( uninstall_dirs.str[j] );
2665 uninstall_dirs.str[j] = NULL;
2668 for (j = 0; j < uninstall_dirs.count; j++)
2669 if (uninstall_dirs.str[j]) output_filename( uninstall_dirs.str[j] );
2670 output( "\n" );
2674 /*******************************************************************
2675 * output_importlib_symlinks
2677 static struct strarray output_importlib_symlinks( const struct makefile *make )
2679 struct strarray ret = empty_strarray;
2680 const char *lib, *dst, *ext[4];
2681 int i, count = 0;
2683 ext[count++] = (*dll_ext && !make->implib_objs.count) ? "def" : "a";
2684 if (needs_delay_lib( make )) ext[count++] = "delay.a";
2685 if (needs_cross_lib( make )) ext[count++] = "cross.a";
2687 for (i = 0; i < count; i++)
2689 lib = strmake( "lib%s.%s", make->importlib, ext[i] );
2690 dst = strmake( "dlls/%s", lib );
2691 output( "%s: %s\n", dst, obj_dir_path( make, lib ));
2692 output_symlink_rule( concat_paths( make->obj_dir + strlen("dlls/"), lib ), dst, 0 );
2693 strarray_add( &ret, dst );
2695 return ret;
2699 /*******************************************************************
2700 * output_po_files
2702 static void output_po_files( const struct makefile *make )
2704 const char *po_dir = src_dir_path( make, "po" );
2705 unsigned int i;
2707 if (linguas.count)
2709 for (i = 0; i < linguas.count; i++)
2710 output_filename( strmake( "%s/%s.po", po_dir, linguas.str[i] ));
2711 output( ": %s/wine.pot\n", po_dir );
2712 output( "\t%smsgmerge --previous -q $@ %s/wine.pot | msgattrib --no-obsolete -o $@.new && mv $@.new $@\n",
2713 cmd_prefix( "MSG" ), po_dir );
2714 output( "po:" );
2715 for (i = 0; i < linguas.count; i++)
2716 output_filename( strmake( "%s/%s.po", po_dir, linguas.str[i] ));
2717 output( "\n" );
2719 output( "%s/wine.pot:", po_dir );
2720 output_filenames( make->pot_files );
2721 output( "\n" );
2722 output( "\t%smsgcat -o $@", cmd_prefix( "MSG" ));
2723 output_filenames( make->pot_files );
2724 output( "\n" );
2728 /*******************************************************************
2729 * output_source_y
2731 static void output_source_y( struct makefile *make, struct incl_file *source, const char *obj )
2733 /* add source file dependency for parallel makes */
2734 char *header = strmake( "%s.tab.h", obj );
2736 if (find_include_file( make, header ))
2738 output( "%s: %s\n", obj_dir_path( make, header ), source->filename );
2739 output( "\t%s%s -p %s_ -o %s.tab.c -d %s\n",
2740 cmd_prefix( "BISON" ), bison, obj, obj_dir_path( make, obj ), source->filename );
2741 output( "%s.tab.c: %s %s\n", obj_dir_path( make, obj ),
2742 source->filename, obj_dir_path( make, header ));
2743 strarray_add( &make->clean_files, header );
2745 else output( "%s.tab.c: %s\n", obj_dir_path( make, obj ), source->filename );
2747 output( "\t%s%s -p %s_ -o $@ %s\n", cmd_prefix( "BISON" ), bison, obj, source->filename );
2751 /*******************************************************************
2752 * output_source_l
2754 static void output_source_l( struct makefile *make, struct incl_file *source, const char *obj )
2756 output( "%s.yy.c: %s\n", obj_dir_path( make, obj ), source->filename );
2757 output( "\t%s%s -o$@ %s\n", cmd_prefix( "FLEX" ), flex, source->filename );
2761 /*******************************************************************
2762 * output_source_h
2764 static void output_source_h( struct makefile *make, struct incl_file *source, const char *obj )
2766 if (source->file->flags & FLAG_GENERATED)
2767 strarray_add( &make->all_targets, source->name );
2768 else
2769 add_install_rule( make, source->name, source->name,
2770 strmake( "D$(includedir)/wine/%s", get_include_install_path( source->name ) ));
2774 /*******************************************************************
2775 * output_source_rc
2777 static void output_source_rc( struct makefile *make, struct incl_file *source, const char *obj )
2779 struct strarray defines = get_source_defines( make, source, obj );
2780 const char *po_dir = NULL;
2781 unsigned int i;
2783 if (source->file->flags & FLAG_GENERATED) strarray_add( &make->clean_files, source->name );
2784 if (linguas.count && (source->file->flags & FLAG_RC_PO)) po_dir = "po";
2785 strarray_add( &make->res_files, strmake( "%s.res", obj ));
2786 if (source->file->flags & FLAG_RC_PO)
2788 strarray_add( &make->pot_files, strmake( "%s.pot", obj ));
2789 output( "%s.pot ", obj_dir_path( make, obj ) );
2791 output( "%s.res: %s", obj_dir_path( make, obj ), source->filename );
2792 output_filename( tools_path( make, "wrc" ));
2793 output_filenames( source->dependencies );
2794 output( "\n" );
2795 output( "\t%s%s -u -o $@", cmd_prefix( "WRC" ), tools_path( make, "wrc" ) );
2796 if (make->is_win16) output_filename( "-m16" );
2797 else output_filenames( target_flags );
2798 output_filename( "--nostdinc" );
2799 if (po_dir) output_filename( strmake( "--po-dir=%s", po_dir ));
2800 output_filenames( defines );
2801 output_filename( source->filename );
2802 output( "\n" );
2803 if (po_dir)
2805 output( "%s.res:", obj_dir_path( make, obj ));
2806 for (i = 0; i < linguas.count; i++)
2807 output_filename( strmake( "%s/%s.mo", po_dir, linguas.str[i] ));
2808 output( "\n" );
2813 /*******************************************************************
2814 * output_source_mc
2816 static void output_source_mc( struct makefile *make, struct incl_file *source, const char *obj )
2818 unsigned int i;
2819 char *obj_path = obj_dir_path( make, obj );
2821 strarray_add( &make->res_files, strmake( "%s.res", obj ));
2822 strarray_add( &make->pot_files, strmake( "%s.pot", obj ));
2823 output( "%s.pot %s.res: %s", obj_path, obj_path, source->filename );
2824 output_filename( tools_path( make, "wmc" ));
2825 output_filenames( source->dependencies );
2826 output( "\n" );
2827 output( "\t%s%s -u -o $@ %s", cmd_prefix( "WMC" ), tools_path( make, "wmc" ), source->filename );
2828 if (linguas.count)
2830 output_filename( "--po-dir=po" );
2831 output( "\n" );
2832 output( "%s.res:", obj_dir_path( make, obj ));
2833 for (i = 0; i < linguas.count; i++)
2834 output_filename( strmake( "po/%s.mo", linguas.str[i] ));
2836 output( "\n" );
2840 /*******************************************************************
2841 * output_source_res
2843 static void output_source_res( struct makefile *make, struct incl_file *source, const char *obj )
2845 strarray_add( &make->res_files, source->name );
2849 /*******************************************************************
2850 * output_source_idl
2852 static void output_source_idl( struct makefile *make, struct incl_file *source, const char *obj )
2854 struct strarray defines = get_source_defines( make, source, obj );
2855 struct strarray targets = empty_strarray;
2856 char *dest;
2857 unsigned int i;
2859 if (!source->file->flags) source->file->flags |= FLAG_IDL_HEADER | FLAG_INSTALL;
2860 if (find_include_file( make, strmake( "%s.h", obj ))) source->file->flags |= FLAG_IDL_HEADER;
2862 for (i = 0; i < sizeof(idl_outputs) / sizeof(idl_outputs[0]); i++)
2864 if (!(source->file->flags & idl_outputs[i].flag)) continue;
2865 dest = strmake( "%s%s", obj, idl_outputs[i].ext );
2866 if (!find_src_file( make, dest )) strarray_add( &make->clean_files, dest );
2867 strarray_add( &targets, dest );
2869 if (source->file->flags & FLAG_IDL_PROXY) strarray_add( &make->dlldata_files, source->name );
2870 if (source->file->flags & FLAG_INSTALL)
2872 add_install_rule( make, source->name, xstrdup( source->name ),
2873 strmake( "D$(includedir)/wine/%s.idl", get_include_install_path( obj ) ));
2874 if (source->file->flags & FLAG_IDL_HEADER)
2875 add_install_rule( make, source->name, strmake( "%s.h", obj ),
2876 strmake( "d$(includedir)/wine/%s.h", get_include_install_path( obj ) ));
2877 if (source->file->flags & FLAG_IDL_TYPELIB)
2878 add_install_rule( make, source->name, strmake( "%s.tlb", obj ),
2879 strmake( "d$(includedir)/wine/%s.tlb", get_include_install_path( obj ) ));
2881 if (!targets.count) return;
2883 output_filenames_obj_dir( make, targets );
2884 output( ": %s\n", tools_path( make, "widl" ));
2885 output( "\t%s%s -o $@", cmd_prefix( "WIDL" ), tools_path( make, "widl" ) );
2886 output_filenames( target_flags );
2887 output_filename( "--nostdinc" );
2888 output_filenames( defines );
2889 output_filenames( get_expanded_make_var_array( make, "EXTRAIDLFLAGS" ));
2890 output_filenames( get_expanded_file_local_var( make, obj, "EXTRAIDLFLAGS" ));
2891 output_filename( source->filename );
2892 output( "\n" );
2893 output_filenames_obj_dir( make, targets );
2894 output( ": %s", source->filename );
2895 output_filenames( source->dependencies );
2896 output( "\n" );
2900 /*******************************************************************
2901 * output_source_tlb
2903 static void output_source_tlb( struct makefile *make, struct incl_file *source, const char *obj )
2905 strarray_add( &make->all_targets, source->name );
2909 /*******************************************************************
2910 * output_source_x
2912 static void output_source_x( struct makefile *make, struct incl_file *source, const char *obj )
2914 output( "%s.h: %s%s %s\n", obj_dir_path( make, obj ),
2915 tools_dir_path( make, "make_xftmpl" ), tools_ext, source->filename );
2916 output( "\t%s%s%s -H -o $@ %s\n", cmd_prefix( "GEN" ),
2917 tools_dir_path( make, "make_xftmpl" ), tools_ext, source->filename );
2918 if (source->file->flags & FLAG_INSTALL)
2920 add_install_rule( make, source->name, source->name,
2921 strmake( "D$(includedir)/wine/%s", get_include_install_path( source->name ) ));
2922 add_install_rule( make, source->name, strmake( "%s.h", obj ),
2923 strmake( "d$(includedir)/wine/%s.h", get_include_install_path( obj ) ));
2928 /*******************************************************************
2929 * output_source_sfd
2931 static void output_source_sfd( struct makefile *make, struct incl_file *source, const char *obj )
2933 unsigned int i;
2934 char *ttf_obj = strmake( "%s.ttf", obj );
2935 char *ttf_file = src_dir_path( make, ttf_obj );
2937 if (fontforge && !make->src_dir)
2939 output( "%s: %s\n", ttf_file, source->filename );
2940 output( "\t%s%s -script %s %s $@\n", cmd_prefix( "GEN" ),
2941 fontforge, root_src_dir_path( "fonts/genttf.ff" ), source->filename );
2942 if (!(source->file->flags & FLAG_SFD_FONTS)) strarray_add( &make->font_files, ttf_obj );
2944 if (source->file->flags & FLAG_INSTALL)
2946 add_install_rule( make, source->name, ttf_obj, strmake( "D$(fontdir)/%s", ttf_obj ));
2947 output_srcdir_symlink( make, ttf_obj );
2950 if (source->file->flags & FLAG_SFD_FONTS)
2952 struct strarray *array = source->file->args;
2954 for (i = 0; i < array->count; i++)
2956 char *font = strtok( xstrdup(array->str[i]), " \t" );
2957 char *args = strtok( NULL, "" );
2959 strarray_add( &make->all_targets, xstrdup( font ));
2960 output( "%s: %s %s\n", obj_dir_path( make, font ),
2961 tools_path( make, "sfnt2fon" ), ttf_file );
2962 output( "\t%s%s -q -o $@ %s %s\n", cmd_prefix( "GEN" ),
2963 tools_path( make, "sfnt2fon" ), ttf_file, args );
2964 add_install_rule( make, source->name, xstrdup(font), strmake( "d$(fontdir)/%s", font ));
2970 /*******************************************************************
2971 * output_source_svg
2973 static void output_source_svg( struct makefile *make, struct incl_file *source, const char *obj )
2975 static const char * const images[] = { "bmp", "cur", "ico", NULL };
2976 unsigned int i;
2978 if (convert && rsvg && icotool && !make->src_dir)
2980 for (i = 0; images[i]; i++)
2981 if (find_include_file( make, strmake( "%s.%s", obj, images[i] ))) break;
2983 if (images[i])
2985 output( "%s.%s: %s\n", src_dir_path( make, obj ), images[i], source->filename );
2986 output( "\t%sCONVERT=\"%s\" ICOTOOL=\"%s\" RSVG=\"%s\" %s %s $@\n",
2987 cmd_prefix( "GEN" ), convert, icotool, rsvg,
2988 root_src_dir_path( "tools/buildimage" ), source->filename );
2994 /*******************************************************************
2995 * output_source_nls
2997 static void output_source_nls( struct makefile *make, struct incl_file *source, const char *obj )
2999 add_install_rule( make, source->name, source->name,
3000 strmake( "D$(nlsdir)/%s", source->name ));
3001 output_srcdir_symlink( make, strmake( "%s.nls", obj ));
3005 /*******************************************************************
3006 * output_source_desktop
3008 static void output_source_desktop( struct makefile *make, struct incl_file *source, const char *obj )
3010 add_install_rule( make, source->name, source->name,
3011 strmake( "D$(datadir)/applications/%s", source->name ));
3015 /*******************************************************************
3016 * output_source_po
3018 static void output_source_po( struct makefile *make, struct incl_file *source, const char *obj )
3020 output( "%s.mo: %s\n", obj_dir_path( make, obj ), source->filename );
3021 output( "\t%s%s -o $@ %s\n", cmd_prefix( "MSG" ), msgfmt, source->filename );
3022 strarray_add( &make->all_targets, strmake( "%s.mo", obj ));
3026 /*******************************************************************
3027 * output_source_in
3029 static void output_source_in( struct makefile *make, struct incl_file *source, const char *obj )
3031 unsigned int i;
3033 if (strendswith( obj, ".man" ) && source->file->args)
3035 struct strarray symlinks;
3036 char *dir, *dest = replace_extension( obj, ".man", "" );
3037 char *lang = strchr( dest, '.' );
3038 char *section = source->file->args;
3039 if (lang)
3041 *lang++ = 0;
3042 dir = strmake( "$(mandir)/%s/man%s", lang, section );
3044 else dir = strmake( "$(mandir)/man%s", section );
3045 add_install_rule( make, dest, xstrdup(obj), strmake( "d%s/%s.%s", dir, dest, section ));
3046 symlinks = get_expanded_file_local_var( make, dest, "SYMLINKS" );
3047 for (i = 0; i < symlinks.count; i++)
3048 add_install_rule( make, symlinks.str[i], strmake( "%s.%s", dest, section ),
3049 strmake( "y%s/%s.%s", dir, symlinks.str[i], section ));
3050 free( dest );
3051 free( dir );
3053 strarray_add( &make->in_files, xstrdup(obj) );
3054 strarray_add( &make->all_targets, xstrdup(obj) );
3055 output( "%s: %s\n", obj_dir_path( make, obj ), source->filename );
3056 output( "\t%s%s %s >$@ || (rm -f $@ && false)\n", cmd_prefix( "SED" ), sed_cmd, source->filename );
3057 output( "%s:", obj_dir_path( make, obj ));
3058 output_filenames( source->dependencies );
3059 output( "\n" );
3060 add_install_rule( make, obj, xstrdup( obj ), strmake( "d$(datadir)/wine/%s", obj ));
3064 /*******************************************************************
3065 * output_source_spec
3067 static void output_source_spec( struct makefile *make, struct incl_file *source, const char *obj )
3069 struct strarray imports = get_expanded_file_local_var( make, obj, "IMPORTS" );
3070 struct strarray dll_flags = get_expanded_file_local_var( make, obj, "EXTRADLLFLAGS" );
3071 struct strarray all_libs, dep_libs = empty_strarray;
3072 char *dll_name, *obj_name, *output_file;
3073 const char *debug_file;
3075 if (!imports.count) imports = make->imports;
3076 else if (make->use_msvcrt) add_crt_import( make, &imports, NULL );
3078 if (!dll_flags.count) dll_flags = make->extradllflags;
3079 all_libs = add_import_libs( make, &dep_libs, imports, 0, 0 );
3080 add_import_libs( make, &dep_libs, get_default_imports( make ), 0, 0 ); /* dependencies only */
3081 dll_name = strmake( "%s.dll%s", obj, make->is_cross ? "" : dll_ext );
3082 obj_name = strmake( "%s%s", obj_dir_path( make, obj ), make->is_cross ? ".cross.o" : ".o" );
3083 output_file = obj_dir_path( make, dll_name );
3085 strarray_add( &make->clean_files, dll_name );
3086 strarray_add( &make->res_files, strmake( "%s.res", obj ));
3087 output( "%s.res:", obj_dir_path( make, obj ));
3088 output_filename( obj_dir_path( make, dll_name ));
3089 output_filename( tools_path( make, "wrc" ));
3090 output( "\n" );
3091 output( "\t%secho \"%s.dll TESTDLL \\\"%s\\\"\" | %s -u -o $@\n", cmd_prefix( "WRC" ), obj, output_file,
3092 tools_path( make, "wrc" ));
3094 output( "%s:", output_file);
3095 output_filename( source->filename );
3096 output_filename( obj_name );
3097 output_filenames( dep_libs );
3098 output_filename( tools_path( make, "winebuild" ));
3099 output_filename( tools_path( make, "winegcc" ));
3100 output( "\n" );
3101 output_winegcc_command( make, make->is_cross );
3102 output_filename( "-s" );
3103 output_filenames( dll_flags );
3104 output_filename( "-shared" );
3105 output_filename( source->filename );
3106 output_filename( obj_name );
3107 if ((debug_file = get_debug_file( make, dll_name )))
3108 output_filename( strmake( "-Wl,--debug-file,%s", obj_dir_path( make, debug_file )));
3109 output_filenames( all_libs );
3110 output_filename( make->is_cross ? "$(CROSSLDFLAGS)" : "$(LDFLAGS)" );
3111 output( "\n" );
3115 /*******************************************************************
3116 * output_source_default
3118 static void output_source_default( struct makefile *make, struct incl_file *source, const char *obj )
3120 struct strarray defines = get_source_defines( make, source, obj );
3121 int is_dll_src = (make->testdll &&
3122 strendswith( source->name, ".c" ) &&
3123 find_src_file( make, replace_extension( source->name, ".c", ".spec" )));
3124 int need_cross = (crosstarget &&
3125 !(source->file->flags & FLAG_C_UNIX) &&
3126 (make->is_cross ||
3127 ((source->file->flags & FLAG_C_IMPLIB) &&
3128 (needs_cross_lib( make ) || needs_delay_lib( make ))) ||
3129 (make->staticlib && needs_cross_lib( make ))));
3130 int need_obj = ((*dll_ext || !(source->file->flags & FLAG_C_UNIX)) &&
3131 (!need_cross ||
3132 (source->file->flags & FLAG_C_IMPLIB) ||
3133 (make->module && make->staticlib)));
3135 if ((source->file->flags & FLAG_GENERATED) &&
3136 (!make->testdll || !strendswith( source->filename, "testlist.c" )))
3137 strarray_add( &make->clean_files, source->basename );
3138 if (source->file->flags & FLAG_C_IMPLIB) strarray_add( &make->implib_objs, strmake( "%s.o", obj ));
3140 if (need_obj)
3142 if ((source->file->flags & FLAG_C_UNIX) && *dll_ext)
3143 strarray_add( &make->unixobj_files, strmake( "%s.o", obj ));
3144 else if (!is_dll_src && !(source->file->flags & FLAG_C_IMPLIB))
3145 strarray_add( &make->object_files, strmake( "%s.o", obj ));
3146 else
3147 strarray_add( &make->clean_files, strmake( "%s.o", obj ));
3148 output( "%s.o: %s\n", obj_dir_path( make, obj ), source->filename );
3149 output( "\t%s$(CC) -c -o $@ %s", cmd_prefix( "CC" ), source->filename );
3150 output_filenames( defines );
3151 if (make->module || make->staticlib || make->sharedlib || make->testdll)
3153 output_filenames( dll_flags );
3154 if (source->use_msvcrt) output_filenames( msvcrt_flags );
3156 output_filenames( extra_cflags );
3157 output_filenames( cpp_flags );
3158 output_filename( "$(CFLAGS)" );
3159 output( "\n" );
3161 if (need_cross)
3163 if (!is_dll_src && !(source->file->flags & FLAG_C_IMPLIB))
3164 strarray_add( &make->crossobj_files, strmake( "%s.cross.o", obj ));
3165 else
3166 strarray_add( &make->clean_files, strmake( "%s.cross.o", obj ));
3167 output( "%s.cross.o: %s\n", obj_dir_path( make, obj ), source->filename );
3168 output( "\t%s$(CROSSCC) -c -o $@ %s", cmd_prefix( "CC" ), source->filename );
3169 output_filenames( defines );
3170 output_filenames( extra_cross_cflags );
3171 if (source->file->flags & FLAG_C_IMPLIB || (make->module && is_crt_module( make->module )))
3172 output_filename( "-fno-builtin" );
3173 output_filenames( cpp_flags );
3174 output_filename( "$(CROSSCFLAGS)" );
3175 output( "\n" );
3177 if (strendswith( source->name, ".c" ) && !(source->file->flags & FLAG_GENERATED))
3179 strarray_add( &make->c2man_files, source->filename );
3180 if (make->testdll && !is_dll_src)
3182 strarray_add( &make->ok_files, strmake( "%s.ok", obj ));
3183 output( "%s.ok:\n", obj_dir_path( make, obj ));
3184 output( "\t%s%s $(RUNTESTFLAGS) -T . -M %s -p %s%s %s && touch $@\n",
3185 cmd_prefix( "TEST" ),
3186 root_src_dir_path( "tools/runtest" ), make->testdll,
3187 obj_dir_path( make, replace_extension( make->testdll, ".dll", "_test.exe" )),
3188 make->is_cross ? "" : dll_ext, obj );
3191 if (need_obj) output_filename( strmake( "%s.o", obj_dir_path( make, obj )));
3192 if (need_cross) output_filename( strmake( "%s.cross.o", obj_dir_path( make, obj )));
3193 output( ":" );
3194 output_filenames( source->dependencies );
3195 output( "\n" );
3199 /* dispatch table to output rules for a single source file */
3200 static const struct
3202 const char *ext;
3203 void (*fn)( struct makefile *make, struct incl_file *source, const char *obj );
3204 } output_source_funcs[] =
3206 { "y", output_source_y },
3207 { "l", output_source_l },
3208 { "h", output_source_h },
3209 { "rh", output_source_h },
3210 { "inl", output_source_h },
3211 { "rc", output_source_rc },
3212 { "mc", output_source_mc },
3213 { "res", output_source_res },
3214 { "idl", output_source_idl },
3215 { "tlb", output_source_tlb },
3216 { "sfd", output_source_sfd },
3217 { "svg", output_source_svg },
3218 { "nls", output_source_nls },
3219 { "desktop", output_source_desktop },
3220 { "po", output_source_po },
3221 { "in", output_source_in },
3222 { "x", output_source_x },
3223 { "spec", output_source_spec },
3224 { NULL, output_source_default }
3228 /*******************************************************************
3229 * has_object_file
3231 static int has_object_file( struct makefile *make )
3233 struct incl_file *source;
3234 int i;
3236 LIST_FOR_EACH_ENTRY( source, &make->sources, struct incl_file, entry )
3238 char *ext = get_extension( source->name );
3240 if (!ext) fatal_error( "unsupported file type %s\n", source->name );
3241 ext++;
3243 for (i = 0; output_source_funcs[i].ext; i++)
3244 if (!strcmp( ext, output_source_funcs[i].ext )) break;
3246 if (!output_source_funcs[i].ext) return 1; /* default extension builds to an object file */
3248 return 0;
3252 /*******************************************************************
3253 * output_man_pages
3255 static void output_man_pages( struct makefile *make )
3257 if (make->c2man_files.count)
3259 char *spec_file = src_dir_path( make, replace_extension( make->module, ".dll", ".spec" ));
3261 output( "manpages::\n" );
3262 output( "\t%s -w %s", root_src_dir_path( "tools/c2man.pl" ), spec_file );
3263 output_filename( strmake( "-R%s", root_src_dir_path( "" )));
3264 output_filename( strmake( "-I%s", root_src_dir_path( "include" )));
3265 output_filename( strmake( "-o documentation/man%s", man_ext ));
3266 output_filenames( make->c2man_files );
3267 output( "\n" );
3268 output( "htmlpages::\n" );
3269 output( "\t%s -Th -w %s", root_src_dir_path( "tools/c2man.pl" ), spec_file );
3270 output_filename( strmake( "-R%s", root_src_dir_path( "" )));
3271 output_filename( strmake( "-I%s", root_src_dir_path( "include" )));
3272 output_filename( "-o documentation/html" );
3273 output_filenames( make->c2man_files );
3274 output( "\n" );
3275 output( "sgmlpages::\n" );
3276 output( "\t%s -Ts -w %s", root_src_dir_path( "tools/c2man.pl" ), spec_file );
3277 output_filename( strmake( "-R%s", root_src_dir_path( "" )));
3278 output_filename( strmake( "-I%s", root_src_dir_path( "include" )));
3279 output_filename( "-o documentation/api-guide" );
3280 output_filenames( make->c2man_files );
3281 output( "\n" );
3282 output( "xmlpages::\n" );
3283 output( "\t%s -Tx -w %s", root_src_dir_path( "tools/c2man.pl" ), spec_file );
3284 output_filename( strmake( "-R%s", root_src_dir_path( "" )));
3285 output_filename( strmake( "-I%s", root_src_dir_path( "include" )));
3286 output_filename( "-o documentation/api-guide-xml" );
3287 output_filenames( make->c2man_files );
3288 output( "\n" );
3289 strarray_add( &make->phony_targets, "manpages" );
3290 strarray_add( &make->phony_targets, "htmlpages" );
3291 strarray_add( &make->phony_targets, "sgmlpages" );
3292 strarray_add( &make->phony_targets, "xmlpages" );
3297 /*******************************************************************
3298 * output_module
3300 static void output_module( struct makefile *make )
3302 struct strarray all_libs = empty_strarray;
3303 struct strarray dep_libs = empty_strarray;
3304 char *module_path = obj_dir_path( make, make->module );
3305 const char *debug_file = NULL;
3306 char *spec_file = NULL;
3307 unsigned int i;
3309 if (!make->is_exe) spec_file = src_dir_path( make, replace_extension( make->module, ".dll", ".spec" ));
3310 strarray_addall( &all_libs, add_import_libs( make, &dep_libs, make->delayimports, 1, 0 ));
3311 strarray_addall( &all_libs, add_import_libs( make, &dep_libs, make->imports, 0, 0 ));
3312 add_import_libs( make, &dep_libs, get_default_imports( make ), 0, 0 ); /* dependencies only */
3314 if (make->is_cross)
3316 if (delay_load_flag)
3318 for (i = 0; i < make->delayimports.count; i++)
3319 strarray_add( &all_libs, strmake( "%s%s%s", delay_load_flag, make->delayimports.str[i],
3320 strchr( make->delayimports.str[i], '.' ) ? "" : ".dll" ));
3322 strarray_add( &make->all_targets, strmake( "%s", make->module ));
3323 add_install_rule( make, make->module, strmake( "%s", make->module ),
3324 strmake( "c$(dlldir)/%s", make->module ));
3325 debug_file = get_debug_file( make, make->module );
3326 output( "%s:", module_path );
3328 else if (*dll_ext)
3330 if (!make->use_msvcrt) strarray_addall( &all_libs, add_unix_libraries( make, &dep_libs ));
3331 for (i = 0; i < make->delayimports.count; i++)
3332 strarray_add( &all_libs, strmake( "-Wl,-delayload,%s%s", make->delayimports.str[i],
3333 strchr( make->delayimports.str[i], '.' ) ? "" : ".dll" ));
3334 strarray_add( &make->all_targets, strmake( "%s%s", make->module, dll_ext ));
3335 strarray_add( &make->all_targets, strmake( "%s.fake", make->module ));
3336 add_install_rule( make, make->module, strmake( "%s%s", make->module, dll_ext ),
3337 strmake( "p$(dlldir)/%s%s", make->module, dll_ext ));
3338 add_install_rule( make, make->module, strmake( "%s.fake", make->module ),
3339 strmake( "d$(dlldir)/fakedlls/%s", make->module ));
3340 output( "%s%s %s.fake:", module_path, dll_ext, module_path );
3342 else
3344 strarray_addall( &all_libs, add_unix_libraries( make, &dep_libs ));
3345 strarray_add( &make->all_targets, make->module );
3346 add_install_rule( make, make->module, make->module,
3347 strmake( "p$(%s)/%s", spec_file ? "dlldir" : "bindir", make->module ));
3348 debug_file = get_debug_file( make, make->module );
3349 output( "%s:", module_path );
3352 if (spec_file) output_filename( spec_file );
3353 output_filenames_obj_dir( make, make->is_cross ? make->crossobj_files : make->object_files );
3354 output_filenames_obj_dir( make, make->res_files );
3355 output_filenames( dep_libs );
3356 output_filename( tools_path( make, "winebuild" ));
3357 output_filename( tools_path( make, "winegcc" ));
3358 output( "\n" );
3359 output_winegcc_command( make, make->is_cross );
3360 if (make->is_cross) output_filename( "-Wl,--wine-builtin" );
3361 if (spec_file)
3363 output_filename( "-shared" );
3364 output_filename( spec_file );
3366 output_filenames( make->extradllflags );
3367 output_filenames_obj_dir( make, make->is_cross ? make->crossobj_files : make->object_files );
3368 output_filenames_obj_dir( make, make->res_files );
3369 if (debug_file) output_filename( strmake( "-Wl,--debug-file,%s", obj_dir_path( make, debug_file )));
3370 output_filenames( all_libs );
3371 output_filename( make->is_cross ? "$(CROSSLDFLAGS)" : "$(LDFLAGS)" );
3372 output( "\n" );
3374 if (make->unixobj_files.count)
3376 struct strarray unix_imports = empty_strarray;
3377 struct strarray unix_libs = empty_strarray;
3378 struct strarray unix_deps = empty_strarray;
3379 char *ext, *unix_lib = xmalloc( strlen( make->module ) + strlen( dll_ext ) + 1 );
3380 strcpy( unix_lib, make->module );
3381 if ((ext = get_extension( unix_lib ))) *ext = 0;
3382 strcat( unix_lib, dll_ext );
3384 if (!strarray_exists( &make->extradllflags, "-nodefaultlibs" ))
3385 strarray_add( &unix_imports, "ntdll" );
3386 strarray_add( &unix_imports, "winecrt0" );
3388 strarray_addall( &unix_libs, add_import_libs( make, &unix_deps, unix_imports, 0, 1 ));
3389 strarray_addall( &unix_libs, add_unix_libraries( make, &unix_deps ));
3391 strarray_add( &make->all_targets, unix_lib );
3392 add_install_rule( make, make->module, unix_lib, strmake( "p$(dlldir)/%s", unix_lib ));
3393 output( "%s:", obj_dir_path( make, unix_lib ));
3394 if (spec_file) output_filename( spec_file );
3395 output_filenames_obj_dir( make, make->unixobj_files );
3396 output_filenames( unix_deps );
3397 output_filename( tools_path( make, "winebuild" ));
3398 output_filename( tools_path( make, "winegcc" ));
3399 output( "\n" );
3400 output_winegcc_command( make, 0 );
3401 output_filename( "-munix" );
3402 output_filename( "-shared" );
3403 if (spec_file) output_filename( spec_file );
3404 if (strarray_exists( &make->extradllflags, "-nodefaultlibs" )) output_filename( "-nodefaultlibs" );
3405 output_filenames_obj_dir( make, make->unixobj_files );
3406 output_filenames( unix_libs );
3407 output_filename( "$(LDFLAGS)" );
3408 output( "\n" );
3411 if (spec_file && make->importlib)
3413 char *importlib_path = obj_dir_path( make, strmake( "lib%s", make->importlib ));
3414 if (*dll_ext && !make->implib_objs.count)
3416 strarray_add( &make->clean_files, strmake( "lib%s.def", make->importlib ));
3417 output( "%s.def: %s %s\n", importlib_path, tools_path( make, "winebuild" ), spec_file );
3418 output( "\t%s%s -w --def -o $@", cmd_prefix( "BUILD" ), tools_path( make, "winebuild" ) );
3419 output_filenames( target_flags );
3420 if (make->is_win16) output_filename( "-m16" );
3421 output_filename( "--export" );
3422 output_filename( spec_file );
3423 output( "\n" );
3424 add_install_rule( make, make->importlib,
3425 strmake( "lib%s.def", make->importlib ),
3426 strmake( "d$(dlldir)/lib%s.def", make->importlib ));
3428 else
3430 strarray_add( &make->clean_files, strmake( "lib%s.a", make->importlib ));
3431 if (!*dll_ext && needs_delay_lib( make ))
3433 strarray_add( &make->clean_files, strmake( "lib%s.delay.a", make->importlib ));
3434 output( "%s.delay.a ", importlib_path );
3436 output( "%s.a: %s %s", importlib_path, tools_path( make, "winebuild" ), spec_file );
3437 output_filenames_obj_dir( make, make->implib_objs );
3438 output( "\n" );
3439 output( "\t%s%s -w --implib -o $@", cmd_prefix( "BUILD" ), tools_path( make, "winebuild" ) );
3440 output_filenames( target_flags );
3441 if (make->is_win16) output_filename( "-m16" );
3442 output_filename( "--export" );
3443 output_filename( spec_file );
3444 output_filenames_obj_dir( make, make->implib_objs );
3445 output( "\n" );
3446 add_install_rule( make, make->importlib,
3447 strmake( "lib%s.a", make->importlib ),
3448 strmake( "d$(dlldir)/lib%s.a", make->importlib ));
3450 if (crosstarget && (needs_cross_lib( make ) || needs_delay_lib( make )))
3452 struct strarray cross_files = strarray_replace_extension( &make->implib_objs, ".o", ".cross.o" );
3453 if (needs_cross_lib( make ))
3455 strarray_add( &make->clean_files, strmake( "lib%s.cross.a", make->importlib ));
3456 output_filename( strmake( "%s.cross.a", importlib_path ));
3458 if (needs_delay_lib( make ))
3460 strarray_add( &make->clean_files, strmake( "lib%s.delay.a", make->importlib ));
3461 output_filename( strmake( "%s.delay.a", importlib_path ));
3463 output( ": %s %s", tools_path( make, "winebuild" ), spec_file );
3464 output_filenames_obj_dir( make, cross_files );
3465 output( "\n" );
3466 output( "\t%s%s -b %s -w --implib -o $@", cmd_prefix( "BUILD" ),
3467 tools_path( make, "winebuild" ), crosstarget );
3468 if (make->is_win16) output_filename( "-m16" );
3469 output_filename( "--export" );
3470 output_filename( spec_file );
3471 output_filenames_obj_dir( make, cross_files );
3472 output( "\n" );
3474 if (needs_implib_symlink( make ))
3475 strarray_addall( &top_makefile->clean_files, output_importlib_symlinks( make ));
3478 if (spec_file)
3479 output_man_pages( make );
3480 else if (*dll_ext && !make->is_win16 && strendswith( make->module, ".exe" ))
3482 char *binary = replace_extension( make->module, ".exe", "" );
3483 add_install_rule( make, binary, "wineapploader", strmake( "t$(bindir)/%s", binary ));
3488 /*******************************************************************
3489 * output_static_lib
3491 static void output_static_lib( struct makefile *make )
3493 strarray_add( &make->all_targets, make->staticlib );
3494 output( "%s:", obj_dir_path( make, make->staticlib ));
3495 output_filenames_obj_dir( make, make->object_files );
3496 output_filenames_obj_dir( make, make->unixobj_files );
3497 output( "\n\t%srm -f $@ && %s rc $@", cmd_prefix( "AR" ), ar );
3498 output_filenames_obj_dir( make, make->object_files );
3499 output_filenames_obj_dir( make, make->unixobj_files );
3500 output( " && %s $@\n", ranlib );
3501 add_install_rule( make, make->staticlib, make->staticlib,
3502 strmake( "d$(dlldir)/%s", make->staticlib ));
3503 if (needs_cross_lib( make ))
3505 char *name = replace_extension( make->staticlib, ".a", ".cross.a" );
3507 strarray_add( &make->all_targets, name );
3508 output( "%s: %s", obj_dir_path( make, name ), tools_path( make, "winebuild" ));
3509 output_filenames_obj_dir( make, make->crossobj_files );
3510 output( "\n" );
3511 output( "\t%s%s -b %s -w --staticlib -o $@", cmd_prefix( "BUILD" ),
3512 tools_path( make, "winebuild" ), crosstarget );
3513 output_filenames_obj_dir( make, make->crossobj_files );
3514 output( "\n" );
3519 /*******************************************************************
3520 * output_shared_lib
3522 static void output_shared_lib( struct makefile *make )
3524 unsigned int i;
3525 char *basename, *p;
3526 struct strarray names = get_shared_lib_names( make->sharedlib );
3527 struct strarray all_libs = empty_strarray;
3528 struct strarray dep_libs = empty_strarray;
3530 basename = xstrdup( make->sharedlib );
3531 if ((p = strchr( basename, '.' ))) *p = 0;
3533 strarray_addall( &dep_libs, get_local_dependencies( make, basename, make->in_files ));
3534 strarray_addall( &all_libs, get_expanded_file_local_var( make, basename, "LDFLAGS" ));
3535 strarray_addall( &all_libs, add_unix_libraries( make, &dep_libs ));
3537 output( "%s:", obj_dir_path( make, make->sharedlib ));
3538 output_filenames_obj_dir( make, make->object_files );
3539 output_filenames( dep_libs );
3540 output( "\n" );
3541 output( "\t%s$(CC) -o $@", cmd_prefix( "CC" ));
3542 output_filenames_obj_dir( make, make->object_files );
3543 output_filenames( all_libs );
3544 output_filename( "$(LDFLAGS)" );
3545 output( "\n" );
3546 add_install_rule( make, make->sharedlib, make->sharedlib,
3547 strmake( "p$(libdir)/%s", make->sharedlib ));
3548 for (i = 1; i < names.count; i++)
3550 output( "%s: %s\n", obj_dir_path( make, names.str[i] ), obj_dir_path( make, names.str[i-1] ));
3551 output_symlink_rule( names.str[i-1], obj_dir_path( make, names.str[i] ), 0 );
3552 add_install_rule( make, names.str[i], names.str[i-1],
3553 strmake( "y$(libdir)/%s", names.str[i] ));
3555 strarray_addall( &make->all_targets, names );
3559 /*******************************************************************
3560 * output_test_module
3562 static void output_test_module( struct makefile *make )
3564 char *testmodule = replace_extension( make->testdll, ".dll", "_test.exe" );
3565 char *stripped = replace_extension( make->testdll, ".dll", "_test-stripped.exe" );
3566 char *testres = replace_extension( make->testdll, ".dll", "_test.res" );
3567 struct strarray dep_libs = empty_strarray;
3568 struct strarray all_libs = add_import_libs( make, &dep_libs, make->imports, 0, 0 );
3569 struct makefile *parent = get_parent_makefile( make );
3570 const char *ext = make->is_cross ? "" : dll_ext;
3571 const char *debug_file;
3572 char *output_file;
3574 add_import_libs( make, &dep_libs, get_default_imports( make ), 0, 0 ); /* dependencies only */
3575 strarray_add( &make->all_targets, strmake( "%s%s", testmodule, ext ));
3576 strarray_add( &make->clean_files, strmake( "%s%s", stripped, ext ));
3577 output_file = strmake( "%s%s", obj_dir_path( make, testmodule ), ext );
3578 output( "%s:\n", output_file );
3579 output_winegcc_command( make, make->is_cross );
3580 output_filenames( make->extradllflags );
3581 output_filenames_obj_dir( make, make->is_cross ? make->crossobj_files : make->object_files );
3582 output_filenames_obj_dir( make, make->res_files );
3583 if ((debug_file = get_debug_file( make, testmodule )))
3584 output_filename( strmake( "-Wl,--debug-file,%s", obj_dir_path( make, debug_file )));
3585 output_filenames( all_libs );
3586 output_filename( make->is_cross ? "$(CROSSLDFLAGS)" : "$(LDFLAGS)" );
3587 output( "\n" );
3588 output( "%s%s:\n", obj_dir_path( make, stripped ), ext );
3589 output_winegcc_command( make, make->is_cross );
3590 output_filename( "-s" );
3591 output_filename( strmake( "-Wb,-F,%s", testmodule ));
3592 output_filenames( make->extradllflags );
3593 output_filenames_obj_dir( make, make->is_cross ? make->crossobj_files : make->object_files );
3594 output_filenames_obj_dir( make, make->res_files );
3595 output_filenames( all_libs );
3596 output_filename( make->is_cross ? "$(CROSSLDFLAGS)" : "$(LDFLAGS)" );
3597 output( "\n" );
3598 output( "%s%s %s%s:", obj_dir_path( make, testmodule ), ext, obj_dir_path( make, stripped ), ext );
3599 output_filenames_obj_dir( make, make->is_cross ? make->crossobj_files : make->object_files );
3600 output_filenames_obj_dir( make, make->res_files );
3601 output_filenames( dep_libs );
3602 output_filename( tools_path( make, "winebuild" ));
3603 output_filename( tools_path( make, "winegcc" ));
3604 output( "\n" );
3606 output( "programs/winetest/%s: %s%s\n", testres, obj_dir_path( make, stripped ), ext );
3607 output( "\t%secho \"%s TESTRES \\\"%s%s\\\"\" | %s -u -o $@\n", cmd_prefix( "WRC" ),
3608 testmodule, obj_dir_path( make, stripped ), ext, tools_path( make, "wrc" ));
3610 output_filenames_obj_dir( make, make->ok_files );
3611 output( ": %s%s", obj_dir_path( make, testmodule ), ext );
3612 if (parent)
3614 output_filename( parent->is_cross ? obj_dir_path( parent, make->testdll )
3615 : strmake( "%s%s", obj_dir_path( parent, make->testdll ), dll_ext ));
3616 if (parent->unixobj_files.count)
3618 char *ext, *unix_lib = xstrdup( parent->module );
3619 if ((ext = get_extension( unix_lib ))) *ext = 0;
3620 output_filename( strmake( "%s%s", obj_dir_path( parent, unix_lib ), dll_ext ));
3623 output( "\n" );
3624 output( "%s %s:", obj_dir_path( make, "check" ), obj_dir_path( make, "test" ));
3625 if (!make->disabled && parent && !parent->disabled) output_filenames_obj_dir( make, make->ok_files );
3626 output( "\n" );
3627 strarray_add_uniq( &make->phony_targets, obj_dir_path( make, "check" ));
3628 strarray_add_uniq( &make->phony_targets, obj_dir_path( make, "test" ));
3629 output( "%s::\n", obj_dir_path( make, "testclean" ));
3630 output( "\trm -f" );
3631 output_filenames_obj_dir( make, make->ok_files );
3632 output( "\n" );
3633 strarray_addall( &make->clean_files, make->ok_files );
3634 strarray_add_uniq( &make->phony_targets, obj_dir_path( make, "testclean" ));
3638 /*******************************************************************
3639 * output_programs
3641 static void output_programs( struct makefile *make )
3643 unsigned int i, j;
3645 for (i = 0; i < make->programs.count; i++)
3647 char *program_installed = NULL;
3648 char *program = strmake( "%s%s", make->programs.str[i], exe_ext );
3649 struct strarray deps = get_local_dependencies( make, make->programs.str[i], make->in_files );
3650 struct strarray all_libs = get_expanded_file_local_var( make, make->programs.str[i], "LDFLAGS" );
3651 struct strarray objs = get_expanded_file_local_var( make, make->programs.str[i], "OBJS" );
3652 struct strarray symlinks = get_expanded_file_local_var( make, make->programs.str[i], "SYMLINKS" );
3654 if (!objs.count) objs = make->object_files;
3655 if (!strarray_exists( &all_libs, "-nodefaultlibs" ))
3656 strarray_addall( &all_libs, add_unix_libraries( make, &deps ));
3658 output( "%s:", obj_dir_path( make, program ) );
3659 output_filenames_obj_dir( make, objs );
3660 output_filenames( deps );
3661 output( "\n" );
3662 output( "\t%s$(CC) -o $@", cmd_prefix( "CC" ));
3663 output_filenames_obj_dir( make, objs );
3664 output_filenames( all_libs );
3665 output_filename( "$(LDFLAGS)" );
3666 output( "\n" );
3667 strarray_add( &make->all_targets, program );
3669 for (j = 0; j < symlinks.count; j++)
3671 output( "%s: %s\n", obj_dir_path( make, symlinks.str[j] ), obj_dir_path( make, program ));
3672 output_symlink_rule( program, obj_dir_path( make, symlinks.str[j] ), 0 );
3674 strarray_addall( &make->all_targets, symlinks );
3676 add_install_rule( make, program, program_installed ? program_installed : program,
3677 strmake( "p$(bindir)/%s", program ));
3678 for (j = 0; j < symlinks.count; j++)
3679 add_install_rule( make, symlinks.str[j], program,
3680 strmake( "y$(bindir)/%s%s", symlinks.str[j], exe_ext ));
3685 /*******************************************************************
3686 * output_subdirs
3688 static void output_subdirs( struct makefile *make )
3690 struct strarray all_targets = empty_strarray;
3691 struct strarray makefile_deps = empty_strarray;
3692 struct strarray clean_files = empty_strarray;
3693 struct strarray testclean_files = empty_strarray;
3694 struct strarray distclean_files = empty_strarray;
3695 struct strarray dependencies = empty_strarray;
3696 struct strarray install_lib_deps = empty_strarray;
3697 struct strarray install_dev_deps = empty_strarray;
3698 struct strarray tooldeps_deps = empty_strarray;
3699 struct strarray buildtest_deps = empty_strarray;
3700 unsigned int i;
3702 strarray_addall( &clean_files, make->clean_files );
3703 strarray_addall( &distclean_files, make->distclean_files );
3704 strarray_addall( &all_targets, make->all_targets );
3705 for (i = 0; i < subdirs.count; i++)
3707 strarray_add( &makefile_deps, src_dir_path( submakes[i], strmake ( "%s.in", output_makefile_name )));
3708 strarray_addall_uniq( &make->phony_targets, submakes[i]->phony_targets );
3709 strarray_addall_uniq( &make->uninstall_files, submakes[i]->uninstall_files );
3710 strarray_addall_uniq( &dependencies, submakes[i]->dependencies );
3711 strarray_addall_path( &clean_files, submakes[i]->obj_dir, submakes[i]->clean_files );
3712 strarray_addall_path( &distclean_files, submakes[i]->obj_dir, submakes[i]->distclean_files );
3713 strarray_addall_path( &testclean_files, submakes[i]->obj_dir, submakes[i]->ok_files );
3714 strarray_addall_path( &make->pot_files, submakes[i]->obj_dir, submakes[i]->pot_files );
3716 if (submakes[i]->disabled) continue;
3718 strarray_addall_path( &all_targets, submakes[i]->obj_dir, submakes[i]->all_targets );
3719 if (!strcmp( submakes[i]->obj_dir, "tools" ) || !strncmp( submakes[i]->obj_dir, "tools/", 6 ))
3720 strarray_add( &tooldeps_deps, obj_dir_path( submakes[i], "all" ));
3721 if (submakes[i]->testdll)
3722 strarray_add( &buildtest_deps, obj_dir_path( submakes[i], "all" ));
3723 if (submakes[i]->install_rules[INSTALL_LIB].count)
3724 strarray_add( &install_lib_deps, obj_dir_path( submakes[i], "install-lib" ));
3725 if (submakes[i]->install_rules[INSTALL_DEV].count)
3726 strarray_add( &install_dev_deps, obj_dir_path( submakes[i], "install-dev" ));
3728 strarray_addall( &dependencies, makefile_deps );
3729 output( "all:" );
3730 output_filenames( all_targets );
3731 output( "\n" );
3732 output( "Makefile:" );
3733 output_filenames( makefile_deps );
3734 output( "\n" );
3735 output_filenames( dependencies );
3736 output( ":\n" );
3737 if (install_lib_deps.count)
3739 output( "install install-lib::" );
3740 output_filenames( install_lib_deps );
3741 output( "\n" );
3742 strarray_add_uniq( &make->phony_targets, "install" );
3743 strarray_add_uniq( &make->phony_targets, "install-lib" );
3745 if (install_dev_deps.count)
3747 output( "install install-dev::" );
3748 output_filenames( install_dev_deps );
3749 output( "\n" );
3750 strarray_add_uniq( &make->phony_targets, "install" );
3751 strarray_add_uniq( &make->phony_targets, "install-dev" );
3753 output_uninstall_rules( make );
3754 if (buildtest_deps.count)
3756 output( "buildtests:" );
3757 output_filenames( buildtest_deps );
3758 output( "\n" );
3759 strarray_add_uniq( &make->phony_targets, "buildtests" );
3761 output( "check test:" );
3762 output_filenames( testclean_files );
3763 output( "\n" );
3764 strarray_add_uniq( &make->phony_targets, "check" );
3765 strarray_add_uniq( &make->phony_targets, "test" );
3767 output( "clean::\n");
3768 output_rm_filenames( clean_files );
3769 output( "testclean::\n");
3770 output_rm_filenames( testclean_files );
3771 output( "distclean::\n");
3772 output_rm_filenames( distclean_files );
3773 strarray_add_uniq( &make->phony_targets, "distclean" );
3774 strarray_add_uniq( &make->phony_targets, "testclean" );
3776 if (tooldeps_deps.count)
3778 output( "__tooldeps__:" );
3779 output_filenames( tooldeps_deps );
3780 output( "\n" );
3781 strarray_add_uniq( &make->phony_targets, "__tooldeps__" );
3784 if (get_expanded_make_variable( make, "GETTEXTPO_LIBS" )) output_po_files( make );
3786 if (make->phony_targets.count)
3788 output( ".PHONY:" );
3789 output_filenames( make->phony_targets );
3790 output( "\n" );
3795 /*******************************************************************
3796 * output_sources
3798 static void output_sources( struct makefile *make )
3800 struct strarray all_targets = empty_strarray;
3801 struct incl_file *source;
3802 unsigned int i, j;
3804 strarray_add_uniq( &make->phony_targets, "all" );
3806 LIST_FOR_EACH_ENTRY( source, &make->sources, struct incl_file, entry )
3808 char *obj = xstrdup( source->name );
3809 char *ext = get_extension( obj );
3811 if (!ext) fatal_error( "unsupported file type %s\n", source->name );
3812 *ext++ = 0;
3814 for (j = 0; output_source_funcs[j].ext; j++)
3815 if (!strcmp( ext, output_source_funcs[j].ext )) break;
3817 output_source_funcs[j].fn( make, source, obj );
3818 strarray_addall_uniq( &make->dependencies, source->dependencies );
3821 /* special case for winetest: add resource files from other test dirs */
3822 if (make->obj_dir && !strcmp( make->obj_dir, "programs/winetest" ))
3824 struct strarray tests = enable_tests;
3825 if (!tests.count)
3826 for (i = 0; i < subdirs.count; i++)
3827 if (submakes[i]->testdll && !submakes[i]->disabled)
3828 strarray_add( &tests, submakes[i]->testdll );
3829 for (i = 0; i < tests.count; i++)
3830 strarray_add( &make->res_files, replace_extension( tests.str[i], ".dll", "_test.res" ));
3833 if (make->dlldata_files.count)
3835 output( "%s: %s %s\n", obj_dir_path( make, "dlldata.c" ),
3836 tools_path( make, "widl" ), src_dir_path( make, "Makefile.in" ));
3837 output( "\t%s%s --dlldata-only -o $@", cmd_prefix( "WIDL" ), tools_path( make, "widl" ));
3838 output_filenames( make->dlldata_files );
3839 output( "\n" );
3842 if (make->staticlib) output_static_lib( make );
3843 else if (make->module) output_module( make );
3844 else if (make->testdll) output_test_module( make );
3845 else if (make->sharedlib) output_shared_lib( make );
3846 else if (make->programs.count) output_programs( make );
3848 for (i = 0; i < make->scripts.count; i++)
3849 add_install_rule( make, make->scripts.str[i], make->scripts.str[i],
3850 strmake( "S$(bindir)/%s", make->scripts.str[i] ));
3852 for (i = 0; i < make->extra_targets.count; i++)
3853 if (strarray_exists( &make->dependencies, obj_dir_path( make, make->extra_targets.str[i] )))
3854 strarray_add( &make->clean_files, make->extra_targets.str[i] );
3855 else
3856 strarray_add( &make->all_targets, make->extra_targets.str[i] );
3858 if (!make->src_dir) strarray_add( &make->distclean_files, ".gitignore" );
3859 strarray_add( &make->distclean_files, "Makefile" );
3860 if (make->testdll) strarray_add( &make->distclean_files, "testlist.c" );
3862 if (!make->obj_dir)
3863 strarray_addall( &make->distclean_files, get_expanded_make_var_array( make, "CONFIGURE_TARGETS" ));
3864 else if (!strcmp( make->obj_dir, "po" ))
3865 strarray_add( &make->distclean_files, "LINGUAS" );
3867 strarray_addall( &make->clean_files, make->object_files );
3868 strarray_addall( &make->clean_files, make->crossobj_files );
3869 strarray_addall( &make->clean_files, make->unixobj_files );
3870 strarray_addall( &make->clean_files, make->res_files );
3871 strarray_addall( &make->clean_files, make->pot_files );
3872 strarray_addall( &make->clean_files, make->debug_files );
3873 strarray_addall( &make->clean_files, make->all_targets );
3875 if (make == top_makefile)
3877 output_subdirs( make );
3878 return;
3881 strarray_addall( &all_targets, make->all_targets );
3882 strarray_addall( &all_targets, make->font_files );
3883 if (all_targets.count)
3885 output( "%s:", obj_dir_path( make, "all" ));
3886 output_filenames_obj_dir( make, all_targets );
3887 output( "\n" );
3888 strarray_add_uniq( &make->phony_targets, obj_dir_path( make, "all" ));
3890 output_install_rules( make, INSTALL_LIB, "install-lib" );
3891 output_install_rules( make, INSTALL_DEV, "install-dev" );
3893 if (make->clean_files.count)
3895 output( "%s::\n", obj_dir_path( make, "clean" ));
3896 output( "\trm -f" );
3897 output_filenames_obj_dir( make, make->clean_files );
3898 output( "\n" );
3899 strarray_add( &make->phony_targets, obj_dir_path( make, "clean" ));
3904 /*******************************************************************
3905 * create_temp_file
3907 static FILE *create_temp_file( const char *orig )
3909 char *name = xmalloc( strlen(orig) + 13 );
3910 unsigned int i, id = getpid();
3911 int fd;
3912 FILE *ret = NULL;
3914 for (i = 0; i < 100; i++)
3916 sprintf( name, "%s.tmp%08x", orig, id );
3917 if ((fd = open( name, O_RDWR | O_CREAT | O_EXCL, 0666 )) != -1)
3919 ret = fdopen( fd, "w" );
3920 break;
3922 if (errno != EEXIST) break;
3923 id += 7777;
3925 if (!ret) fatal_error( "failed to create output file for '%s'\n", orig );
3926 temp_file_name = name;
3927 return ret;
3931 /*******************************************************************
3932 * rename_temp_file
3934 static void rename_temp_file( const char *dest )
3936 int ret = rename( temp_file_name, dest );
3937 if (ret == -1 && errno == EEXIST)
3939 /* rename doesn't overwrite on windows */
3940 unlink( dest );
3941 ret = rename( temp_file_name, dest );
3943 if (ret == -1) fatal_error( "failed to rename output file to '%s'\n", dest );
3944 temp_file_name = NULL;
3948 /*******************************************************************
3949 * are_files_identical
3951 static int are_files_identical( FILE *file1, FILE *file2 )
3953 for (;;)
3955 char buffer1[8192], buffer2[8192];
3956 int size1 = fread( buffer1, 1, sizeof(buffer1), file1 );
3957 int size2 = fread( buffer2, 1, sizeof(buffer2), file2 );
3958 if (size1 != size2) return 0;
3959 if (!size1) return feof( file1 ) && feof( file2 );
3960 if (memcmp( buffer1, buffer2, size1 )) return 0;
3965 /*******************************************************************
3966 * rename_temp_file_if_changed
3968 static void rename_temp_file_if_changed( const char *dest )
3970 FILE *file1, *file2;
3971 int do_rename = 1;
3973 if ((file1 = fopen( dest, "r" )))
3975 if ((file2 = fopen( temp_file_name, "r" )))
3977 do_rename = !are_files_identical( file1, file2 );
3978 fclose( file2 );
3980 fclose( file1 );
3982 if (!do_rename)
3984 unlink( temp_file_name );
3985 temp_file_name = NULL;
3987 else rename_temp_file( dest );
3991 /*******************************************************************
3992 * output_linguas
3994 static void output_linguas( const struct makefile *make )
3996 const char *dest = obj_dir_path( make, "LINGUAS" );
3997 struct incl_file *source;
3999 output_file = create_temp_file( dest );
4001 output( "# Automatically generated by make depend; DO NOT EDIT!!\n" );
4002 LIST_FOR_EACH_ENTRY( source, &make->sources, struct incl_file, entry )
4003 if (strendswith( source->name, ".po" ))
4004 output( "%s\n", replace_extension( source->name, ".po", "" ));
4006 if (fclose( output_file )) fatal_perror( "write" );
4007 output_file = NULL;
4008 rename_temp_file_if_changed( dest );
4012 /*******************************************************************
4013 * output_testlist
4015 static void output_testlist( const struct makefile *make )
4017 const char *dest = obj_dir_path( make, "testlist.c" );
4018 struct strarray files = empty_strarray;
4019 unsigned int i;
4021 for (i = 0; i < make->ok_files.count; i++)
4022 strarray_add( &files, replace_extension( make->ok_files.str[i], ".ok", "" ));
4024 output_file = create_temp_file( dest );
4026 output( "/* Automatically generated by make depend; DO NOT EDIT!! */\n\n" );
4027 output( "#define WIN32_LEAN_AND_MEAN\n" );
4028 output( "#include <windows.h>\n\n" );
4029 output( "#define STANDALONE\n" );
4030 output( "#include \"wine/test.h\"\n\n" );
4032 for (i = 0; i < files.count; i++) output( "extern void func_%s(void);\n", files.str[i] );
4033 output( "\n" );
4034 output( "const struct test winetest_testlist[] =\n" );
4035 output( "{\n" );
4036 for (i = 0; i < files.count; i++) output( " { \"%s\", func_%s },\n", files.str[i], files.str[i] );
4037 output( " { 0, 0 }\n" );
4038 output( "};\n" );
4040 if (fclose( output_file )) fatal_perror( "write" );
4041 output_file = NULL;
4042 rename_temp_file_if_changed( dest );
4046 /*******************************************************************
4047 * output_gitignore
4049 static void output_gitignore( const char *dest, struct strarray files )
4051 int i;
4053 output_file = create_temp_file( dest );
4055 output( "# Automatically generated by make depend; DO NOT EDIT!!\n" );
4056 for (i = 0; i < files.count; i++)
4058 if (!strchr( files.str[i], '/' )) output( "/" );
4059 output( "%s\n", files.str[i] );
4062 if (fclose( output_file )) fatal_perror( "write" );
4063 output_file = NULL;
4064 rename_temp_file( dest );
4068 /*******************************************************************
4069 * output_stub_makefile
4071 static void output_stub_makefile( struct makefile *make )
4073 struct strarray targets = empty_strarray;
4074 const char *make_var = strarray_get_value( &top_makefile->vars, "MAKE" );
4076 if (make_var) output( "MAKE = %s\n\n", make_var );
4077 output( "all:\n" );
4079 if (make->all_targets.count) strarray_add( &targets, "all" );
4080 if (make->install_rules[INSTALL_LIB].count || make->install_rules[INSTALL_DEV].count)
4081 strarray_add( &targets, "install" );
4082 if (make->install_rules[INSTALL_LIB].count) strarray_add( &targets, "install-lib" );
4083 if (make->install_rules[INSTALL_DEV].count) strarray_add( &targets, "install-dev" );
4084 if (make->clean_files.count) strarray_add( &targets, "clean" );
4085 if (make->ok_files.count)
4087 strarray_add( &targets, "check" );
4088 strarray_add( &targets, "test" );
4089 strarray_add( &targets, "testclean" );
4092 output_filenames( targets );
4093 output_filenames( make->clean_files );
4094 output( ":\n" );
4095 output( "\t@cd %s && $(MAKE) %s/$@\n", get_relative_path( make->obj_dir, "" ), make->obj_dir );
4096 output( ".PHONY:" );
4097 output_filenames( targets );
4098 output( "\n" );
4102 /*******************************************************************
4103 * output_silent_rules
4105 static void output_silent_rules(void)
4107 static const char *cmds[] =
4109 "AR",
4110 "BISON",
4111 "BUILD",
4112 "CC",
4113 "CCLD",
4114 "FLEX",
4115 "GEN",
4116 "LN",
4117 "MSG",
4118 "SED",
4119 "TEST",
4120 "WIDL",
4121 "WMC",
4122 "WRC"
4124 unsigned int i;
4126 output( "V = 0\n" );
4127 for (i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++)
4129 output( "quiet_%s = $(quiet_%s_$(V))\n", cmds[i], cmds[i] );
4130 output( "quiet_%s_0 = @echo \" %-5s \" $@;\n", cmds[i], cmds[i] );
4131 output( "quiet_%s_1 =\n", cmds[i] );
4136 /*******************************************************************
4137 * output_dependencies
4139 static void output_dependencies( struct makefile *make )
4141 struct strarray ignore_files = empty_strarray;
4142 char buffer[1024];
4143 FILE *src_file;
4144 int i, found = 0;
4146 if (make->obj_dir) create_dir( make->obj_dir );
4148 output_file_name = obj_dir_path( make, output_makefile_name );
4149 output_file = create_temp_file( output_file_name );
4151 /* copy the contents of the source makefile */
4152 src_file = open_input_makefile( make );
4153 while (fgets( buffer, sizeof(buffer), src_file ) && !found)
4155 if (fwrite( buffer, 1, strlen(buffer), output_file ) != strlen(buffer)) fatal_perror( "write" );
4156 found = !strncmp( buffer, separator, strlen(separator) );
4158 if (fclose( src_file )) fatal_perror( "close" );
4159 input_file_name = NULL;
4161 if (!found) output( "\n%s (everything below this line is auto-generated; DO NOT EDIT!!)\n", separator );
4163 if (make == top_makefile)
4165 if (silent_rules) output_silent_rules();
4166 for (i = 0; i < subdirs.count; i++) output_sources( submakes[i] );
4167 output_sources( make );
4169 else output_stub_makefile( make );
4171 /* disable implicit rules */
4172 output( ".SUFFIXES:\n" );
4174 fclose( output_file );
4175 output_file = NULL;
4176 rename_temp_file( output_file_name );
4178 strarray_addall( &ignore_files, make->distclean_files );
4179 strarray_addall( &ignore_files, make->clean_files );
4180 if (make->testdll) output_testlist( make );
4181 if (make->obj_dir && !strcmp( make->obj_dir, "po" )) output_linguas( make );
4182 if (!make->src_dir) output_gitignore( obj_dir_path( make, ".gitignore" ), ignore_files );
4184 create_file_directories( make, ignore_files );
4186 output_file_name = NULL;
4190 /*******************************************************************
4191 * load_sources
4193 static void load_sources( struct makefile *make )
4195 static const char *source_vars[] =
4197 "SOURCES",
4198 "C_SRCS",
4199 "OBJC_SRCS",
4200 "RC_SRCS",
4201 "MC_SRCS",
4202 "IDL_SRCS",
4203 "BISON_SRCS",
4204 "LEX_SRCS",
4205 "HEADER_SRCS",
4206 "XTEMPLATE_SRCS",
4207 "SVG_SRCS",
4208 "FONT_SRCS",
4209 "IN_SRCS",
4210 "PO_SRCS",
4211 "MANPAGES",
4212 NULL
4214 const char **var;
4215 unsigned int i;
4216 struct strarray value;
4217 struct incl_file *file;
4219 strarray_set_value( &make->vars, "top_srcdir", root_src_dir_path( "" ));
4220 strarray_set_value( &make->vars, "srcdir", src_dir_path( make, "" ));
4222 make->parent_dir = get_expanded_make_variable( make, "PARENTSRC" );
4223 make->module = get_expanded_make_variable( make, "MODULE" );
4224 make->testdll = get_expanded_make_variable( make, "TESTDLL" );
4225 make->sharedlib = get_expanded_make_variable( make, "SHAREDLIB" );
4226 make->staticlib = get_expanded_make_variable( make, "STATICLIB" );
4227 make->importlib = get_expanded_make_variable( make, "IMPORTLIB" );
4229 make->programs = get_expanded_make_var_array( make, "PROGRAMS" );
4230 make->scripts = get_expanded_make_var_array( make, "SCRIPTS" );
4231 make->imports = get_expanded_make_var_array( make, "IMPORTS" );
4232 make->delayimports = get_expanded_make_var_array( make, "DELAYIMPORTS" );
4233 make->extradllflags = get_expanded_make_var_array( make, "EXTRADLLFLAGS" );
4234 make->install_lib = get_expanded_make_var_array( make, "INSTALL_LIB" );
4235 make->install_dev = get_expanded_make_var_array( make, "INSTALL_DEV" );
4236 make->extra_targets = get_expanded_make_var_array( make, "EXTRA_TARGETS" );
4238 if (make->module && strendswith( make->module, ".a" )) make->staticlib = make->module;
4240 make->is_win16 = strarray_exists( &make->extradllflags, "-m16" );
4241 if ((make->module && make->staticlib) || make->testdll || make->is_win16)
4242 strarray_add_uniq( &make->extradllflags, "-mno-cygwin" );
4244 strarray_addall( &make->extradllflags, get_expanded_make_var_array( make, "APPMODE" ));
4245 make->disabled = make->obj_dir && strarray_exists( &disabled_dirs, make->obj_dir );
4246 make->use_msvcrt = strarray_exists( &make->extradllflags, "-mno-cygwin" );
4247 make->is_exe = strarray_exists( &make->extradllflags, "-mconsole" ) ||
4248 strarray_exists( &make->extradllflags, "-mwindows" );
4250 if (make->module && !make->install_lib.count && !make->install_dev.count)
4252 if (make->importlib) strarray_add( &make->install_dev, make->importlib );
4253 if (make->staticlib) strarray_add( &make->install_dev, make->staticlib );
4254 else strarray_add( &make->install_lib, make->module );
4257 make->include_paths = empty_strarray;
4258 make->include_args = empty_strarray;
4259 make->define_args = empty_strarray;
4260 strarray_add( &make->define_args, "-D__WINESRC__" );
4262 value = get_expanded_make_var_array( make, "EXTRAINCL" );
4263 for (i = 0; i < value.count; i++)
4264 if (!strncmp( value.str[i], "-I", 2 ))
4265 strarray_add_uniq( &make->include_paths, value.str[i] + 2 );
4266 else
4267 strarray_add_uniq( &make->define_args, value.str[i] );
4268 strarray_addall( &make->define_args, get_expanded_make_var_array( make, "EXTRADEFS" ));
4270 strarray_add( &make->include_args, strmake( "-I%s", obj_dir_path( make, "" )));
4271 if (make->src_dir)
4272 strarray_add( &make->include_args, strmake( "-I%s", make->src_dir ));
4273 if (make->parent_dir)
4274 strarray_add( &make->include_args, strmake( "-I%s", src_dir_path( make, make->parent_dir )));
4275 strarray_add( &make->include_args, "-Iinclude" );
4276 if (root_src_dir) strarray_add( &make->include_args, strmake( "-I%s", root_src_dir_path( "include" )));
4278 list_init( &make->sources );
4279 list_init( &make->includes );
4281 for (var = source_vars; *var; var++)
4283 value = get_expanded_make_var_array( make, *var );
4284 for (i = 0; i < value.count; i++) add_src_file( make, value.str[i] );
4287 add_generated_sources( make );
4289 if (!make->use_msvcrt && !has_object_file( make ))
4291 strarray_add( &make->extradllflags, "-mno-cygwin" );
4292 make->use_msvcrt = 1;
4295 if (make->use_msvcrt) add_crt_import( make, &make->imports, &make->define_args );
4297 LIST_FOR_EACH_ENTRY( file, &make->includes, struct incl_file, entry ) parse_file( make, file, 0 );
4298 LIST_FOR_EACH_ENTRY( file, &make->sources, struct incl_file, entry ) get_dependencies( file, file );
4300 make->is_cross = crosstarget && make->use_msvcrt;
4302 if (make->is_cross)
4304 strarray_addall_uniq( &cross_import_libs, make->imports );
4305 strarray_addall_uniq( &cross_import_libs, make->extra_imports );
4306 if (make->is_win16) strarray_add_uniq( &cross_import_libs, "kernel" );
4307 strarray_add_uniq( &cross_import_libs, "winecrt0" );
4308 strarray_add_uniq( &cross_import_libs, "kernel32" );
4309 strarray_add_uniq( &cross_import_libs, "ntdll" );
4312 if (!*dll_ext || make->is_cross)
4313 for (i = 0; i < make->delayimports.count; i++)
4314 strarray_add_uniq( &delay_import_libs, get_base_name( make->delayimports.str[i] ));
4318 /*******************************************************************
4319 * parse_makeflags
4321 static void parse_makeflags( const char *flags )
4323 const char *p = flags;
4324 char *var, *buffer = xmalloc( strlen(flags) + 1 );
4326 while (*p)
4328 while (isspace(*p)) p++;
4329 var = buffer;
4330 while (*p && !isspace(*p))
4332 if (*p == '\\' && p[1]) p++;
4333 *var++ = *p++;
4335 *var = 0;
4336 if (var > buffer) set_make_variable( &cmdline_vars, buffer );
4341 /*******************************************************************
4342 * parse_option
4344 static int parse_option( const char *opt )
4346 if (opt[0] != '-')
4348 if (strchr( opt, '=' )) return set_make_variable( &cmdline_vars, opt );
4349 return 0;
4351 switch(opt[1])
4353 case 'f':
4354 if (opt[2]) output_makefile_name = opt + 2;
4355 break;
4356 case 'R':
4357 relative_dir_mode = 1;
4358 break;
4359 case 'S':
4360 silent_rules = 1;
4361 break;
4362 default:
4363 fprintf( stderr, "Unknown option '%s'\n%s", opt, Usage );
4364 exit(1);
4366 return 1;
4370 /*******************************************************************
4371 * main
4373 int main( int argc, char *argv[] )
4375 const char *makeflags = getenv( "MAKEFLAGS" );
4376 int i, j;
4378 if (makeflags) parse_makeflags( makeflags );
4380 i = 1;
4381 while (i < argc)
4383 if (parse_option( argv[i] ))
4385 for (j = i; j < argc; j++) argv[j] = argv[j+1];
4386 argc--;
4388 else i++;
4391 if (relative_dir_mode)
4393 char *relpath;
4395 if (argc != 3)
4397 fprintf( stderr, "Option -R needs two directories\n%s", Usage );
4398 exit( 1 );
4400 relpath = get_relative_path( argv[1], argv[2] );
4401 printf( "%s\n", relpath ? relpath : "." );
4402 exit( 0 );
4405 if (argc > 1) fatal_error( "Directory arguments not supported in this mode\n" );
4407 atexit( cleanup_files );
4408 signal( SIGTERM, exit_on_signal );
4409 signal( SIGINT, exit_on_signal );
4410 #ifdef SIGHUP
4411 signal( SIGHUP, exit_on_signal );
4412 #endif
4414 for (i = 0; i < HASH_SIZE; i++) list_init( &files[i] );
4416 top_makefile = parse_makefile( NULL );
4418 target_flags = get_expanded_make_var_array( top_makefile, "TARGETFLAGS" );
4419 msvcrt_flags = get_expanded_make_var_array( top_makefile, "MSVCRTFLAGS" );
4420 dll_flags = get_expanded_make_var_array( top_makefile, "DLLFLAGS" );
4421 extra_cflags = get_expanded_make_var_array( top_makefile, "EXTRACFLAGS" );
4422 extra_cross_cflags = get_expanded_make_var_array( top_makefile, "EXTRACROSSCFLAGS" );
4423 cpp_flags = get_expanded_make_var_array( top_makefile, "CPPFLAGS" );
4424 lddll_flags = get_expanded_make_var_array( top_makefile, "LDDLLFLAGS" );
4425 libs = get_expanded_make_var_array( top_makefile, "LIBS" );
4426 enable_tests = get_expanded_make_var_array( top_makefile, "ENABLE_TESTS" );
4427 delay_load_flag = get_expanded_make_variable( top_makefile, "DELAYLOADFLAG" );
4428 top_install_lib = get_expanded_make_var_array( top_makefile, "TOP_INSTALL_LIB" );
4429 top_install_dev = get_expanded_make_var_array( top_makefile, "TOP_INSTALL_DEV" );
4431 root_src_dir = get_expanded_make_variable( top_makefile, "srcdir" );
4432 tools_dir = get_expanded_make_variable( top_makefile, "TOOLSDIR" );
4433 tools_ext = get_expanded_make_variable( top_makefile, "TOOLSEXT" );
4434 exe_ext = get_expanded_make_variable( top_makefile, "EXEEXT" );
4435 man_ext = get_expanded_make_variable( top_makefile, "api_manext" );
4436 dll_ext = (exe_ext && !strcmp( exe_ext, ".exe" )) ? "" : ".so";
4437 crosstarget = get_expanded_make_variable( top_makefile, "CROSSTARGET" );
4438 crossdebug = get_expanded_make_variable( top_makefile, "CROSSDEBUG" );
4439 fontforge = get_expanded_make_variable( top_makefile, "FONTFORGE" );
4440 convert = get_expanded_make_variable( top_makefile, "CONVERT" );
4441 flex = get_expanded_make_variable( top_makefile, "FLEX" );
4442 bison = get_expanded_make_variable( top_makefile, "BISON" );
4443 ar = get_expanded_make_variable( top_makefile, "AR" );
4444 ranlib = get_expanded_make_variable( top_makefile, "RANLIB" );
4445 rsvg = get_expanded_make_variable( top_makefile, "RSVG" );
4446 icotool = get_expanded_make_variable( top_makefile, "ICOTOOL" );
4447 dlltool = get_expanded_make_variable( top_makefile, "DLLTOOL" );
4448 msgfmt = get_expanded_make_variable( top_makefile, "MSGFMT" );
4449 sed_cmd = get_expanded_make_variable( top_makefile, "SED_CMD" );
4450 ln_s = get_expanded_make_variable( top_makefile, "LN_S" );
4452 if (root_src_dir && !strcmp( root_src_dir, "." )) root_src_dir = NULL;
4453 if (tools_dir && !strcmp( tools_dir, "." )) tools_dir = NULL;
4454 if (!exe_ext) exe_ext = "";
4455 if (!tools_ext) tools_ext = "";
4456 if (!man_ext) man_ext = "3w";
4458 top_makefile->src_dir = root_src_dir;
4459 subdirs = get_expanded_make_var_array( top_makefile, "SUBDIRS" );
4460 disabled_dirs = get_expanded_make_var_array( top_makefile, "DISABLED_SUBDIRS" );
4461 submakes = xmalloc( subdirs.count * sizeof(*submakes) );
4463 for (i = 0; i < subdirs.count; i++) submakes[i] = parse_makefile( subdirs.str[i] );
4465 load_sources( top_makefile );
4466 for (i = 0; i < subdirs.count; i++) load_sources( submakes[i] );
4468 output_dependencies( top_makefile );
4469 for (i = 0; i < subdirs.count; i++) output_dependencies( submakes[i] );
4471 return 0;