Back to home page

Wine source

 
 

    


File indexing completed on 2024-05-03 22:28:22

530ee8407 Alex*0001 /*
                0002  * Generate include file dependencies
                0003  *
1dd3051cc Alex*0004  * Copyright 1996, 2013, 2020 Alexandre Julliard
0799c1a78 Alex*0005  *
                0006  * This library is free software; you can redistribute it and/or
                0007  * modify it under the terms of the GNU Lesser General Public
                0008  * License as published by the Free Software Foundation; either
                0009  * version 2.1 of the License, or (at your option) any later version.
                0010  *
                0011  * This library is distributed in the hope that it will be useful,
                0012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                0013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                0014  * Lesser General Public License for more details.
                0015  *
                0016  * You should have received a copy of the GNU Lesser General Public
                0017  * License along with this library; if not, write to the Free Software
360a3f914 Jona*0018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
530ee8407 Alex*0019  */
                0020 
5769d1de0 Alex*0021 #include "config.h"
                0022 
b7ef1b2e2 Alex*0023 #include <assert.h>
530ee8407 Alex*0024 #include <ctype.h>
f25c4d47d Alex*0025 #include <errno.h>
0b9963ad3 Alex*0026 #include <fcntl.h>
530ee8407 Alex*0027 #include <stdio.h>
                0028 #include <stdlib.h>
ffca0d612 Alex*0029 #include <stdarg.h>
530ee8407 Alex*0030 #include <string.h>
0b9963ad3 Alex*0031 #include <sys/types.h>
                0032 #include <sys/stat.h>
207068c48 Alex*0033 
97ca9f8a3 Alex*0034 #include "tools.h"
f25c4d47d Alex*0035 #include "wine/list.h"
530ee8407 Alex*0036 
b69a0e89d Alex*0037 enum incl_type
                0038 {
                0039     INCL_NORMAL,           /* #include "foo.h" */
                0040     INCL_SYSTEM,           /* #include <foo.h> */
                0041     INCL_IMPORT,           /* idl import "foo.idl" */
8e81f6d58 Alex*0042     INCL_IMPORTLIB,        /* idl importlib "foo.tlb" */
b69a0e89d Alex*0043     INCL_CPP_QUOTE,        /* idl cpp_quote("#include \"foo.h\"") */
                0044     INCL_CPP_QUOTE_SYSTEM  /* idl cpp_quote("#include <foo.h>") */
                0045 };
                0046 
                0047 struct dependency
                0048 {
                0049     int                line;          /* source line where this header is included */
                0050     enum incl_type     type;          /* type of include */
                0051     char              *name;          /* header name */
                0052 };
                0053 
                0054 struct file
                0055 {
                0056     struct list        entry;
                0057     char              *name;          /* full file name relative to cwd */
                0058     void              *args;          /* custom arguments for makefile rule */
                0059     unsigned int       flags;         /* flags (see below) */
                0060     unsigned int       deps_count;    /* files in use */
                0061     unsigned int       deps_size;     /* total allocated size */
                0062     struct dependency *deps;          /* all header dependencies */
                0063 };
                0064 
cf34a967c Alex*0065 struct incl_file
530ee8407 Alex*0066 {
f25c4d47d Alex*0067     struct list        entry;
e31276e9a Alex*0068     struct list        hash_entry;
b69a0e89d Alex*0069     struct file       *file;
530ee8407 Alex*0070     char              *name;
                0071     char              *filename;
9da7d620e Alex*0072     char              *basename;      /* base target name for generated files */
e4fca883a Alex*0073     char              *sourcename;    /* source file name for generated headers */
cf34a967c Alex*0074     struct incl_file  *included_by;   /* file that included this one */
d19ad3962 Alex*0075     int                included_line; /* line where this file was included */
8e81f6d58 Alex*0076     enum incl_type     type;          /* type of include */
2094dd96e Alex*0077     unsigned int       arch;          /* architecture for multi-arch files, otherwise 0 */
7e8ac46a5 Alex*0078     unsigned int       use_msvcrt:1;  /* put msvcrt headers in the search path? */
                0079     unsigned int       is_external:1; /* file from external library? */
cf34a967c Alex*0080     struct incl_file  *owner;
9c2725d5d Alex*0081     unsigned int       files_count;   /* files in use */
                0082     unsigned int       files_size;    /* total allocated size */
                0083     struct incl_file **files;
4eb9ad983 Alex*0084     struct strarray    dependencies;  /* file dependencies */
ef8b871e1 Alex*0085     struct strarray    importlibdeps; /* importlib dependencies */
cf34a967c Alex*0086 };
530ee8407 Alex*0087 
b69a0e89d Alex*0088 #define FLAG_GENERATED      0x000001  /* generated file */
                0089 #define FLAG_INSTALL        0x000002  /* file to install */
81da9ff0f RĂ©mi*0090 #define FLAG_TESTDLL        0x000004  /* file is part of a TESTDLL resource */
09e70524f Alex*0091 #define FLAG_IDL_PROXY      0x000100  /* generates a proxy (_p.c) file */
                0092 #define FLAG_IDL_CLIENT     0x000200  /* generates a client (_c.c) file */
                0093 #define FLAG_IDL_SERVER     0x000400  /* generates a server (_s.c) file */
                0094 #define FLAG_IDL_IDENT      0x000800  /* generates an ident (_i.c) file */
                0095 #define FLAG_IDL_REGISTER   0x001000  /* generates a registration (_r.res) file */
04d872508 Alex*0096 #define FLAG_IDL_TYPELIB    0x002000  /* generates a typelib (_l.res) file */
09e70524f Alex*0097 #define FLAG_IDL_REGTYPELIB 0x004000  /* generates a registered typelib (_t.res) file */
                0098 #define FLAG_IDL_HEADER     0x008000  /* generates a header (.h) file */
                0099 #define FLAG_RC_PO          0x010000  /* rc file contains translations */
872dc83e8 Alex*0100 #define FLAG_RC_HEADER      0x020000  /* rc file is a header */
                0101 #define FLAG_C_IMPLIB       0x040000  /* file is part of an import library */
                0102 #define FLAG_C_UNIX         0x080000  /* file is part of a Unix library */
                0103 #define FLAG_SFD_FONTS      0x100000  /* sfd file generated bitmap fonts */
3e2a99901 Alex*0104 #define FLAG_ARM64EC_X64    0x200000  /* use x86_64 object on ARM64EC */
1f3e3fa42 Alex*0105 
                0106 static const struct
                0107 {
                0108     unsigned int flag;
                0109     const char *ext;
                0110 } idl_outputs[] =
                0111 {
04d872508 Alex*0112     { FLAG_IDL_TYPELIB,    "_l.res" },
d7afa5759 Alex*0113     { FLAG_IDL_REGTYPELIB, "_t.res" },
                0114     { FLAG_IDL_CLIENT,     "_c.c" },
                0115     { FLAG_IDL_IDENT,      "_i.c" },
                0116     { FLAG_IDL_PROXY,      "_p.c" },
                0117     { FLAG_IDL_SERVER,     "_s.c" },
                0118     { FLAG_IDL_REGISTER,   "_r.res" },
1f3e3fa42 Alex*0119 };
                0120 
e31276e9a Alex*0121 #define HASH_SIZE 197
b69a0e89d Alex*0122 
                0123 static struct list files[HASH_SIZE];
e31276e9a Alex*0124 static struct list global_includes[HASH_SIZE];
530ee8407 Alex*0125 
dbb55ed91 Alex*0126 enum install_rules { INSTALL_LIB, INSTALL_DEV, INSTALL_TEST, NB_INSTALL_RULES };
                0127 static const char *install_targets[NB_INSTALL_RULES] = { "install-lib", "install-dev", "install-test" };
                0128 static const char *install_variables[NB_INSTALL_RULES] = { "INSTALL_LIB", "INSTALL_DEV", "INSTALL_TEST" };
bf6af2825 Alex*0129 
5004e6bce Jace*0130 #define MAX_ARCHS 6
afc286fb5 Alex*0131 
391731315 Alex*0132 /* variables common to all makefiles */
afc286fb5 Alex*0133 static struct strarray archs;
391731315 Alex*0134 static struct strarray linguas;
                0135 static struct strarray dll_flags;
5e0479c49 Alex*0136 static struct strarray unix_dllflags;
391731315 Alex*0137 static struct strarray msvcrt_flags;
                0138 static struct strarray cpp_flags;
8039941c5 Alex*0139 static struct strarray lddll_flags;
391731315 Alex*0140 static struct strarray libs;
acc6306bc Alex*0141 static struct strarray enable_tests;
391731315 Alex*0142 static struct strarray cmdline_vars;
468af5bbb Alex*0143 static struct strarray subdirs;
bbc302290 Alex*0144 static struct strarray delay_import_libs;
f9cad1bd1 Alex*0145 static struct strarray top_install[NB_INSTALL_RULES];
391731315 Alex*0146 static const char *root_src_dir;
                0147 static const char *tools_dir;
                0148 static const char *tools_ext;
                0149 static const char *exe_ext;
                0150 static const char *fontforge;
                0151 static const char *convert;
1fd60d565 Alex*0152 static const char *flex;
                0153 static const char *bison;
                0154 static const char *ar;
                0155 static const char *ranlib;
391731315 Alex*0156 static const char *rsvg;
                0157 static const char *icotool;
d5ddc93b8 Alex*0158 static const char *msgfmt;
fb43551a0 Alex*0159 static const char *ln_s;
1fd60d565 Alex*0160 static const char *sed_cmd;
857001678 Alex*0161 static const char *wayland_scanner;
56fe04085 Alex*0162 static int so_dll_supported;
fa732145b Alex*0163 static int unix_lib_supported;
afc286fb5 Alex*0164 /* per-architecture global variables */
fa732145b Alex*0165 static const char *dll_ext[MAX_ARCHS];
6a9126491 Alex*0166 static const char *arch_dirs[MAX_ARCHS];
                0167 static const char *arch_pe_dirs[MAX_ARCHS];
9795a0191 Alex*0168 static const char *arch_install_dirs[MAX_ARCHS];
afc286fb5 Alex*0169 static const char *strip_progs[MAX_ARCHS];
55e2335f6 Alex*0170 static const char *debug_flags[MAX_ARCHS];
815e766d9 Alex*0171 static const char *delay_load_flags[MAX_ARCHS];
afc286fb5 Alex*0172 static struct strarray target_flags[MAX_ARCHS];
25735da0d Alex*0173 static struct strarray extra_cflags[MAX_ARCHS];
                0174 static struct strarray extra_cflags_extlib[MAX_ARCHS];
b1f59bc67 Alex*0175 static struct strarray disabled_dirs[MAX_ARCHS];
ba50573f9 Jace*0176 static unsigned int native_archs[MAX_ARCHS];
                0177 static unsigned int hybrid_archs[MAX_ARCHS];
                0178 static struct strarray hybrid_target_flags[MAX_ARCHS];
391731315 Alex*0179 
228684d34 Alex*0180 struct makefile
                0181 {
4eb9ad983 Alex*0182     /* values determined from input makefile */
228684d34 Alex*0183     struct strarray vars;
acd9c551b Alex*0184     struct strarray include_paths;
4eb9ad983 Alex*0185     struct strarray include_args;
228684d34 Alex*0186     struct strarray define_args;
194e09bae Alex*0187     struct strarray unix_cflags;
7626728b5 Alex*0188     struct strarray programs;
5cd339597 Alex*0189     struct strarray scripts;
228684d34 Alex*0190     struct strarray imports;
081df721d Alex*0191     struct strarray delayimports;
                0192     struct strarray extradllflags;
f9cad1bd1 Alex*0193     struct strarray install[NB_INSTALL_RULES];
cb078bd3b Alex*0194     struct strarray extra_targets;
c873db8c1 Alex*0195     struct strarray extra_imports;
4cb68d232 Alex*0196     struct list     sources;
c6ba107a4 Alex*0197     struct list     includes;
228684d34 Alex*0198     const char     *src_dir;
dcf6060ab Alex*0199     const char     *obj_dir;
228684d34 Alex*0200     const char     *parent_dir;
081df721d Alex*0201     const char     *module;
                0202     const char     *testdll;
a4b01382e Alex*0203     const char     *extlib;
081df721d Alex*0204     const char     *staticlib;
                0205     const char     *importlib;
0f62381f6 Alex*0206     const char     *unixlib;
1c2e3fc68 Alex*0207     int             data_only;
081df721d Alex*0208     int             is_win16;
1d6a41024 Alex*0209     int             is_exe;
8d43170b9 Alex*0210     int             disabled[MAX_ARCHS];
4eb9ad983 Alex*0211 
                0212     /* values generated at output time */
                0213     struct strarray in_files;
82acb284b Alex*0214     struct strarray pot_files;
859338a4d Alex*0215     struct strarray test_files;
4eb9ad983 Alex*0216     struct strarray clean_files;
1a52ba0bc Alex*0217     struct strarray distclean_files;
363d078f4 Alex*0218     struct strarray maintainerclean_files;
1a52ba0bc Alex*0219     struct strarray uninstall_files;
6bce2b136 Alex*0220     struct strarray unixobj_files;
f2d60c16e Alex*0221     struct strarray font_files;
83d00d328 Jace*0222     struct strarray debug_files;
4eb9ad983 Alex*0223     struct strarray dlldata_files;
                0224     struct strarray phony_targets;
51b57133c Alex*0225     struct strarray dependencies;
cb5268c72 Alex*0226     struct strarray object_files[MAX_ARCHS];
7bffe6d68 Alex*0227     struct strarray implib_files[MAX_ARCHS];
fec95db07 Alex*0228     struct strarray ok_files[MAX_ARCHS];
6c65fb9cb Alex*0229     struct strarray res_files[MAX_ARCHS];
718c57cab Alex*0230     struct strarray all_targets[MAX_ARCHS];
4eb9ad983 Alex*0231     struct strarray install_rules[NB_INSTALL_RULES];
228684d34 Alex*0232 };
                0233 
f9ddafa80 Alex*0234 static struct makefile *top_makefile;
872dc83e8 Alex*0235 static struct makefile *include_makefile;
468af5bbb Alex*0236 static struct makefile **submakes;
391731315 Alex*0237 
49f88527c Alex*0238 static const char separator[] = "### Dependencies";
e0b1e8154 Alex*0239 static const char *output_makefile_name = "Makefile";
c3aa49529 Alex*0240 static const char *input_file_name;
8aa529417 Alex*0241 static const char *output_file_name;
                0242 static const char *temp_file_name;
067d3f0dd Alex*0243 static int relative_dir_mode;
1a16b9e9a Alex*0244 static int silent_rules;
b7ef1b2e2 Alex*0245 static int input_line;
2af368b88 Alex*0246 static int output_column;
c3aa49529 Alex*0247 static FILE *output_file;
530ee8407 Alex*0248 
                0249 static const char Usage[] =
8f57dfedf Alex*0250     "Usage: makedep [options] [directories]\n"
530ee8407 Alex*0251     "Options:\n"
2da6fc368 Alex*0252     "   -R from to  Compute the relative path between two directories\n"
1a16b9e9a Alex*0253     "   -S          Generate Automake-style silent rules\n"
ca2cb6011 Alex*0254     "   -fxxx       Store output in file 'xxx' (default: Makefile)\n";
530ee8407 Alex*0255 
                0256 
c3aa49529 Alex*0257 static void fatal_error( const char *msg, ... ) __attribute__ ((__format__ (__printf__, 1, 2)));
                0258 static void fatal_perror( const char *msg, ... ) __attribute__ ((__format__ (__printf__, 1, 2)));
2af368b88 Alex*0259 static void output( const char *format, ... ) __attribute__ ((__format__ (__printf__, 1, 2)));
25b081065 Alex*0260 static char *strmake( const char* fmt, ... ) __attribute__ ((__format__ (__printf__, 1, 2)));
c3aa49529 Alex*0261 
ffca0d612 Alex*0262 /*******************************************************************
                0263  *         fatal_error
                0264  */
                0265 static void fatal_error( const char *msg, ... )
                0266 {
                0267     va_list valist;
                0268     va_start( valist, msg );
c3aa49529 Alex*0269     if (input_file_name)
                0270     {
                0271         fprintf( stderr, "%s:", input_file_name );
                0272         if (input_line) fprintf( stderr, "%d:", input_line );
                0273         fprintf( stderr, " error: " );
                0274     }
                0275     else fprintf( stderr, "makedep: error: " );
ffca0d612 Alex*0276     vfprintf( stderr, msg, valist );
                0277     va_end( valist );
                0278     exit(1);
                0279 }
                0280 
                0281 
c3aa49529 Alex*0282 /*******************************************************************
                0283  *         fatal_perror
                0284  */
                0285 static void fatal_perror( const char *msg, ... )
                0286 {
                0287     va_list valist;
                0288     va_start( valist, msg );
                0289     if (input_file_name)
                0290     {
                0291         fprintf( stderr, "%s:", input_file_name );
                0292         if (input_line) fprintf( stderr, "%d:", input_line );
1f3e3fa42 Alex*0293         fprintf( stderr, " error: " );
c3aa49529 Alex*0294     }
1f3e3fa42 Alex*0295     else fprintf( stderr, "makedep: error: " );
                0296     vfprintf( stderr, msg, valist );
c3aa49529 Alex*0297     perror( " " );
                0298     va_end( valist );
                0299     exit(1);
                0300 }
                0301 
                0302 
8aa529417 Alex*0303 /*******************************************************************
                0304  *         cleanup_files
                0305  */
                0306 static void cleanup_files(void)
                0307 {
                0308     if (temp_file_name) unlink( temp_file_name );
                0309     if (output_file_name) unlink( output_file_name );
                0310 }
                0311 
                0312 
                0313 /*******************************************************************
                0314  *         exit_on_signal
                0315  */
                0316 static void exit_on_signal( int sig )
                0317 {
                0318     exit( 1 );  /* this will call the atexit functions */
                0319 }
                0320 
                0321 
c3aa49529 Alex*0322 /*******************************************************************
                0323  *         output
                0324  */
2af368b88 Alex*0325 static void output( const char *format, ... )
c3aa49529 Alex*0326 {
                0327     int ret;
                0328     va_list valist;
                0329 
                0330     va_start( valist, format );
                0331     ret = vfprintf( output_file, format, valist );
                0332     va_end( valist );
                0333     if (ret < 0) fatal_perror( "output" );
2af368b88 Alex*0334     if (format[0] && format[strlen(format) - 1] == '\n') output_column = 0;
                0335     else output_column += ret;
c3aa49529 Alex*0336 }
                0337 
                0338 
43fd82c61 Alex*0339 /*******************************************************************
                0340  *         strarray_get_value
                0341  *
                0342  * Find a value in a name/value pair string array.
                0343  */
5a1067ade Alex*0344 static const char *strarray_get_value( const struct strarray *array, const char *name )
43fd82c61 Alex*0345 {
512c686be Alex*0346     int pos, res, min = 0, max = array->count / 2 - 1;
43fd82c61 Alex*0347 
512c686be Alex*0348     while (min <= max)
                0349     {
                0350         pos = (min + max) / 2;
                0351         if (!(res = strcmp( array->str[pos * 2], name ))) return array->str[pos * 2 + 1];
                0352         if (res < 0) min = pos + 1;
                0353         else max = pos - 1;
                0354     }
43fd82c61 Alex*0355     return NULL;
                0356 }
                0357 
                0358 
                0359 /*******************************************************************
                0360  *         strarray_set_value
                0361  *
                0362  * Define a value in a name/value pair string array.
                0363  */
                0364 static void strarray_set_value( struct strarray *array, const char *name, const char *value )
                0365 {
512c686be Alex*0366     int i, pos, res, min = 0, max = array->count / 2 - 1;
43fd82c61 Alex*0367 
512c686be Alex*0368     while (min <= max)
43fd82c61 Alex*0369     {
512c686be Alex*0370         pos = (min + max) / 2;
                0371         if (!(res = strcmp( array->str[pos * 2], name )))
                0372         {
                0373             /* redefining a variable replaces the previous value */
                0374             array->str[pos * 2 + 1] = value;
                0375             return;
                0376         }
                0377         if (res < 0) min = pos + 1;
                0378         else max = pos - 1;
43fd82c61 Alex*0379     }
512c686be Alex*0380     strarray_add( array, NULL );
                0381     strarray_add( array, NULL );
                0382     for (i = array->count - 1; i > min * 2 + 1; i--) array->str[i] = array->str[i - 2];
                0383     array->str[min * 2] = name;
                0384     array->str[min * 2 + 1] = value;
43fd82c61 Alex*0385 }
                0386 
                0387 
c3aa49529 Alex*0388 /*******************************************************************
                0389  *         output_filename
                0390  */
2af368b88 Alex*0391 static void output_filename( const char *name )
c3aa49529 Alex*0392 {
2af368b88 Alex*0393     if (output_column + strlen(name) + 1 > 100)
c3aa49529 Alex*0394     {
2af368b88 Alex*0395         output( " \\\n" );
                0396         output( "  " );
c3aa49529 Alex*0397     }
2af368b88 Alex*0398     else if (output_column) output( " " );
                0399     output( "%s", name );
7779af1df Alex*0400 }
                0401 
                0402 
                0403 /*******************************************************************
                0404  *         output_filenames
                0405  */
5706cdaa5 Alex*0406 static void output_filenames( struct strarray array )
7779af1df Alex*0407 {
                0408     unsigned int i;
                0409 
5706cdaa5 Alex*0410     for (i = 0; i < array.count; i++) output_filename( array.str[i] );
c3aa49529 Alex*0411 }
                0412 
                0413 
fcc0e7621 Alex*0414 /*******************************************************************
                0415  *         output_rm_filenames
                0416  */
abee72f32 Alex*0417 static void output_rm_filenames( struct strarray array, const char *command )
fcc0e7621 Alex*0418 {
                0419     static const unsigned int max_cmdline = 30000;  /* to be on the safe side */
                0420     unsigned int i, len;
                0421 
                0422     if (!array.count) return;
abee72f32 Alex*0423     output( "\t%s", command );
fcc0e7621 Alex*0424     for (i = len = 0; i < array.count; i++)
                0425     {
                0426         if (len > max_cmdline)
                0427         {
                0428             output( "\n" );
abee72f32 Alex*0429             output( "\t%s", command );
fcc0e7621 Alex*0430             len = 0;
                0431         }
                0432         output_filename( array.str[i] );
                0433         len += strlen( array.str[i] ) + 1;
                0434     }
                0435     output( "\n" );
                0436 }
                0437 
                0438 
aa89eccc7 Alex*0439 /*******************************************************************
                0440  *         get_extension
                0441  */
                0442 static char *get_extension( char *filename )
                0443 {
                0444     char *ext = strrchr( filename, '.' );
                0445     if (ext && strchr( ext, '/' )) ext = NULL;
                0446     return ext;
                0447 }
                0448 
                0449 
4346d68e1 Jace*0450 /*******************************************************************
                0451  *         get_base_name
                0452  */
                0453 static const char *get_base_name( const char *name )
                0454 {
                0455     char *base;
                0456     if (!strchr( name, '.' )) return name;
0f62381f6 Alex*0457     base = xstrdup( name );
4346d68e1 Jace*0458     *strrchr( base, '.' ) = 0;
                0459     return base;
                0460 }
                0461 
                0462 
ec7664d4d Alex*0463 /*******************************************************************
                0464  *         replace_filename
                0465  */
                0466 static char *replace_filename( const char *path, const char *name )
                0467 {
                0468     const char *p;
                0469     char *ret;
                0470     size_t len;
                0471 
                0472     if (!path) return xstrdup( name );
                0473     if (!(p = strrchr( path, '/' ))) return xstrdup( name );
                0474     len = p - path + 1;
                0475     ret = xmalloc( len + strlen( name ) + 1 );
                0476     memcpy( ret, path, len );
                0477     strcpy( ret + len, name );
                0478     return ret;
                0479 }
                0480 
                0481 
1928d6114 Alex*0482 /*******************************************************************
                0483  *         replace_substr
                0484  */
8a2545e48 Alex*0485 static char *replace_substr( const char *str, const char *start, size_t len, const char *replace )
1928d6114 Alex*0486 {
8a2545e48 Alex*0487     size_t pos = start - str;
1928d6114 Alex*0488     char *ret = xmalloc( pos + strlen(replace) + strlen(start + len) + 1 );
                0489     memcpy( ret, str, pos );
                0490     strcpy( ret + pos, replace );
                0491     strcat( ret + pos, start + len );
                0492     return ret;
                0493 }
                0494 
                0495 
067d3f0dd Alex*0496 /*******************************************************************
                0497  *         get_relative_path
                0498  *
                0499  * Determine where the destination path is located relative to the 'from' path.
                0500  */
                0501 static char *get_relative_path( const char *from, const char *dest )
                0502 {
                0503     const char *start;
                0504     char *ret, *p;
                0505     unsigned int dotdots = 0;
                0506 
                0507     /* a path of "." is equivalent to an empty path */
                0508     if (!strcmp( from, "." )) from = "";
                0509 
                0510     for (;;)
                0511     {
                0512         while (*from == '/') from++;
                0513         while (*dest == '/') dest++;
                0514         start = dest;  /* save start of next path element */
                0515         if (!*from) break;
                0516 
                0517         while (*from && *from != '/' && *from == *dest) { from++; dest++; }
                0518         if ((!*from || *from == '/') && (!*dest || *dest == '/')) continue;
                0519 
                0520         /* count remaining elements in 'from' */
                0521         do
                0522         {
                0523             dotdots++;
                0524             while (*from && *from != '/') from++;
                0525             while (*from == '/') from++;
                0526         }
                0527         while (*from);
                0528         break;
                0529     }
                0530 
                0531     if (!start[0] && !dotdots) return NULL;  /* empty path */
                0532 
                0533     ret = xmalloc( 3 * dotdots + strlen( start ) + 1 );
                0534     for (p = ret; dotdots; dotdots--, p += 3) memcpy( p, "../", 3 );
                0535 
                0536     if (start[0]) strcpy( p, start );
                0537     else p[-1] = 0;  /* remove trailing slash */
                0538     return ret;
                0539 }
                0540 
                0541 
c3c35dcff Alex*0542 /*******************************************************************
                0543  *         concat_paths
                0544  */
                0545 static char *concat_paths( const char *base, const char *path )
                0546 {
feb522909 Alex*0547     int i, len;
                0548     char *ret;
                0549 
c16df0cd9 Alex*0550     if (!base || !base[0]) return xstrdup( path && path[0] ? path : "." );
8fdacd15d Alex*0551     if (!path || !path[0]) return xstrdup( base );
c3c35dcff Alex*0552     if (path[0] == '/') return xstrdup( path );
feb522909 Alex*0553 
                0554     len = strlen( base );
                0555     while (len && base[len - 1] == '/') len--;
                0556     while (len && !strncmp( path, "..", 2 ) && (!path[2] || path[2] == '/'))
                0557     {
                0558         for (i = len; i > 0; i--) if (base[i - 1] == '/') break;
                0559         if (i == len - 2 && !memcmp( base + i, "..", 2 )) break;  /* we can't go up if we already have ".." */
                0560         if (i != len - 1 || base[i] != '.')
                0561         {
                0562             path += 2;
                0563             while (*path == '/') path++;
                0564         }
                0565         /* else ignore "." element */
                0566         while (i > 0 && base[i - 1] == '/') i--;
                0567         len = i;
                0568     }
                0569     if (!len && base[0] != '/') return xstrdup( path[0] ? path : "." );
                0570     ret = xmalloc( len + strlen( path ) + 2 );
                0571     memcpy( ret, base, len );
                0572     ret[len++] = '/';
                0573     strcpy( ret + len, path );
                0574     return ret;
c3c35dcff Alex*0575 }
                0576 
                0577 
8d43170b9 Alex*0578 /*******************************************************************
                0579  *         is_native_arch_disabled
                0580  *
                0581  * Check if the makefile was disabled for a PE arch that matches the native arch.
                0582  */
                0583 static int is_native_arch_disabled( struct makefile *make )
                0584 {
                0585     unsigned int arch;
                0586 
56fe04085 Alex*0587     if (archs.count == 1) return 0;
                0588     if (!so_dll_supported) return 1;
                0589 
8d43170b9 Alex*0590     for (arch = 1; arch < archs.count; arch++)
                0591         if (make->disabled[arch] && !strcmp( archs.str[0], archs.str[arch] ))
                0592             return 1;
                0593     return 0;
                0594 }
                0595 
                0596 
ba50573f9 Jace*0597 /*******************************************************************
                0598  *         get_link_arch
                0599  */
                0600 static int get_link_arch( struct makefile *make, unsigned int arch, unsigned int *link_arch )
                0601 {
                0602     unsigned int hybrid_arch = hybrid_archs[arch];
                0603     if (native_archs[arch]) return 0;
                0604     if (hybrid_arch && make->disabled[hybrid_arch]) hybrid_arch = 0;
                0605     if (make->disabled[arch] && !hybrid_arch) return 0;
                0606     *link_arch = hybrid_arch ? hybrid_arch : arch;
                0607     return 1;
                0608 }
                0609 
                0610 
55e2335f6 Alex*0611 /*******************************************************************
                0612  *         is_multiarch
                0613  *
                0614  * Check if arch is one of the PE architectures in multiarch.
                0615  * Also return TRUE for native arch iff there's no PE support.
                0616  */
                0617 static int is_multiarch( unsigned int arch )
                0618 {
                0619     return archs.count == 1 || arch;
                0620 }
                0621 
                0622 
a9183c7e3 Alex*0623 /*******************************************************************
                0624  *         is_using_msvcrt
                0625  *
                0626  * Check if the files of a makefile use msvcrt by default.
                0627  */
                0628 static int is_using_msvcrt( struct makefile *make )
                0629 {
                0630     return make->module || make->testdll;
                0631 }
                0632 
                0633 
6cfdd7e97 Alex*0634 /*******************************************************************
                0635  *         arch_module_name
                0636  */
                0637 static char *arch_module_name( const char *module, unsigned int arch )
                0638 {
fa732145b Alex*0639     return strmake( "%s%s%s", arch_dirs[arch], module, dll_ext[arch] );
6cfdd7e97 Alex*0640 }
                0641 
                0642 
