automake-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 5/8] Qt: another major cleanup, support for per-executable flags


From: Gergely Risko
Subject: [PATCH 5/8] Qt: another major cleanup, support for per-executable flags and subdir-objects, silent rules.
Date: Wed, 8 Jul 2009 14:32:54 +0300

Moved the moc handling from handle_source_transform to
handle_single_transform.  Things like subdir-objects and perexec flags
are much easier to handle there.
---
 ChangeLog   |    2 +-
 automake.in |  107 +++++++++++++++++++++++++++++++++--------------------------
 2 files changed, 61 insertions(+), 48 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index c780be4..b9abf39 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,6 @@
 2009-07-07  Gergely Risko  <address@hidden>
 
-       * automake.in (handle_source_transform): added support for Qt, via
+       * automake.in (handle_single_transform): added support for Qt, via
        the new prog_QTSOURCES variable.
        * NEWS: updated.
 
diff --git a/automake.in b/automake.in
index abfb539..82ca558 100755
--- a/automake.in
+++ b/automake.in
@@ -556,6 +556,10 @@ my %object_map;
 # libtool compilation (the COMPILE_* constants).
 my %object_compilation_map;
 
+# We don't want to emit rules about Qt's MOC generation multiple
+# times.  This is why we have a hashset about the MOC files whose
+# output rules are already printed.
+my %qtmoc_already_generated;
 
 # This keeps track of the directories for which we've already
 # created dirstamp code.  Keys are directories, values are stamp files.
@@ -695,6 +699,7 @@ sub initialize_per_input ()
 
     %object_map = ();
     %object_compilation_map = ();
+    %qtmoc_already_generated = ();
 
     %directory_map = ();
 
@@ -1766,6 +1771,13 @@ sub handle_single_transform ($$$$$%)
     my $nonansi_obj = $obj;
     $nonansi_obj =~ s/\$U//g;
 
+    my $qtsourcesvar = set_seen $derived . '_QTSOURCES';
+    my %qtsources = ();
+    if ($qtsourcesvar)
+    {
+       define_verbose_var ('MOC', '@echo "  MOC   " $@;');
+       for ($qtsourcesvar->value_as_list_recursive) { $qtsources{$_} = 1; }
+    }
     # Turn sources into objects.  We use a while loop like this
     # because we might add to @files in the loop.
     while (scalar @files > 0)
@@ -1843,6 +1855,46 @@ sub handle_single_transform ($$$$$%)
            my ($r, $source_extension)
                = &$subr ($directory, $base, $extension,
                          $nonansi_obj, $have_per_exec_flags, $var);
+
+           # handle target_QTSOURCES variable:
+           my $mocresult = '';
+           if ($qtsources{$full})
+           {
+               # compute the filename that should be used for the
+               # moc output in $mocresult
+               # if we have subdir-objects it starts with the directory
+               $mocresult .= $directory . "/"
+                   if ($directory ne '' && option 'subdir-objects');
+               # then moc_foo.cpp if orig was foo.h or foo.moc if
+               # orig was foo.cpp
+               if ($lang->name eq 'header')
+               {
+                   # if the orig was a header then we have to compile
+                   # the resulted moc with a c++ compiler
+                   $mocresult .=  'moc_' . $base . '.cpp';
+                   unshift (@files, $mocresult);
+               }
+               elsif ($lang->name eq 'cxx')
+               {
+                   $mocresult .= $base . '.moc';
+               }
+               else
+               {
+                   # we only handle meta object compilation for
+                   # sources and headers, nothing else
+                   err_am("$full mentioned in QTSOURCES is neither a header 
nor a C++ file");
+               }
+               # we always clean the compiled moc during make clean
+               $compile_clean_files{$mocresult} = MOSTLY_CLEAN;
+               # but we can rebuild it anytime with this rule
+               if (! $qtmoc_already_generated{$mocresult})
+               {
+                   my $verbose = verbose_flag ('MOC');
+                   $output_rules .= "$mocresult: $full\n".
+                       "\t$verbose\$(MOC) \$(AM_MOCFLAGS) -o \$\@ \$<\n";
+                   $qtmoc_already_generated{$mocresult} = 1;
+               }
+           }
            # Skip this entry if we were asked not to process it.
            next if $r == LANG_IGNORE;
 
@@ -1903,6 +1955,14 @@ sub handle_single_transform ($$$$$%)
                $object = $directory . '/' . $object;
            }
 
+           if ($qtsources{$full} && $lang->name eq 'cxx') {
+               # if we moc a c++ file then the result will be
+               # included back in the c++ file, so we have to put
+               # an explicit dependency from the source to the
+               # generated meta code
+               $output_rules .= "$object: $mocresult\n";
+           }
+
            # If the object file has been renamed (because per-target
            # flags are used) we cannot compile the file with an
            # inference rule: we need an explicit rule.
@@ -2265,53 +2325,6 @@ sub handle_source_transform ($$$$%)
     else
     {
        @keys = map { '$(' . $_ . $one_file . '_OBJECTS)' } @keys;
-       # handle target_QTSOURCES variable:
-       my $var = set_seen $one_file . '_QTSOURCES';
-       if ($var)
-       {
-           # check that all of the qtsources are defined as sources
-
-           my @mocobjects = ();
-           foreach my $file ($var->value_as_list_recursive)
-           {
-               # FIXME: instead of .h use something more general
-               # (e.g. the extension list from the language 'header')
-               if ($file =~ s/\.h$//)
-               {
-                   # add %.h files as moc_%.o to target_QTOBJECTS
-                   push @mocobjects, 'moc_' . $file .
-                       ( $transform{'LIBTOOL'} ? '.lo' : '.$(OBJEXT)' );
-                   # also add moc resulting source file to mostlyclean
-                   $compile_clean_files{"moc_$file.cpp"} = MOSTLY_CLEAN;
-                   # and create a make rule for the actual moccing
-                   #   moc_foo.cpp: foo.h
-                   #           $(MOC) -o $@ $<
-                   $output_rules .= "moc_$file.cpp: \$(srcdir)/$file.h\n".
-                     "\t\$(MOC) \$(AM_MOCFLAGS) -o \$\@ \$<\n";
-               }
-               else
-               {
-                   my $origname = $file;
-                   $file =~ s/\.[^.]+$//;
-                   # also add moc resulting source file to mostlyclean
-                   $compile_clean_files{"$file.moc"} = MOSTLY_CLEAN;
-                   # make rule for the moccing
-                   #   foo.moc: foo.cpp
-                   #           $(MOC) -o $@ $<
-                   $file =~ s/\.[^.]+$//;
-                   $output_rules .= "$file.moc: \$(srcdir)/$origname\n".
-                     "\t\$(MOC) \$(AM_MOCFLAGS) -o \$\@ \$<\n";
-               }
-           }
-           # if there were .h files, then add target_QTOBJECTS to
-           # target_OBJECTS
-           if (@mocobjects)
-           {
-               my $where = $var->rdef (TRUE)->location;
-               define_pretty_variable ($one_file . '_QTOBJECTS', TRUE, $where, 
@mocobjects);
-               push @keys, '$(' . $one_file . '_QTOBJECTS)' if $var;
-           }
-       }
        define_pretty_variable ($one_file . '_OBJECTS', TRUE, $where, @keys);
     }
 
-- 
1.6.3.3





reply via email to

[Prev in Thread] Current Thread [Next in Thread]