From da340169d6518cf42f1cbe169fbf120383202bdc Mon Sep 17 00:00:00 2001
From: Alexandre Julliard <julliard@winehq.org>
Date: Thu, 29 Oct 2015 14:32:45 +0900
Subject: [PATCH] makefiles: Generate rules for installing programs.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
---
 configure                   |  15 +---
 configure.ac                |  15 +---
 server/Makefile.in          |   8 +--
 tools/make_makefiles        |   5 ++
 tools/makedep.c             | 135 +++++++++++++++++++++++++++++-------
 tools/widl/Makefile.in      |   8 +--
 tools/winebuild/Makefile.in |   8 +--
 tools/winedump/Makefile.in  |   7 +-
 tools/winegcc/Makefile.in   |   9 ++-
 tools/winemaker/Makefile.in |   4 +-
 tools/wmc/Makefile.in       |   8 +--
 tools/wrc/Makefile.in       |   8 +--
 12 files changed, 133 insertions(+), 97 deletions(-)

diff --git a/configure b/configure
index 8cf26e4344d..b3a1f26ca54 100755
--- a/configure
+++ b/configure
@@ -7852,12 +7852,6 @@ libwine_soversion=`expr $libwine_version : '\([0-9]*\)\..*'`
 
 LOADER_RULES="
 all: wine.inf
-
-install install-lib:: $wine_binary-installed
-	\$(INSTALL_PROGRAM) $wine_binary-installed \$(DESTDIR)\$(bindir)/$wine_binary
-
-uninstall::
-	\$(RM) \$(DESTDIR)\$(bindir)/$wine_binary
 "
 
 
@@ -14945,18 +14939,13 @@ case $host_os in
 preloader_EXTRADEFS = $BUILTINFLAG
 ${wine_binary}_preloader_OBJS = preloader.o
 ${wine_binary}_preloader_LDFLAGS = -static -nostartfiles -nodefaultlibs -Wl,-Ttext=0x7c400000
-
-install install-lib:: $wine_binary-preloader
-	\$(INSTALL_PROGRAM) $wine_binary-preloader \$(DESTDIR)\$(bindir)/$wine_binary-preloader
-
-uninstall::
-	\$(RM) \$(DESTDIR)\$(bindir)/$wine_binary-preloader
 " ;;
     esac
     ;;
 esac
 as_fn_append LOADER_RULES "
 PROGRAMS = $loader_programs
+INSTALL_LIB = $loader_programs
 "
 
 
@@ -18291,7 +18280,7 @@ clean::
 	\$(RM) fonts server tools $with_wine64/loader/wine $with_wine64/loader/wine-preloader"
 else
     as_fn_append LOADER_RULES "
-install install-lib:: wine.inf install-man-pages
+install install-lib:: wine.inf
 	\$(INSTALL_DATA) wine.inf \$(DESTDIR)\$(datadir)/wine/wine.inf
 	\$(INSTALL_DATA) \$(srcdir)/l_intl.nls \$(DESTDIR)\$(datadir)/wine/l_intl.nls
 