5574c22d5 Alex*0643 /*******************************************************************
                0644  *         arch_make_variable
                0645  */
                0646 static char *arch_make_variable( const char *name, unsigned int arch )
                0647 {
b1f59bc67 Alex*0648     return arch ? strmake( "$(%s_%s)", archs.str[arch], name ) : strmake( "$(%s)", name );
5574c22d5 Alex*0649 }
                0650 
                0651 
dcf6060ab Alex*0652 /*******************************************************************
                0653  *         obj_dir_path
                0654  */
5a1067ade Alex*0655 static char *obj_dir_path( const struct makefile *make, const char *path )
dcf6060ab Alex*0656 {
                0657     return concat_paths( make->obj_dir, path );
                0658 }
                0659 
                0660 
623cfef4a Alex*0661 /*******************************************************************
                0662  *         src_dir_path
                0663  */
5a1067ade Alex*0664 static char *src_dir_path( const struct makefile *make, const char *path )
623cfef4a Alex*0665 {
dcf6060ab Alex*0666     if (make->src_dir) return concat_paths( make->src_dir, path );
f9ddafa80 Alex*0667     return obj_dir_path( make, path );
623cfef4a Alex*0668 }
                0669 
                0670 
                0671 /*******************************************************************
468af5bbb Alex*0672  *         root_src_dir_path
623cfef4a Alex*0673  */
468af5bbb Alex*0674 static char *root_src_dir_path( const char *path )
c16df0cd9 Alex*0675 {
                0676     return concat_paths( root_src_dir, path );
                0677 }
                0678 
                0679 
c7411e22b Alex*0680 /*******************************************************************
                0681  *         tools_dir_path
                0682  */
5a1067ade Alex*0683 static char *tools_dir_path( const struct makefile *make, const char *path )
c7411e22b Alex*0684 {
468af5bbb Alex*0685     if (tools_dir) return strmake( "%s/tools/%s", tools_dir, path );
                0686     return strmake( "tools/%s", path );
c7411e22b Alex*0687 }
                0688 
                0689 
7d1d9b40f Alex*0690 /*******************************************************************
                0691  *         tools_path
                0692  */
5a1067ade Alex*0693 static char *tools_path( const struct makefile *make, const char *name )
7d1d9b40f Alex*0694 {
f9ddafa80 Alex*0695     return strmake( "%s/%s%s", tools_dir_path( make, name ), name, tools_ext );
7d1d9b40f Alex*0696 }
                0697 
                0698 
1dd3051cc Alex*0699 /*******************************************************************
                0700  *         strarray_addall_path
                0701  */
                0702 static void strarray_addall_path( struct strarray *array, const char *dir, struct strarray added )
                0703 {
                0704     unsigned int i;
                0705 
                0706     for (i = 0; i < added.count; i++) strarray_add( array, concat_paths( dir, added.str[i] ));
                0707 }
                0708 
                0709 
b7ef1b2e2 Alex*0710 /*******************************************************************
                0711  *         get_line
                0712  */
                0713 static char *get_line( FILE *file )
                0714 {
                0715     static char *buffer;
8a2545e48 Alex*0716     static size_t size;
b7ef1b2e2 Alex*0717 
                0718     if (!size)
                0719     {
                0720         size = 1024;
                0721         buffer = xmalloc( size );
                0722     }
                0723     if (!fgets( buffer, size, file )) return NULL;
                0724     input_line++;
                0725 
                0726     for (;;)
                0727     {
                0728         char *p = buffer + strlen(buffer);
                0729         /* if line is larger than buffer, resize buffer */
                0730         while (p == buffer + size - 1 && p[-1] != '\n')
                0731         {
                0732             buffer = xrealloc( buffer, size * 2 );
d04c2ccb2 Marc*0733             if (!fgets( buffer + size - 1, size + 1, file )) break;
b7ef1b2e2 Alex*0734             p = buffer + strlen(buffer);
                0735             size *= 2;
                0736         }
                0737         if (p > buffer && p[-1] == '\n')
                0738         {
                0739             *(--p) = 0;
                0740             if (p > buffer && p[-1] == '\r') *(--p) = 0;
                0741             if (p > buffer && p[-1] == '\\')
                0742             {
                0743                 *(--p) = 0;
                0744                 /* line ends in backslash, read continuation line */
d04c2ccb2 Marc*0745                 if (!fgets( p, size - (p - buffer), file )) return buffer;
b7ef1b2e2 Alex*0746                 input_line++;
                0747                 continue;
                0748             }
                0749         }
                0750         return buffer;
                0751     }
                0752 }
                0753 
b69a0e89d Alex*0754 
                0755 /*******************************************************************
                0756  *         hash_filename
                0757  */
                0758 static unsigned int hash_filename( const char *name )
                0759 {
bf6db74f8 Alex*0760     /* FNV-1 hash */
5cb8f0d0d Matt*0761     unsigned int ret = 2166136261u;
bf6db74f8 Alex*0762     while (*name) ret = (ret * 16777619) ^ *name++;
b69a0e89d Alex*0763     return ret % HASH_SIZE;
                0764 }
                0765 
                0766 
                0767 /*******************************************************************
                0768  *         add_file
                0769  */
                0770 static struct file *add_file( const char *name )
                0771 {
                0772     struct file *file = xmalloc( sizeof(*file) );
                0773     memset( file, 0, sizeof(*file) );
                0774     file->name = xstrdup( name );
                0775     return file;
                0776 }
                0777 
                0778 
                0779 /*******************************************************************
                0780  *         add_dependency
                0781  */
                0782 static void add_dependency( struct file *file, const char *name, enum incl_type type )
                0783 {
                0784     if (file->deps_count >= file->deps_size)
                0785     {
                0786         file->deps_size *= 2;
                0787         if (file->deps_size < 16) file->deps_size = 16;
                0788         file->deps = xrealloc( file->deps, file->deps_size * sizeof(*file->deps) );
                0789     }
                0790     file->deps[file->deps_count].line = input_line;
                0791     file->deps[file->deps_count].type = type;
                0792     file->deps[file->deps_count].name = xstrdup( name );
                0793     file->deps_count++;
                0794 }
                0795 
                0796 
8f31f92a7 Alex*0797 /*******************************************************************
                0798  *         find_src_file
                0799  */
5a1067ade Alex*0800 static struct incl_file *find_src_file( const struct makefile *make, const char *name )
8f31f92a7 Alex*0801 {
cf34a967c Alex*0802     struct incl_file *file;
8f31f92a7 Alex*0803 
e31276e9a Alex*0804     if (make == include_makefile)
                0805     {
                0806         unsigned int hash = hash_filename( name );
                0807 
                0808         LIST_FOR_EACH_ENTRY( file, &global_includes[hash], struct incl_file, hash_entry )
                0809             if (!strcmp( name, file->name )) return file;
                0810         return NULL;
                0811     }
                0812 
4cb68d232 Alex*0813     LIST_FOR_EACH_ENTRY( file, &make->sources, struct incl_file, entry )
8f31f92a7 Alex*0814         if (!strcmp( name, file->name )) return file;
                0815     return NULL;
                0816 }
530ee8407 Alex*0817 
133d4cde2 Alex*0818 /*******************************************************************
                0819  *         find_include_file
                0820  */
5a1067ade Alex*0821 static struct incl_file *find_include_file( const struct makefile *make, const char *name )
133d4cde2 Alex*0822 {
cf34a967c Alex*0823     struct incl_file *file;
133d4cde2 Alex*0824 
c6ba107a4 Alex*0825     LIST_FOR_EACH_ENTRY( file, &make->includes, struct incl_file, entry )
4c7a2b4cb Alex*0826     {
                0827         const char *filename = file->filename;
                0828         if (!filename) continue;
                0829         if (make->obj_dir && strlen(make->obj_dir) < strlen(filename))
                0830         {
                0831             filename += strlen(make->obj_dir);
                0832             while (*filename == '/') filename++;
                0833         }
                0834         if (!strcmp( name, filename )) return file;
                0835     }
133d4cde2 Alex*0836     return NULL;
                0837 }
                0838 
530ee8407 Alex*0839 /*******************************************************************
                0840  *         add_include
                0841  *
                0842  * Add an include file if it doesn't already exists.
                0843  */
c6ba107a4 Alex*0844 static struct incl_file *add_include( struct makefile *make, struct incl_file *parent,
8e81f6d58 Alex*0845                                       const char *name, int line, enum incl_type type )
530ee8407 Alex*0846 {
cf34a967c Alex*0847     struct incl_file *include;
530ee8407 Alex*0848 
9c2725d5d Alex*0849     if (parent->files_count >= parent->files_size)
                0850     {
                0851         parent->files_size *= 2;
                0852         if (parent->files_size < 16) parent->files_size = 16;
                0853         parent->files = xrealloc( parent->files, parent->files_size * sizeof(*parent->files) );
                0854     }
ffca0d612 Alex*0855 
c6ba107a4 Alex*0856     LIST_FOR_EACH_ENTRY( include, &make->includes, struct incl_file, entry )
6bce2b136 Alex*0857         if (!parent->use_msvcrt == !include->use_msvcrt && !strcmp( name, include->name ))
                0858             goto found;
f25c4d47d Alex*0859 
cf34a967c Alex*0860     include = xmalloc( sizeof(*include) );
                0861     memset( include, 0, sizeof(*include) );
f25c4d47d Alex*0862     include->name = xstrdup(name);
9c2725d5d Alex*0863     include->included_by = parent;
b69a0e89d Alex*0864     include->included_line = line;
8e81f6d58 Alex*0865     include->type = type;
6bce2b136 Alex*0866     include->use_msvcrt = parent->use_msvcrt;
c6ba107a4 Alex*0867     list_add_tail( &make->includes, &include->entry );
f25c4d47d Alex*0868 found:
9c2725d5d Alex*0869     parent->files[parent->files_count++] = include;
f25c4d47d Alex*0870     return include;
530ee8407 Alex*0871 }
                0872 
                0873 
1cccb5594 Alex*0874 /*******************************************************************
                0875  *         add_generated_source
                0876  *
                0877  * Add a generated source file to the list.
                0878  */
2094dd96e Alex*0879 static struct incl_file *add_generated_source( struct makefile *make, const char *name,
                0880                                                const char *filename, unsigned int arch )
1cccb5594 Alex*0881 {
6f4d1766a Alex*0882     struct incl_file *file = xmalloc( sizeof(*file) );
1cccb5594 Alex*0883 
6a9126491 Alex*0884     name = strmake( "%s%s", arch_dirs[arch], name );
1cccb5594 Alex*0885     memset( file, 0, sizeof(*file) );
b69a0e89d Alex*0886     file->file = add_file( name );
2094dd96e Alex*0887     file->arch = arch;
1cccb5594 Alex*0888     file->name = xstrdup( name );
9da7d620e Alex*0889     file->basename = xstrdup( filename ? filename : name );
                0890     file->filename = obj_dir_path( make, file->basename );
b69a0e89d Alex*0891     file->file->flags = FLAG_GENERATED;
a9183c7e3 Alex*0892     file->use_msvcrt = is_using_msvcrt( make );
4cb68d232 Alex*0893     list_add_tail( &make->sources, &file->entry );
e31276e9a Alex*0894     if (make == include_makefile)
                0895     {
                0896         unsigned int hash = hash_filename( name );
                0897         list_add_tail( &global_includes[hash], &file->hash_entry );
                0898     }
1cccb5594 Alex*0899     return file;
                0900 }
                0901 
                0902 
df50fca0f Alex*0903 /*******************************************************************
                0904  *         skip_spaces
                0905  */
                0906 static char *skip_spaces( const char *p )
                0907 {
                0908     while (*p == ' ' || *p == '\t') p++;
                0909     return (char *)p;
                0910 }
                0911 
                0912 
ae9f33e17 Alex*0913 /*******************************************************************
                0914  *         parse_include_directive
                0915  */
b69a0e89d Alex*0916 static void parse_include_directive( struct file *source, char *str )
ae9f33e17 Alex*0917 {
df50fca0f Alex*0918     char quote, *include, *p = skip_spaces( str );
ae9f33e17 Alex*0919 
                0920     if (*p != '\"' && *p != '<' ) return;
                0921     quote = *p++;
                0922     if (quote == '<') quote = '>';
                0923     include = p;
                0924     while (*p && (*p != quote)) p++;
                0925     if (!*p) fatal_error( "malformed include directive '%s'\n", str );
                0926     *p = 0;
b69a0e89d Alex*0927     add_dependency( source, include, (quote == '>') ? INCL_SYSTEM : INCL_NORMAL );
ae9f33e17 Alex*0928 }
                0929 
                0930 
                0931 /*******************************************************************
                0932  *         parse_pragma_directive
                0933  */
b69a0e89d Alex*0934 static void parse_pragma_directive( struct file *source, char *str )
ae9f33e17 Alex*0935 {
                0936     char *flag, *p = str;
                0937 
df50fca0f Alex*0938     if (*p != ' ' && *p != '\t') return;
                0939     p = strtok( skip_spaces( p ), " \t" );
ae9f33e17 Alex*0940     if (strcmp( p, "makedep" )) return;
                0941 
                0942     while ((flag = strtok( NULL, " \t" )))
                0943     {
                0944         if (!strcmp( flag, "depend" ))
                0945         {
b69a0e89d Alex*0946             while ((p = strtok( NULL, " \t" ))) add_dependency( source, p, INCL_NORMAL );
ae9f33e17 Alex*0947             return;
                0948         }
09e70524f Alex*0949         else if (!strcmp( flag, "install" )) source->flags |= FLAG_INSTALL;
81da9ff0f RĂ©mi*0950         else if (!strcmp( flag, "testdll" )) source->flags |= FLAG_TESTDLL;
09e70524f Alex*0951 
ae9f33e17 Alex*0952         if (strendswith( source->name, ".idl" ))
                0953         {
                0954             if (!strcmp( flag, "header" )) source->flags |= FLAG_IDL_HEADER;
                0955             else if (!strcmp( flag, "proxy" )) source->flags |= FLAG_IDL_PROXY;
                0956             else if (!strcmp( flag, "client" )) source->flags |= FLAG_IDL_CLIENT;
                0957             else if (!strcmp( flag, "server" )) source->flags |= FLAG_IDL_SERVER;
                0958             else if (!strcmp( flag, "ident" )) source->flags |= FLAG_IDL_IDENT;
                0959             else if (!strcmp( flag, "typelib" )) source->flags |= FLAG_IDL_TYPELIB;
                0960             else if (!strcmp( flag, "register" )) source->flags |= FLAG_IDL_REGISTER;
566d3418a Alex*0961             else if (!strcmp( flag, "regtypelib" )) source->flags |= FLAG_IDL_REGTYPELIB;
ae9f33e17 Alex*0962         }
                0963         else if (strendswith( source->name, ".rc" ))
                0964         {
872dc83e8 Alex*0965             if (!strcmp( flag, "header" )) source->flags |= FLAG_RC_HEADER;
                0966             else if (!strcmp( flag, "po" )) source->flags |= FLAG_RC_PO;
ae9f33e17 Alex*0967         }
1cccb5594 Alex*0968         else if (strendswith( source->name, ".sfd" ))
                0969         {
                0970             if (!strcmp( flag, "font" ))
                0971             {
8c0a717a5 Alex*0972                 struct strarray *array = source->args;
                0973 
                0974                 if (!array)
                0975                 {
                0976                     source->args = array = xmalloc( sizeof(*array) );
                0977                     *array = empty_strarray;
                0978                     source->flags |= FLAG_SFD_FONTS;
                0979                 }
                0980                 strarray_add( array, xstrdup( strtok( NULL, "" )));
1cccb5594 Alex*0981                 return;
                0982             }
                0983         }
6bce2b136 Alex*0984         else
                0985         {
                0986             if (!strcmp( flag, "implib" )) source->flags |= FLAG_C_IMPLIB;
                0987             if (!strcmp( flag, "unix" )) source->flags |= FLAG_C_UNIX;
3e2a99901 Alex*0988             if (!strcmp( flag, "arm64ec_x64" )) source->flags |= FLAG_ARM64EC_X64;
6bce2b136 Alex*0989         }
ae9f33e17 Alex*0990     }
                0991 }
                0992 
                0993 
                0994 /*******************************************************************
                0995  *         parse_cpp_directive
                0996  */
b69a0e89d Alex*0997 static void parse_cpp_directive( struct file *source, char *str )
ae9f33e17 Alex*0998 {
df50fca0f Alex*0999     str = skip_spaces( str );
ae9f33e17 Alex*1000     if (*str++ != '#') return;
df50fca0f Alex*1001     str = skip_spaces( str );
ae9f33e17 Alex*1002 
                1003     if (!strncmp( str, "include", 7 ))
                1004         parse_include_directive( source, str + 7 );
                1005     else if (!strncmp( str, "import", 6 ) && strendswith( source->name, ".m" ))
                1006         parse_include_directive( source, str + 6 );
                1007     else if (!strncmp( str, "pragma", 6 ))
                1008         parse_pragma_directive( source, str + 6 );
                1009 }
                1010 
                1011 
530ee8407 Alex*1012 /*******************************************************************
aa89eccc7 Alex*1013  *         parse_idl_file
530ee8407 Alex*1014  */
b69a0e89d Alex*1015 static void parse_idl_file( struct file *source, FILE *file )
530ee8407 Alex*1016 {
b7ef1b2e2 Alex*1017     char *buffer, *include;
d19ad3962 Alex*1018 
c3aa49529 Alex*1019     input_line = 0;
e4fca883a Alex*1020 
b7ef1b2e2 Alex*1021     while ((buffer = get_line( file )))
d19ad3962 Alex*1022     {
0bcf77555 Alex*1023         char quote;
df50fca0f Alex*1024         char *p = skip_spaces( buffer );
0bcf77555 Alex*1025 
8e81f6d58 Alex*1026         if (!strncmp( p, "importlib", 9 ))
                1027         {
df50fca0f Alex*1028             p = skip_spaces( p + 9 );
8e81f6d58 Alex*1029             if (*p++ != '(') continue;
df50fca0f Alex*1030             p = skip_spaces( p );
8e81f6d58 Alex*1031             if (*p++ != '"') continue;
                1032             include = p;
                1033             while (*p && (*p != '"')) p++;
                1034             if (!*p) fatal_error( "malformed importlib directive\n" );
                1035             *p = 0;
                1036             add_dependency( source, include, INCL_IMPORTLIB );
                1037             continue;
                1038         }
                1039 
0bcf77555 Alex*1040         if (!strncmp( p, "import", 6 ))
                1041         {
df50fca0f Alex*1042             p = skip_spaces( p + 6 );
e4fca883a Alex*1043             if (*p != '"') continue;
                1044             include = ++p;
                1045             while (*p && (*p != '"')) p++;
c3aa49529 Alex*1046             if (!*p) fatal_error( "malformed import directive\n" );
e4fca883a Alex*1047             *p = 0;
b69a0e89d Alex*1048             add_dependency( source, include, INCL_IMPORT );
e4fca883a Alex*1049             continue;
0bcf77555 Alex*1050         }
e4fca883a Alex*1051 
b69a0e89d Alex*1052         /* check for #include inside cpp_quote */
                1053         if (!strncmp( p, "cpp_quote", 9 ))
0bcf77555 Alex*1054         {
df50fca0f Alex*1055             p = skip_spaces( p + 9 );
e4fca883a Alex*1056             if (*p++ != '(') continue;
df50fca0f Alex*1057             p = skip_spaces( p );
e4fca883a Alex*1058             if (*p++ != '"') continue;
0bcf77555 Alex*1059             if (*p++ != '#') continue;
df50fca0f Alex*1060             p = skip_spaces( p );
0bcf77555 Alex*1061             if (strncmp( p, "include", 7 )) continue;
df50fca0f Alex*1062             p = skip_spaces( p + 7 );
e4fca883a Alex*1063             if (*p == '\\' && p[1] == '"')
                1064             {
                1065                 p += 2;
                1066                 quote = '"';
                1067             }
                1068             else
                1069             {
                1070                 if (*p++ != '<' ) continue;
                1071                 quote = '>';
                1072             }
                1073             include = p;
                1074             while (*p && (*p != quote)) p++;
                1075             if (!*p || (quote == '"' && p[-1] != '\\'))
c3aa49529 Alex*1076                 fatal_error( "malformed #include directive inside cpp_quote\n" );
e4fca883a Alex*1077             if (quote == '"') p--;  /* remove backslash */
                1078             *p = 0;
b69a0e89d Alex*1079             add_dependency( source, include, (quote == '>') ? INCL_CPP_QUOTE_SYSTEM : INCL_CPP_QUOTE );
e4fca883a Alex*1080             continue;
0bcf77555 Alex*1081         }
                1082 
b69a0e89d Alex*1083         parse_cpp_directive( source, p );
d19ad3962 Alex*1084     }
aa89eccc7 Alex*1085 }
d19ad3962 Alex*1086 
aa89eccc7 Alex*1087 /*******************************************************************
                1088  *         parse_c_file
                1089  */
b69a0e89d Alex*1090 static void parse_c_file( struct file *source, FILE *file )
aa89eccc7 Alex*1091 {
ae9f33e17 Alex*1092     char *buffer;
530ee8407 Alex*1093 
b7ef1b2e2 Alex*1094     input_line = 0;
                1095     while ((buffer = get_line( file )))
530ee8407 Alex*1096     {
b69a0e89d Alex*1097         parse_cpp_directive( source, buffer );
530ee8407 Alex*1098     }
aa89eccc7 Alex*1099 }
                1100 
                1101 
f92ef1c54 Alex*1102 /*******************************************************************
                1103  *         parse_rc_file
                1104  */
b69a0e89d Alex*1105 static void parse_rc_file( struct file *source, FILE *file )
f92ef1c54 Alex*1106 {
                1107     char *buffer, *include;
                1108 
                1109     input_line = 0;
                1110     while ((buffer = get_line( file )))
                1111     {
                1112         char quote;
df50fca0f Alex*1113         char *p = skip_spaces( buffer );
f92ef1c54 Alex*1114 
                1115         if (p[0] == '/' && p[1] == '*')  /* check for magic makedep comment */
                1116         {
df50fca0f Alex*1117             p = skip_spaces( p + 2 );
f92ef1c54 Alex*1118             if (strncmp( p, "@makedep:", 9 )) continue;
df50fca0f Alex*1119             p = skip_spaces( p + 9 );
f92ef1c54 Alex*1120             quote = '"';
                1121             if (*p == quote)
                1122             {
                1123                 include = ++p;
                1124                 while (*p && *p != quote) p++;
                1125             }
                1126             else
                1127             {
                1128                 include = p;
df50fca0f Alex*1129                 while (*p && *p != ' ' && *p != '\t' && *p != '*') p++;
f92ef1c54 Alex*1130             }
                1131             if (!*p)
c3aa49529 Alex*1132                 fatal_error( "malformed makedep comment\n" );
f92ef1c54 Alex*1133             *p = 0;
b69a0e89d Alex*1134             add_dependency( source, include, (quote == '>') ? INCL_SYSTEM : INCL_NORMAL );
ae9f33e17 Alex*1135             continue;
f92ef1c54 Alex*1136         }
ae9f33e17 Alex*1137 
b69a0e89d Alex*1138         parse_cpp_directive( source, buffer );
f92ef1c54 Alex*1139     }
                1140 }
                1141 
                1142 
e2df0ab85 Alex*1143 /*******************************************************************
c2efb3b38 Alex*1144  *         parse_in_file
e2df0ab85 Alex*1145  */
b69a0e89d Alex*1146 static void parse_in_file( struct file *source, FILE *file )
e2df0ab85 Alex*1147 {
                1148     char *p, *buffer;
                1149 
                1150     /* make sure it gets rebuilt when the version changes */
b69a0e89d Alex*1151     add_dependency( source, "config.h", INCL_SYSTEM );
e2df0ab85 Alex*1152 
b69a0e89d Alex*1153     if (!strendswith( source->name, ".man.in" )) return;  /* not a man page */
c2efb3b38 Alex*1154 
e2df0ab85 Alex*1155     input_line = 0;
                1156     while ((buffer = get_line( file )))
                1157     {
                1158         if (strncmp( buffer, ".TH", 3 )) continue;
df50fca0f Alex*1159         p = skip_spaces( buffer + 3 );
bd0ca5103 Alex*1160         if (!(p = strtok( p, " \t" ))) continue;  /* program name */
                1161         if (!(p = strtok( NULL, " \t" ))) continue;  /* man section */
                1162         source->args = xstrdup( p );
1cccb5594 Alex*1163         return;
                1164     }
                1165 }
                1166 
                1167 
                1168 /*******************************************************************
                1169  *         parse_sfd_file
                1170  */
b69a0e89d Alex*1171 static void parse_sfd_file( struct file *source, FILE *file )
1cccb5594 Alex*1172 {
                1173     char *p, *eol, *buffer;
                1174 
                1175     input_line = 0;
                1176     while ((buffer = get_line( file )))
                1177     {
                1178         if (strncmp( buffer, "UComments:", 10 )) continue;
                1179         p = buffer + 10;
                1180         while (*p == ' ') p++;
                1181         if (p[0] == '"' && p[1] && buffer[strlen(buffer) - 1] == '"')
                1182         {
                1183             p++;
                1184             buffer[strlen(buffer) - 1] = 0;
                1185         }
                1186         while ((eol = strstr( p, "+AAoA" )))
                1187         {
                1188             *eol = 0;
df50fca0f Alex*1189             p = skip_spaces( p );
1cccb5594 Alex*1190             if (*p++ == '#')
                1191             {
df50fca0f Alex*1192                 p = skip_spaces( p );
1cccb5594 Alex*1193                 if (!strncmp( p, "pragma", 6 )) parse_pragma_directive( source, p + 6 );
                1194             }
                1195             p = eol + 5;
                1196         }
df50fca0f Alex*1197         p = skip_spaces( p );
1cccb5594 Alex*1198         if (*p++ != '#') return;
df50fca0f Alex*1199         p = skip_spaces( p );
1cccb5594 Alex*1200         if (!strncmp( p, "pragma", 6 )) parse_pragma_directive( source, p + 6 );
e2df0ab85 Alex*1201         return;
                1202     }
                1203 }
                1204 
                1205 
432338497 Alex*1206 static const struct
                1207 {
                1208     const char *ext;
                1209     void (*parse)( struct file *file, FILE *f );
                1210 } parse_functions[] =
                1211 {
                1212     { ".c",   parse_c_file },
                1213     { ".h",   parse_c_file },
                1214     { ".inl", parse_c_file },
                1215     { ".l",   parse_c_file },
                1216     { ".m",   parse_c_file },
                1217     { ".rh",  parse_c_file },
                1218     { ".x",   parse_c_file },
                1219     { ".y",   parse_c_file },
                1220     { ".idl", parse_idl_file },
                1221     { ".rc",  parse_rc_file },
                1222     { ".in",  parse_in_file },
                1223     { ".sfd", parse_sfd_file }
                1224 };
                1225 
b69a0e89d Alex*1226 /*******************************************************************
                1227  *         load_file
                1228  */
                1229 static struct file *load_file( const char *name )
                1230 {
                1231     struct file *file;
                1232     FILE *f;
432338497 Alex*1233     unsigned int i, hash = hash_filename( name );
b69a0e89d Alex*1234 
                1235     LIST_FOR_EACH_ENTRY( file, &files[hash], struct file, entry )
                1236         if (!strcmp( name, file->name )) return file;
                1237 
                1238     if (!(f = fopen( name, "r" ))) return NULL;
                1239 
                1240     file = add_file( name );
bf6db74f8 Alex*1241     list_add_tail( &files[hash], &file->entry );
b69a0e89d Alex*1242     input_file_name = file->name;
                1243     input_line = 0;
                1244 
43eccadce Mich*1245     for (i = 0; i < ARRAY_SIZE(parse_functions); i++)
432338497 Alex*1246     {
                1247         if (!strendswith( name, parse_functions[i].ext )) continue;
                1248         parse_functions[i].parse( file, f );
                1249         break;
                1250     }
b69a0e89d Alex*1251 
                1252     fclose( f );
                1253     input_file_name = NULL;
                1254 
                1255     return file;
                1256 }
                1257 
                1258 
                1259 /*******************************************************************
54c37238a Alex*1260  *         open_include_path_file
                1261  *
                1262  * Open a file from a directory on the include path.
b69a0e89d Alex*1263  */
54c37238a Alex*1264 static struct file *open_include_path_file( const struct makefile *make, const char *dir,
                1265                                             const char *name, char **filename )
b69a0e89d Alex*1266 {
1dd3051cc Alex*1267     char *src_path = concat_paths( dir, name );
54c37238a Alex*1268     struct file *ret = load_file( src_path );
b69a0e89d Alex*1269 
1dd3051cc Alex*1270     if (ret) *filename = src_path;
b69a0e89d Alex*1271     return ret;
                1272 }
                1273 
                1274 
ec7664d4d Alex*1275 /*******************************************************************
                1276  *         open_file_same_dir
                1277  *
                1278  * Open a file in the same directory as the parent.
                1279  */
                1280 static struct file *open_file_same_dir( const struct incl_file *parent, const char *name, char **filename )
                1281 {
                1282     char *src_path = replace_filename( parent->file->name, name );
                1283     struct file *ret = load_file( src_path );
                1284 
                1285     if (ret) *filename = replace_filename( parent->filename, name );
                1286     return ret;
                1287 }
                1288 
                1289 
5d4ca2225 Alex*1290 /*******************************************************************
                1291  *         open_same_dir_generated_file
                1292  *
                1293  * Open a generated_file in the same directory as the parent.
                1294  */
                1295 static struct file *open_same_dir_generated_file( const struct makefile *make,
                1296                                                   const struct incl_file *parent, struct incl_file *file,
                1297                                                   const char *ext, const char *src_ext )
                1298 {
                1299     char *filename;
                1300     struct file *ret = NULL;
                1301 
                1302     if (strendswith( file->name, ext ) &&
                1303         (ret = open_file_same_dir( parent, replace_extension( file->name, ext, src_ext ), &filename )))
                1304     {
                1305         file->sourcename = filename;
                1306         file->filename = obj_dir_path( make, replace_filename( parent->name, file->name ));
                1307     }
                1308     return ret;
                1309 }
                1310 
                1311 
