From 4eb9ad983ecc33d24ccf68692590605dcd02914a Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sat, 17 Feb 2018 09:53:42 +0100 Subject: [PATCH] makefiles: Split the makefile generation into multiple functions. Signed-off-by: Alexandre Julliard --- tools/makedep.c | 1751 ++++++++++++++++++++++++++--------------------- 1 file changed, 956 insertions(+), 795 deletions(-) diff --git a/tools/makedep.c b/tools/makedep.c index ec339e08114..108cb941801 100644 --- a/tools/makedep.c +++ b/tools/makedep.c @@ -35,6 +35,13 @@ #endif #include "wine/list.h" +struct strarray +{ + unsigned int count; /* strings in use */ + unsigned int size; /* total allocated size */ + const char **str; +}; + enum incl_type { INCL_NORMAL, /* #include "foo.h" */ @@ -77,6 +84,7 @@ struct incl_file unsigned int files_count; /* files in use */ unsigned int files_size; /* total allocated size */ struct incl_file **files; + struct strarray dependencies; /* file dependencies */ }; #define FLAG_GENERATED 0x000001 /* generated file */ @@ -113,13 +121,6 @@ static const struct static struct list files[HASH_SIZE]; -struct strarray -{ - unsigned int count; /* strings in use */ - unsigned int size; /* total allocated size */ - const char **str; -}; - static const struct strarray empty_strarray; enum install_rules { INSTALL_LIB, INSTALL_DEV, NB_INSTALL_RULES }; @@ -152,8 +153,10 @@ static const char *ln_s; struct makefile { + /* values determined from input makefile */ struct strarray vars; struct strarray include_paths; + struct strarray include_args; struct strarray define_args; struct strarray programs; struct strarray scripts; @@ -182,6 +185,19 @@ struct makefile int use_msvcrt; int is_win16; struct makefile **submakes; + + /* values generated at output time */ + struct strarray in_files; + struct strarray ok_files; + struct strarray clean_files; + struct strarray object_files; + struct strarray crossobj_files; + struct strarray c2man_files; + struct strarray dlldata_files; + struct strarray implib_objs; + struct strarray all_targets; + struct strarray phony_targets; + struct strarray install_rules[NB_INSTALL_RULES]; }; static struct makefile *top_makefile; @@ -1897,7 +1913,7 @@ static void output_filenames_obj_dir( const struct makefile *make, struct strarr /******************************************************************* * get_dependencies */ -static void get_dependencies( struct strarray *deps, struct incl_file *file, struct incl_file *source ) +static void get_dependencies( struct incl_file *file, struct incl_file *source ) { unsigned int i; @@ -1910,9 +1926,9 @@ static void get_dependencies( struct strarray *deps, struct incl_file *file, str !(source->file->flags & (FLAG_IDL_TYPELIB | FLAG_IDL_REGTYPELIB))) return; /* library is imported only when building a typelib */ file->owner = source; - strarray_add( deps, file->filename ); + strarray_add( &source->dependencies, file->filename ); } - for (i = 0; i < file->files_count; i++) get_dependencies( deps, file->files[i], source ); + for (i = 0; i < file->files_count; i++) get_dependencies( file->files[i], source ); } @@ -2058,18 +2074,18 @@ static struct strarray get_default_imports( const struct makefile *make ) /******************************************************************* * add_install_rule */ -static void add_install_rule( const struct makefile *make, struct strarray *install_rules, - const char *target, const char *file, const char *dest ) +static void add_install_rule( struct makefile *make, const char *target, + const char *file, const char *dest ) { if (strarray_exists( &make->install_lib, target )) { - strarray_add( &install_rules[INSTALL_LIB], file ); - strarray_add( &install_rules[INSTALL_LIB], dest ); + strarray_add( &make->install_rules[INSTALL_LIB], file ); + strarray_add( &make->install_rules[INSTALL_LIB], dest ); } else if (strarray_exists( &make->install_dev, target )) { - strarray_add( &install_rules[INSTALL_DEV], file ); - strarray_add( &install_rules[INSTALL_DEV], dest ); + strarray_add( &make->install_rules[INSTALL_DEV], file ); + strarray_add( &make->install_rules[INSTALL_DEV], dest ); } } @@ -2155,11 +2171,12 @@ static void output_symlink_rule( const char *src_name, const char *link_name ) * Rules are stored as a (file,dest) pair of values. * The first char of dest indicates the type of install. */ -static struct strarray output_install_rules( const struct makefile *make, struct strarray files, - const char *target, struct strarray *phony_targets ) +static struct strarray output_install_rules( struct makefile *make, enum install_rules rules, + const char *target ) { unsigned int i; char *install_sh; + struct strarray files = make->install_rules[rules]; struct strarray uninstall = empty_strarray; struct strarray targets = empty_strarray; @@ -2226,8 +2243,8 @@ static struct strarray output_install_rules( const struct makefile *make, struct strarray_add( &uninstall, dest ); } - strarray_add_uniq( phony_targets, "install" ); - strarray_add_uniq( phony_targets, target ); + strarray_add_uniq( &make->phony_targets, "install" ); + strarray_add_uniq( &make->phony_targets, target ); return uninstall; } @@ -2325,729 +2342,808 @@ static void output_po_files( const struct makefile *make ) /******************************************************************* - * output_sources + * output_source_y */ -static struct strarray output_sources( const struct makefile *make ) +static void output_source_y( struct makefile *make, struct incl_file *source, const char *obj ) +{ + /* add source file dependency for parallel makes */ + char *header = strmake( "%s.tab.h", obj ); + + if (find_include_file( make, header )) + { + output( "%s: %s\n", obj_dir_path( make, header ), source->filename ); + output( "\t$(BISON) -p %s_ -o %s.tab.c -d %s\n", + obj, obj_dir_path( make, obj ), source->filename ); + output( "%s.tab.c: %s %s\n", obj_dir_path( make, obj ), + source->filename, obj_dir_path( make, header )); + strarray_add( &make->clean_files, header ); + } + else output( "%s.tab.c: %s\n", obj, source->filename ); + + output( "\t$(BISON) -p %s_ -o $@ %s\n", obj, source->filename ); +} + + +/******************************************************************* + * output_source_l + */ +static void output_source_l( struct makefile *make, struct incl_file *source, const char *obj ) +{ + output( "%s.yy.c: %s\n", obj_dir_path( make, obj ), source->filename ); + output( "\t$(FLEX) -o$@ %s\n", source->filename ); +} + + +/******************************************************************* + * output_source_h + */ +static void output_source_h( struct makefile *make, struct incl_file *source, const char *obj ) +{ + if (source->file->flags & FLAG_GENERATED) + { + strarray_add( &make->all_targets, source->name ); + } + else + { + strarray_add( &make->install_rules[INSTALL_DEV], source->name ); + strarray_add( &make->install_rules[INSTALL_DEV], + strmake( "D$(includedir)/%s", get_include_install_path( source->name ) )); + } +} + + +/******************************************************************* + * output_source_rc + */ +static void output_source_rc( struct makefile *make, struct incl_file *source, const char *obj ) +{ + struct strarray extradefs = get_expanded_file_local_var( make, obj, "EXTRADEFS" ); + unsigned int i; + + strarray_add( &make->object_files, strmake( "%s.res", obj )); + if (crosstarget) strarray_add( &make->crossobj_files, strmake( "%s.res", obj )); + output( "%s.res: %s\n", obj_dir_path( make, obj ), source->filename ); + output( "\t%s -o $@", tools_path( make, "wrc" ) ); + if (make->is_win16) output_filename( "-m16" ); + else output_filenames( target_flags ); + output_filename( "--nostdinc" ); + output_filenames( make->include_args ); + output_filenames( make->define_args ); + output_filenames( extradefs ); + if (linguas.count && (source->file->flags & FLAG_RC_PO)) + { + char *po_dir = top_obj_dir_path( make, "po" ); + output_filename( strmake( "--po-dir=%s", po_dir )); + output_filename( source->filename ); + output( "\n" ); + output( "%s.res:", obj_dir_path( make, obj )); + for (i = 0; i < linguas.count; i++) + output_filename( strmake( "%s/%s.mo", po_dir, linguas.str[i] )); + output( "\n" ); + } + else + { + output_filename( source->filename ); + output( "\n" ); + } + if (source->file->flags & FLAG_RC_PO) + { + strarray_add( &make->clean_files, strmake( "%s.pot", obj )); + output( "%s.pot: %s\n", obj_dir_path( make, obj ), source->filename ); + output( "\t%s -O pot -o $@", tools_path( make, "wrc" ) ); + if (make->is_win16) output_filename( "-m16" ); + else output_filenames( target_flags ); + output_filename( "--nostdinc" ); + output_filenames( make->include_args ); + output_filenames( make->define_args ); + output_filenames( extradefs ); + output_filename( source->filename ); + output( "\n" ); + output( "%s.pot ", obj_dir_path( make, obj )); + } + output( "%s.res:", obj_dir_path( make, obj )); + output_filename( tools_path( make, "wrc" )); + output_filenames( source->dependencies ); + output( "\n" ); +} + + +/******************************************************************* + * output_source_mc + */ +static void output_source_mc( struct makefile *make, struct incl_file *source, const char *obj ) +{ + unsigned int i; + + strarray_add( &make->object_files, strmake( "%s.res", obj )); + if (crosstarget) strarray_add( &make->crossobj_files, strmake( "%s.res", obj )); + strarray_add( &make->clean_files, strmake( "%s.pot", obj )); + output( "%s.res: %s\n", obj_dir_path( make, obj ), source->filename ); + output( "\t%s -U -O res -o $@ %s", tools_path( make, "wmc" ), source->filename ); + if (linguas.count) + { + char *po_dir = top_obj_dir_path( make, "po" ); + output_filename( strmake( "--po-dir=%s", po_dir )); + output( "\n" ); + output( "%s.res:", obj_dir_path( make, obj )); + for (i = 0; i < linguas.count; i++) + output_filename( strmake( "%s/%s.mo", po_dir, linguas.str[i] )); + } + output( "\n" ); + output( "%s.pot: %s\n", obj_dir_path( make, obj ), source->filename ); + output( "\t%s -O pot -o $@ %s", tools_path( make, "wmc" ), source->filename ); + output( "\n" ); + output( "%s.pot %s.res:", obj_dir_path( make, obj ), obj_dir_path( make, obj )); + output_filename( tools_path( make, "wmc" )); + output_filenames( source->dependencies ); + output( "\n" ); +} + + +/******************************************************************* + * output_source_res + */ +static void output_source_res( struct makefile *make, struct incl_file *source, const char *obj ) +{ + strarray_add( &make->object_files, source->name ); + if (crosstarget) strarray_add( &make->crossobj_files, source->name ); +} + + +/******************************************************************* + * output_source_idl + */ +static void output_source_idl( struct makefile *make, struct incl_file *source, const char *obj ) +{ + struct strarray extradefs = get_expanded_file_local_var( make, obj, "EXTRADEFS" ); + struct strarray targets = empty_strarray; + char *dest; + unsigned int i; + + if (!source->file->flags) source->file->flags |= FLAG_IDL_HEADER | FLAG_INSTALL; + if (find_include_file( make, strmake( "%s.h", obj ))) source->file->flags |= FLAG_IDL_HEADER; + + for (i = 0; i < sizeof(idl_outputs) / sizeof(idl_outputs[0]); i++) + { + if (!(source->file->flags & idl_outputs[i].flag)) continue; + dest = strmake( "%s%s", obj, idl_outputs[i].ext ); + if (!find_src_file( make, dest )) strarray_add( &make->clean_files, dest ); + strarray_add( &targets, dest ); + } + if (source->file->flags & FLAG_IDL_PROXY) strarray_add( &make->dlldata_files, source->name ); + if (source->file->flags & FLAG_INSTALL) + { + strarray_add( &make->install_rules[INSTALL_DEV], xstrdup( source->name )); + strarray_add( &make->install_rules[INSTALL_DEV], + strmake( "D$(includedir)/%s.idl", get_include_install_path( obj ) )); + if (source->file->flags & FLAG_IDL_HEADER) + { + strarray_add( &make->install_rules[INSTALL_DEV], strmake( "%s.h", obj )); + strarray_add( &make->install_rules[INSTALL_DEV], + strmake( "d$(includedir)/%s.h", get_include_install_path( obj ) )); + } + } + if (!targets.count) return; + + output_filenames_obj_dir( make, targets ); + output( ": %s\n", tools_path( make, "widl" )); + output( "\t%s -o $@", tools_path( make, "widl" ) ); + output_filenames( target_flags ); + output_filenames( make->include_args ); + output_filenames( make->define_args ); + output_filenames( extradefs ); + output_filenames( get_expanded_make_var_array( make, "EXTRAIDLFLAGS" )); + output_filename( source->filename ); + output( "\n" ); + output_filenames_obj_dir( make, targets ); + output( ": %s", source->filename ); + output_filenames( source->dependencies ); + output( "\n" ); +} + + +/******************************************************************* + * output_source_tlb + */ +static void output_source_tlb( struct makefile *make, struct incl_file *source, const char *obj ) +{ + strarray_add( &make->all_targets, source->name ); +} + + +/******************************************************************* + * output_source_x + */ +static void output_source_x( struct makefile *make, struct incl_file *source, const char *obj ) +{ + output( "%s.h: %s%s %s\n", obj_dir_path( make, obj ), + tools_dir_path( make, "make_xftmpl" ), tools_ext, source->filename ); + output( "\t%s%s -H -o $@ %s\n", + tools_dir_path( make, "make_xftmpl" ), tools_ext, source->filename ); + if (source->file->flags & FLAG_INSTALL) + { + strarray_add( &make->install_rules[INSTALL_DEV], source->name ); + strarray_add( &make->install_rules[INSTALL_DEV], + strmake( "D$(includedir)/%s", get_include_install_path( source->name ) )); + strarray_add( &make->install_rules[INSTALL_DEV], strmake( "%s.h", obj )); + strarray_add( &make->install_rules[INSTALL_DEV], + strmake( "d$(includedir)/%s.h", get_include_install_path( obj ) )); + } +} + + +/******************************************************************* + * output_source_sfd + */ +static void output_source_sfd( struct makefile *make, struct incl_file *source, const char *obj ) +{ + unsigned int i; + char *ttf_file = src_dir_path( make, strmake( "%s.ttf", obj )); + + if (fontforge && !make->src_dir) + { + output( "%s: %s\n", ttf_file, source->filename ); + output( "\t%s -script %s %s $@\n", + fontforge, top_src_dir_path( make, "fonts/genttf.ff" ), source->filename ); + if (!(source->file->flags & FLAG_SFD_FONTS)) output( "all: %s\n", ttf_file ); + } + if (source->file->flags & FLAG_INSTALL) + { + strarray_add( &make->install_rules[INSTALL_LIB], strmake( "%s.ttf", obj )); + strarray_add( &make->install_rules[INSTALL_LIB], strmake( "D$(fontdir)/%s.ttf", obj )); + } + if (source->file->flags & FLAG_SFD_FONTS) + { + struct strarray *array = source->file->args; + + for (i = 0; i < array->count; i++) + { + char *font = strtok( xstrdup(array->str[i]), " \t" ); + char *args = strtok( NULL, "" ); + + strarray_add( &make->all_targets, xstrdup( font )); + output( "%s: %s %s\n", obj_dir_path( make, font ), + tools_path( make, "sfnt2fon" ), ttf_file ); + output( "\t%s -o $@ %s %s\n", tools_path( make, "sfnt2fon" ), ttf_file, args ); + strarray_add( &make->install_rules[INSTALL_LIB], xstrdup(font) ); + strarray_add( &make->install_rules[INSTALL_LIB], strmake( "d$(fontdir)/%s", font )); + } + } +} + + +/******************************************************************* + * output_source_svg + */ +static void output_source_svg( struct makefile *make, struct incl_file *source, const char *obj ) +{ + static const char * const images[] = { "bmp", "cur", "ico", NULL }; + unsigned int i; + + if (convert && rsvg && icotool && !make->src_dir) + { + for (i = 0; images[i]; i++) + if (find_include_file( make, strmake( "%s.%s", obj, images[i] ))) break; + + if (images[i]) + { + output( "%s.%s: %s\n", src_dir_path( make, obj ), images[i], source->filename ); + output( "\tCONVERT=\"%s\" ICOTOOL=\"%s\" RSVG=\"%s\" %s %s $@\n", convert, icotool, rsvg, + top_src_dir_path( make, "tools/buildimage" ), source->filename ); + } + } +} + + +/******************************************************************* + * output_source_po + */ +static void output_source_po( struct makefile *make, struct incl_file *source, const char *obj ) +{ + output( "%s.mo: %s\n", obj_dir_path( make, obj ), source->filename ); + output( "\t%s -o $@ %s\n", msgfmt, source->filename ); + strarray_add( &make->all_targets, strmake( "%s.mo", obj )); +} + + +/******************************************************************* + * output_source_in + */ +static void output_source_in( struct makefile *make, struct incl_file *source, const char *obj ) +{ + unsigned int i; + + if (strendswith( obj, ".man" ) && source->file->args) + { + struct strarray symlinks; + char *dir, *dest = replace_extension( obj, ".man", "" ); + char *lang = strchr( dest, '.' ); + char *section = source->file->args; + if (lang) + { + *lang++ = 0; + dir = strmake( "$(mandir)/%s/man%s", lang, section ); + } + else dir = strmake( "$(mandir)/man%s", section ); + add_install_rule( make, dest, xstrdup(obj), strmake( "d%s/%s.%s", dir, dest, section )); + symlinks = get_expanded_file_local_var( make, dest, "SYMLINKS" ); + for (i = 0; i < symlinks.count; i++) + add_install_rule( make, symlinks.str[i], strmake( "%s.%s", dest, section ), + strmake( "y%s/%s.%s", dir, symlinks.str[i], section )); + free( dest ); + free( dir ); + } + strarray_add( &make->in_files, xstrdup(obj) ); + strarray_add( &make->all_targets, xstrdup(obj) ); + output( "%s: %s\n", obj_dir_path( make, obj ), source->filename ); + output( "\t$(SED_CMD) %s >$@ || (rm -f $@ && false)\n", source->filename ); + output( "%s:", obj_dir_path( make, obj )); + output_filenames( source->dependencies ); + output( "\n" ); + add_install_rule( make, obj, xstrdup( obj ), strmake( "d$(datadir)/wine/%s", obj )); +} + + +/******************************************************************* + * output_source_default + */ +static void output_source_default( struct makefile *make, struct incl_file *source, const char *obj ) +{ + struct strarray extradefs = get_expanded_file_local_var( make, obj, "EXTRADEFS" ); + int need_cross = make->testdll || + (source->file->flags & FLAG_C_IMPLIB) || + (make->module && make->staticlib); + + if ((source->file->flags & FLAG_GENERATED) && + (!make->testdll || !strendswith( source->filename, "testlist.c" ))) + strarray_add( &make->clean_files, source->filename ); + if (source->file->flags & FLAG_C_IMPLIB) strarray_add( &make->implib_objs, strmake( "%s.o", obj )); + strarray_add( &make->object_files, strmake( "%s.o", obj )); + output( "%s.o: %s\n", obj_dir_path( make, obj ), source->filename ); + output( "\t$(CC) -c -o $@ %s", source->filename ); + output_filenames( make->include_args ); + output_filenames( make->define_args ); + output_filenames( extradefs ); + if (make->module || make->staticlib || make->sharedlib || make->testdll) + { + output_filenames( dll_flags ); + if (make->use_msvcrt) output_filenames( msvcrt_flags ); + } + output_filenames( extra_cflags ); + output_filenames( cpp_flags ); + output_filename( "$(CFLAGS)" ); + output( "\n" ); + if (crosstarget && need_cross) + { + strarray_add( &make->crossobj_files, strmake( "%s.cross.o", obj )); + output( "%s.cross.o: %s\n", obj_dir_path( make, obj ), source->filename ); + output( "\t$(CROSSCC) -c -o $@ %s", source->filename ); + output_filenames( make->include_args ); + output_filenames( make->define_args ); + output_filenames( extradefs ); + if (make->use_msvcrt) output_filenames( msvcrt_flags ); + output_filename( "-DWINE_CROSSTEST" ); + output_filenames( cpp_flags ); + output_filename( "$(CROSSCFLAGS)" ); + output( "\n" ); + } + if (strendswith( source->name, ".c" ) && !(source->file->flags & FLAG_GENERATED)) + { + strarray_add( &make->c2man_files, source->filename ); + if (make->testdll) + { + strarray_add( &make->ok_files, strmake( "%s.ok", obj )); + output( "%s.ok:\n", obj_dir_path( make, obj )); + output( "\t%s $(RUNTESTFLAGS) -T %s -M %s -p %s%s %s && touch $@\n", + top_src_dir_path( make, "tools/runtest" ), top_obj_dir_path( make, "" ), + make->testdll, replace_extension( make->testdll, ".dll", "_test.exe" ), + dll_ext, obj ); + } + } + output( "%s.o", obj_dir_path( make, obj )); + if (crosstarget && need_cross) output( " %s.cross.o", obj_dir_path( make, obj )); + output( ":" ); + output_filenames( source->dependencies ); + output( "\n" ); +} + + +/* dispatch table to output rules for a single source file */ +static const struct +{ + const char *ext; + void (*fn)( struct makefile *make, struct incl_file *source, const char *obj ); +} output_source_funcs[] = +{ + { "y", output_source_y }, + { "l", output_source_l }, + { "h", output_source_h }, + { "rh", output_source_h }, + { "inl", output_source_h }, + { "rc", output_source_rc }, + { "mc", output_source_mc }, + { "res", output_source_res }, + { "idl", output_source_idl }, + { "tlb", output_source_tlb }, + { "sfd", output_source_sfd }, + { "svg", output_source_svg }, + { "po", output_source_po }, + { "in", output_source_in }, + { "x", output_source_x }, + { NULL, output_source_default } +}; + + +/******************************************************************* + * output_man_pages + */ +static void output_man_pages( struct makefile *make ) +{ + if (make->c2man_files.count) + { + char *spec_file = src_dir_path( make, replace_extension( make->module, ".dll", ".spec" )); + + output( "manpages::\n" ); + output( "\t%s -w %s", top_src_dir_path( make, "tools/c2man.pl" ), spec_file ); + output_filename( strmake( "-R%s", top_src_dir_path( make, "" ))); + output_filename( strmake( "-I%s", top_src_dir_path( make, "include" ))); + output_filename( strmake( "-o %s/man%s", + top_obj_dir_path( make, "documentation" ), man_ext )); + output_filenames( make->c2man_files ); + output( "\n" ); + output( "htmlpages::\n" ); + output( "\t%s -Th -w %s", top_src_dir_path( make, "tools/c2man.pl" ), spec_file ); + output_filename( strmake( "-R%s", top_src_dir_path( make, "" ))); + output_filename( strmake( "-I%s", top_src_dir_path( make, "include" ))); + output_filename( strmake( "-o %s", + top_obj_dir_path( make, "documentation/html" ))); + output_filenames( make->c2man_files ); + output( "\n" ); + output( "sgmlpages::\n" ); + output( "\t%s -Ts -w %s", top_src_dir_path( make, "tools/c2man.pl" ), spec_file ); + output_filename( strmake( "-R%s", top_src_dir_path( make, "" ))); + output_filename( strmake( "-I%s", top_src_dir_path( make, "include" ))); + output_filename( strmake( "-o %s", + top_obj_dir_path( make, "documentation/api-guide" ))); + output_filenames( make->c2man_files ); + output( "\n" ); + output( "xmlpages::\n" ); + output( "\t%s -Tx -w %s", top_src_dir_path( make, "tools/c2man.pl" ), spec_file ); + output_filename( strmake( "-R%s", top_src_dir_path( make, "" ))); + output_filename( strmake( "-I%s", top_src_dir_path( make, "include" ))); + output_filename( strmake( "-o %s", + top_obj_dir_path( make, "documentation/api-guide-xml" ))); + output_filenames( make->c2man_files ); + output( "\n" ); + strarray_add( &make->phony_targets, "manpages" ); + strarray_add( &make->phony_targets, "htmlpages" ); + strarray_add( &make->phony_targets, "sgmlpages" ); + strarray_add( &make->phony_targets, "xmlpages" ); + } + else output( "manpages htmlpages sgmlpages xmlpages::\n" ); +} + + +/******************************************************************* + * output_module + */ +static void output_module( struct makefile *make ) +{ + struct strarray all_libs = empty_strarray; + struct strarray dep_libs = empty_strarray; + char *module_path = obj_dir_path( make, make->module ); + char *spec_file = NULL; + unsigned int i; + + if (!make->appmode.count) + spec_file = src_dir_path( make, replace_extension( make->module, ".dll", ".spec" )); + strarray_addall( &all_libs, add_import_libs( make, &dep_libs, make->delayimports, 0 )); + strarray_addall( &all_libs, add_import_libs( make, &dep_libs, make->imports, 0 )); + add_import_libs( make, &dep_libs, get_default_imports( make ), 0 ); /* dependencies only */ + strarray_addall( &all_libs, add_default_libraries( make, &dep_libs )); + + if (*dll_ext) + { + for (i = 0; i < make->delayimports.count; i++) + strarray_add( &all_libs, strmake( "-Wb,-d%s", make->delayimports.str[i] )); + strarray_add( &make->all_targets, strmake( "%s%s", make->module, dll_ext )); + strarray_add( &make->all_targets, strmake( "%s.fake", make->module )); + add_install_rule( make, make->module, strmake( "%s%s", make->module, dll_ext ), + strmake( "p$(dlldir)/%s%s", make->module, dll_ext )); + add_install_rule( make, make->module, strmake( "%s.fake", make->module ), + strmake( "d$(fakedlldir)/%s", make->module )); + output( "%s%s %s.fake:", module_path, dll_ext, module_path ); + } + else + { + strarray_add( &all_libs, "-lwine" ); + strarray_add( &make->all_targets, make->module ); + add_install_rule( make, make->module, make->module, + strmake( "p$(%s)/%s", spec_file ? "dlldir" : "bindir", make->module )); + output( "%s:", module_path ); + } + if (spec_file) output_filename( spec_file ); + output_filenames_obj_dir( make, make->object_files ); + output_filenames( dep_libs ); + output_filename( tools_path( make, "winebuild" )); + output_filename( tools_path( make, "winegcc" )); + output( "\n" ); + output( "\t%s -o $@", tools_path( make, "winegcc" )); + output_filename( strmake( "-B%s", tools_dir_path( make, "winebuild" ))); + if (tools_dir) output_filename( strmake( "--sysroot=%s", top_obj_dir_path( make, "" ))); + output_filenames( target_flags ); + output_filenames( unwind_flags ); + if (spec_file) + { + output( " -shared %s", spec_file ); + output_filenames( make->extradllflags ); + } + else output_filenames( make->appmode ); + output_filenames_obj_dir( make, make->object_files ); + output_filenames( all_libs ); + output_filename( "$(LDFLAGS)" ); + output( "\n" ); + + if (spec_file && make->importlib) + { + char *importlib_path = obj_dir_path( make, strmake( "lib%s", make->importlib )); + if (*dll_ext && !make->implib_objs.count) + { + strarray_add( &make->clean_files, strmake( "lib%s.def", make->importlib )); + output( "%s.def: %s %s\n", importlib_path, tools_path( make, "winebuild" ), spec_file ); + output( "\t%s -w --def -o $@ --export %s", tools_path( make, "winebuild" ), spec_file ); + output_filenames( target_flags ); + if (make->is_win16) output_filename( "-m16" ); + output( "\n" ); + add_install_rule( make, make->importlib, + strmake( "lib%s.def", make->importlib ), + strmake( "d$(dlldir)/lib%s.def", make->importlib )); + } + else + { + strarray_add( &make->clean_files, strmake( "lib%s.a", make->importlib )); + output( "%s.a: %s %s", importlib_path, tools_path( make, "winebuild" ), spec_file ); + output_filenames_obj_dir( make, make->implib_objs ); + output( "\n" ); + output( "\t%s -w --implib -o $@ --export %s", tools_path( make, "winebuild" ), spec_file ); + output_filenames( target_flags ); + output_filenames_obj_dir( make, make->implib_objs ); + output( "\n" ); + add_install_rule( make, make->importlib, + strmake( "lib%s.a", make->importlib ), + strmake( "d$(dlldir)/lib%s.a", make->importlib )); + } + if (crosstarget && !make->is_win16) + { + struct strarray cross_files = strarray_replace_extension( &make->implib_objs, ".o", ".cross.o" ); + strarray_add( &make->clean_files, strmake( "lib%s.cross.a", make->importlib )); + output( "%s.cross.a: %s %s", importlib_path, tools_path( make, "winebuild" ), spec_file ); + output_filenames_obj_dir( make, cross_files ); + output( "\n" ); + output( "\t%s -b %s -w --implib -o $@ --export %s", + tools_path( make, "winebuild" ), crosstarget, spec_file ); + output_filenames_obj_dir( make, cross_files ); + output( "\n" ); + } + } + + if (spec_file) + output_man_pages( make ); + else if (*dll_ext) + { + char *binary = replace_extension( make->module, ".exe", "" ); + add_install_rule( make, binary, "wineapploader", strmake( "t$(bindir)/%s", binary )); + } +} + + +/******************************************************************* + * output_static_lib + */ +static void output_static_lib( struct makefile *make ) +{ + strarray_add( &make->all_targets, make->staticlib ); + output( "%s:", obj_dir_path( make, make->staticlib )); + output_filenames_obj_dir( make, make->object_files ); + output( "\n\trm -f $@\n" ); + output( "\t$(AR) $(ARFLAGS) $@" ); + output_filenames_obj_dir( make, make->object_files ); + output( "\n\t$(RANLIB) $@\n" ); + add_install_rule( make, make->staticlib, make->staticlib, + strmake( "d$(dlldir)/%s", make->staticlib )); + if (crosstarget && make->module) + { + char *name = replace_extension( make->staticlib, ".a", ".cross.a" ); + + strarray_add( &make->all_targets, name ); + output( "%s:", obj_dir_path( make, name )); + output_filenames_obj_dir( make, make->crossobj_files ); + output( "\n\trm -f $@\n" ); + output( "\t%s-ar $(ARFLAGS) $@", crosstarget ); + output_filenames_obj_dir( make, make->crossobj_files ); + output( "\n\t%s-ranlib $@\n", crosstarget ); + } +} + + +/******************************************************************* + * output_shared_lib + */ +static void output_shared_lib( struct makefile *make ) +{ + unsigned int i; + char *basename, *p; + struct strarray names = get_shared_lib_names( make->sharedlib ); + struct strarray all_libs = empty_strarray; + struct strarray dep_libs = empty_strarray; + + basename = xstrdup( make->sharedlib ); + if ((p = strchr( basename, '.' ))) *p = 0; + + strarray_addall( &dep_libs, get_local_dependencies( make, basename, make->in_files )); + strarray_addall( &all_libs, get_expanded_file_local_var( make, basename, "LDFLAGS" )); + strarray_addall( &all_libs, add_default_libraries( make, &dep_libs )); + + output( "%s:", obj_dir_path( make, make->sharedlib )); + output_filenames_obj_dir( make, make->object_files ); + output_filenames( dep_libs ); + output( "\n" ); + output( "\t$(CC) -o $@" ); + output_filenames_obj_dir( make, make->object_files ); + output_filenames( all_libs ); + output_filename( "$(LDFLAGS)" ); + output( "\n" ); + add_install_rule( make, make->sharedlib, make->sharedlib, + strmake( "p$(libdir)/%s", make->sharedlib )); + for (i = 1; i < names.count; i++) + { + output( "%s: %s\n", obj_dir_path( make, names.str[i] ), obj_dir_path( make, names.str[i-1] )); + output_symlink_rule( obj_dir_path( make, names.str[i-1] ), obj_dir_path( make, names.str[i] )); + add_install_rule( make, names.str[i], names.str[i-1], + strmake( "y$(libdir)/%s", names.str[i] )); + } + strarray_addall( &make->all_targets, names ); +} + + +/******************************************************************* + * output_import_lib + */ +static void output_import_lib( struct makefile *make ) +{ + char *def_file = replace_extension( make->importlib, ".a", ".def" ); + + /* stand-alone import lib (for libwine) */ + if (!strncmp( def_file, "lib", 3 )) def_file += 3; + output( "%s: %s\n", obj_dir_path( make, make->importlib ), src_dir_path( make, def_file )); + output( "\t%s -l $@ -d %s\n", dlltool, src_dir_path( make, def_file )); + add_install_rule( make, make->importlib, make->importlib, strmake( "d$(libdir)/%s", make->importlib )); + strarray_add( &make->all_targets, make->importlib ); +} + + +/******************************************************************* + * output_test_module + */ +static void output_test_module( struct makefile *make ) +{ + char *testmodule = replace_extension( make->testdll, ".dll", "_test.exe" ); + char *stripped = replace_extension( make->testdll, ".dll", "_test-stripped.exe" ); + char *testres = replace_extension( make->testdll, ".dll", "_test.res" ); + struct strarray dep_libs = empty_strarray; + struct strarray all_libs = add_import_libs( make, &dep_libs, make->imports, 0 ); + + add_import_libs( make, &dep_libs, get_default_imports( make ), 0 ); /* dependencies only */ + strarray_addall( &all_libs, libs ); + strarray_add( &make->all_targets, strmake( "%s%s", testmodule, dll_ext )); + strarray_add( &make->clean_files, strmake( "%s%s", stripped, dll_ext )); + output( "%s%s:\n", obj_dir_path( make, testmodule ), dll_ext ); + output( "\t%s -o $@", tools_path( make, "winegcc" )); + output_filename( strmake( "-B%s", tools_dir_path( make, "winebuild" ))); + if (tools_dir) output_filename( strmake( "--sysroot=%s", top_obj_dir_path( make, "" ))); + output_filenames( target_flags ); + output_filenames( unwind_flags ); + output_filenames( make->appmode ); + output_filenames_obj_dir( make, make->object_files ); + output_filenames( all_libs ); + output_filename( "$(LDFLAGS)" ); + output( "\n" ); + output( "%s%s:\n", obj_dir_path( make, stripped ), dll_ext ); + output( "\t%s -s -o $@", tools_path( make, "winegcc" )); + output_filename( strmake( "-B%s", tools_dir_path( make, "winebuild" ))); + if (tools_dir) output_filename( strmake( "--sysroot=%s", top_obj_dir_path( make, "" ))); + output_filenames( target_flags ); + output_filenames( unwind_flags ); + output_filename( strmake( "-Wb,-F,%s", testmodule )); + output_filenames( make->appmode ); + output_filenames_obj_dir( make, make->object_files ); + output_filenames( all_libs ); + output_filename( "$(LDFLAGS)" ); + output( "\n" ); + output( "%s%s %s%s:", obj_dir_path( make, testmodule ), dll_ext, + obj_dir_path( make, stripped ), dll_ext ); + output_filenames_obj_dir( make, make->object_files ); + output_filenames( dep_libs ); + output_filename( tools_path( make, "winebuild" )); + output_filename( tools_path( make, "winegcc" )); + output( "\n" ); + + if (!make->disabled) + output( "all: %s/%s\n", top_obj_dir_path( make, "programs/winetest" ), testres ); + output( "%s/%s: %s%s\n", top_obj_dir_path( make, "programs/winetest" ), testres, + obj_dir_path( make, stripped ), dll_ext ); + output( "\techo \"%s TESTRES \\\"%s%s\\\"\" | %s -o $@\n", + testmodule, obj_dir_path( make, stripped ), dll_ext, tools_path( make, "wrc" )); + + if (crosstarget) + { + char *crosstest = replace_extension( make->testdll, ".dll", "_crosstest.exe" ); + + dep_libs = empty_strarray; + all_libs = add_import_libs( make, &dep_libs, make->imports, 1 ); + add_import_libs( make, &dep_libs, get_default_imports( make ), 1 ); /* dependencies only */ + strarray_addall( &all_libs, libs ); + strarray_add( &make->clean_files, crosstest ); + output( "%s:", obj_dir_path( make, crosstest )); + output_filenames_obj_dir( make, make->crossobj_files ); + output_filenames( dep_libs ); + output_filename( tools_path( make, "winebuild" )); + output_filename( tools_path( make, "winegcc" )); + output( "\n" ); + output( "\t%s -o $@ -b %s", tools_path( make, "winegcc" ), crosstarget ); + output_filename( strmake( "-B%s", tools_dir_path( make, "winebuild" ))); + if (tools_dir) output_filename( strmake( "--sysroot=%s", top_obj_dir_path( make, "" ))); + output_filename( "--lib-suffix=.cross.a" ); + output_filenames_obj_dir( make, make->crossobj_files ); + output_filenames( all_libs ); + output_filename( "$(LDFLAGS)" ); + output( "\n" ); + if (!make->disabled) + { + output( "%s: %s\n", obj_dir_path( make, "crosstest" ), obj_dir_path( make, crosstest )); + strarray_add( &make->phony_targets, obj_dir_path( make, "crosstest" )); + if (make->obj_dir) output( "crosstest: %s\n", obj_dir_path( make, "crosstest" )); + } + } + + output_filenames_obj_dir( make, make->ok_files ); + output( ": %s%s ../%s%s\n", testmodule, dll_ext, make->testdll, dll_ext ); + if (!make->disabled) + { + output( "check test:" ); + output_filenames_obj_dir( make, make->ok_files ); + output( "\n" ); + strarray_add( &make->phony_targets, "check" ); + strarray_add( &make->phony_targets, "test" ); + } + output( "testclean::\n" ); + output( "\trm -f" ); + output_filenames_obj_dir( make, make->ok_files ); + output( "\n" ); + strarray_addall( &make->clean_files, make->ok_files ); + strarray_add( &make->phony_targets, "testclean" ); +} + + +/******************************************************************* + * output_programs + */ +static void output_programs( struct makefile *make ) { - struct incl_file *source; unsigned int i, j; - struct strarray object_files = empty_strarray; - struct strarray crossobj_files = empty_strarray; - struct strarray res_files = empty_strarray; - struct strarray clean_files = empty_strarray; - struct strarray uninstall_files = empty_strarray; - struct strarray mo_files = empty_strarray; - struct strarray ok_files = empty_strarray; - struct strarray in_files = empty_strarray; - struct strarray dlldata_files = empty_strarray; - struct strarray c2man_files = empty_strarray; - struct strarray implib_objs = empty_strarray; - struct strarray includes = empty_strarray; - struct strarray phony_targets = empty_strarray; - struct strarray all_targets = empty_strarray; - struct strarray install_rules[NB_INSTALL_RULES]; char *ldrpath_local = get_expanded_make_variable( make, "LDRPATH_LOCAL" ); char *ldrpath_install = get_expanded_make_variable( make, "LDRPATH_INSTALL" ); - for (i = 0; i < NB_INSTALL_RULES; i++) install_rules[i] = empty_strarray; - - for (i = 0; i < linguas.count; i++) - strarray_add( &mo_files, strmake( "%s/%s.mo", top_obj_dir_path( make, "po" ), linguas.str[i] )); - - strarray_add( &phony_targets, "all" ); - strarray_add( &includes, strmake( "-I%s", obj_dir_path( make, "" ))); - if (make->src_dir) strarray_add( &includes, strmake( "-I%s", make->src_dir )); - if (make->parent_dir) strarray_add( &includes, strmake( "-I%s", src_dir_path( make, make->parent_dir ))); - strarray_add( &includes, strmake( "-I%s", top_obj_dir_path( make, "include" ))); - if (make->top_src_dir) - strarray_add( &includes, strmake( "-I%s", top_src_dir_path( make, "include" ))); - if (make->use_msvcrt) - strarray_add( &includes, strmake( "-I%s", top_src_dir_path( make, "include/msvcrt" ))); - for (i = 0; i < make->include_paths.count; i++) - strarray_add( &includes, strmake( "-I%s", obj_dir_path( make, make->include_paths.str[i] ))); - - LIST_FOR_EACH_ENTRY( source, &make->sources, struct incl_file, entry ) - { - struct strarray dependencies = empty_strarray; - struct strarray extradefs; - char *obj = xstrdup( source->name ); - char *ext = get_extension( obj ); - - if (!ext) fatal_error( "unsupported file type %s\n", source->name ); - *ext++ = 0; - - extradefs = get_expanded_file_local_var( make, obj, "EXTRADEFS" ); - get_dependencies( &dependencies, source, source ); - - if (!strcmp( ext, "y" )) /* yacc file */ - { - /* add source file dependency for parallel makes */ - char *header = strmake( "%s.tab.h", obj ); - - if (find_include_file( make, header )) - { - output( "%s: %s\n", obj_dir_path( make, header ), source->filename ); - output( "\t$(BISON) -p %s_ -o %s.tab.c -d %s\n", - obj, obj_dir_path( make, obj ), source->filename ); - output( "%s.tab.c: %s %s\n", obj_dir_path( make, obj ), - source->filename, obj_dir_path( make, header )); - strarray_add( &clean_files, header ); - } - else output( "%s.tab.c: %s\n", obj, source->filename ); - - output( "\t$(BISON) -p %s_ -o $@ %s\n", obj, source->filename ); - } - else if (!strcmp( ext, "x" )) /* template file */ - { - output( "%s.h: %s%s %s\n", obj_dir_path( make, obj ), - tools_dir_path( make, "make_xftmpl" ), tools_ext, source->filename ); - output( "\t%s%s -H -o $@ %s\n", - tools_dir_path( make, "make_xftmpl" ), tools_ext, source->filename ); - if (source->file->flags & FLAG_INSTALL) - { - strarray_add( &install_rules[INSTALL_DEV], source->name ); - strarray_add( &install_rules[INSTALL_DEV], - strmake( "D$(includedir)/%s", get_include_install_path( source->name ) )); - strarray_add( &install_rules[INSTALL_DEV], strmake( "%s.h", obj )); - strarray_add( &install_rules[INSTALL_DEV], - strmake( "d$(includedir)/%s.h", get_include_install_path( obj ) )); - } - } - else if (!strcmp( ext, "l" )) /* lex file */ - { - output( "%s.yy.c: %s\n", obj_dir_path( make, obj ), source->filename ); - output( "\t$(FLEX) -o$@ %s\n", source->filename ); - } - else if (!strcmp( ext, "rc" )) /* resource file */ - { - strarray_add( &res_files, strmake( "%s.res", obj )); - output( "%s.res: %s\n", obj_dir_path( make, obj ), source->filename ); - output( "\t%s -o $@", tools_path( make, "wrc" ) ); - if (make->is_win16) output_filename( "-m16" ); - else output_filenames( target_flags ); - output_filename( "--nostdinc" ); - output_filenames( includes ); - output_filenames( make->define_args ); - output_filenames( extradefs ); - if (mo_files.count && (source->file->flags & FLAG_RC_PO)) - { - output_filename( strmake( "--po-dir=%s", top_obj_dir_path( make, "po" ))); - output_filename( source->filename ); - output( "\n" ); - output( "%s.res:", obj_dir_path( make, obj )); - output_filenames( mo_files ); - output( "\n" ); - } - else - { - output_filename( source->filename ); - output( "\n" ); - } - if (source->file->flags & FLAG_RC_PO) - { - strarray_add( &clean_files, strmake( "%s.pot", obj )); - output( "%s.pot: %s\n", obj_dir_path( make, obj ), source->filename ); - output( "\t%s -O pot -o $@", tools_path( make, "wrc" ) ); - if (make->is_win16) output_filename( "-m16" ); - else output_filenames( target_flags ); - output_filename( "--nostdinc" ); - output_filenames( includes ); - output_filenames( make->define_args ); - output_filenames( extradefs ); - output_filename( source->filename ); - output( "\n" ); - output( "%s.pot ", obj_dir_path( make, obj )); - } - output( "%s.res:", obj_dir_path( make, obj )); - output_filename( tools_path( make, "wrc" )); - output_filenames( dependencies ); - output( "\n" ); - } - else if (!strcmp( ext, "mc" )) /* message file */ - { - strarray_add( &res_files, strmake( "%s.res", obj )); - strarray_add( &clean_files, strmake( "%s.pot", obj )); - output( "%s.res: %s\n", obj_dir_path( make, obj ), source->filename ); - output( "\t%s -U -O res -o $@ %s", tools_path( make, "wmc" ), source->filename ); - if (mo_files.count) - { - output_filename( strmake( "--po-dir=%s", top_obj_dir_path( make, "po" ))); - output( "\n" ); - output( "%s.res:", obj_dir_path( make, obj )); - output_filenames( mo_files ); - } - output( "\n" ); - output( "%s.pot: %s\n", obj_dir_path( make, obj ), source->filename ); - output( "\t%s -O pot -o $@ %s", tools_path( make, "wmc" ), source->filename ); - output( "\n" ); - output( "%s.pot %s.res:", obj_dir_path( make, obj ), obj_dir_path( make, obj )); - output_filename( tools_path( make, "wmc" )); - output_filenames( dependencies ); - output( "\n" ); - } - else if (!strcmp( ext, "idl" )) /* IDL file */ - { - struct strarray targets = empty_strarray; - char *dest; - - if (!source->file->flags) source->file->flags |= FLAG_IDL_HEADER | FLAG_INSTALL; - if (find_include_file( make, strmake( "%s.h", obj ))) source->file->flags |= FLAG_IDL_HEADER; - - for (i = 0; i < sizeof(idl_outputs) / sizeof(idl_outputs[0]); i++) - { - if (!(source->file->flags & idl_outputs[i].flag)) continue; - dest = strmake( "%s%s", obj, idl_outputs[i].ext ); - if (!find_src_file( make, dest )) strarray_add( &clean_files, dest ); - strarray_add( &targets, dest ); - } - if (source->file->flags & FLAG_IDL_PROXY) strarray_add( &dlldata_files, source->name ); - if (source->file->flags & FLAG_INSTALL) - { - strarray_add( &install_rules[INSTALL_DEV], xstrdup( source->name )); - strarray_add( &install_rules[INSTALL_DEV], - strmake( "D$(includedir)/%s.idl", get_include_install_path( obj ) )); - if (source->file->flags & FLAG_IDL_HEADER) - { - strarray_add( &install_rules[INSTALL_DEV], strmake( "%s.h", obj )); - strarray_add( &install_rules[INSTALL_DEV], - strmake( "d$(includedir)/%s.h", get_include_install_path( obj ) )); - } - } - if (!targets.count) continue; - output_filenames_obj_dir( make, targets ); - output( ": %s\n", tools_path( make, "widl" )); - output( "\t%s -o $@", tools_path( make, "widl" ) ); - output_filenames( target_flags ); - output_filenames( includes ); - output_filenames( make->define_args ); - output_filenames( extradefs ); - output_filenames( get_expanded_make_var_array( make, "EXTRAIDLFLAGS" )); - output_filename( source->filename ); - output( "\n" ); - output_filenames_obj_dir( make, targets ); - output( ": %s", source->filename ); - output_filenames( dependencies ); - output( "\n" ); - } - else if (!strcmp( ext, "in" )) /* .in file or man page */ - { - if (strendswith( obj, ".man" ) && source->file->args) - { - struct strarray symlinks; - char *dir, *dest = replace_extension( obj, ".man", "" ); - char *lang = strchr( dest, '.' ); - char *section = source->file->args; - if (lang) - { - *lang++ = 0; - dir = strmake( "$(mandir)/%s/man%s", lang, section ); - } - else dir = strmake( "$(mandir)/man%s", section ); - add_install_rule( make, install_rules, dest, xstrdup(obj), - strmake( "d%s/%s.%s", dir, dest, section )); - symlinks = get_expanded_file_local_var( make, dest, "SYMLINKS" ); - for (i = 0; i < symlinks.count; i++) - add_install_rule( make, install_rules, symlinks.str[i], - strmake( "%s.%s", dest, section ), - strmake( "y%s/%s.%s", dir, symlinks.str[i], section )); - free( dest ); - free( dir ); - } - strarray_add( &in_files, xstrdup(obj) ); - strarray_add( &all_targets, xstrdup(obj) ); - output( "%s: %s\n", obj_dir_path( make, obj ), source->filename ); - output( "\t$(SED_CMD) %s >$@ || (rm -f $@ && false)\n", source->filename ); - output( "%s:", obj_dir_path( make, obj )); - output_filenames( dependencies ); - output( "\n" ); - add_install_rule( make, install_rules, obj, xstrdup( obj ), - strmake( "d$(datadir)/wine/%s", obj )); - } - else if (!strcmp( ext, "sfd" )) /* font file */ - { - char *ttf_file = src_dir_path( make, strmake( "%s.ttf", obj )); - if (fontforge && !make->src_dir) - { - output( "%s: %s\n", ttf_file, source->filename ); - output( "\t%s -script %s %s $@\n", - fontforge, top_src_dir_path( make, "fonts/genttf.ff" ), source->filename ); - if (!(source->file->flags & FLAG_SFD_FONTS)) output( "all: %s\n", ttf_file ); - } - if (source->file->flags & FLAG_INSTALL) - { - strarray_add( &install_rules[INSTALL_LIB], strmake( "%s.ttf", obj )); - strarray_add( &install_rules[INSTALL_LIB], strmake( "D$(fontdir)/%s.ttf", obj )); - } - if (source->file->flags & FLAG_SFD_FONTS) - { - struct strarray *array = source->file->args; - - for (i = 0; i < array->count; i++) - { - char *font = strtok( xstrdup(array->str[i]), " \t" ); - char *args = strtok( NULL, "" ); - - strarray_add( &all_targets, xstrdup( font )); - output( "%s: %s %s\n", obj_dir_path( make, font ), - tools_path( make, "sfnt2fon" ), ttf_file ); - output( "\t%s -o $@ %s %s\n", tools_path( make, "sfnt2fon" ), ttf_file, args ); - strarray_add( &install_rules[INSTALL_LIB], xstrdup(font) ); - strarray_add( &install_rules[INSTALL_LIB], strmake( "d$(fontdir)/%s", font )); - } - } - } - else if (!strcmp( ext, "svg" )) /* svg file */ - { - if (convert && rsvg && icotool && !make->src_dir) - { - static const char * const images[] = { "bmp", "cur", "ico", NULL }; - - for (i = 0; images[i]; i++) - if (find_include_file( make, strmake( "%s.%s", obj, images[i] ))) break; - - if (images[i]) - { - output( "%s.%s: %s\n", src_dir_path( make, obj ), images[i], source->filename ); - output( "\tCONVERT=\"%s\" ICOTOOL=\"%s\" RSVG=\"%s\" %s %s $@\n", convert, icotool, rsvg, - top_src_dir_path( make, "tools/buildimage" ), source->filename ); - } - } - } - else if (!strcmp( ext, "po" )) /* po file */ - { - output( "%s.mo: %s\n", obj_dir_path( make, obj ), source->filename ); - output( "\t%s -o $@ %s\n", msgfmt, source->filename ); - strarray_add( &all_targets, strmake( "%s.mo", obj )); - } - else if (!strcmp( ext, "res" )) - { - strarray_add( &res_files, source->name ); - } - else if (!strcmp( ext, "tlb" )) - { - strarray_add( &all_targets, source->name ); - } - else if (!strcmp( ext, "h" ) || !strcmp( ext, "rh" ) || !strcmp( ext, "inl" )) /* header file */ - { - if (source->file->flags & FLAG_GENERATED) - { - strarray_add( &all_targets, source->name ); - } - else - { - strarray_add( &install_rules[INSTALL_DEV], source->name ); - strarray_add( &install_rules[INSTALL_DEV], - strmake( "D$(includedir)/%s", get_include_install_path( source->name ) )); - } - } - else - { - int need_cross = make->testdll || - (source->file->flags & FLAG_C_IMPLIB) || - (make->module && make->staticlib); - - if ((source->file->flags & FLAG_GENERATED) && - (!make->testdll || !strendswith( source->filename, "testlist.c" ))) - strarray_add( &clean_files, source->filename ); - if (source->file->flags & FLAG_C_IMPLIB) strarray_add( &implib_objs, strmake( "%s.o", obj )); - strarray_add( &object_files, strmake( "%s.o", obj )); - output( "%s.o: %s\n", obj_dir_path( make, obj ), source->filename ); - output( "\t$(CC) -c -o $@ %s", source->filename ); - output_filenames( includes ); - output_filenames( make->define_args ); - output_filenames( extradefs ); - if (make->module || make->staticlib || make->sharedlib || make->testdll) - { - output_filenames( dll_flags ); - if (make->use_msvcrt) output_filenames( msvcrt_flags ); - } - output_filenames( extra_cflags ); - output_filenames( cpp_flags ); - output_filename( "$(CFLAGS)" ); - output( "\n" ); - if (crosstarget && need_cross) - { - strarray_add( &crossobj_files, strmake( "%s.cross.o", obj )); - output( "%s.cross.o: %s\n", obj_dir_path( make, obj ), source->filename ); - output( "\t$(CROSSCC) -c -o $@ %s", source->filename ); - output_filenames( includes ); - output_filenames( make->define_args ); - output_filenames( extradefs ); - if (make->use_msvcrt) output_filenames( msvcrt_flags ); - output_filename( "-DWINE_CROSSTEST" ); - output_filenames( cpp_flags ); - output_filename( "$(CROSSCFLAGS)" ); - output( "\n" ); - } - if (make->testdll && !strcmp( ext, "c" ) && !(source->file->flags & FLAG_GENERATED)) - { - strarray_add( &ok_files, strmake( "%s.ok", obj )); - output( "%s.ok:\n", obj_dir_path( make, obj )); - output( "\t%s $(RUNTESTFLAGS) -T %s -M %s -p %s%s %s && touch $@\n", - top_src_dir_path( make, "tools/runtest" ), top_obj_dir_path( make, "" ), - make->testdll, replace_extension( make->testdll, ".dll", "_test.exe" ), - dll_ext, obj ); - } - if (!strcmp( ext, "c" ) && !(source->file->flags & FLAG_GENERATED)) - strarray_add( &c2man_files, source->filename ); - output( "%s.o", obj_dir_path( make, obj )); - if (crosstarget && need_cross) output( " %s.cross.o", obj_dir_path( make, obj )); - output( ":" ); - output_filenames( dependencies ); - output( "\n" ); - } - free( obj ); - } - - /* rules for files that depend on multiple sources */ - - if (dlldata_files.count) - { - output( "%s: %s %s\n", obj_dir_path( make, "dlldata.c" ), - tools_path( make, "widl" ), src_dir_path( make, "Makefile.in" )); - output( "\t%s --dlldata-only -o $@", tools_path( make, "widl" )); - output_filenames( dlldata_files ); - output( "\n" ); - } - - if (make->module && !make->staticlib) - { - struct strarray all_libs = empty_strarray; - struct strarray dep_libs = empty_strarray; - char *module_path = obj_dir_path( make, make->module ); - char *spec_file = NULL; - - if (!make->appmode.count) - spec_file = src_dir_path( make, replace_extension( make->module, ".dll", ".spec" )); - strarray_addall( &all_libs, add_import_libs( make, &dep_libs, make->delayimports, 0 )); - strarray_addall( &all_libs, add_import_libs( make, &dep_libs, make->imports, 0 )); - add_import_libs( make, &dep_libs, get_default_imports( make ), 0 ); /* dependencies only */ - strarray_addall( &all_libs, add_default_libraries( make, &dep_libs )); - - if (*dll_ext) - { - for (i = 0; i < make->delayimports.count; i++) - strarray_add( &all_libs, strmake( "-Wb,-d%s", make->delayimports.str[i] )); - strarray_add( &all_targets, strmake( "%s%s", make->module, dll_ext )); - strarray_add( &all_targets, strmake( "%s.fake", make->module )); - add_install_rule( make, install_rules, make->module, strmake( "%s%s", make->module, dll_ext ), - strmake( "p$(dlldir)/%s%s", make->module, dll_ext )); - add_install_rule( make, install_rules, make->module, strmake( "%s.fake", make->module ), - strmake( "d$(fakedlldir)/%s", make->module )); - output( "%s%s %s.fake:", module_path, dll_ext, module_path ); - } - else - { - strarray_add( &all_libs, "-lwine" ); - strarray_add( &all_targets, make->module ); - add_install_rule( make, install_rules, make->module, make->module, - strmake( "p$(%s)/%s", spec_file ? "dlldir" : "bindir", make->module )); - output( "%s:", module_path ); - } - if (spec_file) output_filename( spec_file ); - output_filenames_obj_dir( make, object_files ); - output_filenames_obj_dir( make, res_files ); - output_filenames( dep_libs ); - output_filename( tools_path( make, "winebuild" )); - output_filename( tools_path( make, "winegcc" )); - output( "\n" ); - output( "\t%s -o $@", tools_path( make, "winegcc" )); - output_filename( strmake( "-B%s", tools_dir_path( make, "winebuild" ))); - if (tools_dir) output_filename( strmake( "--sysroot=%s", top_obj_dir_path( make, "" ))); - output_filenames( target_flags ); - output_filenames( unwind_flags ); - if (spec_file) - { - output( " -shared %s", spec_file ); - output_filenames( make->extradllflags ); - } - else output_filenames( make->appmode ); - output_filenames_obj_dir( make, object_files ); - output_filenames_obj_dir( make, res_files ); - output_filenames( all_libs ); - output_filename( "$(LDFLAGS)" ); - output( "\n" ); - - if (spec_file && make->importlib) - { - char *importlib_path = obj_dir_path( make, strmake( "lib%s", make->importlib )); - if (*dll_ext && !implib_objs.count) - { - strarray_add( &clean_files, strmake( "lib%s.def", make->importlib )); - output( "%s.def: %s %s\n", importlib_path, tools_path( make, "winebuild" ), spec_file ); - output( "\t%s -w --def -o $@ --export %s", tools_path( make, "winebuild" ), spec_file ); - output_filenames( target_flags ); - if (make->is_win16) output_filename( "-m16" ); - output( "\n" ); - add_install_rule( make, install_rules, make->importlib, - strmake( "lib%s.def", make->importlib ), - strmake( "d$(dlldir)/lib%s.def", make->importlib )); - } - else - { - strarray_add( &clean_files, strmake( "lib%s.a", make->importlib )); - output( "%s.a: %s %s", importlib_path, tools_path( make, "winebuild" ), spec_file ); - output_filenames_obj_dir( make, implib_objs ); - output( "\n" ); - output( "\t%s -w --implib -o $@ --export %s", tools_path( make, "winebuild" ), spec_file ); - output_filenames( target_flags ); - output_filenames_obj_dir( make, implib_objs ); - output( "\n" ); - add_install_rule( make, install_rules, make->importlib, - strmake( "lib%s.a", make->importlib ), - strmake( "d$(dlldir)/lib%s.a", make->importlib )); - } - if (crosstarget && !make->is_win16) - { - struct strarray cross_files = strarray_replace_extension( &implib_objs, ".o", ".cross.o" ); - strarray_add( &clean_files, strmake( "lib%s.cross.a", make->importlib )); - output( "%s.cross.a: %s %s", importlib_path, tools_path( make, "winebuild" ), spec_file ); - output_filenames_obj_dir( make, cross_files ); - output( "\n" ); - output( "\t%s -b %s -w --implib -o $@ --export %s", - tools_path( make, "winebuild" ), crosstarget, spec_file ); - output_filenames_obj_dir( make, cross_files ); - output( "\n" ); - } - } - - if (spec_file) - { - if (c2man_files.count) - { - output( "manpages::\n" ); - output( "\t%s -w %s", top_src_dir_path( make, "tools/c2man.pl" ), spec_file ); - output_filename( strmake( "-R%s", top_src_dir_path( make, "" ))); - output_filename( strmake( "-I%s", top_src_dir_path( make, "include" ))); - output_filename( strmake( "-o %s/man%s", - top_obj_dir_path( make, "documentation" ), man_ext )); - output_filenames( c2man_files ); - output( "\n" ); - output( "htmlpages::\n" ); - output( "\t%s -Th -w %s", top_src_dir_path( make, "tools/c2man.pl" ), spec_file ); - output_filename( strmake( "-R%s", top_src_dir_path( make, "" ))); - output_filename( strmake( "-I%s", top_src_dir_path( make, "include" ))); - output_filename( strmake( "-o %s", - top_obj_dir_path( make, "documentation/html" ))); - output_filenames( c2man_files ); - output( "\n" ); - output( "sgmlpages::\n" ); - output( "\t%s -Ts -w %s", top_src_dir_path( make, "tools/c2man.pl" ), spec_file ); - output_filename( strmake( "-R%s", top_src_dir_path( make, "" ))); - output_filename( strmake( "-I%s", top_src_dir_path( make, "include" ))); - output_filename( strmake( "-o %s", - top_obj_dir_path( make, "documentation/api-guide" ))); - output_filenames( c2man_files ); - output( "\n" ); - output( "xmlpages::\n" ); - output( "\t%s -Tx -w %s", top_src_dir_path( make, "tools/c2man.pl" ), spec_file ); - output_filename( strmake( "-R%s", top_src_dir_path( make, "" ))); - output_filename( strmake( "-I%s", top_src_dir_path( make, "include" ))); - output_filename( strmake( "-o %s", - top_obj_dir_path( make, "documentation/api-guide-xml" ))); - output_filenames( c2man_files ); - output( "\n" ); - strarray_add( &phony_targets, "manpages" ); - strarray_add( &phony_targets, "htmlpages" ); - strarray_add( &phony_targets, "sgmlpages" ); - strarray_add( &phony_targets, "xmlpages" ); - } - else output( "manpages htmlpages sgmlpages xmlpages::\n" ); - } - else if (*dll_ext) - { - char *binary = replace_extension( make->module, ".exe", "" ); - add_install_rule( make, install_rules, binary, "wineapploader", - strmake( "t$(bindir)/%s", binary )); - } - } - - if (make->staticlib) - { - strarray_add( &all_targets, make->staticlib ); - output( "%s:", obj_dir_path( make, make->staticlib )); - output_filenames_obj_dir( make, object_files ); - output( "\n\trm -f $@\n" ); - output( "\t$(AR) $(ARFLAGS) $@" ); - output_filenames_obj_dir( make, object_files ); - output( "\n\t$(RANLIB) $@\n" ); - add_install_rule( make, install_rules, make->staticlib, make->staticlib, - strmake( "d$(dlldir)/%s", make->staticlib )); - if (crosstarget && make->module) - { - char *name = replace_extension( make->staticlib, ".a", ".cross.a" ); - - strarray_add( &all_targets, name ); - output( "%s:", obj_dir_path( make, name )); - output_filenames_obj_dir( make, crossobj_files ); - output( "\n\trm -f $@\n" ); - output( "\t%s-ar $(ARFLAGS) $@", crosstarget ); - output_filenames_obj_dir( make, crossobj_files ); - output( "\n\t%s-ranlib $@\n", crosstarget ); - } - } - - if (make->sharedlib) - { - char *basename, *p; - struct strarray names = get_shared_lib_names( make->sharedlib ); - struct strarray all_libs = empty_strarray; - struct strarray dep_libs = empty_strarray; - - basename = xstrdup( make->sharedlib ); - if ((p = strchr( basename, '.' ))) *p = 0; - - strarray_addall( &dep_libs, get_local_dependencies( make, basename, in_files )); - strarray_addall( &all_libs, get_expanded_file_local_var( make, basename, "LDFLAGS" )); - strarray_addall( &all_libs, add_default_libraries( make, &dep_libs )); - - output( "%s:", obj_dir_path( make, make->sharedlib )); - output_filenames_obj_dir( make, object_files ); - output_filenames( dep_libs ); - output( "\n" ); - output( "\t$(CC) -o $@" ); - output_filenames_obj_dir( make, object_files ); - output_filenames( all_libs ); - output_filename( "$(LDFLAGS)" ); - output( "\n" ); - add_install_rule( make, install_rules, make->sharedlib, make->sharedlib, - strmake( "p$(libdir)/%s", make->sharedlib )); - for (i = 1; i < names.count; i++) - { - output( "%s: %s\n", obj_dir_path( make, names.str[i] ), obj_dir_path( make, names.str[i-1] )); - output_symlink_rule( obj_dir_path( make, names.str[i-1] ), obj_dir_path( make, names.str[i] )); - add_install_rule( make, install_rules, names.str[i], names.str[i-1], - strmake( "y$(libdir)/%s", names.str[i] )); - } - strarray_addall( &all_targets, names ); - } - - if (make->importlib && !make->module) /* stand-alone import lib (for libwine) */ - { - char *def_file = replace_extension( make->importlib, ".a", ".def" ); - - if (!strncmp( def_file, "lib", 3 )) def_file += 3; - output( "%s: %s\n", obj_dir_path( make, make->importlib ), src_dir_path( make, def_file )); - output( "\t%s -l $@ -d %s\n", dlltool, src_dir_path( make, def_file )); - add_install_rule( make, install_rules, make->importlib, make->importlib, - strmake( "d$(libdir)/%s", make->importlib )); - strarray_add( &all_targets, make->importlib ); - } - - if (make->testdll) - { - char *testmodule = replace_extension( make->testdll, ".dll", "_test.exe" ); - char *stripped = replace_extension( make->testdll, ".dll", "_test-stripped.exe" ); - char *testres = replace_extension( make->testdll, ".dll", "_test.res" ); - struct strarray dep_libs = empty_strarray; - struct strarray all_libs = add_import_libs( make, &dep_libs, make->imports, 0 ); - - add_import_libs( make, &dep_libs, get_default_imports( make ), 0 ); /* dependencies only */ - strarray_addall( &all_libs, libs ); - strarray_add( &all_targets, strmake( "%s%s", testmodule, dll_ext )); - strarray_add( &clean_files, strmake( "%s%s", stripped, dll_ext )); - output( "%s%s:\n", obj_dir_path( make, testmodule ), dll_ext ); - output( "\t%s -o $@", tools_path( make, "winegcc" )); - output_filename( strmake( "-B%s", tools_dir_path( make, "winebuild" ))); - if (tools_dir) output_filename( strmake( "--sysroot=%s", top_obj_dir_path( make, "" ))); - output_filenames( target_flags ); - output_filenames( unwind_flags ); - output_filenames( make->appmode ); - output_filenames_obj_dir( make, object_files ); - output_filenames_obj_dir( make, res_files ); - output_filenames( all_libs ); - output_filename( "$(LDFLAGS)" ); - output( "\n" ); - output( "%s%s:\n", obj_dir_path( make, stripped ), dll_ext ); - output( "\t%s -o $@", tools_path( make, "winegcc" )); - output_filename( strmake( "-B%s", tools_dir_path( make, "winebuild" ))); - if (tools_dir) output_filename( strmake( "--sysroot=%s", top_obj_dir_path( make, "" ))); - output_filenames( target_flags ); - output_filenames( unwind_flags ); - output_filename( strmake( "-Wb,-F,%s", testmodule )); - output_filenames( make->appmode ); - output_filenames_obj_dir( make, object_files ); - output_filenames_obj_dir( make, res_files ); - output_filenames( all_libs ); - output_filename( "$(LDFLAGS)" ); - output( "\n" ); - output( "%s%s %s%s:", obj_dir_path( make, testmodule ), dll_ext, - obj_dir_path( make, stripped ), dll_ext ); - output_filenames_obj_dir( make, object_files ); - output_filenames_obj_dir( make, res_files ); - output_filenames( dep_libs ); - output_filename( tools_path( make, "winebuild" )); - output_filename( tools_path( make, "winegcc" )); - output( "\n" ); - - if (!make->disabled) - output( "all: %s/%s\n", top_obj_dir_path( make, "programs/winetest" ), testres ); - output( "%s/%s: %s%s\n", top_obj_dir_path( make, "programs/winetest" ), testres, - obj_dir_path( make, stripped ), dll_ext ); - output( "\techo \"%s TESTRES \\\"%s%s\\\"\" | %s -o $@\n", - testmodule, obj_dir_path( make, stripped ), dll_ext, tools_path( make, "wrc" )); - - if (crosstarget) - { - char *crosstest = replace_extension( make->testdll, ".dll", "_crosstest.exe" ); - - dep_libs = empty_strarray; - all_libs = add_import_libs( make, &dep_libs, make->imports, 1 ); - add_import_libs( make, &dep_libs, get_default_imports( make ), 1 ); /* dependencies only */ - strarray_addall( &all_libs, libs ); - strarray_add( &clean_files, crosstest ); - output( "%s:", obj_dir_path( make, crosstest )); - output_filenames_obj_dir( make, crossobj_files ); - output_filenames_obj_dir( make, res_files ); - output_filenames( dep_libs ); - output_filename( tools_path( make, "winebuild" )); - output_filename( tools_path( make, "winegcc" )); - output( "\n" ); - output( "\t%s -o $@ -b %s", tools_path( make, "winegcc" ), crosstarget ); - output_filename( strmake( "-B%s", tools_dir_path( make, "winebuild" ))); - if (tools_dir) output_filename( strmake( "--sysroot=%s", top_obj_dir_path( make, "" ))); - output_filename( "--lib-suffix=.cross.a" ); - output_filenames_obj_dir( make, crossobj_files ); - output_filenames_obj_dir( make, res_files ); - output_filenames( all_libs ); - output_filename( "$(LDFLAGS)" ); - output( "\n" ); - if (!make->disabled) - { - output( "%s: %s\n", obj_dir_path( make, "crosstest" ), obj_dir_path( make, crosstest )); - strarray_add( &phony_targets, obj_dir_path( make, "crosstest" )); - if (make->obj_dir) output( "crosstest: %s\n", obj_dir_path( make, "crosstest" )); - } - } - - output_filenames_obj_dir( make, ok_files ); - output( ": %s%s ../%s%s\n", testmodule, dll_ext, make->testdll, dll_ext ); - if (!make->disabled) - { - output( "check test:" ); - output_filenames_obj_dir( make, ok_files ); - output( "\n" ); - strarray_add( &phony_targets, "check" ); - strarray_add( &phony_targets, "test" ); - } - output( "testclean::\n" ); - output( "\trm -f" ); - output_filenames_obj_dir( make, ok_files ); - output( "\n" ); - strarray_addall( &clean_files, ok_files ); - strarray_add( &phony_targets, "testclean" ); - } - for (i = 0; i < make->programs.count; i++) { char *program_installed = NULL; char *program = strmake( "%s%s", make->programs.str[i], exe_ext ); - struct strarray deps = get_local_dependencies( make, make->programs.str[i], in_files ); + struct strarray deps = get_local_dependencies( make, make->programs.str[i], make->in_files ); struct strarray all_libs = get_expanded_file_local_var( make, make->programs.str[i], "LDFLAGS" ); struct strarray objs = get_expanded_file_local_var( make, make->programs.str[i], "OBJS" ); struct strarray symlinks = get_expanded_file_local_var( make, make->programs.str[i], "SYMLINKS" ); - if (!objs.count) objs = object_files; + if (!objs.count) objs = make->object_files; strarray_addall( &all_libs, add_default_libraries( make, &deps )); output( "%s:", obj_dir_path( make, program ) ); @@ -3074,121 +3170,171 @@ static struct strarray output_sources( const struct makefile *make ) output( "\t$(CC) -o $@" ); output_filenames_obj_dir( make, objs ); output_filename( ldrpath_install ); - strarray_add( &all_targets, program_installed ); + strarray_add( &make->all_targets, program_installed ); } } output_filenames( all_libs ); output_filename( "$(LDFLAGS)" ); output( "\n" ); - strarray_add( &all_targets, program ); + strarray_add( &make->all_targets, program ); for (j = 0; j < symlinks.count; j++) { output( "%s: %s\n", obj_dir_path( make, symlinks.str[j] ), obj_dir_path( make, program )); output_symlink_rule( obj_dir_path( make, program ), obj_dir_path( make, symlinks.str[j] )); } - strarray_addall( &all_targets, symlinks ); + strarray_addall( &make->all_targets, symlinks ); - add_install_rule( make, install_rules, program, program_installed ? program_installed : program, + add_install_rule( make, program, program_installed ? program_installed : program, strmake( "p$(bindir)/%s", program )); for (j = 0; j < symlinks.count; j++) - add_install_rule( make, install_rules, symlinks.str[j], program, + add_install_rule( make, symlinks.str[j], program, strmake( "y$(bindir)/%s%s", symlinks.str[j], exe_ext )); } +} + + +/******************************************************************* + * output_subdirs + */ +static void output_subdirs( struct makefile *make ) +{ + struct strarray build_deps = empty_strarray; + struct strarray makefile_deps = empty_strarray; + struct strarray distclean_files = get_expanded_make_var_array( make, "CONFIGURE_TARGETS" ); + unsigned int i; + + strarray_add( &distclean_files, obj_dir_path( make, output_makefile_name )); + if (!make->src_dir) strarray_add( &distclean_files, obj_dir_path( make, ".gitignore" )); + for (i = 0; i < make->subdirs.count; i++) + { + const struct makefile *submake = make->submakes[i]; + + strarray_add( &makefile_deps, top_src_dir_path( make, base_dir_path( submake, + strmake ( "%s.in", output_makefile_name )))); + strarray_add( &distclean_files, base_dir_path( submake, output_makefile_name )); + if (!make->src_dir) strarray_add( &distclean_files, base_dir_path( submake, ".gitignore" )); + if (submake->testdll) strarray_add( &distclean_files, base_dir_path( submake, "testlist.c" )); + strarray_addall( &build_deps, output_importlib_symlinks( make, submake )); + } + output( "Makefile:" ); + output_filenames( makefile_deps ); + output( "\n" ); + output_filenames( makefile_deps ); + output( ":\n" ); + output( "distclean::\n"); + output( "\trm -f" ); + output_filenames( distclean_files ); + output( "\n" ); + strarray_add( &make->phony_targets, "distclean" ); + + if (build_deps.count) + { + output( "__builddeps__:" ); + output_filenames( build_deps ); + output( "\n" ); + strarray_addall( &make->clean_files, build_deps ); + } + if (get_expanded_make_variable( make, "GETTEXTPO_LIBS" )) output_po_files( make ); +} + + +/******************************************************************* + * output_sources + */ +static struct strarray output_sources( struct makefile *make ) +{ + struct incl_file *source; + unsigned int i, j; + struct strarray uninstall_files = empty_strarray; + + strarray_add( &make->phony_targets, "all" ); + + LIST_FOR_EACH_ENTRY( source, &make->sources, struct incl_file, entry ) + { + char *obj = xstrdup( source->name ); + char *ext = get_extension( obj ); + + if (!ext) fatal_error( "unsupported file type %s\n", source->name ); + *ext++ = 0; + + for (j = 0; output_source_funcs[j].ext; j++) + if (!strcmp( ext, output_source_funcs[j].ext )) break; + + output_source_funcs[j].fn( make, source, obj ); + free( obj ); + } + + if (make->dlldata_files.count) + { + output( "%s: %s %s\n", obj_dir_path( make, "dlldata.c" ), + tools_path( make, "widl" ), src_dir_path( make, "Makefile.in" )); + output( "\t%s --dlldata-only -o $@", tools_path( make, "widl" )); + output_filenames( make->dlldata_files ); + output( "\n" ); + } + + if (make->staticlib) output_static_lib( make ); + else if (make->module) output_module( make ); + else if (make->importlib) output_import_lib( make ); + else if (make->sharedlib) output_shared_lib( make ); + else if (make->testdll) output_test_module( make ); + + if (make->programs.count) output_programs( make ); for (i = 0; i < make->scripts.count; i++) - add_install_rule( make, install_rules, make->scripts.str[i], make->scripts.str[i], + add_install_rule( make, make->scripts.str[i], make->scripts.str[i], strmake( "S$(bindir)/%s", make->scripts.str[i] )); + if (make->subdirs.count) output_subdirs( make ); + if (!make->disabled) { - if (all_targets.count) + if (make->all_targets.count) { output( "all:" ); - output_filenames_obj_dir( make, all_targets ); + output_filenames_obj_dir( make, make->all_targets ); output( "\n" ); } - strarray_addall( &uninstall_files, output_install_rules( make, install_rules[INSTALL_LIB], - "install-lib", &phony_targets )); - strarray_addall( &uninstall_files, output_install_rules( make, install_rules[INSTALL_DEV], - "install-dev", &phony_targets )); + strarray_addall( &uninstall_files, output_install_rules( make, INSTALL_LIB, "install-lib" )); + strarray_addall( &uninstall_files, output_install_rules( make, INSTALL_DEV, "install-dev" )); if (uninstall_files.count) { output( "uninstall::\n" ); output( "\trm -f" ); output_filenames( uninstall_files ); output( "\n" ); - strarray_add_uniq( &phony_targets, "uninstall" ); + strarray_add_uniq( &make->phony_targets, "uninstall" ); } } - strarray_addall( &clean_files, object_files ); - strarray_addall( &clean_files, crossobj_files ); - strarray_addall( &clean_files, res_files ); - strarray_addall( &clean_files, all_targets ); - strarray_addall( &clean_files, get_expanded_make_var_array( make, "EXTRA_TARGETS" )); + strarray_addall( &make->clean_files, make->object_files ); + for (i = 0; i < make->crossobj_files.count; i++) + strarray_add_uniq( &make->clean_files, make->crossobj_files.str[i] ); + strarray_addall( &make->clean_files, make->all_targets ); + strarray_addall( &make->clean_files, get_expanded_make_var_array( make, "EXTRA_TARGETS" )); - if (make->subdirs.count) - { - struct strarray build_deps = empty_strarray; - struct strarray makefile_deps = empty_strarray; - struct strarray distclean_files = get_expanded_make_var_array( make, "CONFIGURE_TARGETS" ); - - strarray_add( &distclean_files, obj_dir_path( make, output_makefile_name )); - if (!make->src_dir) strarray_add( &distclean_files, obj_dir_path( make, ".gitignore" )); - for (i = 0; i < make->subdirs.count; i++) - { - const struct makefile *submake = make->submakes[i]; - - strarray_add( &makefile_deps, top_src_dir_path( make, base_dir_path( submake, - strmake ( "%s.in", output_makefile_name )))); - strarray_add( &distclean_files, base_dir_path( submake, output_makefile_name )); - if (!make->src_dir) strarray_add( &distclean_files, base_dir_path( submake, ".gitignore" )); - if (submake->testdll) strarray_add( &distclean_files, base_dir_path( submake, "testlist.c" )); - strarray_addall( &build_deps, output_importlib_symlinks( make, submake )); - } - output( "Makefile:" ); - output_filenames( makefile_deps ); - output( "\n" ); - output_filenames( makefile_deps ); - output( ":\n" ); - output( "distclean::\n"); - output( "\trm -f" ); - output_filenames( distclean_files ); - output( "\n" ); - strarray_add( &phony_targets, "distclean" ); - - if (build_deps.count) - { - output( "__builddeps__:" ); - output_filenames( build_deps ); - output( "\n" ); - strarray_addall( &clean_files, build_deps ); - } - if (get_expanded_make_variable( make, "GETTEXTPO_LIBS" )) output_po_files( make ); - } - - if (clean_files.count) + if (make->clean_files.count) { output( "%s::\n", obj_dir_path( make, "clean" )); output( "\trm -f" ); - output_filenames_obj_dir( make, clean_files ); + output_filenames_obj_dir( make, make->clean_files ); output( "\n" ); if (make->obj_dir) output( "__clean__: %s\n", obj_dir_path( make, "clean" )); - strarray_add( &phony_targets, obj_dir_path( make, "clean" )); + strarray_add( &make->phony_targets, obj_dir_path( make, "clean" )); } - if (phony_targets.count) + if (make->phony_targets.count) { output( ".PHONY:" ); - output_filenames( phony_targets ); + output_filenames( make->phony_targets ); output( "\n" ); } if (!make->base_dir) - strarray_addall( &clean_files, get_expanded_make_var_array( make, "CONFIGURE_TARGETS" )); - return clean_files; + strarray_addall( &make->clean_files, get_expanded_make_var_array( make, "CONFIGURE_TARGETS" )); + return make->clean_files; } @@ -3385,7 +3531,7 @@ static void output_top_variables( const struct makefile *make ) /******************************************************************* * output_dependencies */ -static void output_dependencies( const struct makefile *make ) +static void output_dependencies( struct makefile *make ) { struct strarray targets, ignore_files = empty_strarray; char buffer[1024]; @@ -3507,6 +3653,7 @@ static void load_sources( struct makefile *make ) } make->include_paths = empty_strarray; + make->include_args = empty_strarray; make->define_args = empty_strarray; strarray_add( &make->define_args, "-D__WINESRC__" ); @@ -3518,6 +3665,19 @@ static void load_sources( struct makefile *make ) strarray_add_uniq( &make->define_args, value.str[i] ); strarray_addall( &make->define_args, get_expanded_make_var_array( make, "EXTRADEFS" )); + strarray_add( &make->include_args, strmake( "-I%s", obj_dir_path( make, "" ))); + if (make->src_dir) + strarray_add( &make->include_args, strmake( "-I%s", make->src_dir )); + if (make->parent_dir) + strarray_add( &make->include_args, strmake( "-I%s", src_dir_path( make, make->parent_dir ))); + strarray_add( &make->include_args, strmake( "-I%s", top_obj_dir_path( make, "include" ))); + if (make->top_src_dir) + strarray_add( &make->include_args, strmake( "-I%s", top_src_dir_path( make, "include" ))); + if (make->use_msvcrt) + strarray_add( &make->include_args, strmake( "-I%s", top_src_dir_path( make, "include/msvcrt" ))); + for (i = 0; i < make->include_paths.count; i++) + strarray_add( &make->include_args, strmake( "-I%s", obj_dir_path( make, make->include_paths.str[i] ))); + list_init( &make->sources ); list_init( &make->includes ); @@ -3540,6 +3700,7 @@ static void load_sources( struct makefile *make ) } LIST_FOR_EACH_ENTRY( file, &make->includes, struct incl_file, entry ) parse_file( make, file, 0 ); + LIST_FOR_EACH_ENTRY( file, &make->sources, struct incl_file, entry ) get_dependencies( file, file ); }