diff --git a/configure.ac b/configure.ac
index ff74f8dfca9..3d48b67df95 100644
--- a/configure.ac
+++ b/configure.ac
@@ -691,12 +691,6 @@ libwine_soversion=`expr $libwine_version : '\([[0-9]]*\)\..*'`
 
 AC_SUBST(LOADER_RULES,["
 all: wine.inf
-
-install install-lib:: $wine_binary-installed
-	\$(INSTALL_PROGRAM) $wine_binary-installed \$(DESTDIR)\$(bindir)/$wine_binary
-
-uninstall::
-	\$(RM) \$(DESTDIR)\$(bindir)/$wine_binary
 "])
 
 case $host_os in
@@ -2039,18 +2033,13 @@ case $host_os in
 preloader_EXTRADEFS = $BUILTINFLAG
 ${wine_binary}_preloader_OBJS = preloader.o
 ${wine_binary}_preloader_LDFLAGS = -static -nostartfiles -nodefaultlibs -Wl,-Ttext=0x7c400000
-
-install install-lib:: $wine_binary-preloader
-	\$(INSTALL_PROGRAM) $wine_binary-preloader \$(DESTDIR)\$(bindir)/$wine_binary-preloader
-
-uninstall::
-	\$(RM) \$(DESTDIR)\$(bindir)/$wine_binary-preloader
 "]) ;;
     esac
     ;;
 esac
 AS_VAR_APPEND([LOADER_RULES],["
 PROGRAMS = $loader_programs
+INSTALL_LIB = $loader_programs
 "])
 
 dnl **** Check for functions ****
@@ -3758,7 +3747,7 @@ clean::
 	\$(RM) fonts server tools $with_wine64/loader/wine $with_wine64/loader/wine-preloader])
 else
     AS_VAR_APPEND([LOADER_RULES],["
-install install-lib:: wine.inf install-man-pages
+install install-lib:: wine.inf
 	\$(INSTALL_DATA) wine.inf \$(DESTDIR)\$(datadir)/wine/wine.inf
 	\$(INSTALL_DATA) \$(srcdir)/l_intl.nls \$(DESTDIR)\$(datadir)/wine/l_intl.nls
 
diff --git a/server/Makefile.in b/server/Makefile.in
index 7a1ac11489b..75ba1997c80 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -52,10 +52,4 @@ MANPAGES = \
 
 EXTRALIBS = -lwine $(POLL_LIBS) $(RT_LIBS)
 
-.PHONY: install install-lib uninstall
-
-install install-lib:: wineserver-installed install-man-pages
-	$(INSTALL_PROGRAM) wineserver-installed $(DESTDIR)$(bindir)/wineserver
-
-uninstall::
-	$(RM) $(DESTDIR)$(bindir)/wineserver
+INSTALL_LIB = $(PROGRAMS)
diff --git a/tools/make_makefiles b/tools/make_makefiles
index 069d0ae9b7c..4b539cdbefb 100755
--- a/tools/make_makefiles
+++ b/tools/make_makefiles
@@ -274,6 +274,11 @@ sub parse_makefile($)
             ${$make{"=flags"}}{"clean"} = 1 if $var eq "EXTRA_TARGETS";
             next;
         }
+        if (/^\s*INSTALL_(LIB|DEV)\s*=\s*/)
+        {
+            ${$make{"=flags"}}{$1 eq "LIB" ? "install-lib" : "install-dev"} = 1;
+            next;
+        }
         if (/(install-lib|install-dev|clean)\s*:/)
         {
             ${$make{"=flags"}}{$1} = 1;
diff --git a/tools/makedep.c b/tools/makedep.c
index 295e5e8386f..9a21397003b 100644
--- a/tools/makedep.c
+++ b/tools/makedep.c
@@ -154,6 +154,10 @@ struct makefile
     struct strarray imports;
     struct strarray delayimports;
     struct strarray extradllflags;
+    struct strarray install_lib;
+    struct strarray install_dev;
+    struct strarray install_lib_rules;
+    struct strarray install_dev_rules;
     struct list     sources;
     struct list     includes;
     const char     *base_dir;
@@ -1756,6 +1760,92 @@ static void output_include( struct incl_file *pFile, struct incl_file *owner )
 }
 
 
+/*******************************************************************
+ *         add_install_rule
+ */
+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( &make->install_lib_rules, file );
+        strarray_add( &make->install_lib_rules, dest );
+    }
+    else if (strarray_exists( &make->install_dev, target ))
+    {
+        strarray_add( &make->install_dev_rules, file );
+        strarray_add( &make->install_dev_rules, dest );
+    }
+}
+
+
+/*******************************************************************
+ *         output_install_rules
+ *
+ * Rules are stored as a (file,dest) pair of values.
+ * The first char of dest indicates the type of install.
+ */
+static void output_install_rules( struct makefile *make, struct strarray files,
+                                  const char *target, struct strarray *phony_targets )
+{
+    unsigned int i;
+    char *install_sh;
+    struct strarray targets = empty_strarray;
+
+    if (!files.count) return;
+
+    for (i = 0; i < files.count; i += 2)
+        if (files.str[i + 1][0] >= 'a' && files.str[i + 1][0] <= 'z')  /* only for files in object dir */
+            strarray_add_uniq( &targets, files.str[i] );
+
+    output( "install %s::", target );
+    output_filenames_obj_dir( make, targets );
+    output( "\n" );
+
+    install_sh = top_dir_path( make, "tools/install-sh" );
+    for (i = 0; i < files.count; i += 2)
+    {
+        const char *file = files.str[i];
+        const char *dest = files.str[i + 1];
+
+        switch (*dest)
+        {
+        case 'd':  /* data file */
+            output( "\t%s -m 644 $(INSTALL_DATA_FLAGS) %s $(DESTDIR)%s\n",
+                    install_sh, obj_dir_path( make, file ), dest + 1 );
+            break;
+        case 'D':  /* data file in source dir */
+            output( "\t%s -m 644 $(INSTALL_DATA_FLAGS) %s $(DESTDIR)%s\n",
+                    install_sh, src_dir_path( make, file ), dest + 1 );
+            break;
+        case 'p':  /* program file */
+            output( "\tSTRIPPROG=\"$(STRIP)\" %s $(INSTALL_PROGRAM_FLAGS) %s $(DESTDIR)%s\n",
+                    install_sh, obj_dir_path( make, file ), dest + 1 );
+            break;
+        case 's':  /* script */
+            output( "\t%s $(INSTALL_SCRIPT_FLAGS) %s $(DESTDIR)%s\n",
+                    install_sh, obj_dir_path( make, file ), dest + 1 );
+            break;
+        case 'S':  /* script in source dir */
+            output( "\t%s $(INSTALL_SCRIPT_FLAGS) %s $(DESTDIR)%s\n",
+                    install_sh, src_dir_path( make, file ), dest + 1 );
+            break;
+        default:
+            assert(0);
+        }
+    }
+
+    output( "uninstall::\n" );
+    output( "\t$(RM)" );
+    for (i = 0; i < files.count; i += 2) output_filename( strmake( "$(DESTDIR)%s", files.str[i + 1] + 1 ));
+    output( "\n" );
+
+    strarray_add( phony_targets, "install" );
+    strarray_add( phony_targets, target );
+    strarray_add( phony_targets, "uninstall" );
+}
+
+
 /*******************************************************************
  *         output_sources
  */
@@ -1933,18 +2023,13 @@ static struct strarray output_sources( struct makefile *make, struct strarray *t
                 if (lang)
                 {
                     *lang++ = 0;
-                    dir = strmake( "$(DESTDIR)$(mandir)/%s/man%s", lang, section );
+                    dir = strmake( "$(mandir)/%s/man%s", lang, section );
                 }
-                else dir = strmake( "$(DESTDIR)$(mandir)/man%s", section );
-                output( "install-man-pages:: %s\n", obj_dir_path( make, obj ));
-                output( "\t$(INSTALL_DATA) %s %s/%s.%s\n", obj_dir_path( make, obj ), dir, dest, section );
-                output( "uninstall::\n" );
-                output( "\t$(RM) %s/%s.%s\n", dir, dest, section );
+                else dir = strmake( "$(mandir)/man%s", section );
+                add_install_rule( make, dest, xstrdup(obj), strmake( "d%s/%s.%s", dir, dest, section ));
                 free( dest );
                 free( dir );
                 strarray_add( &all_targets, xstrdup(obj) );
-                strarray_add_uniq( &phony_targets, "install-man-pages" );
-                strarray_add_uniq( &phony_targets, "uninstall" );
             }
             else strarray_add( &clean_files, xstrdup(obj) );
             output( "%s: %s\n", obj_dir_path( make, obj ), source->filename );
@@ -1963,10 +2048,8 @@ static struct strarray output_sources( struct makefile *make, struct strarray *t
             }
             if (source->file->flags & FLAG_INSTALL)
             {
-                output( "install install-lib::\n" );
-                output( "\t$(INSTALL_DATA) %s $(DESTDIR)$(fontdir)/%s.ttf\n", ttf_file, obj );
-                output( "uninstall::\n" );
-                output( "\t$(RM) $(DESTDIR)$(fontdir)/%s.ttf\n", obj );
+                strarray_add( &make->install_lib_rules, ttf_file );
+                strarray_add( &make->install_lib_rules, strmake( "D$(fontdir)/%s.ttf", obj ));
             }
             if (source->file->flags & FLAG_SFD_FONTS)
             {
@@ -1981,19 +2064,10 @@ static struct strarray output_sources( struct makefile *make, struct strarray *t
                     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 );
-                    output( "install install-lib:: %s\n", font );
-                    output( "\t$(INSTALL_DATA) %s $(DESTDIR)$(fontdir)/%s\n",
-                            obj_dir_path( make, font ), font );
-                    output( "uninstall::\n" );
-                    output( "\t$(RM) $(DESTDIR)$(fontdir)/%s\n", font );
+                    strarray_add( &make->install_lib_rules, xstrdup(font) );
+                    strarray_add( &make->install_lib_rules, strmake( "d$(fontdir)/%s", font ));
                 }
             }