b69a0e89d Alex*1312 /*******************************************************************
                1313  *         open_local_file
                1314  *
                1315  * Open a file in the source directory of the makefile.
                1316  */
5a1067ade Alex*1317 static struct file *open_local_file( const struct makefile *make, const char *path, char **filename )
b69a0e89d Alex*1318 {
468af5bbb Alex*1319     char *src_path = src_dir_path( make, path );
b69a0e89d Alex*1320     struct file *ret = load_file( src_path );
                1321 
                1322     /* if not found, try parent dir */
                1323     if (!ret && make->parent_dir)
                1324     {
                1325         free( src_path );
                1326         path = strmake( "%s/%s", make->parent_dir, path );
468af5bbb Alex*1327         src_path = src_dir_path( make, path );
b69a0e89d Alex*1328         ret = load_file( src_path );
                1329     }
                1330 
468af5bbb Alex*1331     if (ret) *filename = src_path;
b69a0e89d Alex*1332     return ret;
                1333 }
                1334 
                1335 
9da181365 Alex*1336 /*******************************************************************
                1337  *         open_local_generated_file
                1338  *
                1339  * Open a generated file in the directory of the makefile.
                1340  */
                1341 static struct file *open_local_generated_file( const struct makefile *make, struct incl_file *file,
                1342                                                const char *ext, const char *src_ext )
                1343 {
e31276e9a Alex*1344     struct incl_file *include;
9da181365 Alex*1345 
                1346     if (strendswith( file->name, ext ) &&
e31276e9a Alex*1347         (include = find_src_file( make, replace_extension( file->name, ext, src_ext ) )))
9da181365 Alex*1348     {
e31276e9a Alex*1349         file->sourcename = include->filename;
9da181365 Alex*1350         file->filename = obj_dir_path( make, file->name );
e31276e9a Alex*1351         return include->file;
9da181365 Alex*1352     }
e31276e9a Alex*1353     return NULL;
9da181365 Alex*1354 }
                1355 
                1356 
b69a0e89d Alex*1357 /*******************************************************************
                1358  *         open_global_file
                1359  *
                1360  * Open a file in the top-level source directory.
                1361  */
e31276e9a Alex*1362 static struct file *open_global_file( const char *path, char **filename )
b69a0e89d Alex*1363 {
468af5bbb Alex*1364     char *src_path = root_src_dir_path( path );
b69a0e89d Alex*1365     struct file *ret = load_file( src_path );
                1366 
468af5bbb Alex*1367     if (ret) *filename = src_path;
b69a0e89d Alex*1368     return ret;
                1369 }
                1370 
                1371 
                1372 /*******************************************************************
                1373  *         open_global_header
                1374  *
                1375  * Open a file in the global include source directory.
                1376  */
e31276e9a Alex*1377 static struct file *open_global_header( const char *path, char **filename )
b69a0e89d Alex*1378 {
e31276e9a Alex*1379     struct incl_file *include = find_src_file( include_makefile, path );
                1380 
                1381     if (!include) return NULL;
                1382     *filename = include->filename;
                1383     return include->file;
b69a0e89d Alex*1384 }
                1385 
                1386 
9da181365 Alex*1387 /*******************************************************************
                1388  *         open_global_generated_file
                1389  *
                1390  * Open a generated file in the top-level source directory.
                1391  */
                1392 static struct file *open_global_generated_file( const struct makefile *make, struct incl_file *file,
                1393                                                 const char *ext, const char *src_ext )
                1394 {
e31276e9a Alex*1395     struct incl_file *include;
9da181365 Alex*1396 
                1397     if (strendswith( file->name, ext ) &&
e31276e9a Alex*1398         (include = find_src_file( include_makefile, replace_extension( file->name, ext, src_ext ) )))
9da181365 Alex*1399     {
e31276e9a Alex*1400         file->sourcename = include->filename;
9da181365 Alex*1401         file->filename = strmake( "include/%s", file->name );
e31276e9a Alex*1402         return include->file;
9da181365 Alex*1403     }
e31276e9a Alex*1404     return NULL;
9da181365 Alex*1405 }
                1406 
                1407 
b69a0e89d Alex*1408 /*******************************************************************
                1409  *         open_src_file
                1410  */
5a1067ade Alex*1411 static struct file *open_src_file( const struct makefile *make, struct incl_file *pFile )
b69a0e89d Alex*1412 {
                1413     struct file *file = open_local_file( make, pFile->name, &pFile->filename );
                1414 
                1415     if (!file) fatal_perror( "open %s", pFile->name );
                1416     return file;
                1417 }
                1418 
                1419 
ef8b871e1 Alex*1420 /*******************************************************************
                1421  *         find_importlib_module
                1422  */
                1423 static struct makefile *find_importlib_module( const char *name )
                1424 {
                1425     unsigned int i, len;
                1426 
                1427     for (i = 0; i < subdirs.count; i++)
                1428     {
                1429         if (strncmp( submakes[i]->obj_dir, "dlls/", 5 )) continue;
                1430         len = strlen(submakes[i]->obj_dir);
                1431         if (strncmp( submakes[i]->obj_dir + 5, name, len - 5 )) continue;
                1432         if (!name[len - 5] || !strcmp( name + len - 5, ".dll" )) return submakes[i];
                1433     }
                1434     return NULL;
                1435 }
                1436 
                1437 
b69a0e89d Alex*1438 /*******************************************************************
                1439  *         open_include_file
                1440  */
5a1067ade Alex*1441 static struct file *open_include_file( const struct makefile *make, struct incl_file *pFile )
b69a0e89d Alex*1442 {
                1443     struct file *file = NULL;
                1444     unsigned int i, len;
                1445 
                1446     errno = ENOENT;
                1447 
9da181365 Alex*1448     /* check for generated files */
                1449     if ((file = open_local_generated_file( make, pFile, ".tab.h", ".y" ))) return file;
                1450     if ((file = open_local_generated_file( make, pFile, ".h", ".idl" ))) return file;
3c0a2fa5a Alex*1451     if (fontforge && (file = open_local_generated_file( make, pFile, ".ttf", ".sfd" ))) return file;
                1452     if (convert && rsvg && icotool)
                1453     {
                1454         if ((file = open_local_generated_file( make, pFile, ".bmp", ".svg" ))) return file;
                1455         if ((file = open_local_generated_file( make, pFile, ".cur", ".svg" ))) return file;
                1456         if ((file = open_local_generated_file( make, pFile, ".ico", ".svg" ))) return file;
                1457     }
857001678 Alex*1458     if ((file = open_local_generated_file( make, pFile, "-client-protocol.h", ".xml" ))) return file;
b69a0e89d Alex*1459 
cb078bd3b Alex*1460     /* check for extra targets */
                1461     if (strarray_exists( &make->extra_targets, pFile->name ))
                1462     {
3f330361d Alex*1463         pFile->sourcename = src_dir_path( make, pFile->name );
cb078bd3b Alex*1464         pFile->filename = obj_dir_path( make, pFile->name );
                1465         return NULL;
                1466     }
                1467 
b69a0e89d Alex*1468     /* now try in source dir */
                1469     if ((file = open_local_file( make, pFile->name, &pFile->filename ))) return file;
                1470 
ef8b871e1 Alex*1471     /* check for global importlib (module dependency) */
                1472     if (pFile->type == INCL_IMPORTLIB && find_importlib_module( pFile->name ))
                1473     {
                1474         pFile->filename = pFile->name;
                1475         return NULL;
                1476     }
                1477 
9da181365 Alex*1478     /* check for generated files in global includes */
                1479     if ((file = open_global_generated_file( make, pFile, ".h", ".idl" ))) return file;
                1480     if ((file = open_global_generated_file( make, pFile, ".h", ".h.in" ))) return file;
b69a0e89d Alex*1481     if (strendswith( pFile->name, "tmpl.h" ) &&
9da181365 Alex*1482         (file = open_global_generated_file( make, pFile, ".h", ".x" ))) return file;
b69a0e89d Alex*1483 
                1484     /* check in global includes source dir */
e31276e9a Alex*1485     if ((file = open_global_header( pFile->name, &pFile->filename ))) return file;
b69a0e89d Alex*1486 
                1487     /* check in global msvcrt includes */
6bce2b136 Alex*1488     if (pFile->use_msvcrt &&
e31276e9a Alex*1489         (file = open_global_header( strmake( "msvcrt/%s", pFile->name ), &pFile->filename )))
b69a0e89d Alex*1490         return file;
                1491 
                1492     /* now search in include paths */
acd9c551b Alex*1493     for (i = 0; i < make->include_paths.count; i++)
b69a0e89d Alex*1494     {
acd9c551b Alex*1495         const char *dir = make->include_paths.str[i];
b69a0e89d Alex*1496 
468af5bbb Alex*1497         if (root_src_dir)
b69a0e89d Alex*1498         {
468af5bbb Alex*1499             len = strlen( root_src_dir );
                1500             if (!strncmp( dir, root_src_dir, len ) && (!dir[len] || dir[len] == '/'))
b69a0e89d Alex*1501             {
                1502                 while (dir[len] == '/') len++;
e31276e9a Alex*1503                 file = open_global_file( concat_paths( dir + len, pFile->name ), &pFile->filename );
b69a0e89d Alex*1504             }
                1505         }
a4b01382e Alex*1506         else
b69a0e89d Alex*1507         {
a4b01382e Alex*1508             if (*dir == '/') continue;
                1509             file = open_include_path_file( make, dir, pFile->name, &pFile->filename );
b69a0e89d Alex*1510         }
a4b01382e Alex*1511         if (!file) continue;
                1512         pFile->is_external = 1;
                1513         return file;
b69a0e89d Alex*1514     }
87f7818f4 Alex*1515 
8e81f6d58 Alex*1516     if (pFile->type == INCL_SYSTEM) return NULL;  /* ignore system files we cannot find */
b69a0e89d Alex*1517 
                1518     /* try in src file directory */
5d4ca2225 Alex*1519     if ((file = open_same_dir_generated_file( make, pFile->included_by, pFile, ".tab.h", ".y" )) ||
                1520         (file = open_same_dir_generated_file( make, pFile->included_by, pFile, ".h", ".idl" )) ||
                1521         (file = open_file_same_dir( pFile->included_by, pFile->name, &pFile->filename )))
a4b01382e Alex*1522     {
                1523         pFile->is_external = pFile->included_by->is_external;
                1524         return file;
                1525     }
                1526 
                1527     if (make->extlib) return NULL; /* ignore missing files in external libs */
b69a0e89d Alex*1528 
                1529     fprintf( stderr, "%s:%d: error: ", pFile->included_by->file->name, pFile->included_line );
                1530     perror( pFile->name );
                1531     pFile = pFile->included_by;
                1532     while (pFile && pFile->included_by)
                1533     {
                1534         const char *parent = pFile->included_by->sourcename;
                1535         if (!parent) parent = pFile->included_by->file->name;
                1536         fprintf( stderr, "%s:%d: note: %s was first included here\n",
                1537                  parent, pFile->included_line, pFile->name );
                1538         pFile = pFile->included_by;
                1539     }
                1540     exit(1);
                1541 }
                1542 
                1543 
                1544 /*******************************************************************
                1545  *         add_all_includes
                1546  */
c6ba107a4 Alex*1547 static void add_all_includes( struct makefile *make, struct incl_file *parent, struct file *file )
b69a0e89d Alex*1548 {
                1549     unsigned int i;
                1550 
                1551     for (i = 0; i < file->deps_count; i++)
                1552     {
                1553         switch (file->deps[i].type)
                1554         {
                1555         case INCL_NORMAL:
                1556         case INCL_IMPORT:
8e81f6d58 Alex*1557             add_include( make, parent, file->deps[i].name, file->deps[i].line, INCL_NORMAL );
                1558             break;
                1559         case INCL_IMPORTLIB:
                1560             add_include( make, parent, file->deps[i].name, file->deps[i].line, INCL_IMPORTLIB );
b69a0e89d Alex*1561             break;
                1562         case INCL_SYSTEM:
8e81f6d58 Alex*1563             add_include( make, parent, file->deps[i].name, file->deps[i].line, INCL_SYSTEM );
b69a0e89d Alex*1564             break;
                1565         case INCL_CPP_QUOTE:
                1566         case INCL_CPP_QUOTE_SYSTEM:
                1567             break;
                1568         }
                1569     }
                1570 }
                1571 
                1572 
aa89eccc7 Alex*1573 /*******************************************************************
                1574  *         parse_file
                1575  */
f9ddafa80 Alex*1576 static void parse_file( struct makefile *make, struct incl_file *source, int src )
aa89eccc7 Alex*1577 {
8e81f6d58 Alex*1578     struct file *file = src ? open_src_file( make, source ) : open_include_file( make, source );
8f31f92a7 Alex*1579 
aa89eccc7 Alex*1580     if (!file) return;
b69a0e89d Alex*1581 
                1582     source->file = file;
                1583     source->files_count = 0;
                1584     source->files_size = file->deps_count;
                1585     source->files = xmalloc( source->files_size * sizeof(*source->files) );
f1549e7f6 Jace*1586 
                1587     if (strendswith( file->name, ".m" )) file->flags |= FLAG_C_UNIX;
6bce2b136 Alex*1588     if (file->flags & FLAG_C_UNIX) source->use_msvcrt = 0;
0d537c854 Jace*1589     else if (file->flags & FLAG_C_IMPLIB) source->use_msvcrt = 1;
b69a0e89d Alex*1590 
                1591     if (source->sourcename)
                1592     {
                1593         if (strendswith( source->sourcename, ".idl" ))
                1594         {
                1595             unsigned int i;
                1596 
                1597             /* generated .h file always includes these */
8e81f6d58 Alex*1598             add_include( make, source, "rpc.h", 0, INCL_NORMAL );
                1599             add_include( make, source, "rpcndr.h", 0, INCL_NORMAL );
b69a0e89d Alex*1600             for (i = 0; i < file->deps_count; i++)
                1601             {
                1602                 switch (file->deps[i].type)
                1603                 {
                1604                 case INCL_IMPORT:
                1605                     if (strendswith( file->deps[i].name, ".idl" ))
c6ba107a4 Alex*1606                         add_include( make, source, replace_extension( file->deps[i].name, ".idl", ".h" ),
8e81f6d58 Alex*1607                                      file->deps[i].line, INCL_NORMAL );
b69a0e89d Alex*1608                     else
8e81f6d58 Alex*1609                         add_include( make, source, file->deps[i].name, file->deps[i].line, INCL_NORMAL );
b69a0e89d Alex*1610                     break;
                1611                 case INCL_CPP_QUOTE:
8e81f6d58 Alex*1612                     add_include( make, source, file->deps[i].name, file->deps[i].line, INCL_NORMAL );
b69a0e89d Alex*1613                     break;
                1614                 case INCL_CPP_QUOTE_SYSTEM:
8e81f6d58 Alex*1615                     add_include( make, source, file->deps[i].name, file->deps[i].line, INCL_SYSTEM );
b69a0e89d Alex*1616                     break;
                1617                 case INCL_NORMAL:
                1618                 case INCL_SYSTEM:
8e81f6d58 Alex*1619                 case INCL_IMPORTLIB:
b69a0e89d Alex*1620                     break;
                1621                 }
                1622             }
                1623             return;
                1624         }
                1625         if (strendswith( source->sourcename, ".y" ))
                1626             return;  /* generated .tab.h doesn't include anything */
                1627     }
                1628 
c6ba107a4 Alex*1629     add_all_includes( make, source, file );
530ee8407 Alex*1630 }
                1631 
                1632 
b9966054c Alex*1633 /*******************************************************************
                1634  *         add_src_file
                1635  *
                1636  * Add a source file to the list.
                1637  */
f9ddafa80 Alex*1638 static struct incl_file *add_src_file( struct makefile *make, const char *name )
b9966054c Alex*1639 {
6f4d1766a Alex*1640     struct incl_file *file = xmalloc( sizeof(*file) );
b9966054c Alex*1641 
                1642     memset( file, 0, sizeof(*file) );
                1643     file->name = xstrdup(name);
a9183c7e3 Alex*1644     file->use_msvcrt = is_using_msvcrt( make );
a4b01382e Alex*1645     file->is_external = !!make->extlib;
4cb68d232 Alex*1646     list_add_tail( &make->sources, &file->entry );
e31276e9a Alex*1647     if (make == include_makefile)
                1648     {
                1649         unsigned int hash = hash_filename( name );
                1650         list_add_tail( &global_includes[hash], &file->hash_entry );
                1651     }
f9ddafa80 Alex*1652     parse_file( make, file, 1 );
b9966054c Alex*1653     return file;
1f3e3fa42 Alex*1654 }
b9cb6d4f9 Alex*1655 
1f3e3fa42 Alex*1656 
e0b1e8154 Alex*1657 /*******************************************************************
                1658  *         open_input_makefile
                1659  */
5a1067ade Alex*1660 static FILE *open_input_makefile( const struct makefile *make )
e0b1e8154 Alex*1661 {
                1662     FILE *ret;
                1663 
468af5bbb Alex*1664     if (make->obj_dir)
b78ef40ab Alex*1665         input_file_name = root_src_dir_path( obj_dir_path( make, "Makefile.in" ));
ca2cb6011 Alex*1666     else
                1667         input_file_name = output_makefile_name;  /* always use output name for main Makefile */
e0b1e8154 Alex*1668 
                1669     input_line = 0;
6f8e5d4e1 Alex*1670     if (!(ret = fopen( input_file_name, "r" ))) fatal_perror( "open" );
e0b1e8154 Alex*1671     return ret;
                1672 }
                1673 
                1674 
1928d6114 Alex*1675 /*******************************************************************
                1676  *         get_make_variable
                1677  */
5a1067ade Alex*1678 static const char *get_make_variable( const struct makefile *make, const char *name )
1928d6114 Alex*1679 {
5a1067ade Alex*1680     const char *ret;
83fe4ffb3 Alex*1681 
43fd82c61 Alex*1682     if ((ret = strarray_get_value( &cmdline_vars, name ))) return ret;
228684d34 Alex*1683     if ((ret = strarray_get_value( &make->vars, name ))) return ret;
f9ddafa80 Alex*1684     if (top_makefile && (ret = strarray_get_value( &top_makefile->vars, name ))) return ret;
1928d6114 Alex*1685     return NULL;
                1686 }
                1687 
                1688 
                1689 /*******************************************************************
                1690  *         get_expanded_make_variable
                1691  */
5a1067ade Alex*1692 static char *get_expanded_make_variable( const struct makefile *make, const char *name )
1928d6114 Alex*1693 {
5a1067ade Alex*1694     const char *var;
                1695     char *p, *end, *expand, *tmp;
1928d6114 Alex*1696 
5a1067ade Alex*1697     var = get_make_variable( make, name );
                1698     if (!var) return NULL;
1928d6114 Alex*1699 
5a1067ade Alex*1700     p = expand = xstrdup( var );
1928d6114 Alex*1701     while ((p = strchr( p, '$' )))
                1702     {
                1703         if (p[1] == '(')
                1704         {
                1705             if (!(end = strchr( p + 2, ')' ))) fatal_error( "syntax error in '%s'\n", expand );
                1706             *end++ = 0;
                1707             if (strchr( p + 2, ':' )) fatal_error( "pattern replacement not supported for '%s'\n", p + 2 );
f9ddafa80 Alex*1708             var = get_make_variable( make, p + 2 );
1928d6114 Alex*1709             tmp = replace_substr( expand, p, end - p, var ? var : "" );
581be47a4 Alex*1710             /* switch to the new string */
                1711             p = tmp + (p - expand);
                1712             free( expand );
                1713             expand = tmp;
1928d6114 Alex*1714         }
ce25c8958 Alex*1715         else if (p[1] == '{')  /* don't expand ${} variables */
                1716         {
                1717             if (!(end = strchr( p + 2, '}' ))) fatal_error( "syntax error in '%s'\n", expand );
                1718             p = end + 1;
                1719         }
1928d6114 Alex*1720         else if (p[1] == '$')
                1721         {
581be47a4 Alex*1722             p += 2;
1928d6114 Alex*1723         }
                1724         else fatal_error( "syntax error in '%s'\n", expand );
                1725     }
c29ea6108 Alex*1726 
                1727     /* consider empty variables undefined */
df50fca0f Alex*1728     p = skip_spaces( expand );
c29ea6108 Alex*1729     if (*p) return expand;
                1730     free( expand );
                1731     return NULL;
1928d6114 Alex*1732 }
                1733 
                1734 
                1735 /*******************************************************************
                1736  *         get_expanded_make_var_array
                1737  */
5a1067ade Alex*1738 static struct strarray get_expanded_make_var_array( const struct makefile *make, const char *name )
1928d6114 Alex*1739 {
7779af1df Alex*1740     struct strarray ret = empty_strarray;
1928d6114 Alex*1741     char *value, *token;
                1742 
f9ddafa80 Alex*1743     if ((value = get_expanded_make_variable( make, name )))
1928d6114 Alex*1744         for (token = strtok( value, " \t" ); token; token = strtok( NULL, " \t" ))
                1745             strarray_add( &ret, token );
                1746     return ret;
                1747 }
                1748 
                1749 
7626728b5 Alex*1750 /*******************************************************************
90e7a7359 Alex*1751  *         get_expanded_file_local_var
7626728b5 Alex*1752  */
90e7a7359 Alex*1753 static struct strarray get_expanded_file_local_var( const struct makefile *make, const char *file,
                1754                                                     const char *name )
7626728b5 Alex*1755 {
90e7a7359 Alex*1756     char *p, *var = strmake( "%s_%s", file, name );
7626728b5 Alex*1757 
                1758     for (p = var; *p; p++) if (!isalnum( *p )) *p = '_';
90e7a7359 Alex*1759     return get_expanded_make_var_array( make, var );
7626728b5 Alex*1760 }
                1761 
                1762 
b1f59bc67 Alex*1763 /*******************************************************************
                1764  *         get_expanded_arch_var
                1765  */
                1766 static char *get_expanded_arch_var( const struct makefile *make, const char *name, int arch )
                1767 {
                1768     return get_expanded_make_variable( make, arch ? strmake( "%s_%s", archs.str[arch], name ) : name );
                1769 }
                1770 
                1771 
                1772 /*******************************************************************
                1773  *         get_expanded_arch_var_array
                1774  */
                1775 static struct strarray get_expanded_arch_var_array( const struct makefile *make, const char *name, int arch )
                1776 {
                1777     return get_expanded_make_var_array( make, arch ? strmake( "%s_%s", archs.str[arch], name ) : name );
                1778 }
                1779 
                1780 
c29ea6108 Alex*1781 /*******************************************************************
                1782  *         set_make_variable
                1783  */
                1784 static int set_make_variable( struct strarray *array, const char *assignment )
                1785 {
                1786     char *p, *name;
                1787 
                1788     p = name = xstrdup( assignment );
                1789     while (isalnum(*p) || *p == '_') p++;
                1790     if (name == p) return 0;  /* not a variable */
                1791     if (isspace(*p))
                1792     {
                1793         *p++ = 0;
df50fca0f Alex*1794         p = skip_spaces( p );
c29ea6108 Alex*1795     }
                1796     if (*p != '=') return 0;  /* not an assignment */
                1797     *p++ = 0;
df50fca0f Alex*1798     p = skip_spaces( p );
c29ea6108 Alex*1799 
43fd82c61 Alex*1800     strarray_set_value( array, name, p );
c29ea6108 Alex*1801     return 1;
                1802 }
                1803 
                1804 
1928d6114 Alex*1805 /*******************************************************************
                1806  *         parse_makefile
                1807  */
49f88527c Alex*1808 static struct makefile *parse_makefile( const char *path )
1928d6114 Alex*1809 {
                1810     char *buffer;
                1811     FILE *file;
f9ddafa80 Alex*1812     struct makefile *make = xmalloc( sizeof(*make) );
1928d6114 Alex*1813 
f9ddafa80 Alex*1814     memset( make, 0, sizeof(*make) );
468af5bbb Alex*1815     make->obj_dir = path;
                1816     if (root_src_dir) make->src_dir = root_src_dir_path( make->obj_dir );
872dc83e8 Alex*1817     if (path && !strcmp( path, "include" )) include_makefile = make;
f9ddafa80 Alex*1818 
e0b1e8154 Alex*1819     file = open_input_makefile( make );
1928d6114 Alex*1820     while ((buffer = get_line( file )))
                1821     {
49f88527c Alex*1822         if (!strncmp( buffer, separator, strlen(separator) )) break;
c29ea6108 Alex*1823         if (*buffer == '\t') continue;  /* command */
df50fca0f Alex*1824         buffer = skip_spaces( buffer );
c29ea6108 Alex*1825         if (*buffer == '#') continue;  /* comment */
f9ddafa80 Alex*1826         set_make_variable( &make->vars, buffer );
1928d6114 Alex*1827     }
                1828     fclose( file );
                1829     input_file_name = NULL;
f9ddafa80 Alex*1830     return make;
1928d6114 Alex*1831 }
                1832 
                1833 
47c0f64fd Alex*1834 /*******************************************************************
                1835  *         add_generated_sources
                1836  */
f9ddafa80 Alex*1837 static void add_generated_sources( struct makefile *make )
47c0f64fd Alex*1838 {
2094dd96e Alex*1839     unsigned int i, arch;
6f4d1766a Alex*1840     struct incl_file *source, *next, *file, *dlldata = NULL;
364f97c2e Alex*1841     struct strarray objs = get_expanded_make_var_array( make, "EXTRA_OBJS" );
47c0f64fd Alex*1842 
4cb68d232 Alex*1843     LIST_FOR_EACH_ENTRY_SAFE( source, next, &make->sources, struct incl_file, entry )
47c0f64fd Alex*1844     {
2094dd96e Alex*1845         for (arch = 0; arch < archs.count; arch++)
47c0f64fd Alex*1846         {
a9183c7e3 Alex*1847             if (!is_multiarch( arch )) continue;
2094dd96e Alex*1848             if (source->file->flags & FLAG_IDL_CLIENT)
6f4d1766a Alex*1849             {
2094dd96e Alex*1850                 file = add_generated_source( make, replace_extension( source->name, ".idl", "_c.c" ), NULL, arch );
                1851                 add_dependency( file->file, replace_extension( source->name, ".idl", ".h" ), INCL_NORMAL );
                1852                 add_all_includes( make, file, file->file );
                1853             }
                1854             if (source->file->flags & FLAG_IDL_SERVER)
                1855             {
                1856                 file = add_generated_source( make, replace_extension( source->name, ".idl", "_s.c" ), NULL, arch );
                1857                 add_dependency( file->file, "wine/exception.h", INCL_NORMAL );
                1858                 add_dependency( file->file, replace_extension( source->name, ".idl", ".h" ), INCL_NORMAL );
                1859                 add_all_includes( make, file, file->file );
                1860             }
                1861             if (source->file->flags & FLAG_IDL_IDENT)
                1862             {
                1863                 file = add_generated_source( make, replace_extension( source->name, ".idl", "_i.c" ), NULL, arch );
                1864                 add_dependency( file->file, "rpc.h", INCL_NORMAL );
                1865                 add_dependency( file->file, "rpcndr.h", INCL_NORMAL );
                1866                 add_dependency( file->file, "guiddef.h", INCL_NORMAL );
                1867                 add_all_includes( make, file, file->file );
                1868             }
                1869             if (source->file->flags & FLAG_IDL_PROXY)
                1870             {
                1871                 file = add_generated_source( make, replace_extension( source->name, ".idl", "_p.c" ), NULL, arch );
                1872                 add_dependency( file->file, "objbase.h", INCL_NORMAL );
                1873                 add_dependency( file->file, "rpcproxy.h", INCL_NORMAL );
                1874                 add_dependency( file->file, "wine/exception.h", INCL_NORMAL );
                1875                 add_dependency( file->file, replace_extension( source->name, ".idl", ".h" ), INCL_NORMAL );
                1876                 add_all_includes( make, file, file->file );
                1877             }
                1878             if (source->file->flags & FLAG_IDL_TYPELIB)
                1879             {
                1880                 add_generated_source( make, replace_extension( source->name, ".idl", "_l.res" ), NULL, arch );
                1881             }
                1882             if (source->file->flags & FLAG_IDL_REGTYPELIB)
                1883             {
                1884                 add_generated_source( make, replace_extension( source->name, ".idl", "_t.res" ), NULL, arch );
                1885             }
                1886             if (source->file->flags & FLAG_IDL_REGISTER)
                1887             {
                1888                 add_generated_source( make, replace_extension( source->name, ".idl", "_r.res" ), NULL, arch );
6f4d1766a Alex*1889             }
47c0f64fd Alex*1890         }
2094dd96e Alex*1891 
                1892         /* now the arch-independent files */
                1893 
                1894         if ((source->file->flags & FLAG_IDL_PROXY) && !dlldata)
47c0f64fd Alex*1895         {
2094dd96e Alex*1896             dlldata = add_generated_source( make, "dlldata.o", "dlldata.c", 0 );
                1897             add_dependency( dlldata->file, "objbase.h", INCL_NORMAL );
                1898             add_dependency( dlldata->file, "rpcproxy.h", INCL_NORMAL );
                1899             add_all_includes( make, dlldata, dlldata->file );
47c0f64fd Alex*1900         }
8e81f6d58 Alex*1901         if (source->file->flags & FLAG_IDL_HEADER)
                1902         {
2094dd96e Alex*1903             add_generated_source( make, replace_extension( source->name, ".idl", ".h" ), NULL, 0 );
8e81f6d58 Alex*1904         }
316448cd4 Alex*1905         if (!source->file->flags && strendswith( source->name, ".idl" ))
                1906         {
872dc83e8 Alex*1907             if (!strncmp( source->name, "wine/", 5 )) continue;
                1908             source->file->flags = FLAG_IDL_HEADER | FLAG_INSTALL;
2094dd96e Alex*1909             add_generated_source( make, replace_extension( source->name, ".idl", ".h" ), NULL, 0 );
316448cd4 Alex*1910         }
9b9b0dce1 Alex*1911         if (strendswith( source->name, ".x" ))
                1912         {
2094dd96e Alex*1913             add_generated_source( make, replace_extension( source->name, ".x", ".h" ), NULL, 0 );
9b9b0dce1 Alex*1914         }
47c0f64fd Alex*1915         if (strendswith( source->name, ".y" ))
                1916         {
2094dd96e Alex*1917             file = add_generated_source( make, replace_extension( source->name, ".y", ".tab.c" ), NULL, 0 );
9c2725d5d Alex*1918             /* steal the includes list from the source file */
                1919             file->files_count = source->files_count;
                1920             file->files_size = source->files_size;
                1921             file->files = source->files;
                1922             source->files_count = source->files_size = 0;
                1923             source->files = NULL;
47c0f64fd Alex*1924         }
                1925         if (strendswith( source->name, ".l" ))
                1926         {
2094dd96e Alex*1927             file = add_generated_source( make, replace_extension( source->name, ".l", ".yy.c" ), NULL, 0 );
9c2725d5d Alex*1928             /* steal the includes list from the source file */
                1929             file->files_count = source->files_count;
                1930             file->files_size = source->files_size;
                1931             file->files = source->files;
                1932             source->files_count = source->files_size = 0;
                1933             source->files = NULL;
47c0f64fd Alex*1934         }
0bb029f92 Alex*1935         if (strendswith( source->name, ".po" ))
                1936         {
8d43170b9 Alex*1937             if (!make->disabled[0])
0bb029f92 Alex*1938                 strarray_add_uniq( &linguas, replace_extension( source->name, ".po", "" ));
                1939         }
c873db8c1 Alex*1940         if (strendswith( source->name, ".spec" ))
                1941         {
                1942             char *obj = replace_extension( source->name, ".spec", "" );
                1943             strarray_addall_uniq( &make->extra_imports,
                1944                                   get_expanded_file_local_var( make, obj, "IMPORTS" ));
                1945         }
857001678 Alex*1946         if (strendswith( source->name, ".xml" ))
                1947         {
                1948             char *code_name = replace_extension( source->name , ".xml", "-protocol.c" );
                1949             char *header_name = replace_extension( source->name , ".xml", "-client-protocol.h" );
                1950 
                1951             file = add_generated_source( make, code_name, NULL, 0 );
                1952             file->file->flags |= FLAG_C_UNIX;
                1953             file->use_msvcrt = 0;
                1954             file = add_generated_source( make, header_name, NULL, 0 );
                1955             file->file->flags |= FLAG_C_UNIX;
                1956             file->use_msvcrt = 0;
                1957 
                1958             free( code_name );
                1959             free( header_name );
                1960         }
47c0f64fd Alex*1961     }
5a1067ade Alex*1962     if (make->testdll)
47c0f64fd Alex*1963     {
2094dd96e Alex*1964         for (arch = 0; arch < archs.count; arch++)
                1965         {
a9183c7e3 Alex*1966             if (!is_multiarch( arch )) continue;
2094dd96e Alex*1967             file = add_generated_source( make, "testlist.o", "testlist.c", arch );
                1968             add_dependency( file->file, "wine/test.h", INCL_NORMAL );
                1969             add_all_includes( make, file, file->file );
                1970         }
47c0f64fd Alex*1971     }
364f97c2e Alex*1972     for (i = 0; i < objs.count; i++)
                1973     {
                1974         /* default to .c for unknown extra object files */
                1975         if (strendswith( objs.str[i], ".o" ))
9b8afa0f8 Alex*1976         {
2094dd96e Alex*1977             file = add_generated_source( make, objs.str[i], replace_extension( objs.str[i], ".o", ".c" ), 0);
5e0479c49 Alex*1978             file->file->flags |= FLAG_C_UNIX;
                1979             file->use_msvcrt = 0;
9b8afa0f8 Alex*1980         }
364f97c2e Alex*1981         else if (strendswith( objs.str[i], ".res" ))
2094dd96e Alex*1982             add_generated_source( make, replace_extension( objs.str[i], ".res", ".rc" ), NULL, 0 );
364f97c2e Alex*1983         else
2094dd96e Alex*1984             add_generated_source( make, objs.str[i], NULL, 0 );
364f97c2e Alex*1985     }
47c0f64fd Alex*1986 }
                1987 
                1988 
