mshtml: Use get_element helper in IHTMLDocument3::get_documentElement implementation.
[wine.git] / tools / makedep.c
blobd6019b85cb615c4d9aff9f1fc7e8977b93ffe7dc
1 /*
2 * Generate include file dependencies
4 * Copyright 1996, 2013 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"
22 #define NO_LIBWINE_PORT
23 #include "wine/port.h"
25 #include <assert.h>
26 #include <ctype.h>
27 #include <errno.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <stdarg.h>
31 #include <signal.h>
32 #include <string.h>
33 #ifdef HAVE_UNISTD_H
34 # include <unistd.h>
35 #endif
36 #include "wine/list.h"
38 struct strarray
40 unsigned int count; /* strings in use */
41 unsigned int size; /* total allocated size */
42 const char **str;
45 enum incl_type
47 INCL_NORMAL, /* #include "foo.h" */
48 INCL_SYSTEM, /* #include <foo.h> */
49 INCL_IMPORT, /* idl import "foo.idl" */
50 INCL_IMPORTLIB, /* idl importlib "foo.tlb" */
51 INCL_CPP_QUOTE, /* idl cpp_quote("#include \"foo.h\"") */
52 INCL_CPP_QUOTE_SYSTEM /* idl cpp_quote("#include <foo.h>") */
55 struct dependency
57 int line; /* source line where this header is included */
58 enum incl_type type; /* type of include */
59 char *name; /* header name */
62 struct file
64 struct list entry;
65 char *name; /* full file name relative to cwd */
66 void *args; /* custom arguments for makefile rule */
67 unsigned int flags; /* flags (see below) */
68 unsigned int deps_count; /* files in use */
69 unsigned int deps_size; /* total allocated size */
70 struct dependency *deps; /* all header dependencies */
73 struct incl_file
75 struct list entry;
76 struct file *file;
77 char *name;
78 char *filename;
79 char *sourcename; /* source file name for generated headers */
80 struct incl_file *included_by; /* file that included this one */
81 int included_line; /* line where this file was included */
82 enum incl_type type; /* type of include */
83 struct incl_file *owner;
84 unsigned int files_count; /* files in use */
85 unsigned int files_size; /* total allocated size */
86 struct incl_file **files;
87 struct strarray dependencies; /* file dependencies */
90 #define FLAG_GENERATED 0x000001 /* generated file */
91 #define FLAG_INSTALL 0x000002 /* file to install */
92 #define FLAG_IDL_PROXY 0x000100 /* generates a proxy (_p.c) file */
93 #define FLAG_IDL_CLIENT 0x000200 /* generates a client (_c.c) file */
94 #define FLAG_IDL_SERVER 0x000400 /* generates a server (_s.c) file */
95 #define FLAG_IDL_IDENT 0x000800 /* generates an ident (_i.c) file */
96 #define FLAG_IDL_REGISTER 0x001000 /* generates a registration (_r.res) file */
97 #define FLAG_IDL_TYPELIB 0x002000 /* generates a typelib (.tlb) file */
98 #define FLAG_IDL_REGTYPELIB 0x004000 /* generates a registered typelib (_t.res) file */
99 #define FLAG_IDL_HEADER 0x008000 /* generates a header (.h) file */
100 #define FLAG_RC_PO 0x010000 /* rc file contains translations */
101 #define FLAG_C_IMPLIB 0x020000 /* file is part of an import library */
102 #define FLAG_SFD_FONTS 0x040000 /* sfd file generated bitmap fonts */
104 static const struct
106 unsigned int flag;
107 const char *ext;
108 } idl_outputs[] =
110 { FLAG_IDL_TYPELIB, ".tlb" },
111 { FLAG_IDL_REGTYPELIB, "_t.res" },
112 { FLAG_IDL_CLIENT, "_c.c" },
113 { FLAG_IDL_IDENT, "_i.c" },
114 { FLAG_IDL_PROXY, "_p.c" },
115 { FLAG_IDL_SERVER, "_s.c" },
116 { FLAG_IDL_REGISTER, "_r.res" },
117 { FLAG_IDL_HEADER, ".h" }
120 #define HASH_SIZE 997
122 static struct list files[HASH_SIZE];
124 static const struct strarray empty_strarray;
126 enum install_rules { INSTALL_LIB, INSTALL_DEV, NB_INSTALL_RULES };
128 /* variables common to all makefiles */
129 static struct strarray linguas;
130 static struct strarray dll_flags;
131 static struct strarray target_flags;
132 static struct strarray msvcrt_flags;
133 static struct strarray extra_cflags;
134 static struct strarray cpp_flags;
135 static struct strarray unwind_flags;
136 static struct strarray libs;
137 static struct strarray cmdline_vars;
138 static struct strarray disabled_dirs;
139 static const char *root_src_dir;
140 static const char *tools_dir;
141 static const char *tools_ext;
142 static const char *exe_ext;
143 static const char *dll_ext;
144 static const char *man_ext;
145 static const char *crosstarget;
146 static const char *fontforge;
147 static const char *convert;
148 static const char *rsvg;
149 static const char *icotool;
150 static const char *dlltool;
151 static const char *msgfmt;
152 static const char *ln_s;
154 struct makefile
156 /* values determined from input makefile */
157 struct strarray vars;
158 struct strarray include_paths;
159 struct strarray include_args;
160 struct strarray define_args;
161 struct strarray programs;
162 struct strarray scripts;
163 struct strarray appmode;
164 struct strarray imports;
165 struct strarray subdirs;
166 struct strarray delayimports;
167 struct strarray extradllflags;
168 struct strarray install_lib;
169 struct strarray install_dev;
170 struct list sources;
171 struct list includes;
172 const char *base_dir;
173 const char *src_dir;
174 const char *obj_dir;
175 const char *top_src_dir;
176 const char *top_obj_dir;
177 const char *parent_dir;
178 const char *module;
179 const char *testdll;
180 const char *sharedlib;
181 const char *staticlib;
182 const char *staticimplib;
183 const char *importlib;
184 int disabled;
185 int use_msvcrt;
186 int is_win16;
187 struct makefile **submakes;
189 /* values generated at output time */
190 struct strarray in_files;
191 struct strarray ok_files;
192 struct strarray clean_files;
193 struct strarray object_files;
194 struct strarray crossobj_files;
195 struct strarray c2man_files;
196 struct strarray dlldata_files;
197 struct strarray implib_objs;
198 struct strarray all_targets;
199 struct strarray phony_targets;
200 struct strarray install_rules[NB_INSTALL_RULES];
203 static struct makefile *top_makefile;
205 static const char separator[] = "### Dependencies";
206 static const char *output_makefile_name = "Makefile";
207 static const char *input_file_name;
208 static const char *output_file_name;
209 static const char *temp_file_name;
210 static int relative_dir_mode;
211 static int input_line;
212 static int output_column;
213 static FILE *output_file;
215 static const char Usage[] =
216 "Usage: makedep [options] [directories]\n"
217 "Options:\n"
218 " -R from to Compute the relative path between two directories\n"
219 " -fxxx Store output in file 'xxx' (default: Makefile)\n";
222 #ifndef __GNUC__
223 #define __attribute__(x)
224 #endif
226 static void fatal_error( const char *msg, ... ) __attribute__ ((__format__ (__printf__, 1, 2)));
227 static void fatal_perror( const char *msg, ... ) __attribute__ ((__format__ (__printf__, 1, 2)));
228 static void output( const char *format, ... ) __attribute__ ((__format__ (__printf__, 1, 2)));
229 static char *strmake( const char* fmt, ... ) __attribute__ ((__format__ (__printf__, 1, 2)));
231 /*******************************************************************
232 * fatal_error
234 static void fatal_error( const char *msg, ... )
236 va_list valist;
237 va_start( valist, msg );
238 if (input_file_name)
240 fprintf( stderr, "%s:", input_file_name );
241 if (input_line) fprintf( stderr, "%d:", input_line );
242 fprintf( stderr, " error: " );
244 else fprintf( stderr, "makedep: error: " );
245 vfprintf( stderr, msg, valist );
246 va_end( valist );
247 exit(1);
251 /*******************************************************************
252 * fatal_perror
254 static void fatal_perror( const char *msg, ... )
256 va_list valist;
257 va_start( valist, msg );
258 if (input_file_name)
260 fprintf( stderr, "%s:", input_file_name );
261 if (input_line) fprintf( stderr, "%d:", input_line );
262 fprintf( stderr, " error: " );
264 else fprintf( stderr, "makedep: error: " );
265 vfprintf( stderr, msg, valist );
266 perror( " " );
267 va_end( valist );
268 exit(1);
272 /*******************************************************************
273 * cleanup_files
275 static void cleanup_files(void)
277 if (temp_file_name) unlink( temp_file_name );
278 if (output_file_name) unlink( output_file_name );
282 /*******************************************************************
283 * exit_on_signal
285 static void exit_on_signal( int sig )
287 exit( 1 ); /* this will call the atexit functions */
291 /*******************************************************************
292 * xmalloc
294 static void *xmalloc( size_t size )
296 void *res;
297 if (!(res = malloc (size ? size : 1)))
298 fatal_error( "Virtual memory exhausted.\n" );
299 return res;
303 /*******************************************************************
304 * xrealloc
306 static void *xrealloc (void *ptr, size_t size)
308 void *res;
309 assert( size );
310 if (!(res = realloc( ptr, size )))
311 fatal_error( "Virtual memory exhausted.\n" );
312 return res;
315 /*******************************************************************
316 * xstrdup
318 static char *xstrdup( const char *str )
320 char *res = strdup( str );
321 if (!res) fatal_error( "Virtual memory exhausted.\n" );
322 return res;
326 /*******************************************************************
327 * strmake
329 static char *strmake( const char* fmt, ... )
331 int n;
332 size_t size = 100;
333 va_list ap;
335 for (;;)
337 char *p = xmalloc (size);
338 va_start(ap, fmt);
339 n = vsnprintf (p, size, fmt, ap);
340 va_end(ap);
341 if (n == -1) size *= 2;
342 else if ((size_t)n >= size) size = n + 1;
343 else return xrealloc( p, n + 1 );
344 free(p);
349 /*******************************************************************
350 * strendswith
352 static int strendswith( const char* str, const char* end )
354 size_t l = strlen( str );
355 size_t m = strlen( end );
357 return l >= m && strcmp(str + l - m, end) == 0;
361 /*******************************************************************
362 * output
364 static void output( const char *format, ... )
366 int ret;
367 va_list valist;
369 va_start( valist, format );
370 ret = vfprintf( output_file, format, valist );
371 va_end( valist );
372 if (ret < 0) fatal_perror( "output" );
373 if (format[0] && format[strlen(format) - 1] == '\n') output_column = 0;
374 else output_column += ret;
378 /*******************************************************************
379 * strarray_add
381 static void strarray_add( struct strarray *array, const char *str )
383 if (array->count == array->size)
385 if (array->size) array->size *= 2;
386 else array->size = 16;
387 array->str = xrealloc( array->str, sizeof(array->str[0]) * array->size );
389 array->str[array->count++] = str;
393 /*******************************************************************
394 * strarray_addall
396 static void strarray_addall( struct strarray *array, struct strarray added )
398 unsigned int i;
400 for (i = 0; i < added.count; i++) strarray_add( array, added.str[i] );
404 /*******************************************************************
405 * strarray_exists
407 static int strarray_exists( const struct strarray *array, const char *str )
409 unsigned int i;
411 for (i = 0; i < array->count; i++) if (!strcmp( array->str[i], str )) return 1;
412 return 0;
416 /*******************************************************************
417 * strarray_add_uniq
419 static void strarray_add_uniq( struct strarray *array, const char *str )
421 if (!strarray_exists( array, str )) strarray_add( array, str );
425 /*******************************************************************
426 * strarray_get_value
428 * Find a value in a name/value pair string array.
430 static const char *strarray_get_value( const struct strarray *array, const char *name )
432 int pos, res, min = 0, max = array->count / 2 - 1;
434 while (min <= max)
436 pos = (min + max) / 2;
437 if (!(res = strcmp( array->str[pos * 2], name ))) return array->str[pos * 2 + 1];
438 if (res < 0) min = pos + 1;
439 else max = pos - 1;
441 return NULL;
445 /*******************************************************************
446 * strarray_set_value
448 * Define a value in a name/value pair string array.
450 static void strarray_set_value( struct strarray *array, const char *name, const char *value )
452 int i, pos, res, min = 0, max = array->count / 2 - 1;
454 while (min <= max)
456 pos = (min + max) / 2;
457 if (!(res = strcmp( array->str[pos * 2], name )))
459 /* redefining a variable replaces the previous value */
460 array->str[pos * 2 + 1] = value;
461 return;
463 if (res < 0) min = pos + 1;
464 else max = pos - 1;
466 strarray_add( array, NULL );
467 strarray_add( array, NULL );
468 for (i = array->count - 1; i > min * 2 + 1; i--) array->str[i] = array->str[i - 2];
469 array->str[min * 2] = name;
470 array->str[min * 2 + 1] = value;
474 /*******************************************************************
475 * output_filename
477 static void output_filename( const char *name )
479 if (output_column + strlen(name) + 1 > 100)
481 output( " \\\n" );
482 output( " " );
484 else if (output_column) output( " " );
485 output( "%s", name );
489 /*******************************************************************
490 * output_filenames
492 static void output_filenames( struct strarray array )
494 unsigned int i;
496 for (i = 0; i < array.count; i++) output_filename( array.str[i] );
500 /*******************************************************************
501 * output_rm_filenames
503 static void output_rm_filenames( struct strarray array )
505 static const unsigned int max_cmdline = 30000; /* to be on the safe side */
506 unsigned int i, len;
508 if (!array.count) return;
509 output( "\trm -f" );
510 for (i = len = 0; i < array.count; i++)
512 if (len > max_cmdline)
514 output( "\n" );
515 output( "\trm -f" );
516 len = 0;
518 output_filename( array.str[i] );
519 len += strlen( array.str[i] ) + 1;
521 output( "\n" );
525 /*******************************************************************
526 * get_extension
528 static char *get_extension( char *filename )
530 char *ext = strrchr( filename, '.' );
531 if (ext && strchr( ext, '/' )) ext = NULL;
532 return ext;
536 /*******************************************************************
537 * replace_extension
539 static char *replace_extension( const char *name, const char *old_ext, const char *new_ext )
541 char *ret;
542 size_t name_len = strlen( name );
543 size_t ext_len = strlen( old_ext );
545 if (name_len >= ext_len && !strcmp( name + name_len - ext_len, old_ext )) name_len -= ext_len;
546 ret = xmalloc( name_len + strlen( new_ext ) + 1 );
547 memcpy( ret, name, name_len );
548 strcpy( ret + name_len, new_ext );
549 return ret;
553 /*******************************************************************
554 * replace_filename
556 static char *replace_filename( const char *path, const char *name )
558 const char *p;
559 char *ret;
560 size_t len;
562 if (!path) return xstrdup( name );
563 if (!(p = strrchr( path, '/' ))) return xstrdup( name );
564 len = p - path + 1;
565 ret = xmalloc( len + strlen( name ) + 1 );
566 memcpy( ret, path, len );
567 strcpy( ret + len, name );
568 return ret;
572 /*******************************************************************
573 * strarray_replace_extension
575 static struct strarray strarray_replace_extension( const struct strarray *array,
576 const char *old_ext, const char *new_ext )
578 unsigned int i;
579 struct strarray ret;
581 ret.count = ret.size = array->count;
582 ret.str = xmalloc( sizeof(ret.str[0]) * ret.size );
583 for (i = 0; i < array->count; i++) ret.str[i] = replace_extension( array->str[i], old_ext, new_ext );
584 return ret;
588 /*******************************************************************
589 * replace_substr
591 static char *replace_substr( const char *str, const char *start, size_t len, const char *replace )
593 size_t pos = start - str;
594 char *ret = xmalloc( pos + strlen(replace) + strlen(start + len) + 1 );
595 memcpy( ret, str, pos );
596 strcpy( ret + pos, replace );
597 strcat( ret + pos, start + len );
598 return ret;
602 /*******************************************************************
603 * get_relative_path
605 * Determine where the destination path is located relative to the 'from' path.
607 static char *get_relative_path( const char *from, const char *dest )
609 const char *start;
610 char *ret, *p;
611 unsigned int dotdots = 0;
613 /* a path of "." is equivalent to an empty path */
614 if (!strcmp( from, "." )) from = "";
616 for (;;)
618 while (*from == '/') from++;
619 while (*dest == '/') dest++;
620 start = dest; /* save start of next path element */
621 if (!*from) break;
623 while (*from && *from != '/' && *from == *dest) { from++; dest++; }
624 if ((!*from || *from == '/') && (!*dest || *dest == '/')) continue;
626 /* count remaining elements in 'from' */
629 dotdots++;
630 while (*from && *from != '/') from++;
631 while (*from == '/') from++;
633 while (*from);
634 break;
637 if (!start[0] && !dotdots) return NULL; /* empty path */
639 ret = xmalloc( 3 * dotdots + strlen( start ) + 1 );
640 for (p = ret; dotdots; dotdots--, p += 3) memcpy( p, "../", 3 );
642 if (start[0]) strcpy( p, start );
643 else p[-1] = 0; /* remove trailing slash */
644 return ret;
648 /*******************************************************************
649 * concat_paths
651 static char *concat_paths( const char *base, const char *path )
653 if (!base || !base[0]) return xstrdup( path && path[0] ? path : "." );
654 if (!path || !path[0]) return xstrdup( base );
655 if (path[0] == '/') return xstrdup( path );
656 return strmake( "%s/%s", base, path );
660 /*******************************************************************
661 * base_dir_path
663 static char *base_dir_path( const struct makefile *make, const char *path )
665 return concat_paths( make->base_dir, path );
669 /*******************************************************************
670 * obj_dir_path
672 static char *obj_dir_path( const struct makefile *make, const char *path )
674 return concat_paths( make->obj_dir, path );
678 /*******************************************************************
679 * src_dir_path
681 static char *src_dir_path( const struct makefile *make, const char *path )
683 if (make->src_dir) return concat_paths( make->src_dir, path );
684 return obj_dir_path( make, path );
688 /*******************************************************************
689 * top_obj_dir_path
691 static char *top_obj_dir_path( const struct makefile *make, const char *path )
693 return concat_paths( make->top_obj_dir, path );
697 /*******************************************************************
698 * top_src_dir_path
700 static char *top_src_dir_path( const struct makefile *make, const char *path )
702 if (make->top_src_dir) return concat_paths( make->top_src_dir, path );
703 return top_obj_dir_path( make, path );
707 /*******************************************************************
708 * root_dir_path
710 static char *root_dir_path( const char *path )
712 return concat_paths( root_src_dir, path );
716 /*******************************************************************
717 * tools_dir_path
719 static char *tools_dir_path( const struct makefile *make, const char *path )
721 if (tools_dir) return top_obj_dir_path( make, strmake( "%s/tools/%s", tools_dir, path ));
722 return top_obj_dir_path( make, strmake( "tools/%s", path ));
726 /*******************************************************************
727 * tools_path
729 static char *tools_path( const struct makefile *make, const char *name )
731 return strmake( "%s/%s%s", tools_dir_path( make, name ), name, tools_ext );
735 /*******************************************************************
736 * get_line
738 static char *get_line( FILE *file )
740 static char *buffer;
741 static size_t size;
743 if (!size)
745 size = 1024;
746 buffer = xmalloc( size );
748 if (!fgets( buffer, size, file )) return NULL;
749 input_line++;
751 for (;;)
753 char *p = buffer + strlen(buffer);
754 /* if line is larger than buffer, resize buffer */
755 while (p == buffer + size - 1 && p[-1] != '\n')
757 buffer = xrealloc( buffer, size * 2 );
758 if (!fgets( buffer + size - 1, size + 1, file )) break;
759 p = buffer + strlen(buffer);
760 size *= 2;
762 if (p > buffer && p[-1] == '\n')
764 *(--p) = 0;
765 if (p > buffer && p[-1] == '\r') *(--p) = 0;
766 if (p > buffer && p[-1] == '\\')
768 *(--p) = 0;
769 /* line ends in backslash, read continuation line */
770 if (!fgets( p, size - (p - buffer), file )) return buffer;
771 input_line++;
772 continue;
775 return buffer;
780 /*******************************************************************
781 * hash_filename
783 static unsigned int hash_filename( const char *name )
785 /* FNV-1 hash */
786 unsigned int ret = 2166136261u;
787 while (*name) ret = (ret * 16777619) ^ *name++;
788 return ret % HASH_SIZE;
792 /*******************************************************************
793 * add_file
795 static struct file *add_file( const char *name )
797 struct file *file = xmalloc( sizeof(*file) );
798 memset( file, 0, sizeof(*file) );
799 file->name = xstrdup( name );
800 return file;
804 /*******************************************************************
805 * add_dependency
807 static void add_dependency( struct file *file, const char *name, enum incl_type type )
809 /* enforce some rules for the Wine tree */
811 if (!memcmp( name, "../", 3 ))
812 fatal_error( "#include directive with relative path not allowed\n" );
814 if (!strcmp( name, "config.h" ))
816 if (strendswith( file->name, ".h" ))
817 fatal_error( "config.h must not be included by a header file\n" );
818 if (file->deps_count)
819 fatal_error( "config.h must be included before anything else\n" );
821 else if (!strcmp( name, "wine/port.h" ))
823 if (strendswith( file->name, ".h" ))
824 fatal_error( "wine/port.h must not be included by a header file\n" );
825 if (!file->deps_count) fatal_error( "config.h must be included before wine/port.h\n" );
826 if (file->deps_count > 1)
827 fatal_error( "wine/port.h must be included before everything except config.h\n" );
828 if (strcmp( file->deps[0].name, "config.h" ))
829 fatal_error( "config.h must be included before wine/port.h\n" );
832 if (file->deps_count >= file->deps_size)
834 file->deps_size *= 2;
835 if (file->deps_size < 16) file->deps_size = 16;
836 file->deps = xrealloc( file->deps, file->deps_size * sizeof(*file->deps) );
838 file->deps[file->deps_count].line = input_line;
839 file->deps[file->deps_count].type = type;
840 file->deps[file->deps_count].name = xstrdup( name );
841 file->deps_count++;
845 /*******************************************************************
846 * find_src_file
848 static struct incl_file *find_src_file( const struct makefile *make, const char *name )
850 struct incl_file *file;
852 LIST_FOR_EACH_ENTRY( file, &make->sources, struct incl_file, entry )
853 if (!strcmp( name, file->name )) return file;
854 return NULL;
857 /*******************************************************************
858 * find_include_file
860 static struct incl_file *find_include_file( const struct makefile *make, const char *name )
862 struct incl_file *file;
864 LIST_FOR_EACH_ENTRY( file, &make->includes, struct incl_file, entry )
865 if (!strcmp( name, file->name )) return file;
866 return NULL;
869 /*******************************************************************
870 * add_include
872 * Add an include file if it doesn't already exists.
874 static struct incl_file *add_include( struct makefile *make, struct incl_file *parent,
875 const char *name, int line, enum incl_type type )
877 struct incl_file *include;
879 if (parent->files_count >= parent->files_size)
881 parent->files_size *= 2;
882 if (parent->files_size < 16) parent->files_size = 16;
883 parent->files = xrealloc( parent->files, parent->files_size * sizeof(*parent->files) );
886 LIST_FOR_EACH_ENTRY( include, &make->includes, struct incl_file, entry )
887 if (!strcmp( name, include->name )) goto found;
889 include = xmalloc( sizeof(*include) );
890 memset( include, 0, sizeof(*include) );
891 include->name = xstrdup(name);
892 include->included_by = parent;
893 include->included_line = line;
894 include->type = type;
895 list_add_tail( &make->includes, &include->entry );
896 found:
897 parent->files[parent->files_count++] = include;
898 return include;
902 /*******************************************************************
903 * add_generated_source
905 * Add a generated source file to the list.
907 static struct incl_file *add_generated_source( struct makefile *make,
908 const char *name, const char *filename )
910 struct incl_file *file;
912 if ((file = find_src_file( make, name ))) return file; /* we already have it */
913 file = xmalloc( sizeof(*file) );
914 memset( file, 0, sizeof(*file) );
915 file->file = add_file( name );
916 file->name = xstrdup( name );
917 file->filename = obj_dir_path( make, filename ? filename : name );
918 file->file->flags = FLAG_GENERATED;
919 list_add_tail( &make->sources, &file->entry );
920 return file;
924 /*******************************************************************
925 * parse_include_directive
927 static void parse_include_directive( struct file *source, char *str )
929 char quote, *include, *p = str;
931 while (*p && isspace(*p)) p++;
932 if (*p != '\"' && *p != '<' ) return;
933 quote = *p++;
934 if (quote == '<') quote = '>';
935 include = p;
936 while (*p && (*p != quote)) p++;
937 if (!*p) fatal_error( "malformed include directive '%s'\n", str );
938 *p = 0;
939 add_dependency( source, include, (quote == '>') ? INCL_SYSTEM : INCL_NORMAL );
943 /*******************************************************************
944 * parse_pragma_directive
946 static void parse_pragma_directive( struct file *source, char *str )
948 char *flag, *p = str;
950 if (!isspace( *p )) return;
951 while (*p && isspace(*p)) p++;
952 p = strtok( p, " \t" );
953 if (strcmp( p, "makedep" )) return;
955 while ((flag = strtok( NULL, " \t" )))
957 if (!strcmp( flag, "depend" ))
959 while ((p = strtok( NULL, " \t" ))) add_dependency( source, p, INCL_NORMAL );
960 return;
962 else if (!strcmp( flag, "install" )) source->flags |= FLAG_INSTALL;
964 if (strendswith( source->name, ".idl" ))
966 if (!strcmp( flag, "header" )) source->flags |= FLAG_IDL_HEADER;
967 else if (!strcmp( flag, "proxy" )) source->flags |= FLAG_IDL_PROXY;
968 else if (!strcmp( flag, "client" )) source->flags |= FLAG_IDL_CLIENT;
969 else if (!strcmp( flag, "server" )) source->flags |= FLAG_IDL_SERVER;
970 else if (!strcmp( flag, "ident" )) source->flags |= FLAG_IDL_IDENT;
971 else if (!strcmp( flag, "typelib" )) source->flags |= FLAG_IDL_TYPELIB;
972 else if (!strcmp( flag, "register" )) source->flags |= FLAG_IDL_REGISTER;
973 else if (!strcmp( flag, "regtypelib" )) source->flags |= FLAG_IDL_REGTYPELIB;
975 else if (strendswith( source->name, ".rc" ))
977 if (!strcmp( flag, "po" )) source->flags |= FLAG_RC_PO;
979 else if (strendswith( source->name, ".sfd" ))
981 if (!strcmp( flag, "font" ))
983 struct strarray *array = source->args;
985 if (!array)
987 source->args = array = xmalloc( sizeof(*array) );
988 *array = empty_strarray;
989 source->flags |= FLAG_SFD_FONTS;
991 strarray_add( array, xstrdup( strtok( NULL, "" )));
992 return;
995 else if (!strcmp( flag, "implib" )) source->flags |= FLAG_C_IMPLIB;
1000 /*******************************************************************
1001 * parse_cpp_directive
1003 static void parse_cpp_directive( struct file *source, char *str )
1005 while (*str && isspace(*str)) str++;
1006 if (*str++ != '#') return;
1007 while (*str && isspace(*str)) str++;
1009 if (!strncmp( str, "include", 7 ))
1010 parse_include_directive( source, str + 7 );
1011 else if (!strncmp( str, "import", 6 ) && strendswith( source->name, ".m" ))
1012 parse_include_directive( source, str + 6 );
1013 else if (!strncmp( str, "pragma", 6 ))
1014 parse_pragma_directive( source, str + 6 );
1018 /*******************************************************************
1019 * parse_idl_file
1021 static void parse_idl_file( struct file *source, FILE *file )
1023 char *buffer, *include;
1025 input_line = 0;
1027 while ((buffer = get_line( file )))
1029 char quote;
1030 char *p = buffer;
1031 while (*p && isspace(*p)) p++;
1033 if (!strncmp( p, "importlib", 9 ))
1035 p += 9;
1036 while (*p && isspace(*p)) p++;
1037 if (*p++ != '(') continue;
1038 while (*p && isspace(*p)) p++;
1039 if (*p++ != '"') continue;
1040 include = p;
1041 while (*p && (*p != '"')) p++;
1042 if (!*p) fatal_error( "malformed importlib directive\n" );
1043 *p = 0;
1044 add_dependency( source, include, INCL_IMPORTLIB );
1045 continue;
1048 if (!strncmp( p, "import", 6 ))
1050 p += 6;
1051 while (*p && isspace(*p)) p++;
1052 if (*p != '"') continue;
1053 include = ++p;
1054 while (*p && (*p != '"')) p++;
1055 if (!*p) fatal_error( "malformed import directive\n" );
1056 *p = 0;
1057 add_dependency( source, include, INCL_IMPORT );
1058 continue;
1061 /* check for #include inside cpp_quote */
1062 if (!strncmp( p, "cpp_quote", 9 ))
1064 p += 9;
1065 while (*p && isspace(*p)) p++;
1066 if (*p++ != '(') continue;
1067 while (*p && isspace(*p)) p++;
1068 if (*p++ != '"') continue;
1069 if (*p++ != '#') continue;
1070 while (*p && isspace(*p)) p++;
1071 if (strncmp( p, "include", 7 )) continue;
1072 p += 7;
1073 while (*p && isspace(*p)) p++;
1074 if (*p == '\\' && p[1] == '"')
1076 p += 2;
1077 quote = '"';
1079 else
1081 if (*p++ != '<' ) continue;
1082 quote = '>';
1084 include = p;
1085 while (*p && (*p != quote)) p++;
1086 if (!*p || (quote == '"' && p[-1] != '\\'))
1087 fatal_error( "malformed #include directive inside cpp_quote\n" );
1088 if (quote == '"') p--; /* remove backslash */
1089 *p = 0;
1090 add_dependency( source, include, (quote == '>') ? INCL_CPP_QUOTE_SYSTEM : INCL_CPP_QUOTE );
1091 continue;
1094 parse_cpp_directive( source, p );
1098 /*******************************************************************
1099 * parse_c_file
1101 static void parse_c_file( struct file *source, FILE *file )
1103 char *buffer;
1105 input_line = 0;
1106 while ((buffer = get_line( file )))
1108 parse_cpp_directive( source, buffer );
1113 /*******************************************************************
1114 * parse_rc_file
1116 static void parse_rc_file( struct file *source, FILE *file )
1118 char *buffer, *include;
1120 input_line = 0;
1121 while ((buffer = get_line( file )))
1123 char quote;
1124 char *p = buffer;
1125 while (*p && isspace(*p)) p++;
1127 if (p[0] == '/' && p[1] == '*') /* check for magic makedep comment */
1129 p += 2;
1130 while (*p && isspace(*p)) p++;
1131 if (strncmp( p, "@makedep:", 9 )) continue;
1132 p += 9;
1133 while (*p && isspace(*p)) p++;
1134 quote = '"';
1135 if (*p == quote)
1137 include = ++p;
1138 while (*p && *p != quote) p++;
1140 else
1142 include = p;
1143 while (*p && !isspace(*p) && *p != '*') p++;
1145 if (!*p)
1146 fatal_error( "malformed makedep comment\n" );
1147 *p = 0;
1148 add_dependency( source, include, (quote == '>') ? INCL_SYSTEM : INCL_NORMAL );
1149 continue;
1152 parse_cpp_directive( source, buffer );
1157 /*******************************************************************
1158 * parse_in_file
1160 static void parse_in_file( struct file *source, FILE *file )
1162 char *p, *buffer;
1164 /* make sure it gets rebuilt when the version changes */
1165 add_dependency( source, "config.h", INCL_SYSTEM );
1167 if (!strendswith( source->name, ".man.in" )) return; /* not a man page */
1169 input_line = 0;
1170 while ((buffer = get_line( file )))
1172 if (strncmp( buffer, ".TH", 3 )) continue;
1173 if (!(p = strtok( buffer, " \t" ))) continue; /* .TH */
1174 if (!(p = strtok( NULL, " \t" ))) continue; /* program name */
1175 if (!(p = strtok( NULL, " \t" ))) continue; /* man section */
1176 source->args = xstrdup( p );
1177 return;
1182 /*******************************************************************
1183 * parse_sfd_file
1185 static void parse_sfd_file( struct file *source, FILE *file )
1187 char *p, *eol, *buffer;
1189 input_line = 0;
1190 while ((buffer = get_line( file )))
1192 if (strncmp( buffer, "UComments:", 10 )) continue;
1193 p = buffer + 10;
1194 while (*p == ' ') p++;
1195 if (p[0] == '"' && p[1] && buffer[strlen(buffer) - 1] == '"')
1197 p++;
1198 buffer[strlen(buffer) - 1] = 0;
1200 while ((eol = strstr( p, "+AAoA" )))
1202 *eol = 0;
1203 while (*p && isspace(*p)) p++;
1204 if (*p++ == '#')
1206 while (*p && isspace(*p)) p++;
1207 if (!strncmp( p, "pragma", 6 )) parse_pragma_directive( source, p + 6 );
1209 p = eol + 5;
1211 while (*p && isspace(*p)) p++;
1212 if (*p++ != '#') return;
1213 while (*p && isspace(*p)) p++;
1214 if (!strncmp( p, "pragma", 6 )) parse_pragma_directive( source, p + 6 );
1215 return;
1220 static const struct
1222 const char *ext;
1223 void (*parse)( struct file *file, FILE *f );
1224 } parse_functions[] =
1226 { ".c", parse_c_file },
1227 { ".h", parse_c_file },
1228 { ".inl", parse_c_file },
1229 { ".l", parse_c_file },
1230 { ".m", parse_c_file },
1231 { ".rh", parse_c_file },
1232 { ".x", parse_c_file },
1233 { ".y", parse_c_file },
1234 { ".idl", parse_idl_file },
1235 { ".rc", parse_rc_file },
1236 { ".in", parse_in_file },
1237 { ".sfd", parse_sfd_file }
1240 /*******************************************************************
1241 * load_file
1243 static struct file *load_file( const char *name )
1245 struct file *file;
1246 FILE *f;
1247 unsigned int i, hash = hash_filename( name );
1249 LIST_FOR_EACH_ENTRY( file, &files[hash], struct file, entry )
1250 if (!strcmp( name, file->name )) return file;
1252 if (!(f = fopen( name, "r" ))) return NULL;
1254 file = add_file( name );
1255 list_add_tail( &files[hash], &file->entry );
1256 input_file_name = file->name;
1257 input_line = 0;
1259 for (i = 0; i < sizeof(parse_functions) / sizeof(parse_functions[0]); i++)
1261 if (!strendswith( name, parse_functions[i].ext )) continue;
1262 parse_functions[i].parse( file, f );
1263 break;
1266 fclose( f );
1267 input_file_name = NULL;
1269 return file;
1273 /*******************************************************************
1274 * open_include_path_file
1276 * Open a file from a directory on the include path.
1278 static struct file *open_include_path_file( const struct makefile *make, const char *dir,
1279 const char *name, char **filename )
1281 char *src_path = base_dir_path( make, concat_paths( dir, name ));
1282 struct file *ret = load_file( src_path );
1284 if (ret) *filename = src_dir_path( make, concat_paths( dir, name ));
1285 return ret;
1289 /*******************************************************************
1290 * open_file_same_dir
1292 * Open a file in the same directory as the parent.
1294 static struct file *open_file_same_dir( const struct incl_file *parent, const char *name, char **filename )
1296 char *src_path = replace_filename( parent->file->name, name );
1297 struct file *ret = load_file( src_path );
1299 if (ret) *filename = replace_filename( parent->filename, name );
1300 free( src_path );
1301 return ret;
1305 /*******************************************************************
1306 * open_local_file
1308 * Open a file in the source directory of the makefile.
1310 static struct file *open_local_file( const struct makefile *make, const char *path, char **filename )
1312 char *src_path = root_dir_path( base_dir_path( make, path ));
1313 struct file *ret = load_file( src_path );
1315 /* if not found, try parent dir */
1316 if (!ret && make->parent_dir)
1318 free( src_path );
1319 path = strmake( "%s/%s", make->parent_dir, path );
1320 src_path = root_dir_path( base_dir_path( make, path ));
1321 ret = load_file( src_path );
1324 if (ret) *filename = src_dir_path( make, path );
1325 free( src_path );
1326 return ret;
1330 /*******************************************************************
1331 * open_global_file
1333 * Open a file in the top-level source directory.
1335 static struct file *open_global_file( const struct makefile *make, const char *path, char **filename )
1337 char *src_path = root_dir_path( path );
1338 struct file *ret = load_file( src_path );
1340 if (ret) *filename = top_src_dir_path( make, path );
1341 free( src_path );
1342 return ret;
1346 /*******************************************************************
1347 * open_global_header
1349 * Open a file in the global include source directory.
1351 static struct file *open_global_header( const struct makefile *make, const char *path, char **filename )
1353 return open_global_file( make, strmake( "include/%s", path ), filename );
1357 /*******************************************************************
1358 * open_src_file
1360 static struct file *open_src_file( const struct makefile *make, struct incl_file *pFile )
1362 struct file *file = open_local_file( make, pFile->name, &pFile->filename );
1364 if (!file) fatal_perror( "open %s", pFile->name );
1365 return file;
1369 /*******************************************************************
1370 * open_include_file
1372 static struct file *open_include_file( const struct makefile *make, struct incl_file *pFile )
1374 struct file *file = NULL;
1375 char *filename;
1376 unsigned int i, len;
1378 errno = ENOENT;
1380 /* check for generated bison header */
1382 if (strendswith( pFile->name, ".tab.h" ) &&
1383 (file = open_local_file( make, replace_extension( pFile->name, ".tab.h", ".y" ), &filename )))
1385 pFile->sourcename = filename;
1386 pFile->filename = obj_dir_path( make, pFile->name );
1387 return file;
1390 /* check for corresponding idl file in source dir */
1392 if (strendswith( pFile->name, ".h" ) &&
1393 (file = open_local_file( make, replace_extension( pFile->name, ".h", ".idl" ), &filename )))
1395 pFile->sourcename = filename;
1396 pFile->filename = obj_dir_path( make, pFile->name );
1397 return file;
1400 /* check for corresponding tlb file in source dir */
1402 if (strendswith( pFile->name, ".tlb" ) &&
1403 (file = open_local_file( make, replace_extension( pFile->name, ".tlb", ".idl" ), &filename )))
1405 pFile->sourcename = filename;
1406 pFile->filename = obj_dir_path( make, pFile->name );
1407 return file;
1410 /* now try in source dir */
1411 if ((file = open_local_file( make, pFile->name, &pFile->filename ))) return file;
1413 /* check for corresponding idl file in global includes */
1415 if (strendswith( pFile->name, ".h" ) &&
1416 (file = open_global_header( make, replace_extension( pFile->name, ".h", ".idl" ), &filename )))
1418 pFile->sourcename = filename;
1419 pFile->filename = top_obj_dir_path( make, strmake( "include/%s", pFile->name ));
1420 return file;
1423 /* check for corresponding .in file in global includes (for config.h.in) */
1425 if (strendswith( pFile->name, ".h" ) &&
1426 (file = open_global_header( make, replace_extension( pFile->name, ".h", ".h.in" ), &filename )))
1428 pFile->sourcename = filename;
1429 pFile->filename = top_obj_dir_path( make, strmake( "include/%s", pFile->name ));
1430 return file;
1433 /* check for corresponding .x file in global includes */
1435 if (strendswith( pFile->name, "tmpl.h" ) &&
1436 (file = open_global_header( make, replace_extension( pFile->name, ".h", ".x" ), &filename )))
1438 pFile->sourcename = filename;
1439 pFile->filename = top_obj_dir_path( make, strmake( "include/%s", pFile->name ));
1440 return file;
1443 /* check for corresponding .tlb file in global includes */
1445 if (strendswith( pFile->name, ".tlb" ) &&
1446 (file = open_global_header( make, replace_extension( pFile->name, ".tlb", ".idl" ), &filename )))
1448 pFile->sourcename = filename;
1449 pFile->filename = top_obj_dir_path( make, strmake( "include/%s", pFile->name ));
1450 return file;
1453 /* check in global includes source dir */
1455 if ((file = open_global_header( make, pFile->name, &pFile->filename ))) return file;
1457 /* check in global msvcrt includes */
1458 if (make->use_msvcrt &&
1459 (file = open_global_header( make, strmake( "msvcrt/%s", pFile->name ), &pFile->filename )))
1460 return file;
1462 /* now search in include paths */
1463 for (i = 0; i < make->include_paths.count; i++)
1465 const char *dir = make->include_paths.str[i];
1466 const char *prefix = make->top_src_dir ? make->top_src_dir : make->top_obj_dir;
1468 if (prefix)
1470 len = strlen( prefix );
1471 if (!strncmp( dir, prefix, len ) && (!dir[len] || dir[len] == '/'))
1473 while (dir[len] == '/') len++;
1474 file = open_global_file( make, concat_paths( dir + len, pFile->name ), &pFile->filename );
1475 if (file) return file;
1477 if (make->top_src_dir) continue; /* ignore paths that don't point to the top source dir */
1479 if (*dir != '/')
1481 if ((file = open_include_path_file( make, dir, pFile->name, &pFile->filename )))
1482 return file;
1485 if (pFile->type == INCL_SYSTEM) return NULL; /* ignore system files we cannot find */
1487 /* try in src file directory */
1488 if ((file = open_file_same_dir( pFile->included_by, pFile->name, &pFile->filename ))) return file;
1490 fprintf( stderr, "%s:%d: error: ", pFile->included_by->file->name, pFile->included_line );
1491 perror( pFile->name );
1492 pFile = pFile->included_by;
1493 while (pFile && pFile->included_by)
1495 const char *parent = pFile->included_by->sourcename;
1496 if (!parent) parent = pFile->included_by->file->name;
1497 fprintf( stderr, "%s:%d: note: %s was first included here\n",
1498 parent, pFile->included_line, pFile->name );
1499 pFile = pFile->included_by;
1501 exit(1);
1505 /*******************************************************************
1506 * add_all_includes
1508 static void add_all_includes( struct makefile *make, struct incl_file *parent, struct file *file )
1510 unsigned int i;
1512 parent->files_count = 0;
1513 parent->files_size = file->deps_count;
1514 parent->files = xmalloc( parent->files_size * sizeof(*parent->files) );
1515 for (i = 0; i < file->deps_count; i++)
1517 switch (file->deps[i].type)
1519 case INCL_NORMAL:
1520 case INCL_IMPORT:
1521 add_include( make, parent, file->deps[i].name, file->deps[i].line, INCL_NORMAL );
1522 break;
1523 case INCL_IMPORTLIB:
1524 add_include( make, parent, file->deps[i].name, file->deps[i].line, INCL_IMPORTLIB );
1525 break;
1526 case INCL_SYSTEM:
1527 add_include( make, parent, file->deps[i].name, file->deps[i].line, INCL_SYSTEM );
1528 break;
1529 case INCL_CPP_QUOTE:
1530 case INCL_CPP_QUOTE_SYSTEM:
1531 break;
1537 /*******************************************************************
1538 * parse_file
1540 static void parse_file( struct makefile *make, struct incl_file *source, int src )
1542 struct file *file = src ? open_src_file( make, source ) : open_include_file( make, source );
1544 if (!file) return;
1546 source->file = file;
1547 source->files_count = 0;
1548 source->files_size = file->deps_count;
1549 source->files = xmalloc( source->files_size * sizeof(*source->files) );
1551 if (source->sourcename)
1553 if (strendswith( source->sourcename, ".idl" ))
1555 unsigned int i;
1557 if (strendswith( source->name, ".tlb" )) return; /* typelibs don't include anything */
1559 /* generated .h file always includes these */
1560 add_include( make, source, "rpc.h", 0, INCL_NORMAL );
1561 add_include( make, source, "rpcndr.h", 0, INCL_NORMAL );
1562 for (i = 0; i < file->deps_count; i++)
1564 switch (file->deps[i].type)
1566 case INCL_IMPORT:
1567 if (strendswith( file->deps[i].name, ".idl" ))
1568 add_include( make, source, replace_extension( file->deps[i].name, ".idl", ".h" ),
1569 file->deps[i].line, INCL_NORMAL );
1570 else
1571 add_include( make, source, file->deps[i].name, file->deps[i].line, INCL_NORMAL );
1572 break;
1573 case INCL_CPP_QUOTE:
1574 add_include( make, source, file->deps[i].name, file->deps[i].line, INCL_NORMAL );
1575 break;
1576 case INCL_CPP_QUOTE_SYSTEM:
1577 add_include( make, source, file->deps[i].name, file->deps[i].line, INCL_SYSTEM );
1578 break;
1579 case INCL_NORMAL:
1580 case INCL_SYSTEM:
1581 case INCL_IMPORTLIB:
1582 break;
1585 return;
1587 if (strendswith( source->sourcename, ".y" ))
1588 return; /* generated .tab.h doesn't include anything */
1591 add_all_includes( make, source, file );
1595 /*******************************************************************
1596 * add_src_file
1598 * Add a source file to the list.
1600 static struct incl_file *add_src_file( struct makefile *make, const char *name )
1602 struct incl_file *file;
1604 if ((file = find_src_file( make, name ))) return file; /* we already have it */
1605 file = xmalloc( sizeof(*file) );
1606 memset( file, 0, sizeof(*file) );
1607 file->name = xstrdup(name);
1608 list_add_tail( &make->sources, &file->entry );
1609 parse_file( make, file, 1 );
1610 return file;
1614 /*******************************************************************
1615 * open_input_makefile
1617 static FILE *open_input_makefile( const struct makefile *make )
1619 FILE *ret;
1621 if (make->base_dir)
1622 input_file_name = root_dir_path( base_dir_path( make, strmake( "%s.in", output_makefile_name )));
1623 else
1624 input_file_name = output_makefile_name; /* always use output name for main Makefile */
1626 input_line = 0;
1627 if (!(ret = fopen( input_file_name, "r" ))) fatal_perror( "open" );
1628 return ret;
1632 /*******************************************************************
1633 * get_make_variable
1635 static const char *get_make_variable( const struct makefile *make, const char *name )
1637 const char *ret;
1639 if ((ret = strarray_get_value( &cmdline_vars, name ))) return ret;
1640 if ((ret = strarray_get_value( &make->vars, name ))) return ret;
1641 if (top_makefile && (ret = strarray_get_value( &top_makefile->vars, name ))) return ret;
1642 return NULL;
1646 /*******************************************************************
1647 * get_expanded_make_variable
1649 static char *get_expanded_make_variable( const struct makefile *make, const char *name )
1651 const char *var;
1652 char *p, *end, *expand, *tmp;
1654 var = get_make_variable( make, name );
1655 if (!var) return NULL;
1657 p = expand = xstrdup( var );
1658 while ((p = strchr( p, '$' )))
1660 if (p[1] == '(')
1662 if (!(end = strchr( p + 2, ')' ))) fatal_error( "syntax error in '%s'\n", expand );
1663 *end++ = 0;
1664 if (strchr( p + 2, ':' )) fatal_error( "pattern replacement not supported for '%s'\n", p + 2 );
1665 var = get_make_variable( make, p + 2 );
1666 tmp = replace_substr( expand, p, end - p, var ? var : "" );
1667 /* switch to the new string */
1668 p = tmp + (p - expand);
1669 free( expand );
1670 expand = tmp;
1672 else if (p[1] == '{') /* don't expand ${} variables */
1674 if (!(end = strchr( p + 2, '}' ))) fatal_error( "syntax error in '%s'\n", expand );
1675 p = end + 1;
1677 else if (p[1] == '$')
1679 p += 2;
1681 else fatal_error( "syntax error in '%s'\n", expand );
1684 /* consider empty variables undefined */
1685 p = expand;
1686 while (*p && isspace(*p)) p++;
1687 if (*p) return expand;
1688 free( expand );
1689 return NULL;
1693 /*******************************************************************
1694 * get_expanded_make_var_array
1696 static struct strarray get_expanded_make_var_array( const struct makefile *make, const char *name )
1698 struct strarray ret = empty_strarray;
1699 char *value, *token;
1701 if ((value = get_expanded_make_variable( make, name )))
1702 for (token = strtok( value, " \t" ); token; token = strtok( NULL, " \t" ))
1703 strarray_add( &ret, token );
1704 return ret;
1708 /*******************************************************************
1709 * get_expanded_file_local_var
1711 static struct strarray get_expanded_file_local_var( const struct makefile *make, const char *file,
1712 const char *name )
1714 char *p, *var = strmake( "%s_%s", file, name );
1716 for (p = var; *p; p++) if (!isalnum( *p )) *p = '_';
1717 return get_expanded_make_var_array( make, var );
1721 /*******************************************************************
1722 * set_make_variable
1724 static int set_make_variable( struct strarray *array, const char *assignment )
1726 char *p, *name;
1728 p = name = xstrdup( assignment );
1729 while (isalnum(*p) || *p == '_') p++;
1730 if (name == p) return 0; /* not a variable */
1731 if (isspace(*p))
1733 *p++ = 0;
1734 while (isspace(*p)) p++;
1736 if (*p != '=') return 0; /* not an assignment */
1737 *p++ = 0;
1738 while (isspace(*p)) p++;
1740 strarray_set_value( array, name, p );
1741 return 1;
1745 /*******************************************************************
1746 * parse_makefile
1748 static struct makefile *parse_makefile( const char *path )
1750 char *buffer;
1751 FILE *file;
1752 struct makefile *make = xmalloc( sizeof(*make) );
1754 memset( make, 0, sizeof(*make) );
1755 if (path)
1757 make->top_obj_dir = get_relative_path( path, "" );
1758 make->base_dir = path;
1759 if (!strcmp( make->base_dir, "." )) make->base_dir = NULL;
1762 file = open_input_makefile( make );
1763 while ((buffer = get_line( file )))
1765 if (!strncmp( buffer, separator, strlen(separator) )) break;
1766 if (*buffer == '\t') continue; /* command */
1767 while (isspace( *buffer )) buffer++;
1768 if (*buffer == '#') continue; /* comment */
1769 set_make_variable( &make->vars, buffer );
1771 fclose( file );
1772 input_file_name = NULL;
1773 return make;
1777 /*******************************************************************
1778 * add_generated_sources
1780 static void add_generated_sources( struct makefile *make )
1782 struct incl_file *source, *next, *file;
1784 LIST_FOR_EACH_ENTRY_SAFE( source, next, &make->sources, struct incl_file, entry )
1786 if (source->file->flags & FLAG_IDL_CLIENT)
1788 file = add_generated_source( make, replace_extension( source->name, ".idl", "_c.c" ), NULL );
1789 add_dependency( file->file, replace_extension( source->name, ".idl", ".h" ), INCL_NORMAL );
1790 add_all_includes( make, file, file->file );
1792 if (source->file->flags & FLAG_IDL_SERVER)
1794 file = add_generated_source( make, replace_extension( source->name, ".idl", "_s.c" ), NULL );
1795 add_dependency( file->file, "wine/exception.h", INCL_NORMAL );
1796 add_dependency( file->file, replace_extension( source->name, ".idl", ".h" ), INCL_NORMAL );
1797 add_all_includes( make, file, file->file );
1799 if (source->file->flags & FLAG_IDL_IDENT)
1801 file = add_generated_source( make, replace_extension( source->name, ".idl", "_i.c" ), NULL );
1802 add_dependency( file->file, "rpc.h", INCL_NORMAL );
1803 add_dependency( file->file, "rpcndr.h", INCL_NORMAL );
1804 add_dependency( file->file, "guiddef.h", INCL_NORMAL );
1805 add_all_includes( make, file, file->file );
1807 if (source->file->flags & FLAG_IDL_PROXY)
1809 file = add_generated_source( make, "dlldata.o", "dlldata.c" );
1810 add_dependency( file->file, "objbase.h", INCL_NORMAL );
1811 add_dependency( file->file, "rpcproxy.h", INCL_NORMAL );
1812 add_all_includes( make, file, file->file );
1813 file = add_generated_source( make, replace_extension( source->name, ".idl", "_p.c" ), NULL );
1814 add_dependency( file->file, "objbase.h", INCL_NORMAL );
1815 add_dependency( file->file, "rpcproxy.h", INCL_NORMAL );
1816 add_dependency( file->file, "wine/exception.h", INCL_NORMAL );
1817 add_dependency( file->file, replace_extension( source->name, ".idl", ".h" ), INCL_NORMAL );
1818 add_all_includes( make, file, file->file );
1820 if (source->file->flags & FLAG_IDL_TYPELIB)
1822 add_generated_source( make, replace_extension( source->name, ".idl", ".tlb" ), NULL );
1824 if (source->file->flags & FLAG_IDL_REGTYPELIB)
1826 add_generated_source( make, replace_extension( source->name, ".idl", "_t.res" ), NULL );
1828 if (source->file->flags & FLAG_IDL_REGISTER)
1830 add_generated_source( make, replace_extension( source->name, ".idl", "_r.res" ), NULL );
1832 if (source->file->flags & FLAG_IDL_HEADER)
1834 add_generated_source( make, replace_extension( source->name, ".idl", ".h" ), NULL );
1836 if (!source->file->flags && strendswith( source->name, ".idl" ))
1838 add_generated_source( make, replace_extension( source->name, ".idl", ".h" ), NULL );
1840 if (strendswith( source->name, ".x" ))
1842 add_generated_source( make, replace_extension( source->name, ".x", ".h" ), NULL );
1844 if (strendswith( source->name, ".y" ))
1846 file = add_generated_source( make, replace_extension( source->name, ".y", ".tab.c" ), NULL );
1847 /* steal the includes list from the source file */
1848 file->files_count = source->files_count;
1849 file->files_size = source->files_size;
1850 file->files = source->files;
1851 source->files_count = source->files_size = 0;
1852 source->files = NULL;
1854 if (strendswith( source->name, ".l" ))
1856 file = add_generated_source( make, replace_extension( source->name, ".l", ".yy.c" ), NULL );
1857 /* steal the includes list from the source file */
1858 file->files_count = source->files_count;
1859 file->files_size = source->files_size;
1860 file->files = source->files;
1861 source->files_count = source->files_size = 0;
1862 source->files = NULL;
1864 if (source->file->flags & FLAG_C_IMPLIB)
1866 if (!make->staticimplib && make->importlib && *dll_ext)
1867 make->staticimplib = strmake( "lib%s.a", make->importlib );
1869 if (strendswith( source->name, ".po" ))
1871 if (!make->disabled)
1872 strarray_add_uniq( &linguas, replace_extension( source->name, ".po", "" ));
1875 if (make->testdll)
1877 file = add_generated_source( make, "testlist.o", "testlist.c" );
1878 add_dependency( file->file, "wine/test.h", INCL_NORMAL );
1879 add_all_includes( make, file, file->file );
1884 /*******************************************************************
1885 * create_dir
1887 static void create_dir( const char *dir )
1889 char *p, *path;
1891 p = path = xstrdup( dir );
1892 while ((p = strchr( p, '/' )))
1894 *p = 0;
1895 if (mkdir( path, 0755 ) == -1 && errno != EEXIST) fatal_perror( "mkdir %s", path );
1896 *p++ = '/';
1897 while (*p == '/') p++;
1899 if (mkdir( path, 0755 ) == -1 && errno != EEXIST) fatal_perror( "mkdir %s", path );
1900 free( path );
1904 /*******************************************************************
1905 * create_file_directories
1907 * Create the base directories of all the files.
1909 static void create_file_directories( const struct makefile *make, struct strarray files )
1911 struct strarray subdirs = empty_strarray;
1912 unsigned int i;
1913 char *dir;
1915 for (i = 0; i < files.count; i++)
1917 if (!strchr( files.str[i], '/' )) continue;
1918 dir = base_dir_path( make, files.str[i] );
1919 *strrchr( dir, '/' ) = 0;
1920 strarray_add_uniq( &subdirs, dir );
1923 for (i = 0; i < subdirs.count; i++) create_dir( subdirs.str[i] );
1927 /*******************************************************************
1928 * output_filenames_obj_dir
1930 static void output_filenames_obj_dir( const struct makefile *make, struct strarray array )
1932 unsigned int i;
1934 for (i = 0; i < array.count; i++) output_filename( obj_dir_path( make, array.str[i] ));
1938 /*******************************************************************
1939 * get_dependencies
1941 static void get_dependencies( struct incl_file *file, struct incl_file *source )
1943 unsigned int i;
1945 if (!file->filename) return;
1947 if (file != source)
1949 if (file->owner == source) return; /* already processed */
1950 if (file->type == INCL_IMPORTLIB &&
1951 !(source->file->flags & (FLAG_IDL_TYPELIB | FLAG_IDL_REGTYPELIB)))
1952 return; /* library is imported only when building a typelib */
1953 file->owner = source;
1954 strarray_add( &source->dependencies, file->filename );
1956 for (i = 0; i < file->files_count; i++) get_dependencies( file->files[i], source );
1960 /*******************************************************************
1961 * get_local_dependencies
1963 * Get the local dependencies of a given target.
1965 static struct strarray get_local_dependencies( const struct makefile *make, const char *name,
1966 struct strarray targets )
1968 unsigned int i;
1969 struct strarray deps = get_expanded_file_local_var( make, name, "DEPS" );
1971 for (i = 0; i < deps.count; i++)
1973 if (strarray_exists( &targets, deps.str[i] ))
1974 deps.str[i] = obj_dir_path( make, deps.str[i] );
1975 else
1976 deps.str[i] = src_dir_path( make, deps.str[i] );
1978 return deps;
1982 /*******************************************************************
1983 * get_static_lib
1985 * Check if makefile builds the named static library and return the full lib path.
1987 static const char *get_static_lib( const struct makefile *make, const char *name )
1989 if (!make->staticlib) return NULL;
1990 if (strncmp( make->staticlib, "lib", 3 )) return NULL;
1991 if (strncmp( make->staticlib + 3, name, strlen(name) )) return NULL;
1992 if (strcmp( make->staticlib + 3 + strlen(name), ".a" )) return NULL;
1993 return base_dir_path( make, make->staticlib );
1997 /*******************************************************************
1998 * add_default_libraries
2000 static struct strarray add_default_libraries( const struct makefile *make, struct strarray *deps )
2002 struct strarray ret = empty_strarray;
2003 struct strarray all_libs = empty_strarray;
2004 unsigned int i, j;
2006 strarray_add( &all_libs, "-lwine_port" );
2007 strarray_addall( &all_libs, get_expanded_make_var_array( make, "EXTRALIBS" ));
2008 strarray_addall( &all_libs, libs );
2010 for (i = 0; i < all_libs.count; i++)
2012 const char *lib = NULL;
2014 if (!strncmp( all_libs.str[i], "-l", 2 ))
2016 const char *name = all_libs.str[i] + 2;
2018 for (j = 0; j < top_makefile->subdirs.count; j++)
2020 const struct makefile *submake = top_makefile->submakes[j];
2022 if ((lib = get_static_lib( submake, name ))) break;
2026 if (lib)
2028 lib = top_obj_dir_path( make, lib );
2029 strarray_add( deps, lib );
2030 strarray_add( &ret, lib );
2032 else strarray_add( &ret, all_libs.str[i] );
2034 return ret;
2038 /*******************************************************************
2039 * add_import_libs
2041 static struct strarray add_import_libs( const struct makefile *make, struct strarray *deps,
2042 struct strarray imports, int cross )
2044 struct strarray ret = empty_strarray;
2045 unsigned int i, j;
2047 for (i = 0; i < imports.count; i++)
2049 const char *name = imports.str[i];
2050 const char *lib = NULL;
2052 for (j = 0; j < top_makefile->subdirs.count; j++)
2054 const struct makefile *submake = top_makefile->submakes[j];
2056 if (submake->importlib && !strcmp( submake->importlib, name ))
2058 if (cross || !*dll_ext || submake->staticimplib)
2059 lib = base_dir_path( submake, strmake( "lib%s.a", name ));
2060 else
2061 strarray_add( deps, top_obj_dir_path( make,
2062 strmake( "%s/lib%s.def", submake->base_dir, name )));
2063 break;
2066 if ((lib = get_static_lib( submake, name ))) break;
2069 if (lib)
2071 if (cross) lib = replace_extension( lib, ".a", ".cross.a" );
2072 lib = top_obj_dir_path( make, lib );
2073 strarray_add( deps, lib );
2074 strarray_add( &ret, lib );
2076 else strarray_add( &ret, strmake( "-l%s", name ));
2078 return ret;
2082 /*******************************************************************
2083 * get_default_imports
2085 static struct strarray get_default_imports( const struct makefile *make )
2087 struct strarray ret = empty_strarray;
2089 if (strarray_exists( &make->extradllflags, "-nodefaultlibs" )) return ret;
2090 if (strarray_exists( &make->appmode, "-mno-cygwin" )) strarray_add( &ret, "msvcrt" );
2091 if (make->is_win16) strarray_add( &ret, "kernel" );
2092 strarray_add( &ret, "kernel32" );
2093 strarray_add( &ret, "ntdll" );
2094 strarray_add( &ret, "winecrt0" );
2095 return ret;
2099 /*******************************************************************
2100 * add_install_rule
2102 static void add_install_rule( struct makefile *make, const char *target,
2103 const char *file, const char *dest )
2105 if (strarray_exists( &make->install_lib, target ))
2107 strarray_add( &make->install_rules[INSTALL_LIB], file );
2108 strarray_add( &make->install_rules[INSTALL_LIB], dest );
2110 else if (strarray_exists( &make->install_dev, target ))
2112 strarray_add( &make->install_rules[INSTALL_DEV], file );
2113 strarray_add( &make->install_rules[INSTALL_DEV], dest );
2118 /*******************************************************************
2119 * get_include_install_path
2121 * Determine the installation path for a given include file.
2123 static const char *get_include_install_path( const char *name )
2125 if (!strncmp( name, "wine/", 5 )) return name + 5;
2126 if (!strncmp( name, "msvcrt/", 7 )) return name;
2127 return strmake( "windows/%s", name );
2131 /*******************************************************************
2132 * get_shared_library_name
2134 * Determine possible names for a shared library with a version number.
2136 static struct strarray get_shared_lib_names( const char *libname )
2138 struct strarray ret = empty_strarray;
2139 const char *ext, *p;
2140 char *name, *first, *second;
2141 size_t len = 0;
2143 strarray_add( &ret, libname );
2145 for (p = libname; (p = strchr( p, '.' )); p++)
2146 if ((len = strspn( p + 1, "0123456789." ))) break;
2148 if (!len) return ret;
2149 ext = p + 1 + len;
2150 if (*ext && ext[-1] == '.') ext--;
2152 /* keep only the first group of digits */
2153 name = xstrdup( libname );
2154 first = name + (p - libname);
2155 if ((second = strchr( first + 1, '.' )))
2157 strcpy( second, ext );
2158 strarray_add( &ret, xstrdup( name ));
2160 /* now remove all digits */
2161 strcpy( first, ext );
2162 strarray_add( &ret, name );
2163 return ret;
2167 /*******************************************************************
2168 * output_symlink_rule
2170 * Output a rule to create a symlink.
2172 static void output_symlink_rule( const char *src_name, const char *link_name )
2174 const char *name;
2176 output( "\trm -f %s && ", link_name );
2178 /* dest path with a directory needs special handling if ln -s isn't supported */
2179 if (strcmp( ln_s, "ln -s" ) && ((name = strrchr( link_name, '/' ))))
2181 char *dir = xstrdup( link_name );
2182 dir[name - link_name] = 0;
2183 output( "cd %s && %s %s %s\n", *dir ? dir : "/", ln_s, src_name, name + 1 );
2184 free( dir );
2186 else
2188 output( "%s %s %s\n", ln_s, src_name, link_name );
2193 /*******************************************************************
2194 * output_install_rules
2196 * Rules are stored as a (file,dest) pair of values.
2197 * The first char of dest indicates the type of install.
2199 static struct strarray output_install_rules( struct makefile *make, enum install_rules rules,
2200 const char *target )
2202 unsigned int i;
2203 char *install_sh;
2204 struct strarray files = make->install_rules[rules];
2205 struct strarray uninstall = empty_strarray;
2206 struct strarray targets = empty_strarray;
2208 if (!files.count) return uninstall;
2210 for (i = 0; i < files.count; i += 2)
2212 const char *file = files.str[i];
2213 switch (*files.str[i + 1])
2215 case 'd': /* data file */
2216 case 'p': /* program file */
2217 case 's': /* script */
2218 strarray_add_uniq( &targets, obj_dir_path( make, file ));
2219 break;
2220 case 't': /* script in tools dir */
2221 strarray_add_uniq( &targets, tools_dir_path( make, file ));
2222 break;
2226 output( "install %s::", target );
2227 output_filenames( targets );
2228 output( "\n" );
2230 install_sh = top_src_dir_path( make, "tools/install-sh" );
2231 for (i = 0; i < files.count; i += 2)
2233 const char *file = files.str[i];
2234 const char *dest = strmake( "$(DESTDIR)%s", files.str[i + 1] + 1 );
2236 switch (*files.str[i + 1])
2238 case 'd': /* data file */
2239 output( "\t%s -m 644 $(INSTALL_DATA_FLAGS) %s %s\n",
2240 install_sh, obj_dir_path( make, file ), dest );
2241 break;
2242 case 'D': /* data file in source dir */
2243 output( "\t%s -m 644 $(INSTALL_DATA_FLAGS) %s %s\n",
2244 install_sh, src_dir_path( make, file ), dest );
2245 break;
2246 case 'p': /* program file */
2247 output( "\tSTRIPPROG=\"$(STRIP)\" %s $(INSTALL_PROGRAM_FLAGS) %s %s\n",
2248 install_sh, obj_dir_path( make, file ), dest );
2249 break;
2250 case 's': /* script */
2251 output( "\t%s $(INSTALL_SCRIPT_FLAGS) %s %s\n",
2252 install_sh, obj_dir_path( make, file ), dest );
2253 break;
2254 case 'S': /* script in source dir */
2255 output( "\t%s $(INSTALL_SCRIPT_FLAGS) %s %s\n",
2256 install_sh, src_dir_path( make, file ), dest );
2257 break;
2258 case 't': /* script in tools dir */
2259 output( "\t%s $(INSTALL_SCRIPT_FLAGS) %s %s\n",
2260 install_sh, tools_dir_path( make, file ), dest );
2261 break;
2262 case 'y': /* symlink */
2263 output_symlink_rule( file, dest );
2264 break;
2265 default:
2266 assert(0);
2268 strarray_add( &uninstall, dest );
2271 strarray_add_uniq( &make->phony_targets, "install" );
2272 strarray_add_uniq( &make->phony_targets, target );
2273 return uninstall;
2277 /*******************************************************************
2278 * output_importlib_symlinks
2280 static struct strarray output_importlib_symlinks( const struct makefile *parent,
2281 const struct makefile *make )
2283 struct strarray ret = empty_strarray;
2284 const char *lib, *dst;
2286 if (!make->module) return ret;
2287 if (!make->importlib) return ret;
2288 if (make->is_win16 && make->disabled) return ret;
2289 if (strncmp( make->base_dir, "dlls/", 5 )) return ret;
2290 if (!strcmp( make->module, make->importlib )) return ret;
2291 if (!strchr( make->importlib, '.' ) &&
2292 !strncmp( make->module, make->importlib, strlen( make->importlib )) &&
2293 !strcmp( make->module + strlen( make->importlib ), ".dll" ))
2294 return ret;
2296 lib = strmake( "lib%s.%s", make->importlib, *dll_ext ? "def" : "a" );
2297 dst = concat_paths( obj_dir_path( parent, "dlls" ), lib );
2298 output( "%s: %s\n", dst, base_dir_path( make, lib ));
2299 output_symlink_rule( concat_paths( make->base_dir + strlen("dlls/"), lib ), dst );
2300 strarray_add( &ret, dst );
2302 if (crosstarget && !make->is_win16)
2304 lib = strmake( "lib%s.cross.a", make->importlib );
2305 dst = concat_paths( obj_dir_path( parent, "dlls" ), lib );
2306 output( "%s: %s\n", dst, base_dir_path( make, lib ));
2307 output_symlink_rule( concat_paths( make->base_dir + strlen("dlls/"), lib ), dst );
2308 strarray_add( &ret, dst );
2310 return ret;
2314 /*******************************************************************
2315 * output_po_files
2317 static void output_po_files( const struct makefile *make )
2319 const char *po_dir = src_dir_path( make, "po" );
2320 struct strarray pot_files = empty_strarray;
2321 struct incl_file *source;
2322 unsigned int i;
2324 for (i = 0; i < make->subdirs.count; i++)
2326 struct makefile *submake = make->submakes[i];
2328 LIST_FOR_EACH_ENTRY( source, &submake->sources, struct incl_file, entry )
2330 if (strendswith( source->name, ".rc" ) && (source->file->flags & FLAG_RC_PO))
2332 char *pot_file = replace_extension( source->name, ".rc", ".pot" );
2333 char *pot_path = base_dir_path( submake, pot_file );
2334 output( "%s: tools/wrc include dummy\n", pot_path );
2335 output( "\t@cd %s && $(MAKE) %s\n", base_dir_path( submake, "" ), pot_file );
2336 strarray_add( &pot_files, pot_path );
2338 else if (strendswith( source->name, ".mc" ))
2340 char *pot_file = replace_extension( source->name, ".mc", ".pot" );
2341 char *pot_path = base_dir_path( submake, pot_file );
2342 output( "%s: tools/wmc include dummy\n", pot_path );
2343 output( "\t@cd %s && $(MAKE) %s\n", base_dir_path( submake, "" ), pot_file );
2344 strarray_add( &pot_files, pot_path );
2348 if (linguas.count)
2350 for (i = 0; i < linguas.count; i++)
2351 output_filename( strmake( "%s/%s.po", po_dir, linguas.str[i] ));
2352 output( ": %s/wine.pot\n", po_dir );
2353 output( "\tmsgmerge --previous -q $@ %s/wine.pot | msgattrib --no-obsolete -o $@.new && mv $@.new $@\n",
2354 po_dir );
2355 output( "po:" );
2356 for (i = 0; i < linguas.count; i++)
2357 output_filename( strmake( "%s/%s.po", po_dir, linguas.str[i] ));
2358 output( "\n" );
2360 output( "%s/wine.pot:", po_dir );
2361 output_filenames( pot_files );
2362 output( "\n" );
2363 output( "\tmsgcat -o $@" );
2364 output_filenames( pot_files );
2365 output( "\n" );
2369 /*******************************************************************
2370 * output_source_y
2372 static void output_source_y( struct makefile *make, struct incl_file *source, const char *obj )
2374 /* add source file dependency for parallel makes */
2375 char *header = strmake( "%s.tab.h", obj );
2377 if (find_include_file( make, header ))
2379 output( "%s: %s\n", obj_dir_path( make, header ), source->filename );
2380 output( "\t$(BISON) -p %s_ -o %s.tab.c -d %s\n",
2381 obj, obj_dir_path( make, obj ), source->filename );
2382 output( "%s.tab.c: %s %s\n", obj_dir_path( make, obj ),
2383 source->filename, obj_dir_path( make, header ));
2384 strarray_add( &make->clean_files, header );
2386 else output( "%s.tab.c: %s\n", obj, source->filename );
2388 output( "\t$(BISON) -p %s_ -o $@ %s\n", obj, source->filename );
2392 /*******************************************************************
2393 * output_source_l
2395 static void output_source_l( struct makefile *make, struct incl_file *source, const char *obj )
2397 output( "%s.yy.c: %s\n", obj_dir_path( make, obj ), source->filename );
2398 output( "\t$(FLEX) -o$@ %s\n", source->filename );
2402 /*******************************************************************
2403 * output_source_h
2405 static void output_source_h( struct makefile *make, struct incl_file *source, const char *obj )
2407 if (source->file->flags & FLAG_GENERATED)
2409 strarray_add( &make->all_targets, source->name );
2411 else
2413 strarray_add( &make->install_rules[INSTALL_DEV], source->name );
2414 strarray_add( &make->install_rules[INSTALL_DEV],
2415 strmake( "D$(includedir)/%s", get_include_install_path( source->name ) ));
2420 /*******************************************************************
2421 * output_source_rc
2423 static void output_source_rc( struct makefile *make, struct incl_file *source, const char *obj )
2425 struct strarray extradefs = get_expanded_file_local_var( make, obj, "EXTRADEFS" );
2426 unsigned int i;
2428 strarray_add( &make->object_files, strmake( "%s.res", obj ));
2429 if (crosstarget) strarray_add( &make->crossobj_files, strmake( "%s.res", obj ));
2430 output( "%s.res: %s\n", obj_dir_path( make, obj ), source->filename );
2431 output( "\t%s -o $@", tools_path( make, "wrc" ) );
2432 if (make->is_win16) output_filename( "-m16" );
2433 else output_filenames( target_flags );
2434 output_filename( "--nostdinc" );
2435 output_filenames( make->include_args );
2436 output_filenames( make->define_args );
2437 output_filenames( extradefs );
2438 if (linguas.count && (source->file->flags & FLAG_RC_PO))
2440 char *po_dir = top_obj_dir_path( make, "po" );
2441 output_filename( strmake( "--po-dir=%s", po_dir ));
2442 output_filename( source->filename );
2443 output( "\n" );
2444 output( "%s.res:", obj_dir_path( make, obj ));
2445 for (i = 0; i < linguas.count; i++)
2446 output_filename( strmake( "%s/%s.mo", po_dir, linguas.str[i] ));
2447 output( "\n" );
2449 else
2451 output_filename( source->filename );
2452 output( "\n" );
2454 if (source->file->flags & FLAG_RC_PO)
2456 strarray_add( &make->clean_files, strmake( "%s.pot", obj ));
2457 output( "%s.pot: %s\n", obj_dir_path( make, obj ), source->filename );
2458 output( "\t%s -O pot -o $@", tools_path( make, "wrc" ) );
2459 if (make->is_win16) output_filename( "-m16" );
2460 else output_filenames( target_flags );
2461 output_filename( "--nostdinc" );
2462 output_filenames( make->include_args );
2463 output_filenames( make->define_args );
2464 output_filenames( extradefs );
2465 output_filename( source->filename );
2466 output( "\n" );
2467 output( "%s.pot ", obj_dir_path( make, obj ));
2469 output( "%s.res:", obj_dir_path( make, obj ));
2470 output_filename( tools_path( make, "wrc" ));
2471 output_filenames( source->dependencies );
2472 output( "\n" );
2476 /*******************************************************************
2477 * output_source_mc
2479 static void output_source_mc( struct makefile *make, struct incl_file *source, const char *obj )
2481 unsigned int i;
2483 strarray_add( &make->object_files, strmake( "%s.res", obj ));
2484 if (crosstarget) strarray_add( &make->crossobj_files, strmake( "%s.res", obj ));
2485 strarray_add( &make->clean_files, strmake( "%s.pot", obj ));
2486 output( "%s.res: %s\n", obj_dir_path( make, obj ), source->filename );
2487 output( "\t%s -U -O res -o $@ %s", tools_path( make, "wmc" ), source->filename );
2488 if (linguas.count)
2490 char *po_dir = top_obj_dir_path( make, "po" );
2491 output_filename( strmake( "--po-dir=%s", po_dir ));
2492 output( "\n" );
2493 output( "%s.res:", obj_dir_path( make, obj ));
2494 for (i = 0; i < linguas.count; i++)
2495 output_filename( strmake( "%s/%s.mo", po_dir, linguas.str[i] ));
2497 output( "\n" );
2498 output( "%s.pot: %s\n", obj_dir_path( make, obj ), source->filename );
2499 output( "\t%s -O pot -o $@ %s", tools_path( make, "wmc" ), source->filename );
2500 output( "\n" );
2501 output( "%s.pot %s.res:", obj_dir_path( make, obj ), obj_dir_path( make, obj ));
2502 output_filename( tools_path( make, "wmc" ));
2503 output_filenames( source->dependencies );
2504 output( "\n" );
2508 /*******************************************************************
2509 * output_source_res
2511 static void output_source_res( struct makefile *make, struct incl_file *source, const char *obj )
2513 strarray_add( &make->object_files, source->name );
2514 if (crosstarget) strarray_add( &make->crossobj_files, source->name );
2518 /*******************************************************************
2519 * output_source_idl
2521 static void output_source_idl( struct makefile *make, struct incl_file *source, const char *obj )
2523 struct strarray extradefs = get_expanded_file_local_var( make, obj, "EXTRADEFS" );
2524 struct strarray targets = empty_strarray;
2525 char *dest;
2526 unsigned int i;
2528 if (!source->file->flags) source->file->flags |= FLAG_IDL_HEADER | FLAG_INSTALL;
2529 if (find_include_file( make, strmake( "%s.h", obj ))) source->file->flags |= FLAG_IDL_HEADER;
2531 for (i = 0; i < sizeof(idl_outputs) / sizeof(idl_outputs[0]); i++)
2533 if (!(source->file->flags & idl_outputs[i].flag)) continue;
2534 dest = strmake( "%s%s", obj, idl_outputs[i].ext );
2535 if (!find_src_file( make, dest )) strarray_add( &make->clean_files, dest );
2536 strarray_add( &targets, dest );
2538 if (source->file->flags & FLAG_IDL_PROXY) strarray_add( &make->dlldata_files, source->name );
2539 if (source->file->flags & FLAG_INSTALL)
2541 strarray_add( &make->install_rules[INSTALL_DEV], xstrdup( source->name ));
2542 strarray_add( &make->install_rules[INSTALL_DEV],
2543 strmake( "D$(includedir)/%s.idl", get_include_install_path( obj ) ));
2544 if (source->file->flags & FLAG_IDL_HEADER)
2546 strarray_add( &make->install_rules[INSTALL_DEV], strmake( "%s.h", obj ));
2547 strarray_add( &make->install_rules[INSTALL_DEV],
2548 strmake( "d$(includedir)/%s.h", get_include_install_path( obj ) ));
2551 if (!targets.count) return;
2553 output_filenames_obj_dir( make, targets );
2554 output( ": %s\n", tools_path( make, "widl" ));
2555 output( "\t%s -o $@", tools_path( make, "widl" ) );
2556 output_filenames( target_flags );
2557 output_filenames( make->include_args );
2558 output_filenames( make->define_args );
2559 output_filenames( extradefs );
2560 output_filenames( get_expanded_make_var_array( make, "EXTRAIDLFLAGS" ));
2561 output_filename( source->filename );
2562 output( "\n" );
2563 output_filenames_obj_dir( make, targets );
2564 output( ": %s", source->filename );
2565 output_filenames( source->dependencies );
2566 output( "\n" );
2570 /*******************************************************************
2571 * output_source_tlb
2573 static void output_source_tlb( struct makefile *make, struct incl_file *source, const char *obj )
2575 strarray_add( &make->all_targets, source->name );
2579 /*******************************************************************
2580 * output_source_x
2582 static void output_source_x( struct makefile *make, struct incl_file *source, const char *obj )
2584 output( "%s.h: %s%s %s\n", obj_dir_path( make, obj ),
2585 tools_dir_path( make, "make_xftmpl" ), tools_ext, source->filename );
2586 output( "\t%s%s -H -o $@ %s\n",
2587 tools_dir_path( make, "make_xftmpl" ), tools_ext, source->filename );
2588 if (source->file->flags & FLAG_INSTALL)
2590 strarray_add( &make->install_rules[INSTALL_DEV], source->name );
2591 strarray_add( &make->install_rules[INSTALL_DEV],
2592 strmake( "D$(includedir)/%s", get_include_install_path( source->name ) ));
2593 strarray_add( &make->install_rules[INSTALL_DEV], strmake( "%s.h", obj ));
2594 strarray_add( &make->install_rules[INSTALL_DEV],
2595 strmake( "d$(includedir)/%s.h", get_include_install_path( obj ) ));
2600 /*******************************************************************
2601 * output_source_sfd
2603 static void output_source_sfd( struct makefile *make, struct incl_file *source, const char *obj )
2605 unsigned int i;
2606 char *ttf_file = src_dir_path( make, strmake( "%s.ttf", obj ));
2608 if (fontforge && !make->src_dir)
2610 output( "%s: %s\n", ttf_file, source->filename );
2611 output( "\t%s -script %s %s $@\n",
2612 fontforge, top_src_dir_path( make, "fonts/genttf.ff" ), source->filename );
2613 if (!(source->file->flags & FLAG_SFD_FONTS)) output( "all: %s\n", ttf_file );
2615 if (source->file->flags & FLAG_INSTALL)
2617 strarray_add( &make->install_rules[INSTALL_LIB], strmake( "%s.ttf", obj ));
2618 strarray_add( &make->install_rules[INSTALL_LIB], strmake( "D$(fontdir)/%s.ttf", obj ));
2620 if (source->file->flags & FLAG_SFD_FONTS)
2622 struct strarray *array = source->file->args;
2624 for (i = 0; i < array->count; i++)
2626 char *font = strtok( xstrdup(array->str[i]), " \t" );
2627 char *args = strtok( NULL, "" );
2629 strarray_add( &make->all_targets, xstrdup( font ));
2630 output( "%s: %s %s\n", obj_dir_path( make, font ),
2631 tools_path( make, "sfnt2fon" ), ttf_file );
2632 output( "\t%s -o $@ %s %s\n", tools_path( make, "sfnt2fon" ), ttf_file, args );
2633 strarray_add( &make->install_rules[INSTALL_LIB], xstrdup(font) );
2634 strarray_add( &make->install_rules[INSTALL_LIB], strmake( "d$(fontdir)/%s", font ));
2640 /*******************************************************************
2641 * output_source_svg
2643 static void output_source_svg( struct makefile *make, struct incl_file *source, const char *obj )
2645 static const char * const images[] = { "bmp", "cur", "ico", NULL };
2646 unsigned int i;
2648 if (convert && rsvg && icotool && !make->src_dir)
2650 for (i = 0; images[i]; i++)
2651 if (find_include_file( make, strmake( "%s.%s", obj, images[i] ))) break;
2653 if (images[i])
2655 output( "%s.%s: %s\n", src_dir_path( make, obj ), images[i], source->filename );
2656 output( "\tCONVERT=\"%s\" ICOTOOL=\"%s\" RSVG=\"%s\" %s %s $@\n", convert, icotool, rsvg,
2657 top_src_dir_path( make, "tools/buildimage" ), source->filename );
2663 /*******************************************************************
2664 * output_source_nls
2666 static void output_source_nls( struct makefile *make, struct incl_file *source, const char *obj )
2668 add_install_rule( make, source->name, source->name,
2669 strmake( "D$(datadir)/wine/%s", source->name ));
2673 /*******************************************************************
2674 * output_source_desktop
2676 static void output_source_desktop( struct makefile *make, struct incl_file *source, const char *obj )
2678 add_install_rule( make, source->name, source->name,
2679 strmake( "D$(datadir)/applications/%s", source->name ));
2683 /*******************************************************************
2684 * output_source_po
2686 static void output_source_po( struct makefile *make, struct incl_file *source, const char *obj )
2688 output( "%s.mo: %s\n", obj_dir_path( make, obj ), source->filename );
2689 output( "\t%s -o $@ %s\n", msgfmt, source->filename );
2690 strarray_add( &make->all_targets, strmake( "%s.mo", obj ));
2694 /*******************************************************************
2695 * output_source_in
2697 static void output_source_in( struct makefile *make, struct incl_file *source, const char *obj )
2699 unsigned int i;
2701 if (strendswith( obj, ".man" ) && source->file->args)
2703 struct strarray symlinks;
2704 char *dir, *dest = replace_extension( obj, ".man", "" );
2705 char *lang = strchr( dest, '.' );
2706 char *section = source->file->args;
2707 if (lang)
2709 *lang++ = 0;
2710 dir = strmake( "$(mandir)/%s/man%s", lang, section );
2712 else dir = strmake( "$(mandir)/man%s", section );
2713 add_install_rule( make, dest, xstrdup(obj), strmake( "d%s/%s.%s", dir, dest, section ));
2714 symlinks = get_expanded_file_local_var( make, dest, "SYMLINKS" );
2715 for (i = 0; i < symlinks.count; i++)
2716 add_install_rule( make, symlinks.str[i], strmake( "%s.%s", dest, section ),
2717 strmake( "y%s/%s.%s", dir, symlinks.str[i], section ));
2718 free( dest );
2719 free( dir );
2721 strarray_add( &make->in_files, xstrdup(obj) );
2722 strarray_add( &make->all_targets, xstrdup(obj) );
2723 output( "%s: %s\n", obj_dir_path( make, obj ), source->filename );
2724 output( "\t$(SED_CMD) %s >$@ || (rm -f $@ && false)\n", source->filename );
2725 output( "%s:", obj_dir_path( make, obj ));
2726 output_filenames( source->dependencies );
2727 output( "\n" );
2728 add_install_rule( make, obj, xstrdup( obj ), strmake( "d$(datadir)/wine/%s", obj ));
2732 /*******************************************************************
2733 * output_source_spec
2735 static void output_source_spec( struct makefile *make, struct incl_file *source, const char *obj )
2737 struct strarray imports = get_expanded_file_local_var( make, obj, "IMPORTS" );
2738 struct strarray all_libs, dep_libs = empty_strarray;
2740 if (!imports.count) imports = make->imports;
2741 all_libs = add_import_libs( make, &dep_libs, imports, 0 );
2742 add_import_libs( make, &dep_libs, get_default_imports( make ), 0 ); /* dependencies only */
2743 strarray_addall( &all_libs, libs );
2745 strarray_add( &make->clean_files, strmake( "%s.dll%s", obj, dll_ext ));
2746 strarray_add( &make->object_files, strmake( "%s.res", obj ));
2747 output( "%s.res: %s.dll%s\n", obj_dir_path( make, obj ), obj_dir_path( make, obj ), dll_ext );
2748 output( "\techo \"%s.dll TESTDLL \\\"%s.dll%s\\\"\" | %s -o $@\n", obj,
2749 obj_dir_path( make, obj ), dll_ext, tools_path( make, "wrc" ));
2751 output( "%s.dll%s:", obj_dir_path( make, obj ), dll_ext );
2752 output_filename( source->filename );
2753 output_filename( strmake( "%s.o", obj_dir_path( make, obj )));
2754 output_filenames( dep_libs );
2755 output_filename( tools_path( make, "winebuild" ));
2756 output_filename( tools_path( make, "winegcc" ));
2757 output( "\n" );
2758 output( "\t%s -s -o $@", tools_path( make, "winegcc" ));
2759 output_filename( strmake( "-B%s", tools_dir_path( make, "winebuild" )));
2760 if (tools_dir) output_filename( strmake( "--sysroot=%s", top_obj_dir_path( make, "" )));
2761 output_filenames( target_flags );
2762 output_filenames( unwind_flags );
2763 output_filenames( make->extradllflags );
2764 output_filename( "-shared" );
2765 output_filename( source->filename );
2766 output_filename( strmake( "%s.o", obj_dir_path( make, obj )));
2767 output_filenames( all_libs );
2768 output_filename( "$(LDFLAGS)" );
2769 output( "\n" );
2771 if (crosstarget)
2773 dep_libs = empty_strarray;
2774 all_libs = add_import_libs( make, &dep_libs, imports, 1 );
2775 add_import_libs( make, &dep_libs, get_default_imports( make ), 1 ); /* dependencies only */
2776 strarray_addall( &all_libs, libs );
2778 strarray_add( &make->clean_files, strmake( "%s.dll", obj ));
2779 strarray_add( &make->crossobj_files, strmake( "%s.cross.res", obj ));
2780 output( "%s.cross.res: %s.dll\n", obj_dir_path( make, obj ), obj_dir_path( make, obj ) );
2781 output( "\techo \"%s.dll TESTDLL \\\"%s.dll\\\"\" | %s -o $@\n", obj,
2782 obj_dir_path( make, obj ), tools_path( make, "wrc" ));
2784 output( "%s.dll:", obj_dir_path( make, obj ));
2785 output_filename( source->filename );
2786 output_filename( strmake( "%s.cross.o", obj_dir_path( make, obj )));
2787 output_filenames( dep_libs );
2788 output_filename( tools_path( make, "winebuild" ));
2789 output_filename( tools_path( make, "winegcc" ));
2790 output( "\n" );
2791 output( "\t%s -s -o $@ -b %s", tools_path( make, "winegcc" ), crosstarget );
2792 output_filename( strmake( "-B%s", tools_dir_path( make, "winebuild" )));
2793 if (tools_dir) output_filename( strmake( "--sysroot=%s", top_obj_dir_path( make, "" )));
2794 output_filename( "--lib-suffix=.cross.a" );
2795 output_filename( "-shared" );
2796 output_filename( source->filename );
2797 output_filename( strmake( "%s.cross.o", obj_dir_path( make, obj )));
2798 output_filenames( all_libs );
2799 output_filename( "$(LDFLAGS)" );
2800 output( "\n" );
2805 /*******************************************************************
2806 * output_source_default
2808 static void output_source_default( struct makefile *make, struct incl_file *source, const char *obj )
2810 struct strarray extradefs = get_expanded_file_local_var( make, obj, "EXTRADEFS" );
2811 int is_dll_src = (make->testdll &&
2812 strendswith( source->name, ".c" ) &&
2813 find_src_file( make, replace_extension( source->name, ".c", ".spec" )));
2814 int need_cross = (make->testdll ||
2815 (source->file->flags & FLAG_C_IMPLIB) ||
2816 (make->module && make->staticlib));
2818 if ((source->file->flags & FLAG_GENERATED) &&
2819 (!make->testdll || !strendswith( source->filename, "testlist.c" )))
2820 strarray_add( &make->clean_files, source->filename );
2821 if (source->file->flags & FLAG_C_IMPLIB) strarray_add( &make->implib_objs, strmake( "%s.o", obj ));
2822 strarray_add( is_dll_src ? &make->clean_files : &make->object_files, strmake( "%s.o", obj ));
2823 output( "%s.o: %s\n", obj_dir_path( make, obj ), source->filename );
2824 output( "\t$(CC) -c -o $@ %s", source->filename );
2825 output_filenames( make->include_args );
2826 output_filenames( make->define_args );
2827 output_filenames( extradefs );
2828 if (make->module || make->staticlib || make->sharedlib || make->testdll)
2830 output_filenames( dll_flags );
2831 if (make->use_msvcrt) output_filenames( msvcrt_flags );
2833 output_filenames( extra_cflags );
2834 output_filenames( cpp_flags );
2835 output_filename( "$(CFLAGS)" );
2836 output( "\n" );
2837 if (crosstarget && need_cross)
2839 strarray_add( is_dll_src ? &make->clean_files : &make->crossobj_files, strmake( "%s.cross.o", obj ));
2840 output( "%s.cross.o: %s\n", obj_dir_path( make, obj ), source->filename );
2841 output( "\t$(CROSSCC) -c -o $@ %s", source->filename );
2842 output_filenames( make->include_args );
2843 output_filenames( make->define_args );
2844 output_filenames( extradefs );
2845 if (make->use_msvcrt) output_filenames( msvcrt_flags );
2846 output_filename( "-DWINE_CROSSTEST" );
2847 output_filenames( cpp_flags );
2848 output_filename( "$(CROSSCFLAGS)" );
2849 output( "\n" );
2851 if (strendswith( source->name, ".c" ) && !(source->file->flags & FLAG_GENERATED))
2853 strarray_add( &make->c2man_files, source->filename );
2854 if (make->testdll && !is_dll_src)
2856 strarray_add( &make->ok_files, strmake( "%s.ok", obj ));
2857 output( "%s.ok:\n", obj_dir_path( make, obj ));
2858 output( "\t%s $(RUNTESTFLAGS) -T %s -M %s -p %s%s %s && touch $@\n",
2859 top_src_dir_path( make, "tools/runtest" ), top_obj_dir_path( make, "" ),
2860 make->testdll, replace_extension( make->testdll, ".dll", "_test.exe" ),
2861 dll_ext, obj );
2864 output( "%s.o", obj_dir_path( make, obj ));
2865 if (crosstarget && need_cross) output( " %s.cross.o", obj_dir_path( make, obj ));
2866 output( ":" );
2867 output_filenames( source->dependencies );
2868 output( "\n" );
2872 /* dispatch table to output rules for a single source file */
2873 static const struct
2875 const char *ext;
2876 void (*fn)( struct makefile *make, struct incl_file *source, const char *obj );
2877 } output_source_funcs[] =
2879 { "y", output_source_y },
2880 { "l", output_source_l },
2881 { "h", output_source_h },
2882 { "rh", output_source_h },
2883 { "inl", output_source_h },
2884 { "rc", output_source_rc },
2885 { "mc", output_source_mc },
2886 { "res", output_source_res },
2887 { "idl", output_source_idl },
2888 { "tlb", output_source_tlb },
2889 { "sfd", output_source_sfd },
2890 { "svg", output_source_svg },
2891 { "nls", output_source_nls },
2892 { "desktop", output_source_desktop },
2893 { "po", output_source_po },
2894 { "in", output_source_in },
2895 { "x", output_source_x },
2896 { "spec", output_source_spec },
2897 { NULL, output_source_default }
2901 /*******************************************************************
2902 * output_man_pages
2904 static void output_man_pages( struct makefile *make )
2906 if (make->c2man_files.count)
2908 char *spec_file = src_dir_path( make, replace_extension( make->module, ".dll", ".spec" ));
2910 output( "manpages::\n" );
2911 output( "\t%s -w %s", top_src_dir_path( make, "tools/c2man.pl" ), spec_file );
2912 output_filename( strmake( "-R%s", top_src_dir_path( make, "" )));
2913 output_filename( strmake( "-I%s", top_src_dir_path( make, "include" )));
2914 output_filename( strmake( "-o %s/man%s",
2915 top_obj_dir_path( make, "documentation" ), man_ext ));
2916 output_filenames( make->c2man_files );
2917 output( "\n" );
2918 output( "htmlpages::\n" );
2919 output( "\t%s -Th -w %s", top_src_dir_path( make, "tools/c2man.pl" ), spec_file );
2920 output_filename( strmake( "-R%s", top_src_dir_path( make, "" )));
2921 output_filename( strmake( "-I%s", top_src_dir_path( make, "include" )));
2922 output_filename( strmake( "-o %s",
2923 top_obj_dir_path( make, "documentation/html" )));
2924 output_filenames( make->c2man_files );
2925 output( "\n" );
2926 output( "sgmlpages::\n" );
2927 output( "\t%s -Ts -w %s", top_src_dir_path( make, "tools/c2man.pl" ), spec_file );
2928 output_filename( strmake( "-R%s", top_src_dir_path( make, "" )));
2929 output_filename( strmake( "-I%s", top_src_dir_path( make, "include" )));
2930 output_filename( strmake( "-o %s",
2931 top_obj_dir_path( make, "documentation/api-guide" )));
2932 output_filenames( make->c2man_files );
2933 output( "\n" );
2934 output( "xmlpages::\n" );
2935 output( "\t%s -Tx -w %s", top_src_dir_path( make, "tools/c2man.pl" ), spec_file );
2936 output_filename( strmake( "-R%s", top_src_dir_path( make, "" )));
2937 output_filename( strmake( "-I%s", top_src_dir_path( make, "include" )));
2938 output_filename( strmake( "-o %s",
2939 top_obj_dir_path( make, "documentation/api-guide-xml" )));
2940 output_filenames( make->c2man_files );
2941 output( "\n" );
2942 strarray_add( &make->phony_targets, "manpages" );
2943 strarray_add( &make->phony_targets, "htmlpages" );
2944 strarray_add( &make->phony_targets, "sgmlpages" );
2945 strarray_add( &make->phony_targets, "xmlpages" );
2947 else output( "manpages htmlpages sgmlpages xmlpages::\n" );
2951 /*******************************************************************
2952 * output_module
2954 static void output_module( struct makefile *make )
2956 struct strarray all_libs = empty_strarray;
2957 struct strarray dep_libs = empty_strarray;
2958 char *module_path = obj_dir_path( make, make->module );
2959 char *spec_file = NULL;
2960 unsigned int i;
2962 if (!make->appmode.count)
2963 spec_file = src_dir_path( make, replace_extension( make->module, ".dll", ".spec" ));
2964 strarray_addall( &all_libs, add_import_libs( make, &dep_libs, make->delayimports, 0 ));
2965 strarray_addall( &all_libs, add_import_libs( make, &dep_libs, make->imports, 0 ));
2966 add_import_libs( make, &dep_libs, get_default_imports( make ), 0 ); /* dependencies only */
2967 strarray_addall( &all_libs, add_default_libraries( make, &dep_libs ));
2969 if (*dll_ext)
2971 for (i = 0; i < make->delayimports.count; i++)
2972 strarray_add( &all_libs, strmake( "-Wb,-d%s", make->delayimports.str[i] ));
2973 strarray_add( &make->all_targets, strmake( "%s%s", make->module, dll_ext ));
2974 strarray_add( &make->all_targets, strmake( "%s.fake", make->module ));
2975 add_install_rule( make, make->module, strmake( "%s%s", make->module, dll_ext ),
2976 strmake( "p$(dlldir)/%s%s", make->module, dll_ext ));
2977 add_install_rule( make, make->module, strmake( "%s.fake", make->module ),
2978 strmake( "d$(fakedlldir)/%s", make->module ));
2979 output( "%s%s %s.fake:", module_path, dll_ext, module_path );
2981 else
2983 strarray_add( &all_libs, "-lwine" );
2984 strarray_add( &make->all_targets, make->module );
2985 add_install_rule( make, make->module, make->module,
2986 strmake( "p$(%s)/%s", spec_file ? "dlldir" : "bindir", make->module ));
2987 output( "%s:", module_path );
2989 if (spec_file) output_filename( spec_file );
2990 output_filenames_obj_dir( make, make->object_files );
2991 output_filenames( dep_libs );
2992 output_filename( tools_path( make, "winebuild" ));
2993 output_filename( tools_path( make, "winegcc" ));
2994 output( "\n" );
2995 output( "\t%s -o $@", tools_path( make, "winegcc" ));
2996 output_filename( strmake( "-B%s", tools_dir_path( make, "winebuild" )));
2997 if (tools_dir) output_filename( strmake( "--sysroot=%s", top_obj_dir_path( make, "" )));
2998 output_filenames( target_flags );
2999 output_filenames( unwind_flags );
3000 if (spec_file)
3002 output( " -shared %s", spec_file );
3003 output_filenames( make->extradllflags );
3005 else output_filenames( make->appmode );
3006 output_filenames_obj_dir( make, make->object_files );
3007 output_filenames( all_libs );
3008 output_filename( "$(LDFLAGS)" );
3009 output( "\n" );
3011 if (spec_file && make->importlib)
3013 char *importlib_path = obj_dir_path( make, strmake( "lib%s", make->importlib ));
3014 if (*dll_ext && !make->implib_objs.count)
3016 strarray_add( &make->clean_files, strmake( "lib%s.def", make->importlib ));
3017 output( "%s.def: %s %s\n", importlib_path, tools_path( make, "winebuild" ), spec_file );
3018 output( "\t%s -w --def -o $@ --export %s", tools_path( make, "winebuild" ), spec_file );
3019 output_filenames( target_flags );
3020 if (make->is_win16) output_filename( "-m16" );
3021 output( "\n" );
3022 add_install_rule( make, make->importlib,
3023 strmake( "lib%s.def", make->importlib ),
3024 strmake( "d$(dlldir)/lib%s.def", make->importlib ));
3026 else
3028 strarray_add( &make->clean_files, strmake( "lib%s.a", make->importlib ));
3029 output( "%s.a: %s %s", importlib_path, tools_path( make, "winebuild" ), spec_file );
3030 output_filenames_obj_dir( make, make->implib_objs );
3031 output( "\n" );
3032 output( "\t%s -w --implib -o $@ --export %s", tools_path( make, "winebuild" ), spec_file );
3033 output_filenames( target_flags );
3034 output_filenames_obj_dir( make, make->implib_objs );
3035 output( "\n" );
3036 add_install_rule( make, make->importlib,
3037 strmake( "lib%s.a", make->importlib ),
3038 strmake( "d$(dlldir)/lib%s.a", make->importlib ));
3040 if (crosstarget && !make->is_win16)
3042 struct strarray cross_files = strarray_replace_extension( &make->implib_objs, ".o", ".cross.o" );
3043 strarray_add( &make->clean_files, strmake( "lib%s.cross.a", make->importlib ));
3044 output( "%s.cross.a: %s %s", importlib_path, tools_path( make, "winebuild" ), spec_file );
3045 output_filenames_obj_dir( make, cross_files );
3046 output( "\n" );
3047 output( "\t%s -b %s -w --implib -o $@ --export %s",
3048 tools_path( make, "winebuild" ), crosstarget, spec_file );
3049 output_filenames_obj_dir( make, cross_files );
3050 output( "\n" );
3054 if (spec_file)
3055 output_man_pages( make );
3056 else if (*dll_ext)
3058 char *binary = replace_extension( make->module, ".exe", "" );
3059 add_install_rule( make, binary, "wineapploader", strmake( "t$(bindir)/%s", binary ));
3064 /*******************************************************************
3065 * output_static_lib
3067 static void output_static_lib( struct makefile *make )
3069 strarray_add( &make->all_targets, make->staticlib );
3070 output( "%s:", obj_dir_path( make, make->staticlib ));
3071 output_filenames_obj_dir( make, make->object_files );
3072 output( "\n\trm -f $@\n" );
3073 output( "\t$(AR) $(ARFLAGS) $@" );
3074 output_filenames_obj_dir( make, make->object_files );
3075 output( "\n\t$(RANLIB) $@\n" );
3076 add_install_rule( make, make->staticlib, make->staticlib,
3077 strmake( "d$(dlldir)/%s", make->staticlib ));
3078 if (crosstarget && make->module)
3080 char *name = replace_extension( make->staticlib, ".a", ".cross.a" );
3082 strarray_add( &make->all_targets, name );
3083 output( "%s:", obj_dir_path( make, name ));
3084 output_filenames_obj_dir( make, make->crossobj_files );
3085 output( "\n\trm -f $@\n" );
3086 output( "\t%s-ar $(ARFLAGS) $@", crosstarget );
3087 output_filenames_obj_dir( make, make->crossobj_files );
3088 output( "\n\t%s-ranlib $@\n", crosstarget );
3093 /*******************************************************************
3094 * output_shared_lib
3096 static void output_shared_lib( struct makefile *make )
3098 unsigned int i;
3099 char *basename, *p;
3100 struct strarray names = get_shared_lib_names( make->sharedlib );
3101 struct strarray all_libs = empty_strarray;
3102 struct strarray dep_libs = empty_strarray;
3104 basename = xstrdup( make->sharedlib );
3105 if ((p = strchr( basename, '.' ))) *p = 0;
3107 strarray_addall( &dep_libs, get_local_dependencies( make, basename, make->in_files ));
3108 strarray_addall( &all_libs, get_expanded_file_local_var( make, basename, "LDFLAGS" ));
3109 strarray_addall( &all_libs, add_default_libraries( make, &dep_libs ));
3111 output( "%s:", obj_dir_path( make, make->sharedlib ));
3112 output_filenames_obj_dir( make, make->object_files );
3113 output_filenames( dep_libs );
3114 output( "\n" );
3115 output( "\t$(CC) -o $@" );
3116 output_filenames_obj_dir( make, make->object_files );
3117 output_filenames( all_libs );
3118 output_filename( "$(LDFLAGS)" );
3119 output( "\n" );
3120 add_install_rule( make, make->sharedlib, make->sharedlib,
3121 strmake( "p$(libdir)/%s", make->sharedlib ));
3122 for (i = 1; i < names.count; i++)
3124 output( "%s: %s\n", obj_dir_path( make, names.str[i] ), obj_dir_path( make, names.str[i-1] ));
3125 output_symlink_rule( obj_dir_path( make, names.str[i-1] ), obj_dir_path( make, names.str[i] ));
3126 add_install_rule( make, names.str[i], names.str[i-1],
3127 strmake( "y$(libdir)/%s", names.str[i] ));
3129 strarray_addall( &make->all_targets, names );
3133 /*******************************************************************
3134 * output_import_lib
3136 static void output_import_lib( struct makefile *make )
3138 char *def_file = replace_extension( make->importlib, ".a", ".def" );
3140 /* stand-alone import lib (for libwine) */
3141 if (!strncmp( def_file, "lib", 3 )) def_file += 3;
3142 output( "%s: %s\n", obj_dir_path( make, make->importlib ), src_dir_path( make, def_file ));
3143 output( "\t%s -l $@ -d %s\n", dlltool, src_dir_path( make, def_file ));
3144 add_install_rule( make, make->importlib, make->importlib, strmake( "d$(libdir)/%s", make->importlib ));
3145 strarray_add( &make->all_targets, make->importlib );
3149 /*******************************************************************
3150 * output_test_module
3152 static void output_test_module( struct makefile *make )
3154 char *testmodule = replace_extension( make->testdll, ".dll", "_test.exe" );
3155 char *stripped = replace_extension( make->testdll, ".dll", "_test-stripped.exe" );
3156 char *testres = replace_extension( make->testdll, ".dll", "_test.res" );
3157 struct strarray dep_libs = empty_strarray;
3158 struct strarray all_libs = add_import_libs( make, &dep_libs, make->imports, 0 );
3160 add_import_libs( make, &dep_libs, get_default_imports( make ), 0 ); /* dependencies only */
3161 strarray_addall( &all_libs, libs );
3162 strarray_add( &make->all_targets, strmake( "%s%s", testmodule, dll_ext ));
3163 strarray_add( &make->clean_files, strmake( "%s%s", stripped, dll_ext ));
3164 output( "%s%s:\n", obj_dir_path( make, testmodule ), dll_ext );
3165 output( "\t%s -o $@", tools_path( make, "winegcc" ));
3166 output_filename( strmake( "-B%s", tools_dir_path( make, "winebuild" )));
3167 if (tools_dir) output_filename( strmake( "--sysroot=%s", top_obj_dir_path( make, "" )));
3168 output_filenames( target_flags );
3169 output_filenames( unwind_flags );
3170 output_filenames( make->appmode );
3171 output_filenames_obj_dir( make, make->object_files );
3172 output_filenames( all_libs );
3173 output_filename( "$(LDFLAGS)" );
3174 output( "\n" );
3175 output( "%s%s:\n", obj_dir_path( make, stripped ), dll_ext );
3176 output( "\t%s -s -o $@", tools_path( make, "winegcc" ));
3177 output_filename( strmake( "-B%s", tools_dir_path( make, "winebuild" )));
3178 if (tools_dir) output_filename( strmake( "--sysroot=%s", top_obj_dir_path( make, "" )));
3179 output_filenames( target_flags );
3180 output_filenames( unwind_flags );
3181 output_filename( strmake( "-Wb,-F,%s", testmodule ));
3182 output_filenames( make->appmode );
3183 output_filenames_obj_dir( make, make->object_files );
3184 output_filenames( all_libs );
3185 output_filename( "$(LDFLAGS)" );
3186 output( "\n" );
3187 output( "%s%s %s%s:", obj_dir_path( make, testmodule ), dll_ext,
3188 obj_dir_path( make, stripped ), dll_ext );
3189 output_filenames_obj_dir( make, make->object_files );
3190 output_filenames( dep_libs );
3191 output_filename( tools_path( make, "winebuild" ));
3192 output_filename( tools_path( make, "winegcc" ));
3193 output( "\n" );
3195 if (!make->disabled)
3196 output( "all: %s/%s\n", top_obj_dir_path( make, "programs/winetest" ), testres );
3197 output( "%s/%s: %s%s\n", top_obj_dir_path( make, "programs/winetest" ), testres,
3198 obj_dir_path( make, stripped ), dll_ext );
3199 output( "\techo \"%s TESTRES \\\"%s%s\\\"\" | %s -o $@\n",
3200 testmodule, obj_dir_path( make, stripped ), dll_ext, tools_path( make, "wrc" ));
3202 if (crosstarget)
3204 char *crosstest = replace_extension( make->testdll, ".dll", "_crosstest.exe" );
3206 dep_libs = empty_strarray;
3207 all_libs = add_import_libs( make, &dep_libs, make->imports, 1 );
3208 add_import_libs( make, &dep_libs, get_default_imports( make ), 1 ); /* dependencies only */
3209 strarray_addall( &all_libs, libs );
3210 strarray_add( &make->clean_files, crosstest );
3211 output( "%s:", obj_dir_path( make, crosstest ));
3212 output_filenames_obj_dir( make, make->crossobj_files );
3213 output_filenames( dep_libs );
3214 output_filename( tools_path( make, "winebuild" ));
3215 output_filename( tools_path( make, "winegcc" ));
3216 output( "\n" );
3217 output( "\t%s -o $@ -b %s", tools_path( make, "winegcc" ), crosstarget );
3218 output_filename( strmake( "-B%s", tools_dir_path( make, "winebuild" )));
3219 if (tools_dir) output_filename( strmake( "--sysroot=%s", top_obj_dir_path( make, "" )));
3220 output_filename( "--lib-suffix=.cross.a" );
3221 output_filenames_obj_dir( make, make->crossobj_files );
3222 output_filenames( all_libs );
3223 output_filename( "$(LDFLAGS)" );
3224 output( "\n" );
3225 if (!make->disabled)
3227 output( "%s: %s\n", obj_dir_path( make, "crosstest" ), obj_dir_path( make, crosstest ));
3228 strarray_add( &make->phony_targets, obj_dir_path( make, "crosstest" ));
3229 if (make->obj_dir) output( "crosstest: %s\n", obj_dir_path( make, "crosstest" ));
3233 output_filenames_obj_dir( make, make->ok_files );
3234 output( ": %s%s ../%s%s\n", testmodule, dll_ext, make->testdll, dll_ext );
3235 if (!make->disabled)
3237 output( "check test:" );
3238 output_filenames_obj_dir( make, make->ok_files );
3239 output( "\n" );
3240 strarray_add( &make->phony_targets, "check" );
3241 strarray_add( &make->phony_targets, "test" );
3243 output( "testclean::\n" );
3244 output( "\trm -f" );
3245 output_filenames_obj_dir( make, make->ok_files );
3246 output( "\n" );
3247 strarray_addall( &make->clean_files, make->ok_files );
3248 strarray_add( &make->phony_targets, "testclean" );
3252 /*******************************************************************
3253 * output_programs
3255 static void output_programs( struct makefile *make )
3257 unsigned int i, j;
3258 char *ldrpath_local = get_expanded_make_variable( make, "LDRPATH_LOCAL" );
3259 char *ldrpath_install = get_expanded_make_variable( make, "LDRPATH_INSTALL" );
3261 for (i = 0; i < make->programs.count; i++)
3263 char *program_installed = NULL;
3264 char *program = strmake( "%s%s", make->programs.str[i], exe_ext );
3265 struct strarray deps = get_local_dependencies( make, make->programs.str[i], make->in_files );
3266 struct strarray all_libs = get_expanded_file_local_var( make, make->programs.str[i], "LDFLAGS" );
3267 struct strarray objs = get_expanded_file_local_var( make, make->programs.str[i], "OBJS" );
3268 struct strarray symlinks = get_expanded_file_local_var( make, make->programs.str[i], "SYMLINKS" );
3270 if (!objs.count) objs = make->object_files;
3271 strarray_addall( &all_libs, add_default_libraries( make, &deps ));
3273 output( "%s:", obj_dir_path( make, program ) );
3274 output_filenames_obj_dir( make, objs );
3275 output_filenames( deps );
3276 output( "\n" );
3277 output( "\t$(CC) -o $@" );
3278 output_filenames_obj_dir( make, objs );
3280 if (strarray_exists( &all_libs, "-lwine" ))
3282 strarray_add( &all_libs, strmake( "-L%s", top_obj_dir_path( make, "libs/wine" )));
3283 if (ldrpath_local && ldrpath_install)
3285 program_installed = strmake( "%s-installed%s", make->programs.str[i], exe_ext );
3286 output_filename( ldrpath_local );
3287 output_filenames( all_libs );
3288 output_filename( "$(LDFLAGS)" );
3289 output( "\n" );
3290 output( "%s:", obj_dir_path( make, program_installed ) );
3291 output_filenames_obj_dir( make, objs );
3292 output_filenames( deps );
3293 output( "\n" );
3294 output( "\t$(CC) -o $@" );
3295 output_filenames_obj_dir( make, objs );
3296 output_filename( ldrpath_install );
3297 strarray_add( &make->all_targets, program_installed );
3301 output_filenames( all_libs );
3302 output_filename( "$(LDFLAGS)" );
3303 output( "\n" );
3304 strarray_add( &make->all_targets, program );
3306 for (j = 0; j < symlinks.count; j++)
3308 output( "%s: %s\n", obj_dir_path( make, symlinks.str[j] ), obj_dir_path( make, program ));
3309 output_symlink_rule( obj_dir_path( make, program ), obj_dir_path( make, symlinks.str[j] ));
3311 strarray_addall( &make->all_targets, symlinks );
3313 add_install_rule( make, program, program_installed ? program_installed : program,
3314 strmake( "p$(bindir)/%s", program ));
3315 for (j = 0; j < symlinks.count; j++)
3316 add_install_rule( make, symlinks.str[j], program,
3317 strmake( "y$(bindir)/%s%s", symlinks.str[j], exe_ext ));
3322 /*******************************************************************
3323 * output_subdirs
3325 static void output_subdirs( struct makefile *make )
3327 struct strarray build_deps = empty_strarray;
3328 struct strarray makefile_deps = empty_strarray;
3329 struct strarray clean_files = empty_strarray;
3330 struct strarray testclean_files = empty_strarray;
3331 struct strarray distclean_files = get_expanded_make_var_array( make, "CONFIGURE_TARGETS" );
3332 unsigned int i, j;
3334 strarray_add( &distclean_files, obj_dir_path( make, output_makefile_name ));
3335 if (!make->src_dir) strarray_add( &distclean_files, obj_dir_path( make, ".gitignore" ));
3336 for (i = 0; i < make->subdirs.count; i++)
3338 const struct makefile *submake = make->submakes[i];
3340 strarray_add( &makefile_deps, top_src_dir_path( make, base_dir_path( submake,
3341 strmake ( "%s.in", output_makefile_name ))));
3342 strarray_add( &distclean_files, base_dir_path( submake, output_makefile_name ));
3343 if (!make->src_dir) strarray_add( &distclean_files, base_dir_path( submake, ".gitignore" ));
3344 for (j = 0; j < submake->clean_files.count; j++)
3345 strarray_add( &clean_files, base_dir_path( submake, submake->clean_files.str[j] ));
3346 if (submake->testdll)
3348 for (j = 0; j < submake->ok_files.count; j++)
3349 strarray_add( &testclean_files, base_dir_path( submake, submake->ok_files.str[j] ));
3350 strarray_add( &distclean_files, base_dir_path( submake, "testlist.c" ));
3352 strarray_addall( &build_deps, output_importlib_symlinks( make, submake ));
3354 output( "Makefile:" );
3355 output_filenames( makefile_deps );
3356 output( "\n" );
3357 output_filenames( makefile_deps );
3358 output( ":\n" );
3359 output( "clean::\n");
3360 output_rm_filenames( clean_files );
3361 output( "testclean::\n");
3362 output_rm_filenames( testclean_files );
3363 output( "distclean::\n");
3364 output_rm_filenames( distclean_files );
3365 strarray_add( &make->phony_targets, "distclean" );
3366 strarray_add( &make->phony_targets, "testclean" );
3368 if (build_deps.count)
3370 output( "__builddeps__:" );
3371 output_filenames( build_deps );
3372 output( "\n" );
3373 strarray_addall( &make->clean_files, build_deps );
3375 if (get_expanded_make_variable( make, "GETTEXTPO_LIBS" )) output_po_files( make );
3379 /*******************************************************************
3380 * output_sources
3382 static struct strarray output_sources( struct makefile *make )
3384 struct incl_file *source;
3385 unsigned int i, j;
3386 struct strarray uninstall_files = empty_strarray;
3388 strarray_add( &make->phony_targets, "all" );
3390 LIST_FOR_EACH_ENTRY( source, &make->sources, struct incl_file, entry )
3392 char *obj = xstrdup( source->name );
3393 char *ext = get_extension( obj );
3395 if (!ext) fatal_error( "unsupported file type %s\n", source->name );
3396 *ext++ = 0;
3398 for (j = 0; output_source_funcs[j].ext; j++)
3399 if (!strcmp( ext, output_source_funcs[j].ext )) break;
3401 output_source_funcs[j].fn( make, source, obj );
3402 free( obj );
3405 if (make->dlldata_files.count)
3407 output( "%s: %s %s\n", obj_dir_path( make, "dlldata.c" ),
3408 tools_path( make, "widl" ), src_dir_path( make, "Makefile.in" ));
3409 output( "\t%s --dlldata-only -o $@", tools_path( make, "widl" ));
3410 output_filenames( make->dlldata_files );
3411 output( "\n" );
3414 if (make->staticlib) output_static_lib( make );
3415 else if (make->module) output_module( make );
3416 else if (make->importlib) output_import_lib( make );
3417 else if (make->sharedlib) output_shared_lib( make );
3418 else if (make->testdll) output_test_module( make );
3420 if (make->programs.count) output_programs( make );
3422 for (i = 0; i < make->scripts.count; i++)
3423 add_install_rule( make, make->scripts.str[i], make->scripts.str[i],
3424 strmake( "S$(bindir)/%s", make->scripts.str[i] ));
3426 if (make->subdirs.count) output_subdirs( make );
3428 if (!make->disabled)
3430 if (make->all_targets.count)
3432 output( "all:" );
3433 output_filenames_obj_dir( make, make->all_targets );
3434 output( "\n" );
3436 strarray_addall( &uninstall_files, output_install_rules( make, INSTALL_LIB, "install-lib" ));
3437 strarray_addall( &uninstall_files, output_install_rules( make, INSTALL_DEV, "install-dev" ));
3438 if (uninstall_files.count)
3440 output( "uninstall::\n" );
3441 output( "\trm -f" );
3442 output_filenames( uninstall_files );
3443 output( "\n" );
3444 strarray_add_uniq( &make->phony_targets, "uninstall" );
3448 strarray_addall( &make->clean_files, make->object_files );
3449 for (i = 0; i < make->crossobj_files.count; i++)
3450 strarray_add_uniq( &make->clean_files, make->crossobj_files.str[i] );
3451 strarray_addall( &make->clean_files, make->all_targets );
3452 strarray_addall( &make->clean_files, get_expanded_make_var_array( make, "EXTRA_TARGETS" ));
3454 if (make->clean_files.count)
3456 output( "%s::\n", obj_dir_path( make, "clean" ));
3457 output( "\trm -f" );
3458 output_filenames_obj_dir( make, make->clean_files );
3459 output( "\n" );
3460 if (make->obj_dir) output( "__clean__: %s\n", obj_dir_path( make, "clean" ));
3461 strarray_add( &make->phony_targets, obj_dir_path( make, "clean" ));
3464 if (make->phony_targets.count)
3466 output( ".PHONY:" );
3467 output_filenames( make->phony_targets );
3468 output( "\n" );
3471 if (!make->base_dir)
3472 strarray_addall( &make->clean_files, get_expanded_make_var_array( make, "CONFIGURE_TARGETS" ));
3473 return make->clean_files;
3477 /*******************************************************************
3478 * create_temp_file
3480 static FILE *create_temp_file( const char *orig )
3482 char *name = xmalloc( strlen(orig) + 13 );
3483 unsigned int i, id = getpid();
3484 int fd;
3485 FILE *ret = NULL;
3487 for (i = 0; i < 100; i++)
3489 sprintf( name, "%s.tmp%08x", orig, id );
3490 if ((fd = open( name, O_RDWR | O_CREAT | O_EXCL, 0666 )) != -1)
3492 ret = fdopen( fd, "w" );
3493 break;
3495 if (errno != EEXIST) break;
3496 id += 7777;
3498 if (!ret) fatal_error( "failed to create output file for '%s'\n", orig );
3499 temp_file_name = name;
3500 return ret;
3504 /*******************************************************************
3505 * rename_temp_file
3507 static void rename_temp_file( const char *dest )
3509 int ret = rename( temp_file_name, dest );
3510 if (ret == -1 && errno == EEXIST)
3512 /* rename doesn't overwrite on windows */
3513 unlink( dest );
3514 ret = rename( temp_file_name, dest );
3516 if (ret == -1) fatal_error( "failed to rename output file to '%s'\n", dest );
3517 temp_file_name = NULL;
3521 /*******************************************************************
3522 * are_files_identical
3524 static int are_files_identical( FILE *file1, FILE *file2 )
3526 for (;;)
3528 char buffer1[8192], buffer2[8192];
3529 int size1 = fread( buffer1, 1, sizeof(buffer1), file1 );
3530 int size2 = fread( buffer2, 1, sizeof(buffer2), file2 );
3531 if (size1 != size2) return 0;
3532 if (!size1) return feof( file1 ) && feof( file2 );
3533 if (memcmp( buffer1, buffer2, size1 )) return 0;
3538 /*******************************************************************
3539 * rename_temp_file_if_changed
3541 static void rename_temp_file_if_changed( const char *dest )
3543 FILE *file1, *file2;
3544 int do_rename = 1;
3546 if ((file1 = fopen( dest, "r" )))
3548 if ((file2 = fopen( temp_file_name, "r" )))
3550 do_rename = !are_files_identical( file1, file2 );
3551 fclose( file2 );
3553 fclose( file1 );
3555 if (!do_rename)
3557 unlink( temp_file_name );
3558 temp_file_name = NULL;
3560 else rename_temp_file( dest );
3564 /*******************************************************************
3565 * output_linguas
3567 static void output_linguas( const struct makefile *make )
3569 const char *dest = base_dir_path( make, "LINGUAS" );
3570 struct incl_file *source;
3572 output_file = create_temp_file( dest );
3574 output( "# Automatically generated by make depend; DO NOT EDIT!!\n" );
3575 LIST_FOR_EACH_ENTRY( source, &make->sources, struct incl_file, entry )
3576 if (strendswith( source->name, ".po" ))
3577 output( "%s\n", replace_extension( source->name, ".po", "" ));
3579 if (fclose( output_file )) fatal_perror( "write" );
3580 output_file = NULL;
3581 rename_temp_file_if_changed( dest );
3585 /*******************************************************************
3586 * output_testlist
3588 static void output_testlist( const struct makefile *make )
3590 const char *dest = base_dir_path( make, "testlist.c" );
3591 struct strarray files = empty_strarray;
3592 unsigned int i;
3594 for (i = 0; i < make->ok_files.count; i++)
3595 strarray_add( &files, replace_extension( make->ok_files.str[i], ".ok", "" ));
3597 output_file = create_temp_file( dest );
3599 output( "/* Automatically generated by make depend; DO NOT EDIT!! */\n\n" );
3600 output( "#define WIN32_LEAN_AND_MEAN\n" );
3601 output( "#include <windows.h>\n\n" );
3602 output( "#define STANDALONE\n" );
3603 output( "#include \"wine/test.h\"\n\n" );
3605 for (i = 0; i < files.count; i++) output( "extern void func_%s(void);\n", files.str[i] );
3606 output( "\n" );
3607 output( "const struct test winetest_testlist[] =\n" );
3608 output( "{\n" );
3609 for (i = 0; i < files.count; i++) output( " { \"%s\", func_%s },\n", files.str[i], files.str[i] );
3610 output( " { 0, 0 }\n" );
3611 output( "};\n" );
3613 if (fclose( output_file )) fatal_perror( "write" );
3614 output_file = NULL;
3615 rename_temp_file_if_changed( dest );
3619 /*******************************************************************
3620 * output_gitignore
3622 static void output_gitignore( const char *dest, struct strarray files )
3624 int i;
3626 output_file = create_temp_file( dest );
3628 output( "# Automatically generated by make depend; DO NOT EDIT!!\n" );
3629 for (i = 0; i < files.count; i++)
3631 if (!strchr( files.str[i], '/' )) output( "/" );
3632 output( "%s\n", files.str[i] );
3635 if (fclose( output_file )) fatal_perror( "write" );
3636 output_file = NULL;
3637 rename_temp_file( dest );
3641 /*******************************************************************
3642 * output_top_variables
3644 static void output_top_variables( const struct makefile *make )
3646 unsigned int i;
3647 struct strarray *vars = &top_makefile->vars;
3649 if (!make->base_dir) return; /* don't output variables in the top makefile */
3651 output( "# Automatically generated by make depend; DO NOT EDIT!!\n\n" );
3652 output( "all:\n\n" );
3653 for (i = 0; i < vars->count; i += 2)
3655 if (!strcmp( vars->str[i], "SUBDIRS" )) continue; /* not inherited */
3656 output( "%s = %s\n", vars->str[i], get_make_variable( make, vars->str[i] ));
3658 output( "\n" );
3662 /*******************************************************************
3663 * output_dependencies
3665 static void output_dependencies( struct makefile *make )
3667 struct strarray targets, ignore_files = empty_strarray;
3668 char buffer[1024];
3669 FILE *src_file;
3670 int found = 0;
3672 if (make->base_dir) create_dir( make->base_dir );
3674 output_file_name = base_dir_path( make, output_makefile_name );
3675 output_file = create_temp_file( output_file_name );
3676 output_top_variables( make );
3678 /* copy the contents of the source makefile */
3679 src_file = open_input_makefile( make );
3680 while (fgets( buffer, sizeof(buffer), src_file ) && !found)
3682 if (fwrite( buffer, 1, strlen(buffer), output_file ) != strlen(buffer)) fatal_perror( "write" );
3683 found = !strncmp( buffer, separator, strlen(separator) );
3685 if (fclose( src_file )) fatal_perror( "close" );
3686 input_file_name = NULL;
3688 if (!found) output( "\n%s (everything below this line is auto-generated; DO NOT EDIT!!)\n", separator );
3689 targets = output_sources( make );
3691 fclose( output_file );
3692 output_file = NULL;
3693 rename_temp_file( output_file_name );
3695 strarray_add( &ignore_files, ".gitignore" );
3696 strarray_add( &ignore_files, "Makefile" );
3697 if (make->testdll)
3699 output_testlist( make );
3700 strarray_add( &ignore_files, "testlist.c" );
3702 if (make->base_dir && !strcmp( make->base_dir, "po" ))
3704 output_linguas( make );
3705 strarray_add( &ignore_files, "LINGUAS" );
3707 strarray_addall( &ignore_files, targets );
3708 if (!make->src_dir) output_gitignore( base_dir_path( make, ".gitignore" ), ignore_files );
3710 create_file_directories( make, targets );
3712 output_file_name = NULL;
3716 /*******************************************************************
3717 * load_sources
3719 static void load_sources( struct makefile *make )
3721 static const char *source_vars[] =
3723 "SOURCES",
3724 "C_SRCS",
3725 "OBJC_SRCS",
3726 "RC_SRCS",
3727 "MC_SRCS",
3728 "IDL_SRCS",
3729 "BISON_SRCS",
3730 "LEX_SRCS",
3731 "HEADER_SRCS",
3732 "XTEMPLATE_SRCS",
3733 "SVG_SRCS",
3734 "FONT_SRCS",
3735 "IN_SRCS",
3736 "PO_SRCS",
3737 "MANPAGES",
3738 NULL
3740 const char **var;
3741 unsigned int i;
3742 struct strarray value;
3743 struct incl_file *file;
3745 if (root_src_dir)
3747 make->top_src_dir = concat_paths( make->top_obj_dir, root_src_dir );
3748 make->src_dir = concat_paths( make->top_src_dir, make->base_dir );
3750 strarray_set_value( &make->vars, "top_builddir", top_obj_dir_path( make, "" ));
3751 strarray_set_value( &make->vars, "top_srcdir", top_src_dir_path( make, "" ));
3752 strarray_set_value( &make->vars, "srcdir", src_dir_path( make, "" ));
3754 make->parent_dir = get_expanded_make_variable( make, "PARENTSRC" );
3755 make->module = get_expanded_make_variable( make, "MODULE" );
3756 make->testdll = get_expanded_make_variable( make, "TESTDLL" );
3757 make->sharedlib = get_expanded_make_variable( make, "SHAREDLIB" );
3758 make->staticlib = get_expanded_make_variable( make, "STATICLIB" );
3759 make->importlib = get_expanded_make_variable( make, "IMPORTLIB" );
3761 make->programs = get_expanded_make_var_array( make, "PROGRAMS" );
3762 make->scripts = get_expanded_make_var_array( make, "SCRIPTS" );
3763 make->appmode = get_expanded_make_var_array( make, "APPMODE" );
3764 make->imports = get_expanded_make_var_array( make, "IMPORTS" );
3765 make->delayimports = get_expanded_make_var_array( make, "DELAYIMPORTS" );
3766 make->extradllflags = get_expanded_make_var_array( make, "EXTRADLLFLAGS" );
3767 make->install_lib = get_expanded_make_var_array( make, "INSTALL_LIB" );
3768 make->install_dev = get_expanded_make_var_array( make, "INSTALL_DEV" );
3770 if (make->module && strendswith( make->module, ".a" )) make->staticlib = make->module;
3772 make->disabled = make->base_dir && strarray_exists( &disabled_dirs, make->base_dir );
3773 make->is_win16 = strarray_exists( &make->extradllflags, "-m16" );
3774 make->use_msvcrt = strarray_exists( &make->appmode, "-mno-cygwin" );
3776 for (i = 0; i < make->imports.count && !make->use_msvcrt; i++)
3777 make->use_msvcrt = !strncmp( make->imports.str[i], "msvcr", 5 ) ||
3778 !strcmp( make->imports.str[i], "ucrtbase" );
3780 if (make->module && !make->install_lib.count && !make->install_dev.count)
3782 if (make->importlib) strarray_add( &make->install_dev, make->importlib );
3783 if (make->staticlib) strarray_add( &make->install_dev, make->staticlib );
3784 else strarray_add( &make->install_lib, make->module );
3787 make->include_paths = empty_strarray;
3788 make->include_args = empty_strarray;
3789 make->define_args = empty_strarray;
3790 strarray_add( &make->define_args, "-D__WINESRC__" );
3792 value = get_expanded_make_var_array( make, "EXTRAINCL" );
3793 for (i = 0; i < value.count; i++)
3794 if (!strncmp( value.str[i], "-I", 2 ))
3795 strarray_add_uniq( &make->include_paths, value.str[i] + 2 );
3796 else
3797 strarray_add_uniq( &make->define_args, value.str[i] );
3798 strarray_addall( &make->define_args, get_expanded_make_var_array( make, "EXTRADEFS" ));
3800 strarray_add( &make->include_args, strmake( "-I%s", obj_dir_path( make, "" )));
3801 if (make->src_dir)
3802 strarray_add( &make->include_args, strmake( "-I%s", make->src_dir ));
3803 if (make->parent_dir)
3804 strarray_add( &make->include_args, strmake( "-I%s", src_dir_path( make, make->parent_dir )));
3805 strarray_add( &make->include_args, strmake( "-I%s", top_obj_dir_path( make, "include" )));
3806 if (make->top_src_dir)
3807 strarray_add( &make->include_args, strmake( "-I%s", top_src_dir_path( make, "include" )));
3808 if (make->use_msvcrt)
3809 strarray_add( &make->include_args, strmake( "-I%s", top_src_dir_path( make, "include/msvcrt" )));
3810 for (i = 0; i < make->include_paths.count; i++)
3811 strarray_add( &make->include_args, strmake( "-I%s", obj_dir_path( make, make->include_paths.str[i] )));
3813 list_init( &make->sources );
3814 list_init( &make->includes );
3816 for (var = source_vars; *var; var++)
3818 value = get_expanded_make_var_array( make, *var );
3819 for (i = 0; i < value.count; i++) add_src_file( make, value.str[i] );
3822 add_generated_sources( make );
3824 value = get_expanded_make_var_array( make, "EXTRA_OBJS" );
3825 for (i = 0; i < value.count; i++)
3827 /* default to .c for unknown extra object files */
3828 if (strendswith( value.str[i], ".o" ))
3829 add_generated_source( make, value.str[i], replace_extension( value.str[i], ".o", ".c" ) );
3830 else
3831 add_generated_source( make, value.str[i], NULL );
3834 LIST_FOR_EACH_ENTRY( file, &make->includes, struct incl_file, entry ) parse_file( make, file, 0 );
3835 LIST_FOR_EACH_ENTRY( file, &make->sources, struct incl_file, entry ) get_dependencies( file, file );
3839 /*******************************************************************
3840 * parse_makeflags
3842 static void parse_makeflags( const char *flags )
3844 const char *p = flags;
3845 char *var, *buffer = xmalloc( strlen(flags) + 1 );
3847 while (*p)
3849 while (isspace(*p)) p++;
3850 var = buffer;
3851 while (*p && !isspace(*p))
3853 if (*p == '\\' && p[1]) p++;
3854 *var++ = *p++;
3856 *var = 0;
3857 if (var > buffer) set_make_variable( &cmdline_vars, buffer );
3862 /*******************************************************************
3863 * parse_option
3865 static int parse_option( const char *opt )
3867 if (opt[0] != '-')
3869 if (strchr( opt, '=' )) return set_make_variable( &cmdline_vars, opt );
3870 return 0;
3872 switch(opt[1])
3874 case 'f':
3875 if (opt[2]) output_makefile_name = opt + 2;
3876 break;
3877 case 'R':
3878 relative_dir_mode = 1;
3879 break;
3880 default:
3881 fprintf( stderr, "Unknown option '%s'\n%s", opt, Usage );
3882 exit(1);
3884 return 1;
3888 /*******************************************************************
3889 * main
3891 int main( int argc, char *argv[] )
3893 const char *makeflags = getenv( "MAKEFLAGS" );
3894 int i, j;
3896 if (makeflags) parse_makeflags( makeflags );
3898 i = 1;
3899 while (i < argc)
3901 if (parse_option( argv[i] ))
3903 for (j = i; j < argc; j++) argv[j] = argv[j+1];
3904 argc--;
3906 else i++;
3909 if (relative_dir_mode)
3911 char *relpath;
3913 if (argc != 3)
3915 fprintf( stderr, "Option -R needs two directories\n%s", Usage );
3916 exit( 1 );
3918 relpath = get_relative_path( argv[1], argv[2] );
3919 printf( "%s\n", relpath ? relpath : "." );
3920 exit( 0 );
3923 atexit( cleanup_files );
3924 signal( SIGTERM, exit_on_signal );
3925 signal( SIGINT, exit_on_signal );
3926 #ifdef SIGHUP
3927 signal( SIGHUP, exit_on_signal );
3928 #endif
3930 for (i = 0; i < HASH_SIZE; i++) list_init( &files[i] );
3932 top_makefile = parse_makefile( NULL );
3934 target_flags = get_expanded_make_var_array( top_makefile, "TARGETFLAGS" );
3935 msvcrt_flags = get_expanded_make_var_array( top_makefile, "MSVCRTFLAGS" );
3936 dll_flags = get_expanded_make_var_array( top_makefile, "DLLFLAGS" );
3937 extra_cflags = get_expanded_make_var_array( top_makefile, "EXTRACFLAGS" );
3938 cpp_flags = get_expanded_make_var_array( top_makefile, "CPPFLAGS" );
3939 unwind_flags = get_expanded_make_var_array( top_makefile, "UNWINDFLAGS" );
3940 libs = get_expanded_make_var_array( top_makefile, "LIBS" );
3942 root_src_dir = get_expanded_make_variable( top_makefile, "srcdir" );
3943 tools_dir = get_expanded_make_variable( top_makefile, "TOOLSDIR" );
3944 tools_ext = get_expanded_make_variable( top_makefile, "TOOLSEXT" );
3945 exe_ext = get_expanded_make_variable( top_makefile, "EXEEXT" );
3946 man_ext = get_expanded_make_variable( top_makefile, "api_manext" );
3947 dll_ext = (exe_ext && !strcmp( exe_ext, ".exe" )) ? "" : ".so";
3948 crosstarget = get_expanded_make_variable( top_makefile, "CROSSTARGET" );
3949 fontforge = get_expanded_make_variable( top_makefile, "FONTFORGE" );
3950 convert = get_expanded_make_variable( top_makefile, "CONVERT" );
3951 rsvg = get_expanded_make_variable( top_makefile, "RSVG" );
3952 icotool = get_expanded_make_variable( top_makefile, "ICOTOOL" );
3953 dlltool = get_expanded_make_variable( top_makefile, "DLLTOOL" );
3954 msgfmt = get_expanded_make_variable( top_makefile, "MSGFMT" );
3955 ln_s = get_expanded_make_variable( top_makefile, "LN_S" );
3957 if (root_src_dir && !strcmp( root_src_dir, "." )) root_src_dir = NULL;
3958 if (tools_dir && !strcmp( tools_dir, "." )) tools_dir = NULL;
3959 if (!exe_ext) exe_ext = "";
3960 if (!tools_ext) tools_ext = "";
3961 if (!man_ext) man_ext = "3w";
3963 if (argc == 1)
3965 disabled_dirs = get_expanded_make_var_array( top_makefile, "DISABLED_SUBDIRS" );
3966 top_makefile->subdirs = get_expanded_make_var_array( top_makefile, "SUBDIRS" );
3967 top_makefile->submakes = xmalloc( top_makefile->subdirs.count * sizeof(*top_makefile->submakes) );
3969 for (i = 0; i < top_makefile->subdirs.count; i++)
3970 top_makefile->submakes[i] = parse_makefile( top_makefile->subdirs.str[i] );
3972 load_sources( top_makefile );
3973 for (i = 0; i < top_makefile->subdirs.count; i++)
3974 load_sources( top_makefile->submakes[i] );
3976 for (i = 0; i < top_makefile->subdirs.count; i++)
3977 output_dependencies( top_makefile->submakes[i] );
3979 output_dependencies( top_makefile );
3980 return 0;
3983 for (i = 1; i < argc; i++)
3985 struct makefile *make = parse_makefile( argv[i] );
3986 load_sources( make );
3987 output_dependencies( make );
3989 return 0;