-            if (source->file->flags & (FLAG_INSTALL | FLAG_SFD_FONTS))
-            {
-                strarray_add_uniq( &phony_targets, "install" );
-                strarray_add_uniq( &phony_targets, "install-lib" );
-                strarray_add_uniq( &phony_targets, "uninstall" );
-            }
             continue;  /* no dependencies */
         }
         else if (!strcmp( ext, "svg" ))  /* svg file */
@@ -2367,6 +2441,7 @@ static struct strarray output_sources( struct makefile *make, struct strarray *t
 
     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 all_libs = empty_strarray;
         struct strarray objs = get_expanded_make_var_array( make,
@@ -2389,8 +2464,7 @@ static struct strarray output_sources( struct makefile *make, struct strarray *t
             strarray_add( &all_libs, strmake( "-L%s", top_obj_dir_path( make, "libs/wine" )));
             if (ldrpath_local && ldrpath_install)
             {
-                char *program_installed = strmake( "%s-installed%s", make->programs.str[i], exe_ext );
-
+                program_installed = strmake( "%s-installed%s", make->programs.str[i], exe_ext );
                 output_filename( ldrpath_local );
                 output_filenames( all_libs );
                 output_filename( "$(LDFLAGS)" );
@@ -2409,6 +2483,9 @@ static struct strarray output_sources( struct makefile *make, struct strarray *t
         output_filename( "$(LDFLAGS)" );
         output( "\n" );
         strarray_add( &all_targets, program );
+
+        add_install_rule( make, program, program_installed ? program_installed : program,
+                          strmake( "p$(bindir)/%s", program ));
     }
 
     if (all_targets.count)
@@ -2418,6 +2495,9 @@ static struct strarray output_sources( struct makefile *make, struct strarray *t
         output( "\n" );
     }
 
+    output_install_rules( make, make->install_lib_rules, "install-lib", &phony_targets );
+    output_install_rules( make, make->install_dev_rules, "install-dev", &phony_targets );
+
     strarray_addall( &clean_files, object_files );
     strarray_addall( &clean_files, crossobj_files );
     strarray_addall( &clean_files, res_files );
@@ -2699,6 +2779,8 @@ static void update_makefile( const char *path )
     make->imports       = get_expanded_make_var_array( make, "IMPORTS" );
     make->delayimports  = get_expanded_make_var_array( make, "DELAYIMPORTS" );
     make->extradllflags = get_expanded_make_var_array( make, "EXTRADLLFLAGS" );
+    make->install_lib   = get_expanded_make_var_array( make, "INSTALL_LIB" );
+    make->install_dev   = get_expanded_make_var_array( make, "INSTALL_DEV" );
 
     if (make->module && strendswith( make->module, ".a" )) make->staticlib = make->module;
 
@@ -2708,6 +2790,9 @@ static void update_makefile( const char *path )
     for (i = 0; i < make->imports.count && !make->use_msvcrt; i++)
         make->use_msvcrt = !strncmp( make->imports.str[i], "msvcr", 5 );
 
+    make->install_lib_rules = empty_strarray;
+    make->install_dev_rules = empty_strarray;
+
     make->include_args = empty_strarray;
     make->define_args = empty_strarray;
     strarray_add( &make->define_args, "-D__WINESRC__" );
diff --git a/tools/widl/Makefile.in b/tools/widl/Makefile.in
index 0c5595ee7af..f8111f3c2f8 100644
--- a/tools/widl/Makefile.in
+++ b/tools/widl/Makefile.in
@@ -23,10 +23,4 @@ widl_EXTRADEFS = -DDEFAULT_INCLUDE_DIR=\"${includedir}/windows/\"
 
 EXTRALIBS = $(LIBWPP)
 
-.PHONY: install install-dev uninstall
-
-install install-dev:: widl$(EXEEXT) install-man-pages
-	$(INSTALL_PROGRAM) widl$(EXEEXT) $(DESTDIR)$(bindir)/widl$(EXEEXT)
-
-uninstall::
-	$(RM) $(DESTDIR)$(bindir)/widl$(EXEEXT)
+INSTALL_DEV = $(PROGRAMS)
diff --git a/tools/winebuild/Makefile.in b/tools/winebuild/Makefile.in
index 39589027a51..0511012742e 100644
--- a/tools/winebuild/Makefile.in
+++ b/tools/winebuild/Makefile.in
@@ -12,10 +12,4 @@ C_SRCS = \
 	spec32.c \
 	utils.c
 
-.PHONY: install install-dev uninstall
-
-install install-dev:: winebuild$(EXEEXT) install-man-pages
-	$(INSTALL_PROGRAM) winebuild$(EXEEXT) $(DESTDIR)$(bindir)/winebuild$(EXEEXT)
-
-uninstall::
-	$(RM) $(DESTDIR)$(bindir)/winebuild$(EXEEXT)
+INSTALL_DEV = $(PROGRAMS)
diff --git a/tools/winedump/Makefile.in b/tools/winedump/Makefile.in
index dd36cff9d27..a93f078eeb6 100644
--- a/tools/winedump/Makefile.in
+++ b/tools/winedump/Makefile.in
@@ -23,11 +23,10 @@ C_SRCS = \
 	symbol.c \
 	tlb.c
 
-.PHONY: install install-dev uninstall
+INSTALL_DEV = $(PROGRAMS)
 
-install install-dev:: winedump$(EXEEXT) install-man-pages
-	$(INSTALL_PROGRAM) winedump$(EXEEXT) $(DESTDIR)$(bindir)/winedump$(EXEEXT)
+install install-dev::
 	$(INSTALL_SCRIPT) $(srcdir)/function_grep.pl $(DESTDIR)$(bindir)/function_grep.pl
 
 uninstall::
-	$(RM) $(DESTDIR)$(bindir)/function_grep.pl $(DESTDIR)$(bindir)/winedump$(EXEEXT)
+	$(RM) $(DESTDIR)$(bindir)/function_grep.pl
diff --git a/tools/winegcc/Makefile.in b/tools/winegcc/Makefile.in
index 3c0670beab5..1a3b2a73565 100644
--- a/tools/winegcc/Makefile.in
+++ b/tools/winegcc/Makefile.in
@@ -16,6 +16,8 @@ winegcc_EXTRADEFS = \
 	-DLD="\"$(LD)\"" \
 	-DPRELINK="\"$(PRELINK)\""
 
+INSTALL_DEV = $(PROGRAMS)
+
 EXTRA_TARGETS = winecpp$(EXEEXT) wineg++$(EXEEXT)
 
 all: $(EXTRA_TARGETS)
@@ -23,15 +25,12 @@ all: $(EXTRA_TARGETS)
 winecpp$(EXEEXT) wineg++$(EXEEXT): winegcc$(EXEEXT)
 	$(RM) $@ && $(LN_S) winegcc$(EXEEXT) $@
 
-.PHONY: install install-dev uninstall
-
-install install-dev:: winegcc$(EXEEXT) install-man-pages
-	$(INSTALL_PROGRAM) winegcc$(EXEEXT) $(DESTDIR)$(bindir)/winegcc$(EXEEXT)
+install install-dev::
 	cd $(DESTDIR)$(bindir) && $(RM) wineg++$(EXEEXT) && $(LN_S) winegcc$(EXEEXT) wineg++$(EXEEXT)
 	cd $(DESTDIR)$(bindir) && $(RM) winecpp$(EXEEXT) && $(LN_S) winegcc$(EXEEXT) winecpp$(EXEEXT)
 	cd $(DESTDIR)$(mandir)/man$(prog_manext) && $(RM) wineg++.$(prog_manext) && $(LN_S) winegcc.$(prog_manext) wineg++.$(prog_manext)
 	cd $(DESTDIR)$(mandir)/man$(prog_manext) && $(RM) winecpp.$(prog_manext) && $(LN_S) winegcc.$(prog_manext) winecpp.$(prog_manext)
 
 uninstall::
-	$(RM) $(DESTDIR)$(bindir)/winegcc$(EXEEXT) $(DESTDIR)$(bindir)/wineg++$(EXEEXT) $(DESTDIR)$(bindir)/winecpp$(EXEEXT)
+	$(RM) $(DESTDIR)$(bindir)/wineg++$(EXEEXT) $(DESTDIR)$(bindir)/winecpp$(EXEEXT)
 	$(RM) $(DESTDIR)$(mandir)/man$(prog_manext)/wineg++.$(prog_manext) $(DESTDIR)$(mandir)/man$(prog_manext)/winecpp.$(prog_manext)
diff --git a/tools/winemaker/Makefile.in b/tools/winemaker/Makefile.in
index 7095ecf0dde..6afa0166848 100644
--- a/tools/winemaker/Makefile.in
+++ b/tools/winemaker/Makefile.in
@@ -3,9 +3,9 @@ MANPAGES = \
 	winemaker.fr.UTF-8.man.in \
 	winemaker.man.in
 
-.PHONY: install install-dev uninstall
+INSTALL_DEV = winemaker
 
-install install-dev:: install-man-pages
+install install-dev::
 	$(INSTALL_SCRIPT) $(srcdir)/winemaker $(DESTDIR)$(bindir)/winemaker
 
 uninstall::
diff --git a/tools/wmc/Makefile.in b/tools/wmc/Makefile.in
index 12a917d2908..41b72369d19 100644
--- a/tools/wmc/Makefile.in
+++ b/tools/wmc/Makefile.in
@@ -13,10 +13,4 @@ BISON_SRCS = mcy.y
 
 EXTRALIBS = $(GETTEXTPO_LIBS) $(LIBWINE_STATIC)
 
-.PHONY: install install-dev uninstall
-
-install install-dev:: wmc$(EXEEXT) install-man-pages
-	$(INSTALL_PROGRAM) wmc$(EXEEXT) $(DESTDIR)$(bindir)/wmc$(EXEEXT)
-
-uninstall::
-	$(RM) $(DESTDIR)$(bindir)/wmc$(EXEEXT)
+INSTALL_DEV = $(PROGRAMS)
diff --git a/tools/wrc/Makefile.in b/tools/wrc/Makefile.in
index b6f80936776..37dbe031112 100644
--- a/tools/wrc/Makefile.in
+++ b/tools/wrc/Makefile.in
@@ -19,10 +19,4 @@ wrc_EXTRADEFS = -DINCLUDEDIR="\"${includedir}\""
 
 EXTRALIBS = $(GETTEXTPO_LIBS) $(LIBWPP) $(LIBWINE_STATIC)
 
-.PHONY: install install-dev uninstall
-
-install install-dev:: wrc$(EXEEXT) install-man-pages
-	$(INSTALL_PROGRAM) wrc$(EXEEXT) $(DESTDIR)$(bindir)/wrc$(EXEEXT)
-
-uninstall::
-	$(RM) $(DESTDIR)$(bindir)/wrc$(EXEEXT)
+INSTALL_DEV = $(PROGRAMS)
-- 
GitLab