16286e45c Alex*1989 /*******************************************************************
                1990  *         create_dir
                1991  */
                1992 static void create_dir( const char *dir )
                1993 {
                1994     char *p, *path;
                1995 
                1996     p = path = xstrdup( dir );
                1997     while ((p = strchr( p, '/' )))
                1998     {
                1999         *p = 0;
                2000         if (mkdir( path, 0755 ) == -1 && errno != EEXIST) fatal_perror( "mkdir %s", path );
                2001         *p++ = '/';
                2002         while (*p == '/') p++;
                2003     }
                2004     if (mkdir( path, 0755 ) == -1 && errno != EEXIST) fatal_perror( "mkdir %s", path );
                2005     free( path );
                2006 }
                2007 
                2008 
f17419ec4 Alex*2009 /*******************************************************************
                2010  *         create_file_directories
                2011  *
                2012  * Create the base directories of all the files.
                2013  */
                2014 static void create_file_directories( const struct makefile *make, struct strarray files )
                2015 {
                2016     struct strarray subdirs = empty_strarray;
                2017     unsigned int i;
                2018     char *dir;
                2019 
                2020     for (i = 0; i < files.count; i++)
                2021     {
                2022         if (!strchr( files.str[i], '/' )) continue;
468af5bbb Alex*2023         dir = obj_dir_path( make, files.str[i] );
f17419ec4 Alex*2024         *strrchr( dir, '/' ) = 0;
                2025         strarray_add_uniq( &subdirs, dir );
                2026     }
                2027 
                2028     for (i = 0; i < subdirs.count; i++) create_dir( subdirs.str[i] );
                2029 }
                2030 
                2031 
dcf6060ab Alex*2032 /*******************************************************************
                2033  *         output_filenames_obj_dir
                2034  */
5a1067ade Alex*2035 static void output_filenames_obj_dir( const struct makefile *make, struct strarray array )
dcf6060ab Alex*2036 {
                2037     unsigned int i;
                2038 
f9ddafa80 Alex*2039     for (i = 0; i < array.count; i++) output_filename( obj_dir_path( make, array.str[i] ));
dcf6060ab Alex*2040 }
                2041 
                2042 
530ee8407 Alex*2043 /*******************************************************************
8e81f6d58 Alex*2044  *         get_dependencies
530ee8407 Alex*2045  */
4eb9ad983 Alex*2046 static void get_dependencies( struct incl_file *file, struct incl_file *source )
530ee8407 Alex*2047 {
8e81f6d58 Alex*2048     unsigned int i;
                2049 
                2050     if (!file->filename) return;
530ee8407 Alex*2051 
8e81f6d58 Alex*2052     if (file != source)
                2053     {
                2054         if (file->owner == source) return;  /* already processed */
ef8b871e1 Alex*2055         if (file->type == INCL_IMPORTLIB)
                2056         {
                2057             if (!(source->file->flags & (FLAG_IDL_TYPELIB | FLAG_IDL_REGTYPELIB)))
                2058                 return;  /* library is imported only when building a typelib */
                2059             strarray_add( &source->importlibdeps, file->filename );
                2060         }
                2061         else strarray_add( &source->dependencies, file->filename );
8e81f6d58 Alex*2062         file->owner = source;
8ec232132 Alex*2063 
                2064         /* sanity checks */
a4b01382e Alex*2065         if (!strcmp( file->filename, "include/config.h" ) &&
                2066             file != source->files[0] && !source->is_external)
8ec232132 Alex*2067         {
                2068             input_file_name = source->filename;
                2069             input_line = 0;
                2070             for (i = 0; i < source->file->deps_count; i++)
                2071             {
                2072                 if (!strcmp( source->file->deps[i].name, file->name ))
                2073                     input_line = source->file->deps[i].line;
                2074             }
                2075             fatal_error( "%s must be included before other headers\n", file->name );
                2076         }
8e81f6d58 Alex*2077     }
8ec232132 Alex*2078 
4eb9ad983 Alex*2079     for (i = 0; i < file->files_count; i++) get_dependencies( file->files[i], source );
530ee8407 Alex*2080 }
                2081 
                2082 
d1578a61a Alex*2083 /*******************************************************************
                2084  *         get_local_dependencies
                2085  *
                2086  * Get the local dependencies of a given target.
                2087  */
                2088 static struct strarray get_local_dependencies( const struct makefile *make, const char *name,
                2089                                                struct strarray targets )
                2090 {
                2091     unsigned int i;
90e7a7359 Alex*2092     struct strarray deps = get_expanded_file_local_var( make, name, "DEPS" );
d1578a61a Alex*2093 
                2094     for (i = 0; i < deps.count; i++)
                2095     {
                2096         if (strarray_exists( &targets, deps.str[i] ))
                2097             deps.str[i] = obj_dir_path( make, deps.str[i] );
                2098         else
                2099             deps.str[i] = src_dir_path( make, deps.str[i] );
                2100     }
                2101     return deps;
                2102 }
                2103 
                2104 
360296227 Alex*2105 /*******************************************************************
255b90c64 Alex*2106  *         get_static_lib
360296227 Alex*2107  *
51087b9b6 Alex*2108  * Find the makefile that builds the named static library (which may be an import lib).
360296227 Alex*2109  */
51087b9b6 Alex*2110 static struct makefile *get_static_lib( const char *name, unsigned int arch )
360296227 Alex*2111 {
51087b9b6 Alex*2112     unsigned int i;
                2113 
                2114     for (i = 0; i < subdirs.count; i++)
                2115     {
                2116         if (submakes[i]->importlib && !strcmp( submakes[i]->importlib, name )) return submakes[i];
                2117         if (!submakes[i]->staticlib) continue;
                2118         if (submakes[i]->disabled[arch]) continue;
                2119         if (strncmp( submakes[i]->staticlib, "lib", 3 )) continue;
                2120         if (strncmp( submakes[i]->staticlib + 3, name, strlen(name) )) continue;
                2121         if (strcmp( submakes[i]->staticlib + 3 + strlen(name), ".a" )) continue;
                2122         return submakes[i];
                2123     }
                2124     return NULL;
360296227 Alex*2125 }
                2126 
                2127 
eda25a58c Alex*2128 /*******************************************************************
                2129  *         get_native_unix_lib
                2130  */
                2131 static const char *get_native_unix_lib( const struct makefile *make, const char *name )
                2132 {
dbe93c8a5 Alex*2133     if (!make->unixlib) return NULL;
eda25a58c Alex*2134     if (strncmp( make->unixlib, name, strlen(name) )) return NULL;
                2135     if (make->unixlib[strlen(name)] != '.') return NULL;
                2136     return obj_dir_path( make, make->unixlib );
                2137 }
                2138 
                2139 
0189cf21c Alex*2140 /*******************************************************************
                2141  *         get_parent_makefile
                2142  */
                2143 static struct makefile *get_parent_makefile( struct makefile *make )
                2144 {
                2145     char *dir, *p;
e5041acfa Stef*2146     unsigned int i;
0189cf21c Alex*2147 
468af5bbb Alex*2148     if (!make->obj_dir) return NULL;
                2149     dir = xstrdup( make->obj_dir );
0189cf21c Alex*2150     if (!(p = strrchr( dir, '/' ))) return NULL;
                2151     *p = 0;
468af5bbb Alex*2152     for (i = 0; i < subdirs.count; i++)
                2153         if (!strcmp( submakes[i]->obj_dir, dir )) return submakes[i];
0189cf21c Alex*2154     return NULL;
                2155 }
                2156 
                2157 
92233bfaf Alex*2158 /*******************************************************************
                2159  *         needs_delay_lib
                2160  */
815e766d9 Alex*2161 static int needs_delay_lib( const struct makefile *make, unsigned int arch )
92233bfaf Alex*2162 {
815e766d9 Alex*2163     if (delay_load_flags[arch]) return 0;
92233bfaf Alex*2164     if (!make->importlib) return 0;
bbc302290 Alex*2165     return strarray_exists( &delay_import_libs, make->importlib );
92233bfaf Alex*2166 }
                2167 
                2168 
360296227 Alex*2169 /*******************************************************************
c73ae99ff Alex*2170  *         add_unix_libraries
360296227 Alex*2171  */
ab5664a5e Alex*2172 static struct strarray add_unix_libraries( const struct makefile *make, struct strarray *deps )
360296227 Alex*2173 {
                2174     struct strarray ret = empty_strarray;
                2175     struct strarray all_libs = empty_strarray;
                2176     unsigned int i, j;
                2177 
1ef7dd2d7 Alex*2178     if (strcmp( make->unixlib, "ntdll.so" )) strarray_add( &all_libs, "-lntdll" );
194e09bae Alex*2179     strarray_addall( &all_libs, get_expanded_make_var_array( make, "UNIX_LIBS" ));
360296227 Alex*2180 
                2181     for (i = 0; i < all_libs.count; i++)
                2182     {
255b90c64 Alex*2183         const char *lib = NULL;
                2184 
360296227 Alex*2185         if (!strncmp( all_libs.str[i], "-l", 2 ))
                2186         {
468af5bbb Alex*2187             for (j = 0; j < subdirs.count; j++)
d1248c8a0 Alex*2188             {
                2189                 if (make == submakes[j]) continue;
1ef7dd2d7 Alex*2190                 if ((lib = get_native_unix_lib( submakes[j], all_libs.str[i] + 2 ))) break;
d1248c8a0 Alex*2191             }
360296227 Alex*2192         }
255b90c64 Alex*2193         if (lib)
                2194         {
                2195             strarray_add( deps, lib );
                2196             strarray_add( &ret, lib );
                2197         }
                2198         else strarray_add( &ret, all_libs.str[i] );
360296227 Alex*2199     }
1ef7dd2d7 Alex*2200 
                2201     strarray_addall( &ret, libs );
360296227 Alex*2202     return ret;
                2203 }
                2204 
                2205 
6ebcc54a5 Alex*2206 /*******************************************************************
                2207  *         is_crt_module
                2208  */
                2209 static int is_crt_module( const char *file )
                2210 {
                2211     return !strncmp( file, "msvcr", 5 ) || !strncmp( file, "ucrt", 4 ) || !strcmp( file, "crtdll.dll" );
                2212 }
                2213 
                2214 
                2215 /*******************************************************************
                2216  *         get_default_crt
                2217  */
                2218 static const char *get_default_crt( const struct makefile *make )
                2219 {
                2220     if (make->module && is_crt_module( make->module )) return NULL;  /* don't add crt import to crt dlls */
                2221     return !make->testdll && (!make->staticlib || make->extlib) ? "ucrtbase" : "msvcrt";
                2222 }
                2223 
                2224 
                2225 /*******************************************************************
                2226  *         get_crt_define
                2227  */
                2228 static const char *get_crt_define( const struct makefile *make )
                2229 {
                2230     const char *crt_dll = NULL;
                2231     unsigned int i, version = 0;
                2232 
                2233     for (i = 0; i < make->imports.count; i++)
                2234     {
                2235         if (!is_crt_module( make->imports.str[i] )) continue;
                2236         if (crt_dll) fatal_error( "More than one C runtime DLL imported: %s and %s\n",
                2237                                   crt_dll, make->imports.str[i] );
                2238         crt_dll = make->imports.str[i];
                2239     }
                2240 
                2241     if (!crt_dll)
                2242     {
                2243         if (strarray_exists( &make->extradllflags, "-nodefaultlibs" )) return "-D_MSVCR_VER=0";
                2244         if (!(crt_dll = get_default_crt( make ))) crt_dll = make->module;
                2245     }
                2246     if (!strncmp( crt_dll, "ucrt", 4 )) return "-D_UCRT";
                2247     sscanf( crt_dll, "msvcr%u", &version );
                2248     return strmake( "-D_MSVCR_VER=%u", version );
                2249 }
                2250 
                2251 
                2252 /*******************************************************************
214223edc RĂ©mi*2253  *         get_default_imports
6ebcc54a5 Alex*2254  */
214223edc RĂ©mi*2255 static struct strarray get_default_imports( const struct makefile *make, struct strarray imports )
6ebcc54a5 Alex*2256 {
                2257     struct strarray ret = empty_strarray;
                2258     const char *crt_dll = get_default_crt( make );
                2259     unsigned int i;
                2260 
                2261     for (i = 0; i < imports.count; i++)
214223edc RĂ©mi*2262         if (is_crt_module( imports.str[i] ))
                2263             crt_dll = imports.str[i];
6ebcc54a5 Alex*2264 
                2265     strarray_add( &ret, "winecrt0" );
                2266     if (crt_dll) strarray_add( &ret, crt_dll );
                2267 
                2268     if (make->is_win16 && (!make->importlib || strcmp( make->importlib, "kernel" )))
                2269         strarray_add( &ret, "kernel" );
                2270 
                2271     strarray_add( &ret, "kernel32" );
                2272     strarray_add( &ret, "ntdll" );
                2273     return ret;
                2274 }
                2275 
c1a0b74d9 RĂ©mi*2276 enum import_type
                2277 {
                2278     IMPORT_TYPE_DIRECT,
                2279     IMPORT_TYPE_DELAYED,
214223edc RĂ©mi*2280     IMPORT_TYPE_DEFAULT,
c1a0b74d9 RĂ©mi*2281 };
6ebcc54a5 Alex*2282 
364165a67 Alex*2283 /*******************************************************************
                2284  *         add_import_libs
                2285  */
                2286 static struct strarray add_import_libs( const struct makefile *make, struct strarray *deps,
24d791e2e Alex*2287                                         struct strarray imports, enum import_type type, unsigned int arch )
364165a67 Alex*2288 {
                2289     struct strarray ret = empty_strarray;
51087b9b6 Alex*2290     unsigned int i;
6ebcc54a5 Alex*2291 
ba50573f9 Jace*2292     if (native_archs[arch]) arch = native_archs[arch];
                2293 
364165a67 Alex*2294     for (i = 0; i < imports.count; i++)
                2295     {
30fb17bda Alex*2296         const char *name = imports.str[i];
51087b9b6 Alex*2297         struct makefile *submake;
364165a67 Alex*2298 
214223edc RĂ©mi*2299         /* add crt import lib only when adding the default imports libs */
                2300         if (is_crt_module( imports.str[i] ) && type != IMPORT_TYPE_DEFAULT) continue;
                2301 
30fb17bda Alex*2302         if (name[0] == '-')
                2303         {
                2304             switch (name[1])
                2305             {
                2306             case 'L': strarray_add( &ret, name ); continue;
                2307             case 'l': name += 2; break;
                2308             default: continue;
                2309             }
                2310         }
                2311         else name = get_base_name( name );
                2312 
51087b9b6 Alex*2313         if ((submake = get_static_lib( name, arch )))
364165a67 Alex*2314         {
51087b9b6 Alex*2315             const char *ext = (type == IMPORT_TYPE_DELAYED && !delay_load_flags[arch]) ? ".delay.a" : ".a";
                2316             const char *lib = obj_dir_path( submake, strmake( "%slib%s%s", arch_dirs[arch], name, ext ));
6ebcc54a5 Alex*2317             strarray_add_uniq( deps, lib );
255b90c64 Alex*2318             strarray_add( &ret, lib );
364165a67 Alex*2319         }
255b90c64 Alex*2320         else strarray_add( &ret, strmake( "-l%s", name ));
364165a67 Alex*2321     }
                2322     return ret;
                2323 }
                2324 
                2325 
da340169d Alex*2326 /*******************************************************************
                2327  *         add_install_rule
                2328  */
8d43170b9 Alex*2329 static void add_install_rule( struct makefile *make, const char *target, unsigned int arch,
4eb9ad983 Alex*2330                               const char *file, const char *dest )
da340169d Alex*2331 {
f9cad1bd1 Alex*2332     unsigned int i;
                2333 
8d43170b9 Alex*2334     if (make->disabled[arch]) return;
                2335 
f9cad1bd1 Alex*2336     for (i = 0; i < NB_INSTALL_RULES; i++)
da340169d Alex*2337     {
f9cad1bd1 Alex*2338         if (strarray_exists( &make->install[i], target ) ||
                2339             strarray_exists( &top_install[i], make->obj_dir ) ||
                2340             strarray_exists( &top_install[i], obj_dir_path( make, target )))
                2341         {
                2342             strarray_add( &make->install_rules[i], file );
                2343             strarray_add( &make->install_rules[i], dest );
                2344             break;
                2345         }
da340169d Alex*2346     }
                2347 }
                2348 
                2349 
432338497 Alex*2350 /*******************************************************************
                2351  *         get_include_install_path
                2352  *
                2353  * Determine the installation path for a given include file.
                2354  */
                2355 static const char *get_include_install_path( const char *name )
                2356 {
                2357     if (!strncmp( name, "wine/", 5 )) return name + 5;
                2358     if (!strncmp( name, "msvcrt/", 7 )) return name;
                2359     return strmake( "windows/%s", name );
                2360 }
                2361 
                2362 
6bce2b136 Alex*2363 /*******************************************************************
                2364  *         get_source_defines
                2365  */
                2366 static struct strarray get_source_defines( struct makefile *make, struct incl_file *source,
                2367                                            const char *obj )
                2368 {
                2369     unsigned int i;
                2370     struct strarray ret = empty_strarray;
                2371 
                2372     strarray_addall( &ret, make->include_args );
                2373     if (source->use_msvcrt)
194e09bae Alex*2374     {
468af5bbb Alex*2375         strarray_add( &ret, strmake( "-I%s", root_src_dir_path( "include/msvcrt" )));
194e09bae Alex*2376         for (i = 0; i < make->include_paths.count; i++)
                2377             strarray_add( &ret, strmake( "-I%s", make->include_paths.str[i] ));
a9183c7e3 Alex*2378         strarray_add( &ret, get_crt_define( make ));
194e09bae Alex*2379     }
6bce2b136 Alex*2380     strarray_addall( &ret, make->define_args );
                2381     strarray_addall( &ret, get_expanded_file_local_var( make, obj, "EXTRADEFS" ));
                2382     return ret;
                2383 }
                2384 
                2385 
a1be6b475 Alex*2386 /*******************************************************************
                2387  *         remove_warning_flags
                2388  */
                2389 static struct strarray remove_warning_flags( struct strarray flags )
                2390 {
                2391     unsigned int i;
                2392     struct strarray ret = empty_strarray;
                2393 
                2394     for (i = 0; i < flags.count; i++)
                2395         if (strncmp( flags.str[i], "-W", 2 ) || !strncmp( flags.str[i], "-Wno-", 5 ))
                2396             strarray_add( &ret, flags.str[i] );
                2397     return ret;
                2398 }
                2399 
                2400 
83d00d328 Jace*2401 /*******************************************************************
                2402  *         get_debug_file
                2403  */
24d791e2e Alex*2404 static const char *get_debug_file( struct makefile *make, const char *name, unsigned int arch )
83d00d328 Jace*2405 {
                2406     const char *debug_file = NULL;
55e2335f6 Alex*2407     if (!debug_flags[arch]) return NULL;
                2408     if (!strcmp( debug_flags[arch], "pdb" )) debug_file = strmake( "%s.pdb", get_base_name( name ));
                2409     else if (!strncmp( debug_flags[arch], "split", 5 )) debug_file = strmake( "%s.debug", name );
83d00d328 Jace*2410     if (debug_file) strarray_add( &make->debug_files, debug_file );
                2411     return debug_file;
                2412 }
                2413 
                2414 
1a16b9e9a Alex*2415 /*******************************************************************
                2416  *         cmd_prefix
                2417  */
                2418 static const char *cmd_prefix( const char *cmd )
                2419 {
                2420     if (!silent_rules) return "";
                2421     return strmake( "$(quiet_%s)", cmd );
                2422 }
                2423 
                2424 
cc7c6a734 Alex*2425 /*******************************************************************
                2426  *         output_winegcc_command
                2427  */
24d791e2e Alex*2428 static void output_winegcc_command( struct makefile *make, unsigned int arch )
cc7c6a734 Alex*2429 {
1a16b9e9a Alex*2430     output( "\t%s%s -o $@", cmd_prefix( "CCLD" ), tools_path( make, "winegcc" ));
468af5bbb Alex*2431     output_filename( "--wine-objdir ." );
08956bc9b Alex*2432     if (tools_dir)
                2433     {
                2434         output_filename( "--winebuild" );
                2435         output_filename( tools_path( make, "winebuild" ));
                2436     }
afc286fb5 Alex*2437     output_filenames( target_flags[arch] );
ba50573f9 Jace*2438     if (native_archs[arch] && !make->disabled[native_archs[arch]])
                2439         output_filenames( hybrid_target_flags[arch] );
a9183c7e3 Alex*2440     if (arch) return;
                2441     output_filename( "-mno-cygwin" );
                2442     output_filenames( lddll_flags );
cc7c6a734 Alex*2443 }
                2444 
                2445 
64124815f Alex*2446 /*******************************************************************
                2447  *         output_symlink_rule
                2448  *
                2449  * Output a rule to create a symlink.
                2450  */
ec99ba1b2 Alex*2451 static void output_symlink_rule( const char *src_name, const char *link_name, int create_dir )
64124815f Alex*2452 {
ec99ba1b2 Alex*2453     const char *name = strrchr( link_name, '/' );
                2454     char *dir = NULL;
64124815f Alex*2455 
ec99ba1b2 Alex*2456     if (name)
64124815f Alex*2457     {
ec99ba1b2 Alex*2458         dir = xstrdup( link_name );
64124815f Alex*2459         dir[name - link_name] = 0;
                2460     }
ec99ba1b2 Alex*2461 
1a16b9e9a Alex*2462     output( "\t%s", cmd_prefix( "LN" ));
ec99ba1b2 Alex*2463     if (create_dir && dir && *dir) output( "%s -d %s && ", root_src_dir_path( "tools/install-sh" ), dir );
                2464     output( "rm -f %s && ", link_name );
                2465 
                2466     /* dest path with a directory needs special handling if ln -s isn't supported */
                2467     if (dir && strcmp( ln_s, "ln -s" ))
                2468         output( "cd %s && %s %s %s\n", *dir ? dir : "/", ln_s, src_name, name + 1 );
64124815f Alex*2469     else
                2470         output( "%s %s %s\n", ln_s, src_name, link_name );
ec99ba1b2 Alex*2471 
                2472     free( dir );
64124815f Alex*2473 }
                2474 
                2475 
4152f944f Alex*2476 /*******************************************************************
                2477  *         output_srcdir_symlink
                2478  *
                2479  * Output rule to create a symlink back to the source directory, for source files
                2480  * that are needed at run-time.
                2481  */
                2482 static void output_srcdir_symlink( struct makefile *make, const char *obj )
                2483 {
3f330361d Alex*2484     char *src_file, *dst_file, *src_name;
4152f944f Alex*2485 
                2486     if (!make->src_dir) return;
                2487     src_file = src_dir_path( make, obj );
3f330361d Alex*2488     dst_file = obj_dir_path( make, obj );
                2489     output( "%s: %s\n", dst_file, src_file );
                2490 
                2491     src_name = src_file;
                2492     if (src_name[0] != '/' && make->obj_dir)
                2493         src_name = concat_paths( get_relative_path( make->obj_dir, "" ), src_name );
                2494 
ec99ba1b2 Alex*2495     output_symlink_rule( src_name, dst_file, 0 );
718c57cab Alex*2496     strarray_add( &make->all_targets[0], obj );
4152f944f Alex*2497 }
                2498 
                2499 
da340169d Alex*2500 /*******************************************************************
733ed0565 Alex*2501  *         output_install_commands
da340169d Alex*2502  */
468af5bbb Alex*2503 static void output_install_commands( struct makefile *make, struct strarray files )
da340169d Alex*2504 {
9795a0191 Alex*2505     unsigned int i, arch;
468af5bbb Alex*2506     char *install_sh = root_src_dir_path( "tools/install-sh" );
da340169d Alex*2507 
                2508     for (i = 0; i < files.count; i += 2)
                2509     {
                2510         const char *file = files.str[i];
2f956a4e0 Alex*2511         const char *dest = strmake( "$(DESTDIR)%s", files.str[i + 1] + 1 );
9795a0191 Alex*2512         char type = *files.str[i + 1];
da340169d Alex*2513 
9795a0191 Alex*2514         switch (type)
da340169d Alex*2515         {
9795a0191 Alex*2516         case '1': case '2': case '3': case '4': case '5':
                2517         case '6': case '7': case '8': case '9': /* arch-dependent program */
                2518             arch = type - '0';
afc286fb5 Alex*2519             output( "\tSTRIPPROG=%s %s -m 644 $(INSTALL_PROGRAM_FLAGS) %s %s\n",
9795a0191 Alex*2520                     strip_progs[arch], install_sh, obj_dir_path( make, file ), dest );
5b0ba5be0 Alex*2521             output( "\t%s --builtin %s\n", tools_path( make, "winebuild" ), dest );
0189cf21c Alex*2522             break;
da340169d Alex*2523         case 'd':  /* data file */
2f956a4e0 Alex*2524             output( "\t%s -m 644 $(INSTALL_DATA_FLAGS) %s %s\n",
                2525                     install_sh, obj_dir_path( make, file ), dest );
da340169d Alex*2526             break;
                2527         case 'D':  /* data file in source dir */
2f956a4e0 Alex*2528             output( "\t%s -m 644 $(INSTALL_DATA_FLAGS) %s %s\n",
                2529                     install_sh, src_dir_path( make, file ), dest );
da340169d Alex*2530             break;
9795a0191 Alex*2531         case '0':  /* native arch program file */
da340169d Alex*2532         case 'p':  /* program file */
2f956a4e0 Alex*2533             output( "\tSTRIPPROG=\"$(STRIP)\" %s $(INSTALL_PROGRAM_FLAGS) %s %s\n",
                2534                     install_sh, obj_dir_path( make, file ), dest );
da340169d Alex*2535             break;
                2536         case 's':  /* script */
2f956a4e0 Alex*2537             output( "\t%s $(INSTALL_SCRIPT_FLAGS) %s %s\n",
                2538                     install_sh, obj_dir_path( make, file ), dest );
da340169d Alex*2539             break;
                2540         case 'S':  /* script in source dir */
2f956a4e0 Alex*2541             output( "\t%s $(INSTALL_SCRIPT_FLAGS) %s %s\n",
                2542                     install_sh, src_dir_path( make, file ), dest );
                2543             break;
                2544         case 't':  /* script in tools dir */
                2545             output( "\t%s $(INSTALL_SCRIPT_FLAGS) %s %s\n",
733ed0565 Alex*2546                     install_sh, tools_dir_path( make, files.str[i] ), dest );
da340169d Alex*2547             break;
356e46a1e Alex*2548         case 'y':  /* symlink */
ec99ba1b2 Alex*2549             output_symlink_rule( files.str[i], dest, 1 );
356e46a1e Alex*2550             break;
da340169d Alex*2551         default:
                2552             assert(0);
                2553         }
1a52ba0bc Alex*2554         strarray_add( &make->uninstall_files, dest );
da340169d Alex*2555     }
733ed0565 Alex*2556 }
                2557 
                2558 
                2559 /*******************************************************************
                2560  *         output_install_rules
                2561  *
                2562  * Rules are stored as a (file,dest) pair of values.
                2563  * The first char of dest indicates the type of install.
                2564  */
f9cad1bd1 Alex*2565 static void output_install_rules( struct makefile *make, enum install_rules rules )
733ed0565 Alex*2566 {
                2567     unsigned int i;
                2568     struct strarray files = make->install_rules[rules];
                2569     struct strarray targets = empty_strarray;
                2570 
                2571     if (!files.count) return;
                2572 
                2573     for (i = 0; i < files.count; i += 2)
                2574     {
                2575         const char *file = files.str[i];
                2576         switch (*files.str[i + 1])
                2577         {
9795a0191 Alex*2578         case '0': case '1': case '2': case '3': case '4':
                2579         case '5': case '6': case '7': case '8': case '9': /* arch-dependent program */
733ed0565 Alex*2580         case 'd':  /* data file */
                2581         case 'p':  /* program file */
                2582         case 's':  /* script */
                2583             strarray_add_uniq( &targets, obj_dir_path( make, file ));
                2584             break;
                2585         case 't':  /* script in tools dir */
                2586             strarray_add_uniq( &targets, tools_dir_path( make, file ));
                2587             break;
                2588         }
                2589     }
                2590 
f9cad1bd1 Alex*2591     output( "%s %s::", obj_dir_path( make, "install" ), obj_dir_path( make, install_targets[rules] ));
733ed0565 Alex*2592     output_filenames( targets );
                2593     output( "\n" );
468af5bbb Alex*2594     output_install_commands( make, files );
5adb93c65 Alex*2595     strarray_add_uniq( &make->phony_targets, obj_dir_path( make, "install" ));
f9cad1bd1 Alex*2596     strarray_add_uniq( &make->phony_targets, obj_dir_path( make, install_targets[rules] ));
1a52ba0bc Alex*2597 }
                2598 
                2599 
                2600 static int cmp_string_length( const char **a, const char **b )
                2601 {
                2602     int paths_a = 0, paths_b = 0;
                2603     const char *p;
                2604 
                2605     for (p = *a; *p; p++) if (*p == '/') paths_a++;
                2606     for (p = *b; *p; p++) if (*p == '/') paths_b++;
                2607     if (paths_b != paths_a) return paths_b - paths_a;
                2608     return strcmp( *a, *b );
                2609 }
                2610 
abee72f32 Alex*2611 /*******************************************************************
                2612  *         get_removable_dirs
                2613  *
                2614  * Retrieve a list of directories to try to remove after deleting the files.
                2615  */
                2616 static struct strarray get_removable_dirs( struct strarray files )
                2617 {
                2618     struct strarray dirs = empty_strarray;
                2619     unsigned int i;
                2620 
                2621     for (i = 0; i < files.count; i++)
                2622     {
                2623         char *dir = xstrdup( files.str[i] );
                2624         while (strchr( dir, '/' ))
                2625         {
                2626             *strrchr( dir, '/' ) = 0;
                2627             strarray_add_uniq( &dirs, xstrdup(dir) );
                2628         }
                2629     }
                2630     strarray_qsort( &dirs, cmp_string_length );
                2631     return dirs;
                2632 }
                2633 
                2634 
1a52ba0bc Alex*2635 /*******************************************************************
                2636  *         output_uninstall_rules
                2637  */
                2638 static void output_uninstall_rules( struct makefile *make )
                2639 {
                2640     static const char *dirs_order[] =
2801d6341 Alex*2641         { "$(includedir)", "$(mandir)", "$(fontdir)", "$(nlsdir)", "$(datadir)", "$(dlldir)" };
1a52ba0bc Alex*2642 
abee72f32 Alex*2643     struct strarray uninstall_dirs;
1a52ba0bc Alex*2644     unsigned int i, j;
                2645 
                2646     if (!make->uninstall_files.count) return;
                2647     output( "uninstall::\n" );
abee72f32 Alex*2648     output_rm_filenames( make->uninstall_files, "rm -f" );
1a52ba0bc Alex*2649     strarray_add_uniq( &make->phony_targets, "uninstall" );
                2650 
468af5bbb Alex*2651     if (!subdirs.count) return;
abee72f32 Alex*2652     uninstall_dirs = get_removable_dirs( make->uninstall_files );
1a52ba0bc Alex*2653     output( "\t-rmdir" );
43eccadce Mich*2654     for (i = 0; i < ARRAY_SIZE(dirs_order); i++)
1a52ba0bc Alex*2655     {
468af5bbb Alex*2656         for (j = 0; j < uninstall_dirs.count; j++)
1a52ba0bc Alex*2657         {
468af5bbb Alex*2658             if (!uninstall_dirs.str[j]) continue;
                2659             if (strncmp( uninstall_dirs.str[j] + strlen("$(DESTDIR)"), dirs_order[i], strlen(dirs_order[i]) ))
1a52ba0bc Alex*2660                 continue;
468af5bbb Alex*2661             output_filename( uninstall_dirs.str[j] );
                2662             uninstall_dirs.str[j] = NULL;
1a52ba0bc Alex*2663         }
                2664     }
468af5bbb Alex*2665     for (j = 0; j < uninstall_dirs.count; j++)
                2666         if (uninstall_dirs.str[j]) output_filename( uninstall_dirs.str[j] );
1a52ba0bc Alex*2667     output( "\n" );
da340169d Alex*2668 }
                2669 
                2670 
ce231568a Alex*2671 /*******************************************************************
                2672  *         output_po_files
                2673  */
363d078f4 Alex*2674 static void output_po_files( struct makefile *make )
ce231568a Alex*2675 {
                2676     const char *po_dir = src_dir_path( make, "po" );
1dd3051cc Alex*2677     unsigned int i;
ce231568a Alex*2678 
                2679     if (linguas.count)
                2680     {
                2681         for (i = 0; i < linguas.count; i++)
                2682             output_filename( strmake( "%s/%s.po", po_dir, linguas.str[i] ));
                2683         output( ": %s/wine.pot\n", po_dir );
1a16b9e9a Alex*2684         output( "\t%smsgmerge --previous -q $@ %s/wine.pot | msgattrib --no-obsolete -o $@.new && mv $@.new $@\n",
                2685                 cmd_prefix( "MSG" ), po_dir );
363d078f4 Alex*2686         output( "po/all:" );
f7a239a50 Alex*2687         for (i = 0; i < linguas.count; i++)
                2688             output_filename( strmake( "%s/%s.po", po_dir, linguas.str[i] ));
                2689         output( "\n" );
ce231568a Alex*2690     }
                2691     output( "%s/wine.pot:", po_dir );
1dd3051cc Alex*2692     output_filenames( make->pot_files );
ce231568a Alex*2693     output( "\n" );
1a16b9e9a Alex*2694     output( "\t%smsgcat -o $@", cmd_prefix( "MSG" ));
1dd3051cc Alex*2695     output_filenames( make->pot_files );
ce231568a Alex*2696     output( "\n" );
363d078f4 Alex*2697     strarray_add( &make->maintainerclean_files, strmake( "%s/wine.pot", po_dir ));
ce231568a Alex*2698 }
                2699 
                2700 
3db94ef2e Alex*2701 /*******************************************************************
4eb9ad983 Alex*2702  *         output_source_y
3db94ef2e Alex*2703  */
4eb9ad983 Alex*2704 static void output_source_y( struct makefile *make, struct incl_file *source, const char *obj )
3db94ef2e Alex*2705 {
4eb9ad983 Alex*2706     char *header = strmake( "%s.tab.h", obj );
31eb8be66 Alex*2707 
4eb9ad983 Alex*2708     if (find_include_file( make, header ))
                2709     {
                2710         output( "%s: %s\n", obj_dir_path( make, header ), source->filename );
6eff423a8 Alex*2711         output( "\t%s%s -o %s.tab.$$$$.c --defines=$@ %s && rm -f %s.tab.$$$$.c\n",
aea0d88ae Alex*2712                 cmd_prefix( "BISON" ), bison, obj_dir_path( make, obj ),
                2713                 source->filename, obj_dir_path( make, obj ));
4eb9ad983 Alex*2714         strarray_add( &make->clean_files, header );
                2715     }
aea0d88ae Alex*2716     output( "%s.tab.c: %s\n", obj_dir_path( make, obj ), source->filename );
f4af3134d Alex*2717     output( "\t%s%s -o $@ %s\n", cmd_prefix( "BISON" ), bison, source->filename );
4eb9ad983 Alex*2718 }
ab4fc685b Alex*2719 
c8a42b473 Alex*2720 
4eb9ad983 Alex*2721 /*******************************************************************
                2722  *         output_source_l
                2723  */
                2724 static void output_source_l( struct makefile *make, struct incl_file *source, const char *obj )
                2725 {
                2726     output( "%s.yy.c: %s\n", obj_dir_path( make, obj ), source->filename );
1a16b9e9a Alex*2727     output( "\t%s%s -o$@ %s\n", cmd_prefix( "FLEX" ), flex, source->filename );
4eb9ad983 Alex*2728 }
                2729 
                2730 
                2731 /*******************************************************************
                2732  *         output_source_h
                2733  */
                2734 static void output_source_h( struct makefile *make, struct incl_file *source, const char *obj )
                2735 {
                2736     if (source->file->flags & FLAG_GENERATED)
718c57cab Alex*2737         strarray_add( &make->all_targets[0], source->name );
872dc83e8 Alex*2738     else if ((source->file->flags & FLAG_INSTALL) || strncmp( source->name, "wine/", 5 ))
8d43170b9 Alex*2739         add_install_rule( make, source->name, 0, source->name,
d84de4ca0 Alex*2740                           strmake( "D$(includedir)/wine/%s", get_include_install_path( source->name ) ));
4eb9ad983 Alex*2741 }
c3aa49529 Alex*2742 
                2743 
4eb9ad983 Alex*2744 /*******************************************************************
                2745  *         output_source_rc
                2746  */
                2747 static void output_source_rc( struct makefile *make, struct incl_file *source, const char *obj )
                2748 {
6bce2b136 Alex*2749     struct strarray defines = get_source_defines( make, source, obj );
6c65fb9cb Alex*2750     const char *po_dir = NULL, *res_file = strmake( "%s.res", obj );
                2751     unsigned int i, arch;
0d533cf0b Alex*2752 
872dc83e8 Alex*2753     if (source->file->flags & FLAG_RC_HEADER) return;
364f97c2e Alex*2754     if (source->file->flags & FLAG_GENERATED) strarray_add( &make->clean_files, source->name );
468af5bbb Alex*2755     if (linguas.count && (source->file->flags & FLAG_RC_PO)) po_dir = "po";
81da9ff0f RĂ©mi*2756     if (!(source->file->flags & FLAG_TESTDLL))
2d39dcafc RĂ©mi*2757     {
                2758         for (arch = 0; arch < archs.count; arch++)
                2759             if (!make->disabled[arch]) strarray_add( &make->res_files[arch], res_file );
                2760     }
                2761     else strarray_add( &make->clean_files, res_file );
                2762 
feb522909 Alex*2763     if (source->file->flags & FLAG_RC_PO)
0a66eaea6 Alex*2764     {
82acb284b Alex*2765         strarray_add( &make->pot_files, strmake( "%s.pot", obj ));
0a66eaea6 Alex*2766         output( "%s.pot ", obj_dir_path( make, obj ) );
                2767     }
6c65fb9cb Alex*2768     output( "%s: %s", obj_dir_path( make, res_file ), source->filename );
0a66eaea6 Alex*2769     output_filename( tools_path( make, "wrc" ));
ad44edebd Alex*2770     if (make->src_dir) output_filename( "nls/locale.nls" );
0a66eaea6 Alex*2771     output_filenames( source->dependencies );
                2772     output( "\n" );
1a16b9e9a Alex*2773     output( "\t%s%s -u -o $@", cmd_prefix( "WRC" ), tools_path( make, "wrc" ) );
4eb9ad983 Alex*2774     if (make->is_win16) output_filename( "-m16" );
                2775     output_filename( "--nostdinc" );
0a66eaea6 Alex*2776     if (po_dir) output_filename( strmake( "--po-dir=%s", po_dir ));
6bce2b136 Alex*2777     output_filenames( defines );
0a66eaea6 Alex*2778     output_filename( source->filename );
                2779     output( "\n" );
                2780     if (po_dir)
4eb9ad983 Alex*2781     {
6c65fb9cb Alex*2782         output( "%s:", obj_dir_path( make, res_file ));
4eb9ad983 Alex*2783         for (i = 0; i < linguas.count; i++)
                2784             output_filename( strmake( "%s/%s.mo", po_dir, linguas.str[i] ));
                2785         output( "\n" );
                2786     }
                2787 }
31eb8be66 Alex*2788 
c00cc015f Alex*2789 
4eb9ad983 Alex*2790 /*******************************************************************
                2791  *         output_source_mc
                2792  */
                2793 static void output_source_mc( struct makefile *make, struct incl_file *source, const char *obj )
                2794 {
6c65fb9cb Alex*2795     unsigned int i, arch;
8247686c1 Alex*2796     char *obj_path = obj_dir_path( make, obj );
6c65fb9cb Alex*2797     char *res_file = strmake( "%s.res", obj );
8f31f92a7 Alex*2798 
a3932d7de Alex*2799     for (arch = 0; arch < archs.count; arch++)
                2800         if (!make->disabled[arch]) strarray_add( &make->res_files[arch], res_file );
82acb284b Alex*2801     strarray_add( &make->pot_files, strmake( "%s.pot", obj ));
8247686c1 Alex*2802     output( "%s.pot %s.res: %s", obj_path, obj_path, source->filename );
                2803     output_filename( tools_path( make, "wmc" ));
                2804     output_filenames( source->dependencies );
c44eb6d62 Alex*2805     if (make->src_dir) output_filename( "nls/locale.nls" );
8247686c1 Alex*2806     output( "\n" );
1a16b9e9a Alex*2807     output( "\t%s%s -u -o $@ %s", cmd_prefix( "WMC" ), tools_path( make, "wmc" ), source->filename );
4eb9ad983 Alex*2808     if (linguas.count)
                2809     {
468af5bbb Alex*2810         output_filename( "--po-dir=po" );
4eb9ad983 Alex*2811         output( "\n" );
                2812         output( "%s.res:", obj_dir_path( make, obj ));
                2813         for (i = 0; i < linguas.count; i++)
468af5bbb Alex*2814             output_filename( strmake( "po/%s.mo", linguas.str[i] ));
4eb9ad983 Alex*2815     }
                2816     output( "\n" );
                2817 }
8f31f92a7 Alex*2818 
8c0a717a5 Alex*2819 
4eb9ad983 Alex*2820 /*******************************************************************
                2821  *         output_source_res
                2822  */
                2823 static void output_source_res( struct makefile *make, struct incl_file *source, const char *obj )
                2824 {
a3932d7de Alex*2825     if (make->disabled[source->arch]) return;
6c65fb9cb Alex*2826     strarray_add( &make->res_files[source->arch], source->name );
4eb9ad983 Alex*2827 }
8e45a6ecb Alex*2828 
                2829 
4eb9ad983 Alex*2830 /*******************************************************************
                2831  *         output_source_idl
                2832  */
                2833 static void output_source_idl( struct makefile *make, struct incl_file *source, const char *obj )
                2834 {
6bce2b136 Alex*2835     struct strarray defines = get_source_defines( make, source, obj );
6fb5e4d99 Alex*2836     struct strarray headers = empty_strarray;
a3932d7de Alex*2837     struct strarray deps = empty_strarray;
6fb5e4d99 Alex*2838     struct strarray multiarch_targets[MAX_ARCHS] = { empty_strarray };
                2839     const char *dest;
                2840     unsigned int i, arch;
4eb9ad983 Alex*2841 
                2842     if (find_include_file( make, strmake( "%s.h", obj ))) source->file->flags |= FLAG_IDL_HEADER;
872dc83e8 Alex*2843     if (!source->file->flags) return;
4eb9ad983 Alex*2844 
                2845     if (source->file->flags & FLAG_IDL_PROXY) strarray_add( &make->dlldata_files, source->name );
                2846     if (source->file->flags & FLAG_INSTALL)
                2847     {
8d43170b9 Alex*2848         add_install_rule( make, source->name, 0, xstrdup( source->name ),
d84de4ca0 Alex*2849                           strmake( "D$(includedir)/wine/%s.idl", get_include_install_path( obj ) ));
4eb9ad983 Alex*2850         if (source->file->flags & FLAG_IDL_HEADER)
8d43170b9 Alex*2851             add_install_rule( make, source->name, 0, strmake( "%s.h", obj ),
d84de4ca0 Alex*2852                               strmake( "d$(includedir)/wine/%s.h", get_include_install_path( obj ) ));
4eb9ad983 Alex*2853     }
6fb5e4d99 Alex*2854     if (source->file->flags & FLAG_IDL_HEADER)
                2855     {
                2856         dest = strmake( "%s.h", obj );
                2857         strarray_add( &headers, dest );
                2858         if (!find_src_file( make, dest )) strarray_add( &make->clean_files, dest );
                2859     }
4eb9ad983 Alex*2860 
6fb5e4d99 Alex*2861     for (i = 0; i < ARRAY_SIZE(idl_outputs); i++)
                2862     {
                2863         if (!(source->file->flags & idl_outputs[i].flag)) continue;
                2864         for (arch = 0; arch < archs.count; arch++)
                2865         {
a9183c7e3 Alex*2866             if (!is_multiarch( arch )) continue;
a3932d7de Alex*2867             if (make->disabled[arch]) continue;
6a9126491 Alex*2868             dest = strmake( "%s%s%s", arch_dirs[arch], obj, idl_outputs[i].ext );
6fb5e4d99 Alex*2869             if (!find_src_file( make, dest )) strarray_add( &make->clean_files, dest );
                2870             strarray_add( &multiarch_targets[arch], dest );
                2871         }
                2872     }
                2873 
                2874     for (arch = 0; arch < archs.count; arch++)
                2875     {
a3932d7de Alex*2876         struct strarray arch_deps = empty_strarray;
                2877 
                2878         if (!arch) strarray_addall( &arch_deps, headers );
                2879         strarray_addall( &arch_deps, multiarch_targets[arch] );
                2880         if (!arch_deps.count) continue;
                2881         output_filenames_obj_dir( make, arch_deps );
6fb5e4d99 Alex*2882         output( ":\n" );
                2883         output( "\t%s%s -o $@", cmd_prefix( "WIDL" ), tools_path( make, "widl" ) );
                2884         output_filenames( target_flags[arch] );
                2885         output_filename( "--nostdinc" );
                2886         output_filename( "-Ldlls/\\*" );
                2887         output_filenames( defines );
                2888         output_filenames( get_expanded_make_var_array( make, "EXTRAIDLFLAGS" ));
                2889         output_filenames( get_expanded_file_local_var( make, obj, "EXTRAIDLFLAGS" ));
f8dde10ff Alex*2890         if (arch) output_filenames( get_expanded_arch_var_array( make, "EXTRAIDLFLAGS", arch ));
6fb5e4d99 Alex*2891         output_filename( source->filename );
                2892         output( "\n" );
a3932d7de Alex*2893         strarray_addall( &deps, arch_deps );
6fb5e4d99 Alex*2894     }
                2895 
a3932d7de Alex*2896     if (deps.count)
                2897     {
                2898         output_filenames_obj_dir( make, deps );
                2899         output( ":" );
                2900         output_filename( tools_path( make, "widl" ));
                2901         output_filename( source->filename );
                2902         output_filenames( source->dependencies );
                2903         output( "\n" );
                2904     }
6fb5e4d99 Alex*2905 
                2906     if (source->importlibdeps.count)
ef8b871e1 Alex*2907     {
6fb5e4d99 Alex*2908         for (arch = 0; arch < archs.count; arch++)
                2909         {
                2910             if (!multiarch_targets[arch].count) continue;
                2911             output_filenames_obj_dir( make, multiarch_targets[arch] );
                2912             output( ":" );
                2913             for (i = 0; i < source->importlibdeps.count; i++)
                2914             {
ba50573f9 Jace*2915                 int native_arch = native_archs[arch] ? native_archs[arch] : arch;
6fb5e4d99 Alex*2916                 struct makefile *submake = find_importlib_module( source->importlibdeps.str[i] );
ba50573f9 Jace*2917                 const char *module = strmake( "%s%s", arch_pe_dirs[native_arch], submake->module );
6a9126491 Alex*2918                 output_filename( obj_dir_path( submake, module ));
6fb5e4d99 Alex*2919             }
                2920             output( "\n" );
                2921         }
ef8b871e1 Alex*2922     }
4eb9ad983 Alex*2923 }
                2924 
                2925 
                2926 /*******************************************************************
                2927  *         output_source_x
                2928  */
                2929 static void output_source_x( struct makefile *make, struct incl_file *source, const char *obj )
                2930 {
                2931     output( "%s.h: %s%s %s\n", obj_dir_path( make, obj ),
                2932             tools_dir_path( make, "make_xftmpl" ), tools_ext, source->filename );
1a16b9e9a Alex*2933     output( "\t%s%s%s -H -o $@ %s\n", cmd_prefix( "GEN" ),
4eb9ad983 Alex*2934             tools_dir_path( make, "make_xftmpl" ), tools_ext, source->filename );
                2935     if (source->file->flags & FLAG_INSTALL)
                2936     {
8d43170b9 Alex*2937         add_install_rule( make, source->name, 0, source->name,
d84de4ca0 Alex*2938                           strmake( "D$(includedir)/wine/%s", get_include_install_path( source->name ) ));
8d43170b9 Alex*2939         add_install_rule( make, source->name, 0, strmake( "%s.h", obj ),
d84de4ca0 Alex*2940                           strmake( "d$(includedir)/wine/%s.h", get_include_install_path( obj ) ));
4eb9ad983 Alex*2941     }
                2942 }
                2943 
                2944 
                2945 /*******************************************************************
                2946  *         output_source_sfd
                2947  */
                2948 static void output_source_sfd( struct makefile *make, struct incl_file *source, const char *obj )
                2949 {
                2950     unsigned int i;
d84de4ca0 Alex*2951     char *ttf_obj = strmake( "%s.ttf", obj );
                2952     char *ttf_file = src_dir_path( make, ttf_obj );
4eb9ad983 Alex*2953 
                2954     if (fontforge && !make->src_dir)
                2955     {
                2956         output( "%s: %s\n", ttf_file, source->filename );
1a16b9e9a Alex*2957         output( "\t%s%s -script %s %s $@\n", cmd_prefix( "GEN" ),
468af5bbb Alex*2958                 fontforge, root_src_dir_path( "fonts/genttf.ff" ), source->filename );
f2d60c16e Alex*2959         if (!(source->file->flags & FLAG_SFD_FONTS)) strarray_add( &make->font_files, ttf_obj );
363d078f4 Alex*2960         strarray_add( &make->maintainerclean_files, ttf_obj );
4eb9ad983 Alex*2961     }
                2962     if (source->file->flags & FLAG_INSTALL)
4152f944f Alex*2963     {
8d43170b9 Alex*2964         add_install_rule( make, source->name, 0, ttf_obj, strmake( "D$(fontdir)/%s", ttf_obj ));
4152f944f Alex*2965         output_srcdir_symlink( make, ttf_obj );
                2966     }
d84de4ca0 Alex*2967 
4eb9ad983 Alex*2968     if (source->file->flags & FLAG_SFD_FONTS)
                2969     {
                2970         struct strarray *array = source->file->args;
                2971 
                2972         for (i = 0; i < array->count; i++)
da19122f1 Alex*2973         {
4eb9ad983 Alex*2974             char *font = strtok( xstrdup(array->str[i]), " \t" );
                2975             char *args = strtok( NULL, "" );
                2976 
718c57cab Alex*2977             strarray_add( &make->all_targets[0], xstrdup( font ));
4eb9ad983 Alex*2978             output( "%s: %s %s\n", obj_dir_path( make, font ),
                2979                     tools_path( make, "sfnt2fon" ), ttf_file );
1a16b9e9a Alex*2980             output( "\t%s%s -q -o $@ %s %s\n", cmd_prefix( "GEN" ),
                2981                     tools_path( make, "sfnt2fon" ), ttf_file, args );
8d43170b9 Alex*2982             add_install_rule( make, source->name, 0, xstrdup(font), strmake( "d$(fontdir)/%s", font ));
8e81f6d58 Alex*2983         }
4eb9ad983 Alex*2984     }
                2985 }
                2986 
                2987 
                2988 /*******************************************************************
                2989  *         output_source_svg
                2990  */
                2991 static void output_source_svg( struct makefile *make, struct incl_file *source, const char *obj )
                2992 {
                2993     static const char * const images[] = { "bmp", "cur", "ico", NULL };
                2994     unsigned int i;
                2995 
363d078f4 Alex*2996     if (convert && rsvg && icotool)
4eb9ad983 Alex*2997     {
                2998         for (i = 0; images[i]; i++)
                2999             if (find_include_file( make, strmake( "%s.%s", obj, images[i] ))) break;
                3000 
                3001         if (images[i])
8e81f6d58 Alex*3002         {
4eb9ad983 Alex*3003             output( "%s.%s: %s\n", src_dir_path( make, obj ), images[i], source->filename );
1a16b9e9a Alex*3004             output( "\t%sCONVERT=\"%s\" ICOTOOL=\"%s\" RSVG=\"%s\" %s %s $@\n",
                3005                     cmd_prefix( "GEN" ), convert, icotool, rsvg,
468af5bbb Alex*3006                     root_src_dir_path( "tools/buildimage" ), source->filename );
363d078f4 Alex*3007             strarray_add( &make->maintainerclean_files, strmake( "%s.%s", obj, images[i] ));
da19122f1 Alex*3008         }
4eb9ad983 Alex*3009     }
                3010 }
                3011 
                3012 
1a49f2e04 Alex*3013 /*******************************************************************
                3014  *         output_source_nls
                3015  */
                3016 static void output_source_nls( struct makefile *make, struct incl_file *source, const char *obj )
                3017 {
8d43170b9 Alex*3018     add_install_rule( make, source->name, 0, source->name,
42a30a693 Alex*3019                       strmake( "D$(nlsdir)/%s", source->name ));
4152f944f Alex*3020     output_srcdir_symlink( make, strmake( "%s.nls", obj ));
1a49f2e04 Alex*3021 }
                3022 
                3023 
                3024 /*******************************************************************
                3025  *         output_source_desktop
                3026  */
                3027 static void output_source_desktop( struct makefile *make, struct incl_file *source, const char *obj )
                3028 {
8d43170b9 Alex*3029     add_install_rule( make, source->name, 0, source->name,
1a49f2e04 Alex*3030                       strmake( "D$(datadir)/applications/%s", source->name ));
                3031 }
                3032 
                3033 
4eb9ad983 Alex*3034 /*******************************************************************
                3035  *         output_source_po
                3036  */
                3037 static void output_source_po( struct makefile *make, struct incl_file *source, const char *obj )
                3038 {
                3039     output( "%s.mo: %s\n", obj_dir_path( make, obj ), source->filename );
1a16b9e9a Alex*3040     output( "\t%s%s -o $@ %s\n", cmd_prefix( "MSG" ), msgfmt, source->filename );
718c57cab Alex*3041     strarray_add( &make->all_targets[0], strmake( "%s.mo", obj ));
4eb9ad983 Alex*3042 }
                3043 
                3044 
                3045 /*******************************************************************
                3046  *         output_source_in
                3047  */
                3048 static void output_source_in( struct makefile *make, struct incl_file *source, const char *obj )
                3049 {
                3050     unsigned int i;
                3051 
872dc83e8 Alex*3052     if (make == include_makefile) return;  /* ignore generated includes */
4eb9ad983 Alex*3053     if (strendswith( obj, ".man" ) && source->file->args)
                3054     {
                3055         struct strarray symlinks;
                3056         char *dir, *dest = replace_extension( obj, ".man", "" );
                3057         char *lang = strchr( dest, '.' );
                3058         char *section = source->file->args;
                3059         if (lang)
432338497 Alex*3060         {
4eb9ad983 Alex*3061             *lang++ = 0;
                3062             dir = strmake( "$(mandir)/%s/man%s", lang, section );
432338497 Alex*3063         }
4eb9ad983 Alex*3064         else dir = strmake( "$(mandir)/man%s", section );
8d43170b9 Alex*3065         add_install_rule( make, dest, 0, obj, strmake( "d%s/%s.%s", dir, dest, section ));
4eb9ad983 Alex*3066         symlinks = get_expanded_file_local_var( make, dest, "SYMLINKS" );
                3067         for (i = 0; i < symlinks.count; i++)
8d43170b9 Alex*3068             add_install_rule( make, symlinks.str[i], 0, strmake( "%s.%s", dest, section ),
4eb9ad983 Alex*3069                               strmake( "y%s/%s.%s", dir, symlinks.str[i], section ));
                3070         free( dest );
                3071         free( dir );
                3072     }
8d43170b9 Alex*3073     strarray_add( &make->in_files, obj );
                3074     strarray_add( &make->all_targets[0], obj );
4eb9ad983 Alex*3075     output( "%s: %s\n", obj_dir_path( make, obj ), source->filename );
1a16b9e9a Alex*3076     output( "\t%s%s %s >$@ || (rm -f $@ && false)\n", cmd_prefix( "SED" ), sed_cmd, source->filename );
4eb9ad983 Alex*3077     output( "%s:", obj_dir_path( make, obj ));
                3078     output_filenames( source->dependencies );
                3079     output( "\n" );
8d43170b9 Alex*3080     add_install_rule( make, obj, 0, obj, strmake( "d$(datadir)/wine/%s", obj ));
4eb9ad983 Alex*3081 }
                3082 
                3083 
2435357d6 Alex*3084 /*******************************************************************
                3085  *         output_source_spec
                3086  */
                3087 static void output_source_spec( struct makefile *make, struct incl_file *source, const char *obj )
81da9ff0f RĂ©mi*3088 {
                3089     /* nothing to do */
                3090 }
                3091 
                3092 
                3093 /*******************************************************************
                3094  *         output_source_testdll
                3095  */
                3096 static void output_source_testdll( struct makefile *make, struct incl_file *source, const char *obj )
2435357d6 Alex*3097 {
                3098     struct strarray imports = get_expanded_file_local_var( make, obj, "IMPORTS" );
4920d08e5 Jace*3099     struct strarray dll_flags = empty_strarray;
214223edc RĂ©mi*3100     struct strarray default_imports = empty_strarray;
b1f59bc67 Alex*3101     struct strarray all_libs, dep_libs;
cfcf5ca28 Alex*3102     const char *dll_name, *obj_name, *res_name, *output_rsrc, *output_file, *debug_file, *ext = ".dll";
dcb160212 RĂ©mi*3103     struct incl_file *spec_file = find_src_file( make, strmake( "%s.spec", obj ));
ba50573f9 Jace*3104     unsigned int arch, link_arch;
2435357d6 Alex*3105 
                3106     if (!imports.count) imports = make->imports;
4920d08e5 Jace*3107     strarray_addall( &dll_flags, make->extradllflags );
                3108     strarray_addall( &dll_flags, get_expanded_file_local_var( make, obj, "EXTRADLLFLAGS" ));
214223edc RĂ©mi*3109     if (!strarray_exists( &dll_flags, "-nodefaultlibs" )) default_imports = get_default_imports( make, imports );
19c1cc1c3 RĂ©mi*3110     if (strarray_exists( &dll_flags, "-mconsole" )) ext = ".exe";
81da9ff0f RĂ©mi*3111 
b1f59bc67 Alex*3112     for (arch = 0; arch < archs.count; arch++)
                3113     {
ba50573f9 Jace*3114         const char *hybrid_obj_name = NULL;
                3115 
                3116         if (!is_multiarch( arch ) || !get_link_arch( make, arch, &link_arch)) continue;
                3117 
b1f59bc67 Alex*3118         all_libs = dep_libs = empty_strarray;
                3119         strarray_addall( &all_libs, add_import_libs( make, &dep_libs, imports, IMPORT_TYPE_DIRECT, arch ) );
                3120         strarray_addall( &all_libs, add_import_libs( make, &dep_libs, default_imports, IMPORT_TYPE_DEFAULT, arch ) );
9576fbeff Alex*3121         if (!arch) strarray_addall( &all_libs, libs );
19c1cc1c3 RĂ©mi*3122         dll_name = arch_module_name( strmake( "%s%s", obj, ext ), arch );
b1f59bc67 Alex*3123         obj_name = obj_dir_path( make, strmake( "%s%s.o", arch_dirs[arch], obj ));
ba50573f9 Jace*3124         if (link_arch != arch)
                3125             hybrid_obj_name = obj_dir_path( make, strmake( "%s%s.o", arch_dirs[link_arch], obj ));
b1f59bc67 Alex*3126         output_file = obj_dir_path( make, dll_name );
d2e79b090 RĂ©mi*3127         output_rsrc = strmake( "%s.res", dll_name );
b1f59bc67 Alex*3128 
2d39dcafc RĂ©mi*3129         if (!find_src_file( make, strmake( "%s.rc", obj ) )) res_name = NULL;
                3130         else res_name = obj_dir_path( make, strmake( "%s.res", obj ) );
                3131 
b1f59bc67 Alex*3132         strarray_add( &make->clean_files, dll_name );
d2e79b090 RĂ©mi*3133         strarray_add( &make->res_files[arch], output_rsrc );
                3134         output( "%s:", obj_dir_path( make, output_rsrc ));
b1f59bc67 Alex*3135         output_filename( output_file );
                3136         output_filename( tools_path( make, "wrc" ));
                3137         output( "\n" );
19c1cc1c3 RĂ©mi*3138         output( "\t%secho \"%s%s TESTDLL \\\"%s\\\"\" | %s -u -o $@\n", cmd_prefix( "WRC" ), obj, ext, output_file,
b1f59bc67 Alex*3139                 tools_path( make, "wrc" ));
2435357d6 Alex*3140 
b1f59bc67 Alex*3141         output( "%s:", output_file );
19c1cc1c3 RĂ©mi*3142         if (spec_file) output_filename( spec_file->filename );
b1f59bc67 Alex*3143         output_filename( obj_name );
ba50573f9 Jace*3144         if (hybrid_obj_name) output_filename( hybrid_obj_name );
2d39dcafc RĂ©mi*3145         if (res_name) output_filename( res_name );
b1f59bc67 Alex*3146         output_filenames( dep_libs );
                3147         output_filename( tools_path( make, "winebuild" ));
                3148         output_filename( tools_path( make, "winegcc" ));
                3149         output( "\n" );
ba50573f9 Jace*3150         output_winegcc_command( make, link_arch );
b1f59bc67 Alex*3151         output_filename( "-s" );
                3152         output_filenames( dll_flags );
ba50573f9 Jace*3153         if (link_arch) output_filenames( get_expanded_arch_var_array( make, "EXTRADLLFLAGS", link_arch ));
19c1cc1c3 RĂ©mi*3154         if (!strcmp( ext, ".dll" )) output_filename( "-shared" );
                3155         if (spec_file) output_filename( spec_file->filename );
b1f59bc67 Alex*3156         output_filename( obj_name );
ba50573f9 Jace*3157         if (hybrid_obj_name) output_filename( hybrid_obj_name );
2d39dcafc RĂ©mi*3158         if (res_name) output_filename( res_name );
ba50573f9 Jace*3159         if ((debug_file = get_debug_file( make, dll_name, link_arch )))
b1f59bc67 Alex*3160             output_filename( strmake( "-Wl,--debug-file,%s", obj_dir_path( make, debug_file )));
                3161         output_filenames( all_libs );
ba50573f9 Jace*3162         output_filename( arch_make_variable( "LDFLAGS", link_arch ));
b1f59bc67 Alex*3163         output( "\n" );
                3164     }
2435357d6 Alex*3165 }
                3166 
                3167 
857001678 Alex*3168 /*******************************************************************
                3169  *         output_source_xml
                3170  */
                3171 static void output_source_xml( struct makefile *make, struct incl_file *source, const char *obj )
                3172 {
                3173     if (wayland_scanner)
                3174     {
                3175         output( "%s-protocol.c: %s\n", obj_dir_path( make, obj ), source->filename );
                3176         output( "\t%s%s private-code %s $@\n", cmd_prefix( "GEN" ), wayland_scanner, source->filename );
                3177         output( "%s-client-protocol.h: %s\n", obj_dir_path( make, obj ), source->filename );
                3178         output( "\t%s%s client-header %s $@\n", cmd_prefix( "GEN" ), wayland_scanner, source->filename );
                3179     }
                3180 }
                3181 
                3182 
4eb9ad983 Alex*3183 /*******************************************************************
7d4ce928e Alex*3184  *         output_source_one_arch
4eb9ad983 Alex*3185  */
7d4ce928e Alex*3186 static void output_source_one_arch( struct makefile *make, struct incl_file *source, const char *obj,
                3187                                     struct strarray defines, struct strarray *targets,
81da9ff0f RĂ©mi*3188                                     unsigned int arch )
4eb9ad983 Alex*3189 {
3e2a99901 Alex*3190     const char *obj_name, *var_cc, *var_cflags;
                3191     struct strarray arch_cflags = empty_strarray;
7d4ce928e Alex*3192 
a3932d7de Alex*3193     if (make->disabled[arch] && !(source->file->flags & FLAG_C_IMPLIB)) return;
                3194 
7d4ce928e Alex*3195     if (arch)
                3196     {
                3197         if (source->file->flags & FLAG_C_UNIX) return;
a9183c7e3 Alex*3198         if (!is_using_msvcrt( make ) && !make->staticlib && !(source->file->flags & FLAG_C_IMPLIB)) return;
7d4ce928e Alex*3199     }
                3200     else if (source->file->flags & FLAG_C_UNIX)
                3201     {
fa732145b Alex*3202         if (!unix_lib_supported) return;
7d4ce928e Alex*3203     }
56fe04085 Alex*3204     else if (archs.count > 1 && is_using_msvcrt( make ))
                3205     {
                3206         if (!so_dll_supported) return;
                3207         if (!(source->file->flags & FLAG_C_IMPLIB) && (!make->staticlib || make->extlib)) return;
                3208     }
7d4ce928e Alex*3209 
6a9126491 Alex*3210     obj_name = strmake( "%s%s.o", source->arch ? "" : arch_dirs[arch], obj );
7d4ce928e Alex*3211     strarray_add( targets, obj_name );
                3212 
                3213     if (source->file->flags & FLAG_C_UNIX)
                3214         strarray_add( &make->unixobj_files, obj_name );
                3215     else if (source->file->flags & FLAG_C_IMPLIB)
                3216         strarray_add( &make->implib_files[arch], obj_name );
81da9ff0f RĂ©mi*3217     else if (!(source->file->flags & FLAG_TESTDLL))
7d4ce928e Alex*3218         strarray_add( &make->object_files[arch], obj_name );
                3219     else
                3220         strarray_add( &make->clean_files, obj_name );
                3221 
3e2a99901 Alex*3222     if ((source->file->flags & FLAG_ARM64EC_X64) && !strcmp( archs.str[arch], "arm64ec" ))
                3223     {
                3224         var_cc     = "$(x86_64_CC)";
                3225         var_cflags = "$(x86_64_CFLAGS)";
                3226         strarray_add( &arch_cflags, "-D__arm64ec_x64__" );
                3227         strarray_addall( &arch_cflags, get_expanded_make_var_array( top_makefile, "x86_64_EXTRACFLAGS" ));
                3228     }
                3229     else
                3230     {
                3231         var_cc     = arch_make_variable( "CC", arch );
                3232         var_cflags = arch_make_variable( "CFLAGS", arch );
                3233         strarray_addall( &arch_cflags, make->extlib ? extra_cflags_extlib[arch] : extra_cflags[arch] );
                3234     }
                3235 
7d4ce928e Alex*3236     output( "%s: %s\n", obj_dir_path( make, obj_name ), source->filename );
3e2a99901 Alex*3237     output( "\t%s%s -c -o $@ %s", cmd_prefix( "CC" ), var_cc, source->filename );
7d4ce928e Alex*3238     output_filenames( defines );
                3239     if (!source->use_msvcrt) output_filenames( make->unix_cflags );
3e2a99901 Alex*3240     output_filenames( arch_cflags );
                3241 
7d4ce928e Alex*3242     if (!arch)
                3243     {
5c98858a9 Alex*3244         if (source->file->flags & FLAG_C_UNIX)
5e0479c49 Alex*3245         {
                3246             output_filenames( unix_dllflags );
                3247         }
518f9a12c Alex*3248         else if (make->module || make->testdll)
0022af881 Alex*3249         {
                3250             output_filenames( dll_flags );
6bce2b136 Alex*3251             if (source->use_msvcrt) output_filenames( msvcrt_flags );
fa732145b Alex*3252             if (!unix_lib_supported && make->module && is_crt_module( make->module ))
63e6eaede Jace*3253                 output_filename( "-fno-builtin" );
0022af881 Alex*3254         }
4eb9ad983 Alex*3255     }
7d4ce928e Alex*3256     else
4eb9ad983 Alex*3257     {
7d4ce928e Alex*3258         if (make->module && is_crt_module( make->module )) output_filename( "-fno-builtin" );
4eb9ad983 Alex*3259     }
7d4ce928e Alex*3260 
                3261     output_filenames( cpp_flags );
3e2a99901 Alex*3262     output_filename( var_cflags );
7d4ce928e Alex*3263     output( "\n" );
                3264 
81da9ff0f RĂ©mi*3265     if (make->testdll && strendswith( source->name, ".c" ) &&
                3266         !(source->file->flags & (FLAG_GENERATED | FLAG_TESTDLL)))
9d494730f Alex*3267     {
7d4ce928e Alex*3268         const char *ok_file, *test_exe;
                3269 
6a9126491 Alex*3270         ok_file = strmake( "%s%s.ok", arch_dirs[arch], obj );
7d4ce928e Alex*3271         test_exe = replace_extension( make->testdll, ".dll", "_test.exe" );
fec95db07 Alex*3272         strarray_add( &make->ok_files[arch], ok_file );
7d4ce928e Alex*3273         output( "%s:\n", obj_dir_path( make, ok_file ));
6cfdd7e97 Alex*3274         output( "\t%s%s $(RUNTESTFLAGS) -T . -M %s -p %s %s && touch $@\n",
9d494730f Alex*3275                 cmd_prefix( "TEST" ),
                3276                 root_src_dir_path( "tools/runtest" ), make->testdll,
6cfdd7e97 Alex*3277                 obj_dir_path( make, arch_module_name( test_exe, arch )), obj );
7d4ce928e Alex*3278     }
                3279 }
                3280 
                3281 
                3282 /*******************************************************************
                3283  *         output_source_default
                3284  */
                3285 static void output_source_default( struct makefile *make, struct incl_file *source, const char *obj )
                3286 {
                3287     struct strarray defines = get_source_defines( make, source, obj );
                3288     struct strarray targets = empty_strarray;
                3289     unsigned int arch;
                3290 
                3291     for (arch = 0; arch < archs.count; arch++)
                3292         if (!source->arch || source->arch == arch)
81da9ff0f RĂ©mi*3293             output_source_one_arch( make, source, obj, defines, &targets, arch );
7d4ce928e Alex*3294 
                3295     if (source->file->flags & FLAG_GENERATED)
                3296     {
                3297         if (!make->testdll || !strendswith( source->filename, "testlist.c" ))
                3298             strarray_add( &make->clean_files, source->basename );
                3299     }
81da9ff0f RĂ©mi*3300     else if (source->file->flags & FLAG_TESTDLL)
                3301     {
                3302         output_source_testdll( make, source, obj );
                3303     }
7d4ce928e Alex*3304     else
                3305     {
81da9ff0f RĂ©mi*3306         if (make->testdll && strendswith( source->name, ".c" ))
7d4ce928e Alex*3307             strarray_add( &make->test_files, obj );
3db94ef2e Alex*3308     }
7d4ce928e Alex*3309 
7e8ac46a5 Alex*3310     if (targets.count && source->dependencies.count)
                3311     {
                3312         output_filenames_obj_dir( make, targets );
                3313         output( ":" );
                3314         output_filenames( source->dependencies );
                3315         output( "\n" );
                3316     }
4eb9ad983 Alex*3317 }
                3318 
                3319 
                3320 /* dispatch table to output rules for a single source file */
                3321 static const struct
                3322 {
                3323     const char *ext;
                3324     void (*fn)( struct makefile *make, struct incl_file *source, const char *obj );
                3325 } output_source_funcs[] =
                3326 {
                3327     { "y", output_source_y },
                3328     { "l", output_source_l },
                3329     { "h", output_source_h },
                3330     { "rh", output_source_h },
                3331     { "inl", output_source_h },
                3332     { "rc", output_source_rc },
                3333     { "mc", output_source_mc },
                3334     { "res", output_source_res },
                3335     { "idl", output_source_idl },
                3336     { "sfd", output_source_sfd },
                3337     { "svg", output_source_svg },
1a49f2e04 Alex*3338     { "nls", output_source_nls },
                3339     { "desktop", output_source_desktop },
4eb9ad983 Alex*3340     { "po", output_source_po },
                3341     { "in", output_source_in },
                3342     { "x", output_source_x },
2435357d6 Alex*3343     { "spec", output_source_spec },
857001678 Alex*3344     { "xml", output_source_xml },
4eb9ad983 Alex*3345     { NULL, output_source_default }
                3346 };
da4c49c74 Alex*3347 
                3348 
1e58882e7 Alex*3349 /*******************************************************************
                3350  *         output_fake_module
                3351  */
aa15f41d0 Alex*3352 static void output_fake_module( struct makefile *make, const char *spec_file )
1e58882e7 Alex*3353 {
                3354     unsigned int arch = 0;  /* fake modules are always native */
aa15f41d0 Alex*3355     const char *name = strmake( "%s%s", arch_pe_dirs[arch], make->module );
1e58882e7 Alex*3356 
a3932d7de Alex*3357     if (make->disabled[arch]) return;
                3358 
1e58882e7 Alex*3359     strarray_add( &make->all_targets[arch], name );
                3360     add_install_rule( make, make->module, arch, name, strmake( "d$(dlldir)/%s", name ));
                3361 
                3362     output( "%s:", obj_dir_path( make, name ));
                3363     if (spec_file) output_filename( spec_file );
                3364     output_filenames_obj_dir( make, make->res_files[arch] );
                3365     output_filename( tools_path( make, "winebuild" ));
                3366     output_filename( tools_path( make, "winegcc" ));
                3367     output( "\n" );
                3368     output_winegcc_command( make, arch );
                3369     output_filename( "-Wb,--fake-module" );
aa15f41d0 Alex*3370     if (!make->is_exe) output_filename( "-shared" );
                3371     if (spec_file) output_filename( spec_file );
1e58882e7 Alex*3372     output_filenames( make->extradllflags );
                3373     output_filenames_obj_dir( make, make->res_files[arch] );
                3374     output( "\n" );
                3375 }
                3376 
                3377 
4eb9ad983 Alex*3378 /*******************************************************************
                3379  *         output_module
                3380  */
24d791e2e Alex*3381 static void output_module( struct makefile *make, unsigned int arch )
4eb9ad983 Alex*3382 {
214223edc RĂ©mi*3383     struct strarray default_imports = empty_strarray;
4eb9ad983 Alex*3384     struct strarray all_libs = empty_strarray;
                3385     struct strarray dep_libs = empty_strarray;
8c68894f0 Alex*3386     struct strarray imports = make->imports;
6a9126491 Alex*3387     const char *module_name;
f153ca0d1 Alex*3388     const char *debug_file;
4eb9ad983 Alex*3389     char *spec_file = NULL;
ba50573f9 Jace*3390     unsigned int i, link_arch;
f6479c051 Alex*3391 
ba50573f9 Jace*3392     if (!get_link_arch( make, arch, &link_arch )) return;
a3932d7de Alex*3393 
f1ff3179a Alex*3394     if (!make->is_exe)
                3395     {
aa15f41d0 Alex*3396         if (make->data_only || strarray_exists( &make->extradllflags, "-Wl,--subsystem,native" ))
f1ff3179a Alex*3397         {
                3398             /* spec file is optional */
                3399             struct incl_file *spec = find_src_file( make, replace_extension( make->module, ".dll", ".spec" ));
                3400             if (spec) spec_file = spec->filename;
                3401         }
                3402         else spec_file = src_dir_path( make, replace_extension( make->module, ".dll", ".spec" ));
                3403     }
8c68894f0 Alex*3404 
1c2e3fc68 Alex*3405     if (!make->data_only)
1ef7dd2d7 Alex*3406     {
6cfdd7e97 Alex*3407         module_name = arch_module_name( make->module, arch );
1ef7dd2d7 Alex*3408 
214223edc RĂ©mi*3409         if (!strarray_exists( &make->extradllflags, "-nodefaultlibs" )) default_imports = get_default_imports( make, imports );
1c2e3fc68 Alex*3410 
24d791e2e Alex*3411         strarray_addall( &all_libs, add_import_libs( make, &dep_libs, imports, IMPORT_TYPE_DIRECT, arch ));
                3412         strarray_addall( &all_libs, add_import_libs( make, &dep_libs, make->delayimports, IMPORT_TYPE_DELAYED, arch ));
                3413         strarray_addall( &all_libs, add_import_libs( make, &dep_libs, default_imports, IMPORT_TYPE_DEFAULT, arch ) );
9576fbeff Alex*3414         if (!arch) strarray_addall( &all_libs, libs );
1c2e3fc68 Alex*3415 
815e766d9 Alex*3416         if (delay_load_flags[arch])
1c2e3fc68 Alex*3417         {
                3418             for (i = 0; i < make->delayimports.count; i++)
020e2b6bb Alex*3419             {
                3420                 struct makefile *import = get_static_lib( make->delayimports.str[i], arch );
                3421                 if (import) strarray_add( &all_libs, strmake( "%s%s", delay_load_flags[arch], import->module ));
                3422             }
1c2e3fc68 Alex*3423         }
b7e3c9315 Alex*3424     }
6a9126491 Alex*3425     else module_name = strmake( "%s%s", arch_pe_dirs[arch], make->module );
f153ca0d1 Alex*3426 
6a9126491 Alex*3427     strarray_add( &make->all_targets[arch], module_name );
1c2e3fc68 Alex*3428     if (make->data_only)
8d43170b9 Alex*3429         add_install_rule( make, make->module, arch, module_name,
b1f59bc67 Alex*3430                           strmake( "d$(dlldir)/%s%s", arch_pe_dirs[arch], make->module ));
4eb9ad983 Alex*3431     else
8d43170b9 Alex*3432         add_install_rule( make, make->module, arch, module_name,
6a9126491 Alex*3433                           strmake( "%c%s%s%s", '0' + arch, arch_install_dirs[arch], make->module,
fa732145b Alex*3434                                    dll_ext[arch] ));
0189cf21c Alex*3435 
f153ca0d1 Alex*3436     output( "%s:", obj_dir_path( make, module_name ));
4eb9ad983 Alex*3437     if (spec_file) output_filename( spec_file );
cb5268c72 Alex*3438     output_filenames_obj_dir( make, make->object_files[arch] );
ba50573f9 Jace*3439     if (link_arch != arch) output_filenames_obj_dir( make, make->object_files[link_arch] );
6c65fb9cb Alex*3440     output_filenames_obj_dir( make, make->res_files[arch] );
4eb9ad983 Alex*3441     output_filenames( dep_libs );
                3442     output_filename( tools_path( make, "winebuild" ));
                3443     output_filename( tools_path( make, "winegcc" ));
                3444     output( "\n" );
ba50573f9 Jace*3445     output_winegcc_command( make, link_arch );
24d791e2e Alex*3446     if (arch) output_filename( "-Wl,--wine-builtin" );
f1ff3179a Alex*3447     if (!make->is_exe) output_filename( "-shared" );
                3448     if (spec_file) output_filename( spec_file );
1d6a41024 Alex*3449     output_filenames( make->extradllflags );
ba50573f9 Jace*3450     if (link_arch) output_filenames( get_expanded_arch_var_array( make, "EXTRADLLFLAGS", link_arch ));
cb5268c72 Alex*3451     output_filenames_obj_dir( make, make->object_files[arch] );
ba50573f9 Jace*3452     if (link_arch != arch) output_filenames_obj_dir( make, make->object_files[link_arch] );
6c65fb9cb Alex*3453     output_filenames_obj_dir( make, make->res_files[arch] );
ba50573f9 Jace*3454     debug_file = get_debug_file( make, module_name, link_arch );
e84394764 Jace*3455     if (debug_file) output_filename( strmake( "-Wl,--debug-file,%s", obj_dir_path( make, debug_file )));
4eb9ad983 Alex*3456     output_filenames( all_libs );
ba50573f9 Jace*3457     output_filename( arch_make_variable( "LDFLAGS", link_arch ));
4eb9ad983 Alex*3458     output( "\n" );
999927317 Alex*3459 
aa15f41d0 Alex*3460     if (!make->data_only && !arch && unix_lib_supported) output_fake_module( make, spec_file );
6944dc518 Alex*3461 }
b7e3c9315 Alex*3462 
6944dc518 Alex*3463 
                3464 /*******************************************************************
                3465  *         output_import_lib
                3466  */
24d791e2e Alex*3467 static void output_import_lib( struct makefile *make, unsigned int arch )
6944dc518 Alex*3468 {
                3469     char *spec_file = src_dir_path( make, replace_extension( make->module, ".dll", ".spec" ));
6a9126491 Alex*3470     const char *name = strmake( "%slib%s.a", arch_dirs[arch], make->importlib );
ba50573f9 Jace*3471     unsigned int hybrid_arch = hybrid_archs[arch];
                3472 
                3473     if (native_archs[arch]) return;
a9b5bb326 Alex*3474 
6a9126491 Alex*3475     strarray_add( &make->clean_files, name );
815e766d9 Alex*3476     if (needs_delay_lib( make, arch ))
a9e00347b Alex*3477     {
6a9126491 Alex*3478         const char *delay_name = replace_extension( name, ".a", ".delay.a" );
                3479         strarray_add( &make->clean_files, delay_name );
                3480         output( "%s ", obj_dir_path( make, delay_name ));
a9e00347b Alex*3481     }
6a9126491 Alex*3482     output( "%s: %s %s", obj_dir_path( make, name ), tools_path( make, "winebuild" ), spec_file );
7bffe6d68 Alex*3483     output_filenames_obj_dir( make, make->implib_files[arch] );
ba50573f9 Jace*3484     if (hybrid_arch) output_filenames_obj_dir( make, make->implib_files[hybrid_arch] );
a9e00347b Alex*3485     output( "\n" );
                3486     output( "\t%s%s -w --implib -o $@", cmd_prefix( "BUILD" ), tools_path( make, "winebuild" ) );
b9375920f RĂ©mi*3487     if (!delay_load_flags[arch]) output_filename( "--without-dlltool" );
ba50573f9 Jace*3488     output_filenames( target_flags[hybrid_arch ? hybrid_arch : arch] );
a9e00347b Alex*3489     if (make->is_win16) output_filename( "-m16" );
ba50573f9 Jace*3490     if (hybrid_arch) output_filenames( hybrid_target_flags[hybrid_arch] );
a9e00347b Alex*3491     output_filename( "--export" );
                3492     output_filename( spec_file );
7bffe6d68 Alex*3493     output_filenames_obj_dir( make, make->implib_files[arch] );
ba50573f9 Jace*3494     if (hybrid_arch) output_filenames_obj_dir( make, make->implib_files[hybrid_arch] );
a9e00347b Alex*3495     output( "\n" );
8d43170b9 Alex*3496 
6a9126491 Alex*3497     add_install_rule( make, make->importlib, arch, name,
9795a0191 Alex*3498                       strmake( "d%slib%s.a", arch_install_dirs[arch], make->importlib ));
a9e00347b Alex*3499 }
a9b5bb326 Alex*3500 
ee81814f2 Alex*3501 
6944dc518 Alex*3502 /*******************************************************************
                3503  *         output_unix_lib
                3504  */
                3505 static void output_unix_lib( struct makefile *make )
                3506 {
                3507     struct strarray unix_deps = empty_strarray;
dbe93c8a5 Alex*3508     struct strarray unix_libs = add_unix_libraries( make, &unix_deps );
9795a0191 Alex*3509     unsigned int arch = 0;  /* unix libs are always native */
6ee09e4d3 Alex*3510 
a3932d7de Alex*3511     if (make->disabled[arch]) return;
                3512 
718c57cab Alex*3513     strarray_add( &make->all_targets[arch], make->unixlib );
8d43170b9 Alex*3514     add_install_rule( make, make->module, arch, make->unixlib,
9795a0191 Alex*3515                       strmake( "p%s%s", arch_install_dirs[arch], make->unixlib ));
6944dc518 Alex*3516     output( "%s:", obj_dir_path( make, make->unixlib ));
                3517     output_filenames_obj_dir( make, make->unixobj_files );
                3518     output_filenames( unix_deps );
dbe93c8a5 Alex*3519     output( "\n" );
                3520     output( "\t%s$(CC) -o $@", cmd_prefix( "CCLD" ));
                3521     output_filenames( get_expanded_make_var_array( make, "UNIXLDFLAGS" ));
6944dc518 Alex*3522     output_filenames_obj_dir( make, make->unixobj_files );
                3523     output_filenames( unix_libs );
                3524     output_filename( "$(LDFLAGS)" );
                3525     output( "\n" );
4eb9ad983 Alex*3526 }
                3527 
f6479c051 Alex*3528 
4eb9ad983 Alex*3529 /*******************************************************************
                3530  *         output_static_lib
                3531  */
24d791e2e Alex*3532 static void output_static_lib( struct makefile *make, unsigned int arch )
4eb9ad983 Alex*3533 {
6a9126491 Alex*3534     const char *name = strmake( "%s%s", arch_dirs[arch], make->staticlib );
ba50573f9 Jace*3535     unsigned int hybrid_arch = hybrid_archs[arch];
                3536 
                3537     if (native_archs[arch]) return;
4eb9ad983 Alex*3538 
24d791e2e Alex*3539     strarray_add( &make->clean_files, name );
                3540     output( "%s: %s", obj_dir_path( make, name ), tools_path( make, "winebuild" ));
cb5268c72 Alex*3541     output_filenames_obj_dir( make, make->object_files[arch] );
ba50573f9 Jace*3542     if (hybrid_arch) output_filenames_obj_dir( make, make->object_files[hybrid_arch] );
24d791e2e Alex*3543     if (!arch) output_filenames_obj_dir( make, make->unixobj_files );
                3544     output( "\n" );
                3545     output( "\t%s%s -w --staticlib -o $@", cmd_prefix( "BUILD" ), tools_path( make, "winebuild" ));
ba50573f9 Jace*3546     output_filenames( target_flags[hybrid_arch ? hybrid_arch : arch] );
cb5268c72 Alex*3547     output_filenames_obj_dir( make, make->object_files[arch] );
ba50573f9 Jace*3548     if (hybrid_arch) output_filenames_obj_dir( make, make->object_files[hybrid_arch] );
24d791e2e Alex*3549     if (!arch) output_filenames_obj_dir( make, make->unixobj_files );
                3550     output( "\n" );
                3551     if (!make->extlib)
8d43170b9 Alex*3552         add_install_rule( make, make->staticlib, arch, name,
9795a0191 Alex*3553                           strmake( "d%s%s", arch_install_dirs[arch], make->staticlib ));
4eb9ad983 Alex*3554 }
908dada66 Alex*3555 
4c208c466 Alex*3556 
4eb9ad983 Alex*3557 /*******************************************************************
                3558  *         output_test_module
                3559  */
24d791e2e Alex*3560 static void output_test_module( struct makefile *make, unsigned int arch )
4eb9ad983 Alex*3561 {
6cfdd7e97 Alex*3562     char *basemodule = replace_extension( make->testdll, ".dll", "" );
                3563     char *stripped = arch_module_name( strmake( "%s_test-stripped.exe", basemodule ), arch );
                3564     char *testmodule = arch_module_name( strmake( "%s_test.exe", basemodule ), arch );
214223edc RĂ©mi*3565     struct strarray default_imports = get_default_imports( make, make->imports );
6cfdd7e97 Alex*3566     struct strarray dep_libs = empty_strarray;
                3567     struct strarray all_libs = empty_strarray;
0189cf21c Alex*3568     struct makefile *parent = get_parent_makefile( make );
83d00d328 Jace*3569     const char *debug_file;
ba50573f9 Jace*3570     unsigned int link_arch;
                3571 
                3572     if (!get_link_arch( make, arch, &link_arch )) return;
4eb9ad983 Alex*3573 
24d791e2e Alex*3574     strarray_addall( &all_libs, add_import_libs( make, &dep_libs, make->imports, IMPORT_TYPE_DIRECT, arch ) );
                3575     strarray_addall( &all_libs, add_import_libs( make, &dep_libs, default_imports, IMPORT_TYPE_DEFAULT, arch ) );
214223edc RĂ©mi*3576 
6cfdd7e97 Alex*3577     strarray_add( &make->all_targets[arch], testmodule );
                3578     strarray_add( &make->clean_files, stripped );
                3579     output( "%s:\n", obj_dir_path( make, testmodule ));
ba50573f9 Jace*3580     output_winegcc_command( make, link_arch );
1d6a41024 Alex*3581     output_filenames( make->extradllflags );
cb5268c72 Alex*3582     output_filenames_obj_dir( make, make->object_files[arch] );
ba50573f9 Jace*3583     if (link_arch != arch) output_filenames_obj_dir( make, make->object_files[link_arch] );
6c65fb9cb Alex*3584     output_filenames_obj_dir( make, make->res_files[arch] );
24d791e2e Alex*3585     if ((debug_file = get_debug_file( make, testmodule, arch )))
e84394764 Jace*3586         output_filename( strmake( "-Wl,--debug-file,%s", obj_dir_path( make, debug_file )));
4eb9ad983 Alex*3587     output_filenames( all_libs );
ba50573f9 Jace*3588     output_filename( arch_make_variable( "LDFLAGS", link_arch ));
4eb9ad983 Alex*3589     output( "\n" );
6cfdd7e97 Alex*3590     output( "%s:\n", obj_dir_path( make, stripped ));
ba50573f9 Jace*3591     output_winegcc_command( make, link_arch );
cc7c6a734 Alex*3592     output_filename( "-s" );
6cfdd7e97 Alex*3593     output_filename( strmake( "-Wb,-F,%s_test.exe", basemodule ));
1d6a41024 Alex*3594     output_filenames( make->extradllflags );
cb5268c72 Alex*3595     output_filenames_obj_dir( make, make->object_files[arch] );
ba50573f9 Jace*3596     if (link_arch != arch) output_filenames_obj_dir( make, make->object_files[link_arch] );
6c65fb9cb Alex*3597     output_filenames_obj_dir( make, make->res_files[arch] );
4eb9ad983 Alex*3598     output_filenames( all_libs );
ba50573f9 Jace*3599     output_filename( arch_make_variable( "LDFLAGS", link_arch ));
4eb9ad983 Alex*3600     output( "\n" );
6cfdd7e97 Alex*3601     output( "%s %s:", obj_dir_path( make, testmodule ), obj_dir_path( make, stripped ));
cb5268c72 Alex*3602     output_filenames_obj_dir( make, make->object_files[arch] );
ba50573f9 Jace*3603     if (link_arch != arch) output_filenames_obj_dir( make, make->object_files[link_arch] );
6c65fb9cb Alex*3604     output_filenames_obj_dir( make, make->res_files[arch] );
4eb9ad983 Alex*3605     output_filenames( dep_libs );
                3606     output_filename( tools_path( make, "winebuild" ));
                3607     output_filename( tools_path( make, "winegcc" ));
                3608     output( "\n" );
                3609 
6a9126491 Alex*3610     output( "programs/winetest/%s%s_test.res: %s\n", arch_dirs[arch], basemodule,
                3611             obj_dir_path( make, stripped ));
6cfdd7e97 Alex*3612     output( "\t%secho \"%s_test.exe TESTRES \\\"%s\\\"\" | %s -u -o $@\n", cmd_prefix( "WRC" ),
                3613             basemodule, obj_dir_path( make, stripped ), tools_path( make, "wrc" ));
8bf0f5fe6 Alex*3614 
8670876db Alex*3615     if (make->disabled[arch] || (parent && parent->disabled[arch]))
                3616     {
fec95db07 Alex*3617         make->ok_files[arch] = empty_strarray;
8670876db Alex*3618         return;
                3619     }
fec95db07 Alex*3620     output_filenames_obj_dir( make, make->ok_files[arch] );
6cfdd7e97 Alex*3621     output( ": %s", obj_dir_path( make, testmodule ));
74aa42a52 Alex*3622     if (parent)
                3623     {
a9183c7e3 Alex*3624         char *parent_module = arch_module_name( make->testdll, arch );
6cfdd7e97 Alex*3625         output_filename( obj_dir_path( parent, parent_module ));
0f62381f6 Alex*3626         if (parent->unixlib) output_filename( obj_dir_path( parent, parent->unixlib ));
74aa42a52 Alex*3627     }
1dd3051cc Alex*3628     output( "\n" );
5adb93c65 Alex*3629     output( "%s %s:", obj_dir_path( make, "check" ), obj_dir_path( make, "test" ));
fec95db07 Alex*3630     output_filenames_obj_dir( make, make->ok_files[arch] );
7715a1aae Alex*3631     output( "\n" );
5adb93c65 Alex*3632     strarray_add_uniq( &make->phony_targets, obj_dir_path( make, "check" ));
                3633     strarray_add_uniq( &make->phony_targets, obj_dir_path( make, "test" ));
                3634     output( "%s::\n", obj_dir_path( make, "testclean" ));
4eb9ad983 Alex*3635     output( "\trm -f" );
fec95db07 Alex*3636     output_filenames_obj_dir( make, make->ok_files[arch] );
4eb9ad983 Alex*3637     output( "\n" );
fec95db07 Alex*3638     strarray_addall( &make->clean_files, make->ok_files[arch] );
5adb93c65 Alex*3639     strarray_add_uniq( &make->phony_targets, obj_dir_path( make, "testclean" ));
4eb9ad983 Alex*3640 }
                3641 
                3642 
                3643 /*******************************************************************
                3644  *         output_programs
                3645  */
                3646 static void output_programs( struct makefile *make )
                3647 {
                3648     unsigned int i, j;
cb5268c72 Alex*3649     unsigned int arch = 0;  /* programs are always native */
31eb8be66 Alex*3650 
7626728b5 Alex*3651     for (i = 0; i < make->programs.count; i++)
                3652     {
da340169d Alex*3653         char *program_installed = NULL;
7626728b5 Alex*3654         char *program = strmake( "%s%s", make->programs.str[i], exe_ext );
4eb9ad983 Alex*3655         struct strarray deps = get_local_dependencies( make, make->programs.str[i], make->in_files );
90e7a7359 Alex*3656         struct strarray all_libs = get_expanded_file_local_var( make, make->programs.str[i], "LDFLAGS" );
                3657         struct strarray objs     = get_expanded_file_local_var( make, make->programs.str[i], "OBJS" );
                3658         struct strarray symlinks = get_expanded_file_local_var( make, make->programs.str[i], "SYMLINKS" );
7626728b5 Alex*3659 
cb5268c72 Alex*3660         if (!objs.count) objs = make->object_files[arch];
c82c63f58 Alex*3661         if (!strarray_exists( &all_libs, "-nodefaultlibs" ))
53e207fde Alex*3662         {
194e09bae Alex*3663             strarray_addall( &all_libs, get_expanded_make_var_array( make, "UNIX_LIBS" ));
53e207fde Alex*3664             strarray_addall( &all_libs, libs );
                3665         }
360296227 Alex*3666 
7626728b5 Alex*3667         output( "%s:", obj_dir_path( make, program ) );
                3668         output_filenames_obj_dir( make, objs );
d1578a61a Alex*3669         output_filenames( deps );
7626728b5 Alex*3670         output( "\n" );
1c2e3fc68 Alex*3671         output( "\t%s$(CC) -o $@", cmd_prefix( "CCLD" ));
7626728b5 Alex*3672         output_filenames_obj_dir( make, objs );
                3673         output_filenames( all_libs );
                3674         output_filename( "$(LDFLAGS)" );
                3675         output( "\n" );
718c57cab Alex*3676         strarray_add( &make->all_targets[arch], program );
da340169d Alex*3677 
64124815f Alex*3678         for (j = 0; j < symlinks.count; j++)
356e46a1e Alex*3679         {
64124815f Alex*3680             output( "%s: %s\n", obj_dir_path( make, symlinks.str[j] ), obj_dir_path( make, program ));
ec99ba1b2 Alex*3681             output_symlink_rule( program, obj_dir_path( make, symlinks.str[j] ), 0 );
356e46a1e Alex*3682         }
718c57cab Alex*3683         strarray_addall( &make->all_targets[arch], symlinks );
356e46a1e Alex*3684 
8d43170b9 Alex*3685         add_install_rule( make, program, arch, program_installed ? program_installed : program,
da340169d Alex*3686                           strmake( "p$(bindir)/%s", program ));
356e46a1e Alex*3687         for (j = 0; j < symlinks.count; j++)
8d43170b9 Alex*3688             add_install_rule( make, symlinks.str[j], arch, program,
356e46a1e Alex*3689                               strmake( "y$(bindir)/%s%s", symlinks.str[j], exe_ext ));
7626728b5 Alex*3690     }
4eb9ad983 Alex*3691 }
                3692 
                3693 
                3694 /*******************************************************************
                3695  *         output_subdirs
                3696  */
                3697 static void output_subdirs( struct makefile *make )
                3698 {
1dd3051cc Alex*3699     struct strarray all_targets = empty_strarray;
4eb9ad983 Alex*3700     struct strarray makefile_deps = empty_strarray;
11ecc76dd Alex*3701     struct strarray clean_files = empty_strarray;
3e6c12e7a Alex*3702     struct strarray testclean_files = empty_strarray;
1a52ba0bc Alex*3703     struct strarray distclean_files = empty_strarray;
abee72f32 Alex*3704     struct strarray distclean_dirs = empty_strarray;
1dd3051cc Alex*3705     struct strarray dependencies = empty_strarray;
f9cad1bd1 Alex*3706     struct strarray install_deps[NB_INSTALL_RULES] = { empty_strarray };
431b64599 Alex*3707     struct strarray tooldeps_deps = empty_strarray;
1dd3051cc Alex*3708     struct strarray buildtest_deps = empty_strarray;
718c57cab Alex*3709     unsigned int i, j, arch;
4eb9ad983 Alex*3710 
1dd3051cc Alex*3711     strarray_addall( &clean_files, make->clean_files );
1a52ba0bc Alex*3712     strarray_addall( &distclean_files, make->distclean_files );
718c57cab Alex*3713     for (arch = 0; arch < archs.count; arch++) strarray_addall( &all_targets, make->all_targets[arch] );
468af5bbb Alex*3714     for (i = 0; i < subdirs.count; i++)
4eb9ad983 Alex*3715     {
abee72f32 Alex*3716         struct strarray subclean = empty_strarray;
                3717         strarray_addall( &subclean, get_removable_dirs( submakes[i]->clean_files ));
                3718         strarray_addall( &subclean, get_removable_dirs( submakes[i]->distclean_files ));
b78ef40ab Alex*3719         strarray_add( &makefile_deps, src_dir_path( submakes[i], "Makefile.in" ));
468af5bbb Alex*3720         strarray_addall_uniq( &make->phony_targets, submakes[i]->phony_targets );
                3721         strarray_addall_uniq( &make->uninstall_files, submakes[i]->uninstall_files );
                3722         strarray_addall_uniq( &dependencies, submakes[i]->dependencies );
                3723         strarray_addall_path( &clean_files, submakes[i]->obj_dir, submakes[i]->clean_files );
                3724         strarray_addall_path( &distclean_files, submakes[i]->obj_dir, submakes[i]->distclean_files );
abee72f32 Alex*3725         strarray_addall_path( &distclean_dirs, submakes[i]->obj_dir, subclean );
363d078f4 Alex*3726         strarray_addall_path( &make->maintainerclean_files, submakes[i]->obj_dir, submakes[i]->maintainerclean_files );
468af5bbb Alex*3727         strarray_addall_path( &make->pot_files, submakes[i]->obj_dir, submakes[i]->pot_files );
                3728 
718c57cab Alex*3729         for (arch = 0; arch < archs.count; arch++)
8d43170b9 Alex*3730         {
                3731             if (submakes[i]->disabled[arch]) continue;
718c57cab Alex*3732             strarray_addall_path( &all_targets, submakes[i]->obj_dir, submakes[i]->all_targets[arch] );
fec95db07 Alex*3733             strarray_addall_path( &testclean_files, submakes[i]->obj_dir, submakes[i]->ok_files[arch] );
8d43170b9 Alex*3734         }
                3735         if (submakes[i]->disabled[0]) continue;
                3736 
363d078f4 Alex*3737         strarray_addall_path( &all_targets, submakes[i]->obj_dir, submakes[i]->font_files );
468af5bbb Alex*3738         if (!strcmp( submakes[i]->obj_dir, "tools" ) || !strncmp( submakes[i]->obj_dir, "tools/", 6 ))
                3739             strarray_add( &tooldeps_deps, obj_dir_path( submakes[i], "all" ));
                3740         if (submakes[i]->testdll)
                3741             strarray_add( &buildtest_deps, obj_dir_path( submakes[i], "all" ));
f9cad1bd1 Alex*3742         for (j = 0; j < NB_INSTALL_RULES; j++)
                3743             if (submakes[i]->install_rules[j].count)
                3744                 strarray_add( &install_deps[j], obj_dir_path( submakes[i], install_targets[j] ));
4eb9ad983 Alex*3745     }
1dd3051cc Alex*3746     strarray_addall( &dependencies, makefile_deps );
e91304e41 Alex*3747     output( "all:" );
1dd3051cc Alex*3748     output_filenames( all_targets );
e91304e41 Alex*3749     output( "\n" );
4eb9ad983 Alex*3750     output( "Makefile:" );
                3751     output_filenames( makefile_deps );
                3752     output( "\n" );
1dd3051cc Alex*3753     output_filenames( dependencies );
4eb9ad983 Alex*3754     output( ":\n" );
f9cad1bd1 Alex*3755     for (j = 0; j < NB_INSTALL_RULES; j++)
431b64599 Alex*3756     {
f9cad1bd1 Alex*3757         if (!install_deps[j].count) continue;
dbb55ed91 Alex*3758         if (strcmp( install_targets[j], "install-test" ))
                3759         {
                3760             output( "install " );
                3761             strarray_add_uniq( &make->phony_targets, "install" );
                3762         }
                3763         output( "%s::", install_targets[j] );
f9cad1bd1 Alex*3764         output_filenames( install_deps[j] );
431b64599 Alex*3765         output( "\n" );
f9cad1bd1 Alex*3766         strarray_add_uniq( &make->phony_targets, install_targets[j] );
1dd3051cc Alex*3767     }
                3768     output_uninstall_rules( make );
                3769     if (buildtest_deps.count)
                3770     {
                3771         output( "buildtests:" );
                3772         output_filenames( buildtest_deps );
5aa0144ec Alex*3773         output( "\n" );
1dd3051cc Alex*3774         strarray_add_uniq( &make->phony_targets, "buildtests" );
e91304e41 Alex*3775     }
1dd3051cc Alex*3776     output( "check test:" );
                3777     output_filenames( testclean_files );
                3778     output( "\n" );
                3779     strarray_add_uniq( &make->phony_targets, "check" );
                3780     strarray_add_uniq( &make->phony_targets, "test" );
2fa7ae05f Alex*3781 
363d078f4 Alex*3782     if (get_expanded_make_variable( make, "GETTEXTPO_LIBS" )) output_po_files( make );
                3783 
11ecc76dd Alex*3784     output( "clean::\n");
abee72f32 Alex*3785     output_rm_filenames( clean_files, "rm -f" );
3e6c12e7a Alex*3786     output( "testclean::\n");
abee72f32 Alex*3787     output_rm_filenames( testclean_files, "rm -f" );
4eb9ad983 Alex*3788     output( "distclean::\n");
abee72f32 Alex*3789     output_rm_filenames( distclean_files, "rm -f" );
                3790     output_rm_filenames( distclean_dirs, "-rmdir 2>/dev/null" );
363d078f4 Alex*3791     output( "maintainer-clean::\n");
abee72f32 Alex*3792     output_rm_filenames( make->maintainerclean_files, "rm -f" );
1dd3051cc Alex*3793     strarray_add_uniq( &make->phony_targets, "distclean" );
                3794     strarray_add_uniq( &make->phony_targets, "testclean" );
363d078f4 Alex*3795     strarray_add_uniq( &make->phony_targets, "maintainer-clean" );
1dd3051cc Alex*3796 
                3797     if (tooldeps_deps.count)
4eb9ad983 Alex*3798     {
1dd3051cc Alex*3799         output( "__tooldeps__:" );
                3800         output_filenames( tooldeps_deps );
4eb9ad983 Alex*3801         output( "\n" );
1dd3051cc Alex*3802         strarray_add_uniq( &make->phony_targets, "__tooldeps__" );
4eb9ad983 Alex*3803     }
1dd3051cc Alex*3804 
                3805     if (make->phony_targets.count)
                3806     {
                3807         output( ".PHONY:" );
                3808         output_filenames( make->phony_targets );
                3809         output( "\n" );
                3810     }
4eb9ad983 Alex*3811 }
                3812 
                3813 
                3814 /*******************************************************************
                3815  *         output_sources
                3816  */
1a52ba0bc Alex*3817 static void output_sources( struct makefile *make )
4eb9ad983 Alex*3818 {
1dd3051cc Alex*3819     struct strarray all_targets = empty_strarray;
4eb9ad983 Alex*3820     struct incl_file *source;
b1f59bc67 Alex*3821     unsigned int i, j, arch;
4eb9ad983 Alex*3822 
5adb93c65 Alex*3823     strarray_add_uniq( &make->phony_targets, "all" );
4eb9ad983 Alex*3824 
                3825     LIST_FOR_EACH_ENTRY( source, &make->sources, struct incl_file, entry )
                3826     {
                3827         char *obj = xstrdup( source->name );
                3828         char *ext = get_extension( obj );
                3829 
                3830         if (!ext) fatal_error( "unsupported file type %s\n", source->name );
                3831         *ext++ = 0;
                3832 
                3833         for (j = 0; output_source_funcs[j].ext; j++)
                3834             if (!strcmp( ext, output_source_funcs[j].ext )) break;
                3835 
                3836         output_source_funcs[j].fn( make, source, obj );
51b57133c Alex*3837         strarray_addall_uniq( &make->dependencies, source->dependencies );
4eb9ad983 Alex*3838     }
                3839 
acc6306bc Alex*3840     /* special case for winetest: add resource files from other test dirs */
468af5bbb Alex*3841     if (make->obj_dir && !strcmp( make->obj_dir, "programs/winetest" ))
acc6306bc Alex*3842     {
b1f59bc67 Alex*3843         for (arch = 0; arch < archs.count; arch++)
8d43170b9 Alex*3844         {
b1f59bc67 Alex*3845             if (!is_multiarch( arch )) continue;
                3846             for (i = 0; i < subdirs.count; i++)
                3847             {
                3848                 if (!submakes[i]->testdll) continue;
                3849                 if (submakes[i]->disabled[arch]) continue;
                3850                 if (enable_tests.count && !strarray_exists( &enable_tests, submakes[i]->testdll )) continue;
                3851                 strarray_add( &make->res_files[arch],
                3852                               strmake( "%s%s", arch_dirs[arch],
                3853                                        replace_extension( submakes[i]->testdll, ".dll", "_test.res" )));
                3854             }
8d43170b9 Alex*3855         }
acc6306bc Alex*3856     }
                3857 
4eb9ad983 Alex*3858     if (make->dlldata_files.count)
                3859     {
                3860         output( "%s: %s %s\n", obj_dir_path( make, "dlldata.c" ),
                3861                 tools_path( make, "widl" ), src_dir_path( make, "Makefile.in" ));
1a16b9e9a Alex*3862         output( "\t%s%s --dlldata-only -o $@", cmd_prefix( "WIDL" ), tools_path( make, "widl" ));
4eb9ad983 Alex*3863         output_filenames( make->dlldata_files );
                3864         output( "\n" );
                3865     }
                3866 
24d791e2e Alex*3867     if (make->staticlib)
                3868     {
b1f59bc67 Alex*3869         for (arch = 0; arch < archs.count; arch++)
56fe04085 Alex*3870             if (is_multiarch( arch ) || (so_dll_supported && !make->extlib))
                3871                 output_static_lib( make, arch );
24d791e2e Alex*3872     }
6944dc518 Alex*3873     else if (make->module)
                3874     {
56fe04085 Alex*3875         for (arch = 0; arch < archs.count; arch++)
                3876         {
                3877             if (is_multiarch( arch )) output_module( make, arch );
                3878             if (make->importlib && (is_multiarch( arch ) || !is_native_arch_disabled( make )))
                3879                 output_import_lib( make, arch );
                3880         }
6944dc518 Alex*3881         if (make->unixlib) output_unix_lib( make );
fa732145b Alex*3882         if (make->is_exe && !make->is_win16 && unix_lib_supported && strendswith( make->module, ".exe" ))
24d791e2e Alex*3883         {
b1f59bc67 Alex*3884             char *binary = replace_extension( make->module, ".exe", "" );
                3885             add_install_rule( make, binary, 0, "wineapploader", strmake( "t$(bindir)/%s", binary ));
24d791e2e Alex*3886         }
6944dc518 Alex*3887     }
b1f59bc67 Alex*3888     else if (make->testdll)
                3889     {
                3890         for (arch = 0; arch < archs.count; arch++)
                3891             if (is_multiarch( arch )) output_test_module( make, arch );
                3892     }
f689c723a Alex*3893     else if (make->programs.count) output_programs( make );
7626728b5 Alex*3894 
5cd339597 Alex*3895     for (i = 0; i < make->scripts.count; i++)
8d43170b9 Alex*3896         add_install_rule( make, make->scripts.str[i], 0, make->scripts.str[i],
5cd339597 Alex*3897                           strmake( "S$(bindir)/%s", make->scripts.str[i] ));
                3898 
96e5ac876 Alex*3899     for (i = 0; i < make->extra_targets.count; i++)
                3900         if (strarray_exists( &make->dependencies, obj_dir_path( make, make->extra_targets.str[i] )))
                3901             strarray_add( &make->clean_files, make->extra_targets.str[i] );
                3902         else
718c57cab Alex*3903             strarray_add( &make->all_targets[0], make->extra_targets.str[i] );
96e5ac876 Alex*3904 
1a52ba0bc Alex*3905     if (!make->src_dir) strarray_add( &make->distclean_files, ".gitignore" );
                3906     strarray_add( &make->distclean_files, "Makefile" );
                3907     if (make->testdll) strarray_add( &make->distclean_files, "testlist.c" );
                3908 
468af5bbb Alex*3909     if (!make->obj_dir)
1a52ba0bc Alex*3910         strarray_addall( &make->distclean_files, get_expanded_make_var_array( make, "CONFIGURE_TARGETS" ));
468af5bbb Alex*3911     else if (!strcmp( make->obj_dir, "po" ))
1a52ba0bc Alex*3912         strarray_add( &make->distclean_files, "LINGUAS" );
                3913 
cb5268c72 Alex*3914     for (arch = 0; arch < archs.count; arch++)
                3915     {
                3916         strarray_addall_uniq( &make->clean_files, make->object_files[arch] );
7bffe6d68 Alex*3917         strarray_addall_uniq( &make->clean_files, make->implib_files[arch] );
6c65fb9cb Alex*3918         strarray_addall_uniq( &make->clean_files, make->res_files[arch] );
718c57cab Alex*3919         strarray_addall_uniq( &make->clean_files, make->all_targets[arch] );
cb5268c72 Alex*3920     }
6bce2b136 Alex*3921     strarray_addall( &make->clean_files, make->unixobj_files );
82acb284b Alex*3922     strarray_addall( &make->clean_files, make->pot_files );
83d00d328 Jace*3923     strarray_addall( &make->clean_files, make->debug_files );
8d6e91616 Alex*3924 
468af5bbb Alex*3925     if (make == top_makefile)
d5ddc93b8 Alex*3926     {
1dd3051cc Alex*3927         output_subdirs( make );
                3928         return;
                3929     }
                3930 
718c57cab Alex*3931     for (arch = 0; arch < archs.count; arch++) strarray_addall( &all_targets, make->all_targets[arch] );
1dd3051cc Alex*3932     strarray_addall( &all_targets, make->font_files );
                3933     if (all_targets.count)
                3934     {
                3935         output( "%s:", obj_dir_path( make, "all" ));
                3936         output_filenames_obj_dir( make, all_targets );
d5ddc93b8 Alex*3937         output( "\n" );
1dd3051cc Alex*3938         strarray_add_uniq( &make->phony_targets, obj_dir_path( make, "all" ));
d5ddc93b8 Alex*3939     }
f9cad1bd1 Alex*3940     for (i = 0; i < NB_INSTALL_RULES; i++) output_install_rules( make, i );
d5ddc93b8 Alex*3941 
1dd3051cc Alex*3942     if (make->clean_files.count)
3b7cc5ec9 Alex*3943     {
1dd3051cc Alex*3944         output( "%s::\n", obj_dir_path( make, "clean" ));
                3945         output( "\trm -f" );
                3946         output_filenames_obj_dir( make, make->clean_files );
3b7cc5ec9 Alex*3947         output( "\n" );
1dd3051cc Alex*3948         strarray_add( &make->phony_targets, obj_dir_path( make, "clean" ));
3b7cc5ec9 Alex*3949     }
3db94ef2e Alex*3950 }
                3951 
                3952 
c31a36412 Alex*3953 /*******************************************************************
                3954  *         create_temp_file
                3955  */
8aa529417 Alex*3956 static FILE *create_temp_file( const char *orig )
c31a36412 Alex*3957 {
3bcad54fc Alex*3958     char *name = xmalloc( strlen(orig) + 13 );
c31a36412 Alex*3959     unsigned int i, id = getpid();
                3960     int fd;
                3961     FILE *ret = NULL;
                3962 
                3963     for (i = 0; i < 100; i++)
                3964     {
c17d1adb6 Bren*3965         snprintf( name, strlen(orig) + 13, "%s.tmp%08x", orig, id );
3e50aaf20 Paul*3966         if ((fd = open( name, O_RDWR | O_CREAT | O_EXCL, 0666 )) != -1)
c31a36412 Alex*3967         {
                3968             ret = fdopen( fd, "w" );
                3969             break;
                3970         }
                3971         if (errno != EEXIST) break;
                3972         id += 7777;
                3973     }
3bcad54fc Alex*3974     if (!ret) fatal_error( "failed to create output file for '%s'\n", orig );
8aa529417 Alex*3975     temp_file_name = name;
c31a36412 Alex*3976     return ret;
                3977 }
                3978 
                3979 
3bcad54fc Alex*3980 /*******************************************************************
                3981  *         rename_temp_file
                3982  */
8aa529417 Alex*3983 static void rename_temp_file( const char *dest )
3bcad54fc Alex*3984 {
8aa529417 Alex*3985     int ret = rename( temp_file_name, dest );
3bcad54fc Alex*3986     if (ret == -1 && errno == EEXIST)
                3987     {
                3988         /* rename doesn't overwrite on windows */
                3989         unlink( dest );
8aa529417 Alex*3990         ret = rename( temp_file_name, dest );
3bcad54fc Alex*3991     }
8aa529417 Alex*3992     if (ret == -1) fatal_error( "failed to rename output file to '%s'\n", dest );
                3993     temp_file_name = NULL;
3bcad54fc Alex*3994 }
                3995 
                3996 
3bae3c651 Alex*3997 /*******************************************************************
                3998  *         are_files_identical
                3999  */
                4000 static int are_files_identical( FILE *file1, FILE *file2 )
                4001 {
                4002     for (;;)
                4003     {
                4004         char buffer1[8192], buffer2[8192];
                4005         int size1 = fread( buffer1, 1, sizeof(buffer1), file1 );
                4006         int size2 = fread( buffer2, 1, sizeof(buffer2), file2 );
                4007         if (size1 != size2) return 0;
                4008         if (!size1) return feof( file1 ) && feof( file2 );
                4009         if (memcmp( buffer1, buffer2, size1 )) return 0;
                4010     }
                4011 }
                4012 
                4013 
                4014 /*******************************************************************
                4015  *         rename_temp_file_if_changed
                4016  */
                4017 static void rename_temp_file_if_changed( const char *dest )
                4018 {
                4019     FILE *file1, *file2;
                4020     int do_rename = 1;
                4021 
                4022     if ((file1 = fopen( dest, "r" )))
                4023     {
                4024         if ((file2 = fopen( temp_file_name, "r" )))
                4025         {
                4026             do_rename = !are_files_identical( file1, file2 );
                4027             fclose( file2 );
                4028         }
                4029         fclose( file1 );
                4030     }
                4031     if (!do_rename)
                4032     {
                4033         unlink( temp_file_name );
                4034         temp_file_name = NULL;
                4035     }
                4036     else rename_temp_file( dest );
                4037 }
                4038 
                4039 
f7a239a50 Alex*4040 /*******************************************************************
                4041  *         output_linguas
                4042  */
                4043 static void output_linguas( const struct makefile *make )
                4044 {
468af5bbb Alex*4045     const char *dest = obj_dir_path( make, "LINGUAS" );
f7a239a50 Alex*4046     struct incl_file *source;
                4047 
                4048     output_file = create_temp_file( dest );
                4049 
                4050     output( "# Automatically generated by make depend; DO NOT EDIT!!\n" );
                4051     LIST_FOR_EACH_ENTRY( source, &make->sources, struct incl_file, entry )
                4052         if (strendswith( source->name, ".po" ))
                4053             output( "%s\n", replace_extension( source->name, ".po", "" ));
                4054 
                4055     if (fclose( output_file )) fatal_perror( "write" );
                4056     output_file = NULL;
                4057     rename_temp_file_if_changed( dest );
                4058 }
                4059 
                4060 
3bae3c651 Alex*4061 /*******************************************************************
                4062  *         output_testlist
                4063  */
da9381cea Alex*4064 static void output_testlist( const struct makefile *make )
3bae3c651 Alex*4065 {
468af5bbb Alex*4066     const char *dest = obj_dir_path( make, "testlist.c" );
da9381cea Alex*4067     unsigned int i;
                4068 
3bae3c651 Alex*4069     output_file = create_temp_file( dest );
                4070 
                4071     output( "/* Automatically generated by make depend; DO NOT EDIT!! */\n\n" );
                4072     output( "#define WIN32_LEAN_AND_MEAN\n" );
                4073     output( "#include <windows.h>\n\n" );
                4074     output( "#define STANDALONE\n" );
                4075     output( "#include \"wine/test.h\"\n\n" );
                4076 
859338a4d Alex*4077     for (i = 0; i < make->test_files.count; i++)
                4078         output( "extern void func_%s(void);\n", make->test_files.str[i] );
3bae3c651 Alex*4079     output( "\n" );
                4080     output( "const struct test winetest_testlist[] =\n" );
                4081     output( "{\n" );
859338a4d Alex*4082     for (i = 0; i < make->test_files.count; i++)
                4083         output( "    { \"%s\", func_%s },\n", make->test_files.str[i], make->test_files.str[i] );
3bae3c651 Alex*4084     output( "    { 0, 0 }\n" );
                4085     output( "};\n" );
                4086 
                4087     if (fclose( output_file )) fatal_perror( "write" );
                4088     output_file = NULL;
                4089     rename_temp_file_if_changed( dest );
                4090 }
                4091 
                4092 
3bcad54fc Alex*4093 /*******************************************************************
                4094  *         output_gitignore
                4095  */
3bae3c651 Alex*4096 static void output_gitignore( const char *dest, struct strarray files )
3bcad54fc Alex*4097 {
e5041acfa Stef*4098     unsigned int i;
3bcad54fc Alex*4099 
8aa529417 Alex*4100     output_file = create_temp_file( dest );
3bcad54fc Alex*4101 
                4102     output( "# Automatically generated by make depend; DO NOT EDIT!!\n" );
3bae3c651 Alex*4103     for (i = 0; i < files.count; i++)
3bcad54fc Alex*4104     {
3bae3c651 Alex*4105         if (!strchr( files.str[i], '/' )) output( "/" );
                4106         output( "%s\n", files.str[i] );
3bcad54fc Alex*4107     }
                4108 
8aa529417 Alex*4109     if (fclose( output_file )) fatal_perror( "write" );
3bcad54fc Alex*4110     output_file = NULL;
8aa529417 Alex*4111     rename_temp_file( dest );
3bcad54fc Alex*4112 }
                4113 
                4114 
ef557a8a8 Alex*4115 /*******************************************************************
1dd3051cc Alex*4116  *         output_stub_makefile
ef557a8a8 Alex*4117  */
1dd3051cc Alex*4118 static void output_stub_makefile( struct makefile *make )
ef557a8a8 Alex*4119 {
1dd3051cc Alex*4120     struct strarray targets = empty_strarray;
                4121     const char *make_var = strarray_get_value( &top_makefile->vars, "MAKE" );
718c57cab Alex*4122     unsigned int i, arch;
1dd3051cc Alex*4123 
718c57cab Alex*4124     for (arch = 0; arch < archs.count; arch++)
                4125         if (make->all_targets[arch].count) strarray_add_uniq( &targets, "all" );
                4126 
f9cad1bd1 Alex*4127     for (i = 0; i < NB_INSTALL_RULES; i++)
                4128     {
                4129         if (!make->install_rules[i].count) continue;
                4130         strarray_add_uniq( &targets, "install" );
                4131         strarray_add( &targets, install_targets[i] );
                4132     }
1dd3051cc Alex*4133     if (make->clean_files.count) strarray_add( &targets, "clean" );
859338a4d Alex*4134     if (make->test_files.count)
8f57dfedf Alex*4135     {
1dd3051cc Alex*4136         strarray_add( &targets, "check" );
                4137         strarray_add( &targets, "test" );
                4138         strarray_add( &targets, "testclean" );
8f57dfedf Alex*4139     }
1dd3051cc Alex*4140 
a3932d7de Alex*4141     if (!targets.count && !make->clean_files.count) return;
                4142 
                4143     output_file_name = obj_dir_path( make, "Makefile" );
                4144     output_file = create_temp_file( output_file_name );
                4145 
                4146     output( "# Auto-generated stub makefile; all rules forward to the top-level makefile\n\n" );
                4147 
                4148     if (make_var) output( "MAKE = %s\n\n", make_var );
                4149 
                4150     output( "all:\n" );
1dd3051cc Alex*4151     output_filenames( targets );
aabd2b54b Alex*4152     output_filenames( make->clean_files );
1dd3051cc Alex*4153     output( ":\n" );
                4154     output( "\t@cd %s && $(MAKE) %s/$@\n", get_relative_path( make->obj_dir, "" ), make->obj_dir );
                4155     output( ".PHONY:" );
                4156     output_filenames( targets );
ef557a8a8 Alex*4157     output( "\n" );
b78ef40ab Alex*4158 
                4159     fclose( output_file );
                4160     output_file = NULL;
                4161     rename_temp_file( output_file_name );
ef557a8a8 Alex*4162 }
                4163 
                4164 
1a16b9e9a Alex*4165 /*******************************************************************
                4166  *         output_silent_rules
                4167  */
                4168 static void output_silent_rules(void)
                4169 {
                4170     static const char *cmds[] =
                4171     {
                4172         "BISON",
                4173         "BUILD",
                4174         "CC",
                4175         "CCLD",
                4176         "FLEX",
                4177         "GEN",
                4178         "LN",
                4179         "MSG",
                4180         "SED",
                4181         "TEST",
                4182         "WIDL",
                4183         "WMC",
                4184         "WRC"
                4185     };
                4186     unsigned int i;
                4187 
                4188     output( "V = 0\n" );
43eccadce Mich*4189     for (i = 0; i < ARRAY_SIZE(cmds); i++)
1a16b9e9a Alex*4190     {
                4191         output( "quiet_%s = $(quiet_%s_$(V))\n", cmds[i], cmds[i] );
                4192         output( "quiet_%s_0 = @echo \"  %-5s \" $@;\n", cmds[i], cmds[i] );
                4193         output( "quiet_%s_1 =\n", cmds[i] );
                4194     }
                4195 }
                4196 
                4197 
530ee8407 Alex*4198 /*******************************************************************
b78ef40ab Alex*4199  *         output_top_makefile
530ee8407 Alex*4200  */
b78ef40ab Alex*4201 static void output_top_makefile( struct makefile *make )
530ee8407 Alex*4202 {
6222e49c3 Alex*4203     char buffer[1024];
ef557a8a8 Alex*4204     FILE *src_file;
e5041acfa Stef*4205     unsigned int i;
                4206     int found = 0;
530ee8407 Alex*4207 
468af5bbb Alex*4208     output_file_name = obj_dir_path( make, output_makefile_name );
6222e49c3 Alex*4209     output_file = create_temp_file( output_file_name );
c31a36412 Alex*4210 
6222e49c3 Alex*4211     /* copy the contents of the source makefile */
e0b1e8154 Alex*4212     src_file = open_input_makefile( make );
8f57dfedf Alex*4213     while (fgets( buffer, sizeof(buffer), src_file ) && !found)
                4214     {
6222e49c3 Alex*4215         if (fwrite( buffer, 1, strlen(buffer), output_file ) != strlen(buffer)) fatal_perror( "write" );
8f57dfedf Alex*4216         found = !strncmp( buffer, separator, strlen(separator) );
                4217     }
6222e49c3 Alex*4218     if (fclose( src_file )) fatal_perror( "close" );
e0b1e8154 Alex*4219     input_file_name = NULL;
c3aa49529 Alex*4220 
8f57dfedf Alex*4221     if (!found) output( "\n%s (everything below this line is auto-generated; DO NOT EDIT!!)\n", separator );
1dd3051cc Alex*4222 
b78ef40ab Alex*4223     if (silent_rules) output_silent_rules();
                4224     for (i = 0; i < subdirs.count; i++) output_sources( submakes[i] );
                4225     output_sources( make );
52dc0ccf6 Zebe*4226     /* disable implicit rules */
                4227     output( ".SUFFIXES:\n" );
                4228 
c3aa49529 Alex*4229     fclose( output_file );
                4230     output_file = NULL;
6222e49c3 Alex*4231     rename_temp_file( output_file_name );
b78ef40ab Alex*4232 }
                4233 
                4234 
                4235 /*******************************************************************
                4236  *         output_dependencies
                4237  */
                4238 static void output_dependencies( struct makefile *make )
                4239 {
                4240     struct strarray ignore_files = empty_strarray;
                4241 
                4242     if (make->obj_dir) create_dir( make->obj_dir );
                4243 
                4244     if (make == top_makefile) output_top_makefile( make );
                4245     else output_stub_makefile( make );
3bcad54fc Alex*4246 
1a52ba0bc Alex*4247     strarray_addall( &ignore_files, make->distclean_files );
                4248     strarray_addall( &ignore_files, make->clean_files );
                4249     if (make->testdll) output_testlist( make );
468af5bbb Alex*4250     if (make->obj_dir && !strcmp( make->obj_dir, "po" )) output_linguas( make );
                4251     if (!make->src_dir) output_gitignore( obj_dir_path( make, ".gitignore" ), ignore_files );
6222e49c3 Alex*4252 
1a52ba0bc Alex*4253     create_file_directories( make, ignore_files );
f17419ec4 Alex*4254 
6222e49c3 Alex*4255     output_file_name = NULL;
1928d6114 Alex*4256 }
                4257 
                4258 
                4259 /*******************************************************************
8f57dfedf Alex*4260  *         load_sources
1928d6114 Alex*4261  */
8f57dfedf Alex*4262 static void load_sources( struct makefile *make )
1928d6114 Alex*4263 {
8d43170b9 Alex*4264     unsigned int i, arch;
1928d6114 Alex*4265     struct strarray value;
                4266     struct incl_file *file;
                4267 
468af5bbb Alex*4268     strarray_set_value( &make->vars, "top_srcdir", root_src_dir_path( "" ));
f9ddafa80 Alex*4269     strarray_set_value( &make->vars, "srcdir", src_dir_path( make, "" ));
228684d34 Alex*4270 
f9ddafa80 Alex*4271     make->parent_dir    = get_expanded_make_variable( make, "PARENTSRC" );
                4272     make->module        = get_expanded_make_variable( make, "MODULE" );
                4273     make->testdll       = get_expanded_make_variable( make, "TESTDLL" );
                4274     make->staticlib     = get_expanded_make_variable( make, "STATICLIB" );
                4275     make->importlib     = get_expanded_make_variable( make, "IMPORTLIB" );
a4b01382e Alex*4276     make->extlib        = get_expanded_make_variable( make, "EXTLIB" );
fa732145b Alex*4277     if (unix_lib_supported) make->unixlib = get_expanded_make_variable( make, "UNIXLIB" );
081df721d Alex*4278 
7626728b5 Alex*4279     make->programs      = get_expanded_make_var_array( make, "PROGRAMS" );
5cd339597 Alex*4280     make->scripts       = get_expanded_make_var_array( make, "SCRIPTS" );
f9ddafa80 Alex*4281     make->imports       = get_expanded_make_var_array( make, "IMPORTS" );
                4282     make->delayimports  = get_expanded_make_var_array( make, "DELAYIMPORTS" );
                4283     make->extradllflags = get_expanded_make_var_array( make, "EXTRADLLFLAGS" );
cb078bd3b Alex*4284     make->extra_targets = get_expanded_make_var_array( make, "EXTRA_TARGETS" );
f9cad1bd1 Alex*4285     for (i = 0; i < NB_INSTALL_RULES; i++)
                4286         make->install[i] = get_expanded_make_var_array( make, install_variables[i] );
081df721d Alex*4287 
a4b01382e Alex*4288     if (make->extlib) make->staticlib = make->extlib;
518f9a12c Alex*4289     if (make->staticlib) make->module = make->staticlib;
2477aa7a1 Alex*4290 
8d43170b9 Alex*4291     if (make->obj_dir)
                4292     {
b1f59bc67 Alex*4293         make->disabled[0] = strarray_exists( &disabled_dirs[0], make->obj_dir );
8d43170b9 Alex*4294         for (arch = 1; arch < archs.count; arch++)
b1f59bc67 Alex*4295             make->disabled[arch] = make->disabled[0] || strarray_exists( &disabled_dirs[arch], make->obj_dir );
8d43170b9 Alex*4296     }
088a787a2 Alex*4297     make->is_win16   = strarray_exists( &make->extradllflags, "-m16" );
1c2e3fc68 Alex*4298     make->data_only  = strarray_exists( &make->extradllflags, "-Wb,--data-only" );
1d6a41024 Alex*4299     make->is_exe     = strarray_exists( &make->extradllflags, "-mconsole" ) ||
                4300                        strarray_exists( &make->extradllflags, "-mwindows" );
299ce6f9f Alex*4301 
f9cad1bd1 Alex*4302     if (make->module)
e0d89a495 Alex*4303     {
f9cad1bd1 Alex*4304         /* add default install rules if nothing was specified */
                4305         for (i = 0; i < NB_INSTALL_RULES; i++) if (make->install[i].count) break;
                4306         if (i == NB_INSTALL_RULES)
                4307         {
                4308             if (make->importlib) strarray_add( &make->install[INSTALL_DEV], make->importlib );
                4309             if (make->staticlib) strarray_add( &make->install[INSTALL_DEV], make->staticlib );
                4310             else strarray_add( &make->install[INSTALL_LIB], make->module );
                4311         }
e0d89a495 Alex*4312     }
da340169d Alex*4313 
acd9c551b Alex*4314     make->include_paths = empty_strarray;
4eb9ad983 Alex*4315     make->include_args = empty_strarray;
228684d34 Alex*4316     make->define_args = empty_strarray;
194e09bae Alex*4317     make->unix_cflags = empty_strarray;
a4b01382e Alex*4318     if (!make->extlib) strarray_add( &make->define_args, "-D__WINESRC__" );
912fd620d Alex*4319     strarray_add( &make->unix_cflags, "-DWINE_UNIX_LIB" );
1a74fdbce Alex*4320 
f9ddafa80 Alex*4321     value = get_expanded_make_var_array( make, "EXTRAINCL" );
1928d6114 Alex*4322     for (i = 0; i < value.count; i++)
e2d96342d Alex*4323     {
1928d6114 Alex*4324         if (!strncmp( value.str[i], "-I", 2 ))
e2d96342d Alex*4325         {
                4326             const char *dir = value.str[i] + 2;
                4327             if (!strncmp( dir, "./", 2 ))
                4328             {
                4329                 dir += 2;
                4330                 while (*dir == '/') dir++;
                4331             }
                4332             strarray_add_uniq( &make->include_paths, dir );
                4333         }
4f04994ef Alex*4334         else if (!strncmp( value.str[i], "-D", 2 ) || !strncmp( value.str[i], "-U", 2 ))
228684d34 Alex*4335             strarray_add_uniq( &make->define_args, value.str[i] );
e2d96342d Alex*4336     }
f9ddafa80 Alex*4337     strarray_addall( &make->define_args, get_expanded_make_var_array( make, "EXTRADEFS" ));
194e09bae Alex*4338     strarray_addall_uniq( &make->unix_cflags, get_expanded_make_var_array( make, "UNIX_CFLAGS" ));
1928d6114 Alex*4339 
4eb9ad983 Alex*4340     strarray_add( &make->include_args, strmake( "-I%s", obj_dir_path( make, "" )));
                4341     if (make->src_dir)
                4342         strarray_add( &make->include_args, strmake( "-I%s", make->src_dir ));
                4343     if (make->parent_dir)
                4344         strarray_add( &make->include_args, strmake( "-I%s", src_dir_path( make, make->parent_dir )));
468af5bbb Alex*4345     strarray_add( &make->include_args, "-Iinclude" );
                4346     if (root_src_dir) strarray_add( &make->include_args, strmake( "-I%s", root_src_dir_path( "include" )));
4eb9ad983 Alex*4347 
4cb68d232 Alex*4348     list_init( &make->sources );
c6ba107a4 Alex*4349     list_init( &make->includes );
1928d6114 Alex*4350 
440771ed4 Alex*4351     value = get_expanded_make_var_array( make, "SOURCES" );
                4352     for (i = 0; i < value.count; i++) add_src_file( make, value.str[i] );
1928d6114 Alex*4353 
f9ddafa80 Alex*4354     add_generated_sources( make );
47c0f64fd Alex*4355 
0959d189c Jace*4356     LIST_FOR_EACH_ENTRY( file, &make->includes, struct incl_file, entry ) parse_file( make, file, 0 );
                4357     LIST_FOR_EACH_ENTRY( file, &make->sources, struct incl_file, entry ) get_dependencies( file, file );
                4358 
b1f59bc67 Alex*4359     for (i = 0; i < make->delayimports.count; i++)
                4360         strarray_add_uniq( &delay_import_libs, get_base_name( make->delayimports.str[i] ));
530ee8407 Alex*4361 }
                4362 
                4363 
cab558b4b Alex*4364 /*******************************************************************
                4365  *         parse_makeflags
                4366  */
                4367 static void parse_makeflags( const char *flags )
                4368 {
                4369     const char *p = flags;
                4370     char *var, *buffer = xmalloc( strlen(flags) + 1 );
                4371 
                4372     while (*p)
                4373     {
df50fca0f Alex*4374         p = skip_spaces( p );
cab558b4b Alex*4375         var = buffer;
                4376         while (*p && !isspace(*p))
                4377         {
                4378             if (*p == '\\' && p[1]) p++;
                4379             *var++ = *p++;
                4380         }
                4381         *var = 0;
                4382         if (var > buffer) set_make_variable( &cmdline_vars, buffer );
                4383     }
                4384 }
                4385 
                4386 
530ee8407 Alex*4387 /*******************************************************************
                4388  *         parse_option
                4389  */
ab8d61d29 Alex*4390 static int parse_option( const char *opt )
530ee8407 Alex*4391 {
ab8d61d29 Alex*4392     if (opt[0] != '-')
                4393     {
                4394         if (strchr( opt, '=' )) return set_make_variable( &cmdline_vars, opt );
                4395         return 0;
                4396     }
530ee8407 Alex*4397     switch(opt[1])
                4398     {
                4399     case 'f':
e0b1e8154 Alex*4400         if (opt[2]) output_makefile_name = opt + 2;
                4401         break;
067d3f0dd Alex*4402     case 'R':
                4403         relative_dir_mode = 1;
                4404         break;
1a16b9e9a Alex*4405     case 'S':
                4406         silent_rules = 1;
                4407         break;
530ee8407 Alex*4408     default:
c3aa49529 Alex*4409         fprintf( stderr, "Unknown option '%s'\n%s", opt, Usage );
530ee8407 Alex*4410         exit(1);
                4411     }
ab8d61d29 Alex*4412     return 1;
530ee8407 Alex*4413 }
                4414 
                4415 
ba50573f9 Jace*4416 /*******************************************************************
                4417  *         find_pe_arch
                4418  */
                4419 static unsigned int find_pe_arch( const char *arch )
                4420 {
                4421     unsigned int i;
                4422     for (i = 1; i < archs.count; i++) if (!strcmp( archs.str[i], arch )) return i;
                4423     return 0;
                4424 }
                4425 
                4426 
530ee8407 Alex*4427 /*******************************************************************
                4428  *         main
                4429  */
                4430 int main( int argc, char *argv[] )
                4431 {
cab558b4b Alex*4432     const char *makeflags = getenv( "MAKEFLAGS" );
b1f59bc67 Alex*4433     const char *target;
ba50573f9 Jace*4434     unsigned int i, j, arch, ec_arch;
530ee8407 Alex*4435 
cab558b4b Alex*4436     if (makeflags) parse_makeflags( makeflags );
                4437 
dea28ee4a Alex*4438     i = 1;
                4439     while (i < argc)
530ee8407 Alex*4440     {
ab8d61d29 Alex*4441         if (parse_option( argv[i] ))
dea28ee4a Alex*4442         {
                4443             for (j = i; j < argc; j++) argv[j] = argv[j+1];
                4444             argc--;
                4445         }
                4446         else i++;
                4447     }
                4448 
067d3f0dd Alex*4449     if (relative_dir_mode)
                4450     {
                4451         char *relpath;
                4452 
                4453         if (argc != 3)
                4454         {
029c56d75 Alex*4455             fprintf( stderr, "Option -R needs two directories\n%s", Usage );
067d3f0dd Alex*4456             exit( 1 );
                4457         }
                4458         relpath = get_relative_path( argv[1], argv[2] );
                4459         printf( "%s\n", relpath ? relpath : "." );
                4460         exit( 0 );
                4461     }
                4462 
9a542f9dd Alex*4463     if (argc > 1) fatal_error( "Directory arguments not supported in this mode\n" );
                4464 
8aa529417 Alex*4465     atexit( cleanup_files );
ae8797c8e Alex*4466     init_signals( exit_on_signal );
8aa529417 Alex*4467 
b69a0e89d Alex*4468     for (i = 0; i < HASH_SIZE; i++) list_init( &files[i] );
e31276e9a Alex*4469     for (i = 0; i < HASH_SIZE; i++) list_init( &global_includes[i] );
b69a0e89d Alex*4470 
49f88527c Alex*4471     top_makefile = parse_makefile( NULL );
f9ddafa80 Alex*4472 
afc286fb5 Alex*4473     target_flags[0]    = get_expanded_make_var_array( top_makefile, "TARGETFLAGS" );
5e0479c49 Alex*4474     msvcrt_flags       = get_expanded_make_var_array( top_makefile, "MSVCRTFLAGS" );
                4475     dll_flags          = get_expanded_make_var_array( top_makefile, "DLLFLAGS" );
                4476     unix_dllflags      = get_expanded_make_var_array( top_makefile, "UNIXDLLFLAGS" );
                4477     cpp_flags          = get_expanded_make_var_array( top_makefile, "CPPFLAGS" );
                4478     lddll_flags        = get_expanded_make_var_array( top_makefile, "LDDLLFLAGS" );
                4479     libs               = get_expanded_make_var_array( top_makefile, "LIBS" );
                4480     enable_tests       = get_expanded_make_var_array( top_makefile, "ENABLE_TESTS" );
f9cad1bd1 Alex*4481     for (i = 0; i < NB_INSTALL_RULES; i++)
                4482         top_install[i] = get_expanded_make_var_array( top_makefile, strmake( "TOP_%s", install_variables[i] ));
5e0479c49 Alex*4483 
                4484     root_src_dir       = get_expanded_make_variable( top_makefile, "srcdir" );
37c0f5c69 Alex*4485     tools_dir          = get_expanded_make_variable( top_makefile, "toolsdir" );
                4486     tools_ext          = get_expanded_make_variable( top_makefile, "toolsext" );
5e0479c49 Alex*4487     exe_ext            = get_expanded_make_variable( top_makefile, "EXEEXT" );
fa732145b Alex*4488     dll_ext[0]         = get_expanded_make_variable( top_makefile, "DLLEXT" );
5e0479c49 Alex*4489     fontforge          = get_expanded_make_variable( top_makefile, "FONTFORGE" );
                4490     convert            = get_expanded_make_variable( top_makefile, "CONVERT" );
                4491     flex               = get_expanded_make_variable( top_makefile, "FLEX" );
                4492     bison              = get_expanded_make_variable( top_makefile, "BISON" );
                4493     ar                 = get_expanded_make_variable( top_makefile, "AR" );
                4494     ranlib             = get_expanded_make_variable( top_makefile, "RANLIB" );
                4495     rsvg               = get_expanded_make_variable( top_makefile, "RSVG" );
                4496     icotool            = get_expanded_make_variable( top_makefile, "ICOTOOL" );
                4497     msgfmt             = get_expanded_make_variable( top_makefile, "MSGFMT" );
                4498     sed_cmd            = get_expanded_make_variable( top_makefile, "SED_CMD" );
                4499     ln_s               = get_expanded_make_variable( top_makefile, "LN_S" );
857001678 Alex*4500     wayland_scanner    = get_expanded_make_variable( top_makefile, "WAYLAND_SCANNER" );
391731315 Alex*4501 
8fdacd15d Alex*4502     if (root_src_dir && !strcmp( root_src_dir, "." )) root_src_dir = NULL;
391731315 Alex*4503     if (tools_dir && !strcmp( tools_dir, "." )) tools_dir = NULL;
7626728b5 Alex*4504     if (!exe_ext) exe_ext = "";
fa732145b Alex*4505     if (!dll_ext[0]) dll_ext[0] = "";
391731315 Alex*4506     if (!tools_ext) tools_ext = "";
afc286fb5 Alex*4507 
fa732145b Alex*4508     unix_lib_supported = !!strcmp( exe_ext, ".exe" );
56fe04085 Alex*4509     so_dll_supported = !!dll_ext[0][0];  /* non-empty dll ext means supported */
fa732145b Alex*4510 
b1f59bc67 Alex*4511     strarray_add( &archs, get_expanded_make_variable( top_makefile, "HOST_ARCH" ));
                4512     strarray_addall( &archs, get_expanded_make_var_array( top_makefile, "PE_ARCHS" ));
                4513 
ba50573f9 Jace*4514     /* check for ARM64X setup */
                4515     if ((ec_arch = find_pe_arch( "arm64ec" )) && (arch = find_pe_arch( "aarch64" )))
                4516     {
                4517         native_archs[ec_arch] = arch;
                4518         hybrid_archs[arch] = ec_arch;
                4519         strarray_add( &hybrid_target_flags[ec_arch], "-marm64x" );
                4520     }
                4521 
6a9126491 Alex*4522     arch_dirs[0] = "";
                4523     arch_pe_dirs[0] = strmake( "%s-windows/", archs.str[0] );
fa732145b Alex*4524     arch_install_dirs[0] = unix_lib_supported ? strmake( "$(dlldir)/%s-unix/", archs.str[0] ) : "$(dlldir)/";
afc286fb5 Alex*4525     strip_progs[0] = "\"$(STRIP)\"";
                4526 
9795a0191 Alex*4527     for (arch = 1; arch < archs.count; arch++)
                4528     {
b1f59bc67 Alex*4529         target = get_expanded_arch_var( top_makefile, "TARGET", arch );
                4530         strarray_add( &target_flags[arch], "-b" );
                4531         strarray_add( &target_flags[arch], target );
6a9126491 Alex*4532         arch_dirs[arch] = strmake( "%s-windows/", archs.str[arch] );
                4533         arch_pe_dirs[arch] = arch_dirs[arch];
                4534         arch_install_dirs[arch] = strmake( "$(dlldir)/%s", arch_dirs[arch] );
b1f59bc67 Alex*4535         strip_progs[arch] = strmake( "%s-strip", target );
fa732145b Alex*4536         dll_ext[arch] = "";
9795a0191 Alex*4537     }
                4538 
55e2335f6 Alex*4539     for (arch = 0; arch < archs.count; arch++)
                4540     {
b1f59bc67 Alex*4541         extra_cflags[arch] = get_expanded_arch_var_array( top_makefile, "EXTRACFLAGS", arch );
25735da0d Alex*4542         extra_cflags_extlib[arch] = remove_warning_flags( extra_cflags[arch] );
b1f59bc67 Alex*4543         disabled_dirs[arch] = get_expanded_arch_var_array( top_makefile, "DISABLED_SUBDIRS", arch );
55e2335f6 Alex*4544         if (!is_multiarch( arch )) continue;
b1f59bc67 Alex*4545         delay_load_flags[arch] = get_expanded_arch_var( top_makefile, "DELAYLOADFLAG", arch );
                4546         debug_flags[arch] = get_expanded_arch_var( top_makefile, "DEBUG", arch );
55e2335f6 Alex*4547     }
                4548 
fa732145b Alex*4549     if (unix_lib_supported)
55e2335f6 Alex*4550     {
815e766d9 Alex*4551         delay_load_flags[0] = "-Wl,-delayload,";
55e2335f6 Alex*4552         debug_flags[0] = NULL;
afc286fb5 Alex*4553     }
391731315 Alex*4554 
468af5bbb Alex*4555     top_makefile->src_dir = root_src_dir;
                4556     subdirs = get_expanded_make_var_array( top_makefile, "SUBDIRS" );
                4557     submakes = xmalloc( subdirs.count * sizeof(*submakes) );
8f57dfedf Alex*4558 
468af5bbb Alex*4559     for (i = 0; i < subdirs.count; i++) submakes[i] = parse_makefile( subdirs.str[i] );
8f57dfedf Alex*4560 
9a542f9dd Alex*4561     load_sources( top_makefile );
e31276e9a Alex*4562     load_sources( include_makefile );
                4563     for (i = 0; i < subdirs.count; i++)
                4564         if (submakes[i] != include_makefile) load_sources( submakes[i] );
8f57dfedf Alex*4565 
1dd3051cc Alex*4566     output_dependencies( top_makefile );
468af5bbb Alex*4567     for (i = 0; i < subdirs.count; i++) output_dependencies( submakes[i] );
8f57dfedf Alex*4568 
530ee8407 Alex*4569     return 0;
                4570 }