| 1 | #!/usr/bin/perl -w |
|---|
| 2 | |
|---|
| 3 | # Expands the specialised KDE tags in Makefile.in to (hopefully) valid |
|---|
| 4 | # make syntax. |
|---|
| 5 | # When called without file parameters, we work recursively on all Makefile.in |
|---|
| 6 | # in and below the current subdirectory. When called with file parameters, |
|---|
| 7 | # only those Makefile.in are changed. |
|---|
| 8 | # The currently supported tags are |
|---|
| 9 | # |
|---|
| 10 | # {program}_METASOURCES |
|---|
| 11 | # where you have a choice of two styles |
|---|
| 12 | # {program}_METASOURCES = name1.moc name2.moc ... [\] |
|---|
| 13 | # {program}_METASOURCES = AUTO |
|---|
| 14 | # The second style requires other tags as well. |
|---|
| 15 | # |
|---|
| 16 | # To install icons : |
|---|
| 17 | # KDE_ICON = iconname iconname2 ... |
|---|
| 18 | # KDE_ICON = AUTO |
|---|
| 19 | # |
|---|
| 20 | # For documentation : |
|---|
| 21 | # http://developer.kde.org/documentation/other/developer-faq.html |
|---|
| 22 | # |
|---|
| 23 | # and more new tags TBD! |
|---|
| 24 | # |
|---|
| 25 | # The concept (and base code) for this program came from automoc, |
|---|
| 26 | # supplied by the following |
|---|
| 27 | # |
|---|
| 28 | # Matthias Ettrich <ettrich@kde.org> (The originator) |
|---|
| 29 | # Kalle Dalheimer <kalle@kde.org> (The original implementator) |
|---|
| 30 | # Harri Porten <porten@tu-harburg.de> |
|---|
| 31 | # Alex Zepeda <jazepeda@pacbell.net> |
|---|
| 32 | # David Faure <faure@kde.org> |
|---|
| 33 | # Stephan Kulow <coolo@kde.org> |
|---|
| 34 | # Dirk Mueller <mueller@kde.org> |
|---|
| 35 | |
|---|
| 36 | use Cwd; |
|---|
| 37 | use File::Find; |
|---|
| 38 | use File::Basename; |
|---|
| 39 | |
|---|
| 40 | # Prototype the functions |
|---|
| 41 | sub initialise (); |
|---|
| 42 | sub processMakefile ($); |
|---|
| 43 | sub updateMakefile (); |
|---|
| 44 | sub restoreMakefile (); |
|---|
| 45 | |
|---|
| 46 | sub removeLine ($$); |
|---|
| 47 | sub appendLines ($); |
|---|
| 48 | sub substituteLine ($$); |
|---|
| 49 | |
|---|
| 50 | sub findMocCandidates (); |
|---|
| 51 | sub pruneMocCandidates ($); |
|---|
| 52 | sub checkMocCandidates (); |
|---|
| 53 | sub addMocRules (); |
|---|
| 54 | sub findKcfgFile($); |
|---|
| 55 | |
|---|
| 56 | sub tag_AUTOMAKE (); |
|---|
| 57 | sub tag_META_INCLUDES (); |
|---|
| 58 | sub tag_METASOURCES (); |
|---|
| 59 | sub tag_POFILES (); |
|---|
| 60 | sub tag_DOCFILES (); |
|---|
| 61 | sub tag_LOCALINSTALL(); |
|---|
| 62 | sub tag_IDLFILES(); |
|---|
| 63 | sub tag_UIFILES(); |
|---|
| 64 | sub tag_KCFGFILES(); |
|---|
| 65 | sub tag_SUBDIRS(); |
|---|
| 66 | sub tag_ICON(); |
|---|
| 67 | sub tag_CLOSURE(); |
|---|
| 68 | sub tag_NO_UNDEFINED(); |
|---|
| 69 | sub tag_NMCHECK(); |
|---|
| 70 | sub tag_DIST(); |
|---|
| 71 | sub tag_KDEINIT(); |
|---|
| 72 | |
|---|
| 73 | # Some global globals... |
|---|
| 74 | $verbose = 0; # a debug flag |
|---|
| 75 | $thisProg = "$0"; # This programs name |
|---|
| 76 | $topdir = cwd(); # The current directory |
|---|
| 77 | @makefiles = (); # Contains all the files we'll process |
|---|
| 78 | @foreignfiles = (); |
|---|
| 79 | $start = (times)[0]; # some stats for testing - comment out for release |
|---|
| 80 | $version = "v0.2"; |
|---|
| 81 | $errorflag = 0; |
|---|
| 82 | $cppExt = "(cpp|cc|cxx|C|c\\+\\+)"; |
|---|
| 83 | $hExt = "(h|H|hh|hxx|hpp|h\\+\\+)"; |
|---|
| 84 | $progId = "KDE tags expanded automatically by " . basename($thisProg); |
|---|
| 85 | $automkCall = "\n"; |
|---|
| 86 | $printname = ""; # used to display the directory the Makefile is in |
|---|
| 87 | $use_final = 1; # create code for --enable-final |
|---|
| 88 | $cleantarget = "clean"; |
|---|
| 89 | $dryrun = 0; |
|---|
| 90 | $pathoption = 0; |
|---|
| 91 | $foreign_libtool = 0; |
|---|
| 92 | |
|---|
| 93 | while (defined ($ARGV[0])) |
|---|
| 94 | { |
|---|
| 95 | $_ = shift; |
|---|
| 96 | if (/^--version$/) |
|---|
| 97 | { |
|---|
| 98 | print STDOUT "\n"; |
|---|
| 99 | print STDOUT basename($thisProg), " $version\n", |
|---|
| 100 | "This is really free software, unencumbered by the GPL.\n", |
|---|
| 101 | "You can do anything you like with it except sueing me.\n", |
|---|
| 102 | "Copyright 1998 Kalle Dalheimer <kalle\@kde.org>\n", |
|---|
| 103 | "Concept, design and unnecessary questions about perl\n", |
|---|
| 104 | " by Matthias Ettrich <ettrich\@kde.org>\n\n", |
|---|
| 105 | "Making it useful by Stephan Kulow <coolo\@kde.org> and\n", |
|---|
| 106 | "Harri Porten <porten\@kde.org>\n", |
|---|
| 107 | "Updated (Feb-1999), John Birch <jb.nz\@writeme.com>\n", |
|---|
| 108 | "Fixes and Improvements by Dirk Mueller <mueller\@kde.org>\n", |
|---|
| 109 | "Current Maintainer Stephan Kulow\n\n"; |
|---|
| 110 | exit 0; |
|---|
| 111 | } |
|---|
| 112 | elsif (/^--verbose$|^-v$/) |
|---|
| 113 | { |
|---|
| 114 | $verbose = 1; # Oh is there a problem...? |
|---|
| 115 | } |
|---|
| 116 | elsif (/^(?:-p|--path=)(.+)$/) |
|---|
| 117 | { |
|---|
| 118 | my $p = $1; |
|---|
| 119 | $thisProg = $p . "/". basename($thisProg); |
|---|
| 120 | warn ("$thisProg doesn't exist\n") if (!(-f $thisProg)); |
|---|
| 121 | $thisProg .= " -p".$p; |
|---|
| 122 | $pathoption=1; |
|---|
| 123 | } |
|---|
| 124 | elsif (/^--help$|^-h$/) |
|---|
| 125 | { |
|---|
| 126 | print STDOUT "Usage $thisProg [OPTION] ... [dir/Makefile.in]...\n", |
|---|
| 127 | "\n", |
|---|
| 128 | "Patches dir/Makefile.in generated by automake\n", |
|---|
| 129 | "(where dir can be an absolute or relative directory name)\n", |
|---|
| 130 | "\n", |
|---|
| 131 | " -v, --verbose verbosely list files processed\n", |
|---|
| 132 | " -h, --help print this help, then exit\n", |
|---|
| 133 | " --version print version number, then exit\n", |
|---|
| 134 | " -p, --path= use the path to am_edit if the path\n", |
|---|
| 135 | " called from is not the one to be used\n", |
|---|
| 136 | " --no-final don't patch for --enable-final\n"; |
|---|
| 137 | |
|---|
| 138 | exit 0; |
|---|
| 139 | } |
|---|
| 140 | elsif (/^--no-final$/) |
|---|
| 141 | { |
|---|
| 142 | $use_final = 0; |
|---|
| 143 | $thisProg .= " --no-final"; |
|---|
| 144 | } |
|---|
| 145 | elsif (/^--foreign-libtool$/) |
|---|
| 146 | { |
|---|
| 147 | $foreign_libtool = 1; |
|---|
| 148 | $thisProg .= " --foreign-libtool"; |
|---|
| 149 | } |
|---|
| 150 | elsif (/^-n$/) |
|---|
| 151 | { |
|---|
| 152 | $dryrun = 1; |
|---|
| 153 | } |
|---|
| 154 | else |
|---|
| 155 | { |
|---|
| 156 | # user selects what input files to check |
|---|
| 157 | # add full path if relative path is given |
|---|
| 158 | $_ = cwd()."/".$_ if (! /^\//); |
|---|
| 159 | print "User wants $_\n" if ($verbose); |
|---|
| 160 | push (@makefiles, $_); |
|---|
| 161 | } |
|---|
| 162 | } |
|---|
| 163 | |
|---|
| 164 | if ($thisProg =~ /^\// && !$pathoption ) |
|---|
| 165 | { |
|---|
| 166 | print STDERR "Illegal full pathname call performed...\n", |
|---|
| 167 | "The call to \"$thisProg\"\nwould be inserted in some Makefile.in.\n", |
|---|
| 168 | "Please use option --path.\n"; |
|---|
| 169 | exit 1; |
|---|
| 170 | } |
|---|
| 171 | |
|---|
| 172 | # Only scan for files when the user hasn't entered data |
|---|
| 173 | if (!@makefiles) |
|---|
| 174 | { |
|---|
| 175 | print STDOUT "Scanning for Makefile.in\n" if ($verbose); |
|---|
| 176 | find (\&add_makefile, cwd()); |
|---|
| 177 | #chdir('$topdir'); |
|---|
| 178 | } else { |
|---|
| 179 | print STDOUT "Using input files specified by user\n" if ($verbose); |
|---|
| 180 | } |
|---|
| 181 | |
|---|
| 182 | foreach $makefile (sort(@makefiles)) |
|---|
| 183 | { |
|---|
| 184 | processMakefile ($makefile); |
|---|
| 185 | last if ($errorflag); |
|---|
| 186 | } |
|---|
| 187 | |
|---|
| 188 | # Just some debug statistics - comment out for release as it uses printf. |
|---|
| 189 | printf STDOUT "Time %.2f CPU sec\n", (times)[0] - $start if ($verbose); |
|---|
| 190 | |
|---|
| 191 | exit $errorflag; # causes make to fail if erroflag is set |
|---|
| 192 | |
|---|
| 193 | #----------------------------------------------------------------------------- |
|---|
| 194 | |
|---|
| 195 | # In conjunction with the "find" call, this builds the list of input files |
|---|
| 196 | sub add_makefile () |
|---|
| 197 | { |
|---|
| 198 | push (@makefiles, $File::Find::name) if (/Makefile.in$/); |
|---|
| 199 | } |
|---|
| 200 | |
|---|
| 201 | #----------------------------------------------------------------------------- |
|---|
| 202 | |
|---|
| 203 | # Processes a single make file |
|---|
| 204 | # The parameter contains the full path name of the Makefile.in to use |
|---|
| 205 | sub processMakefile ($) |
|---|
| 206 | { |
|---|
| 207 | # some useful globals for the subroutines called here |
|---|
| 208 | local ($makefile) = @_; |
|---|
| 209 | local @headerdirs = ('.'); |
|---|
| 210 | local $haveAutomocTag = 0; |
|---|
| 211 | local $MakefileData = ""; |
|---|
| 212 | |
|---|
| 213 | local $cxxsuffix = "KKK"; |
|---|
| 214 | |
|---|
| 215 | local @programs = (); # lists the names of programs and libraries |
|---|
| 216 | local $program = ""; |
|---|
| 217 | |
|---|
| 218 | local @kdeinits = (); # lists the kdeinit targets |
|---|
| 219 | |
|---|
| 220 | local %realObjs = (); # lists the objects compiled into $program |
|---|
| 221 | local %sources = (); # lists the sources used for $program |
|---|
| 222 | local %finalObjs = (); # lists the objects compiled when final |
|---|
| 223 | local %realname = (); # the binary name of program variable |
|---|
| 224 | local %idlfiles = (); # lists the idl files used for $program |
|---|
| 225 | local %globalmocs = ();# list of all mocfiles (in %mocFiles format) |
|---|
| 226 | local %important = (); # list of files to be generated asap |
|---|
| 227 | local %uiFiles = (); |
|---|
| 228 | local %kcfgFiles = (); |
|---|
| 229 | |
|---|
| 230 | local $allidls = ""; |
|---|
| 231 | local $idl_output = "";# lists all idl generated files for cleantarget |
|---|
| 232 | local $ui_output = "";# lists all uic generated files for cleantarget |
|---|
| 233 | local $kcfg_output = "";# lists all kcfg generated files for cleantarget |
|---|
| 234 | |
|---|
| 235 | local %dependmocs = (); |
|---|
| 236 | |
|---|
| 237 | local $metasourceTags = 0; |
|---|
| 238 | local $dep_files = ""; |
|---|
| 239 | local $dep_finals = ""; |
|---|
| 240 | local %target_adds = (); # the targets to add |
|---|
| 241 | local %rule_adds = (); |
|---|
| 242 | local $kdelang = ""; |
|---|
| 243 | local @cleanfiles = (); |
|---|
| 244 | local $cleanMoc = ""; |
|---|
| 245 | local $closure_output = ""; |
|---|
| 246 | |
|---|
| 247 | local %varcontent = (); |
|---|
| 248 | |
|---|
| 249 | $makefileDir = dirname($makefile); |
|---|
| 250 | chdir ($makefileDir); |
|---|
| 251 | $printname = $makefile; |
|---|
| 252 | $printname =~ s/^\Q$topdir\E\///; |
|---|
| 253 | $makefile = basename($makefile); |
|---|
| 254 | |
|---|
| 255 | print STDOUT "Processing makefile $printname\n" if ($verbose); |
|---|
| 256 | |
|---|
| 257 | # Setup and see if we need to do this. |
|---|
| 258 | return if (!initialise()); |
|---|
| 259 | |
|---|
| 260 | tag_AUTOMAKE (); # Allows a "make" to redo the Makefile.in |
|---|
| 261 | tag_META_INCLUDES (); # Supplies directories for src locations |
|---|
| 262 | |
|---|
| 263 | foreach $program (@programs) { |
|---|
| 264 | $sources_changed{$program} = 0; |
|---|
| 265 | $dependmocs{$program} = ""; |
|---|
| 266 | $important{$program} = ""; |
|---|
| 267 | tag_IDLFILES(); # Sorts out idl rules |
|---|
| 268 | tag_NO_UNDEFINED(); |
|---|
| 269 | tag_CLOSURE(); |
|---|
| 270 | tag_NMCHECK(); |
|---|
| 271 | tag_UIFILES(); # Sorts out ui rules |
|---|
| 272 | tag_KCFGFILES(); # Sorts out kcfg rules |
|---|
| 273 | tag_METASOURCES (); # Sorts out the moc rules |
|---|
| 274 | if ($sources_changed{$program}) { |
|---|
| 275 | my $lookup = $program . '_SOURCES\s*=[ \t]*(.*)'; |
|---|
| 276 | |
|---|
| 277 | if($program =~ /libkdeinit_(.*)/) { |
|---|
| 278 | my $prog = $1; |
|---|
| 279 | substituteLine($prog . '_SOURCES\s*=[ \t]*(.*)', |
|---|
| 280 | "${prog}_SOURCES = ${prog}_dummy.$cxxsuffix\n" . |
|---|
| 281 | "libkdeinit_${prog}_SOURCES = " . $sources{$program}); |
|---|
| 282 | $sources{$prog} = "${prog}_dummy.$cxxsuffix"; |
|---|
| 283 | } |
|---|
| 284 | else { |
|---|
| 285 | substituteLine($lookup, "$program\_SOURCES=" . $sources{$program}); |
|---|
| 286 | } |
|---|
| 287 | } |
|---|
| 288 | if ($important{$program}) { |
|---|
| 289 | local %source_dict = (); |
|---|
| 290 | for $source (split(/[\034\s]+/, $sources{$program})) { |
|---|
| 291 | $source_dict{$source} = 1; |
|---|
| 292 | } |
|---|
| 293 | for $source (@cleanfiles) { |
|---|
| 294 | $source_dict{$source} = 0; |
|---|
| 295 | } |
|---|
| 296 | for $source (keys %source_dict) { |
|---|
| 297 | next if (!$source); |
|---|
| 298 | if ($source_dict{$source} && $source ne '$(licq_gui)') { |
|---|
| 299 | # sanity check |
|---|
| 300 | if (! -f $source) { |
|---|
| 301 | print STDERR "Error: $source is listed in a _SOURCE line in $printname, but doesn't exist yet. Put it in DISTCLEANFILES!\n"; |
|---|
| 302 | } else { |
|---|
| 303 | $target_adds{"\$(srcdir)/$source"} .= $important{$program}; |
|---|
| 304 | } |
|---|
| 305 | } |
|---|
| 306 | } |
|---|
| 307 | } |
|---|
| 308 | } |
|---|
| 309 | if ($cleanMoc) { |
|---|
| 310 | # Always add dist clean tag |
|---|
| 311 | # Add extra *.moc.cpp files created for USE_AUTOMOC because they |
|---|
| 312 | # aren't included in the normal *.moc clean rules. |
|---|
| 313 | appendLines ("$cleantarget-metasources:\n\t-rm -f $cleanMoc\n"); |
|---|
| 314 | $target_adds{"$cleantarget-am"} .= "$cleantarget-metasources "; |
|---|
| 315 | } |
|---|
| 316 | |
|---|
| 317 | tag_DIST() unless ($kdeopts{"noautodist"}); |
|---|
| 318 | |
|---|
| 319 | if ($idl_output) { |
|---|
| 320 | appendLines ("$cleantarget-idl:\n\t-rm -f $idl_output\n"); |
|---|
| 321 | $target_adds{"$cleantarget-am"} .= "$cleantarget-idl "; |
|---|
| 322 | } |
|---|
| 323 | |
|---|
| 324 | if ($ui_output) { |
|---|
| 325 | appendLines ("$cleantarget-ui:\n\t-rm -f $ui_output\n"); |
|---|
| 326 | $target_adds{"$cleantarget-am"} .= "$cleantarget-ui "; |
|---|
| 327 | } |
|---|
| 328 | |
|---|
| 329 | if ($kcfg_output) { |
|---|
| 330 | appendLines ("$cleantarget-kcfg:\n\t-rm -f $kcfg_output\n"); |
|---|
| 331 | $target_adds{"$cleantarget-am"} .= "$cleantarget-kcfg "; |
|---|
| 332 | } |
|---|
| 333 | |
|---|
| 334 | if ($closure_output) { |
|---|
| 335 | appendLines ("$cleantarget-closures:\n\t-rm -f $closure_output\n"); |
|---|
| 336 | $target_adds{"$cleantarget-am"} .= "$cleantarget-closures "; |
|---|
| 337 | } |
|---|
| 338 | |
|---|
| 339 | if ($MakefileData =~ /\nKDE_LANG\s*=\s*(\S*)\s*\n/) { |
|---|
| 340 | $kdelang = '$(KDE_LANG)' |
|---|
| 341 | } else { |
|---|
| 342 | $kdelang = ''; |
|---|
| 343 | } |
|---|
| 344 | |
|---|
| 345 | tag_POFILES (); # language rules for po directory |
|---|
| 346 | tag_DOCFILES (); # language rules for doc directories |
|---|
| 347 | tag_LOCALINSTALL(); # add $(DESTDIR) before all kde_ dirs |
|---|
| 348 | tag_ICON(); |
|---|
| 349 | tag_SUBDIRS(); |
|---|
| 350 | |
|---|
| 351 | my $tmp = "force-reedit:\n"; |
|---|
| 352 | $tmp .= "\t$automkCall\n\tcd \$(top_srcdir) && perl $thisProg $printname\n\n"; |
|---|
| 353 | appendLines($tmp); |
|---|
| 354 | |
|---|
| 355 | make_bcheck_target(); |
|---|
| 356 | make_meta_classes(); |
|---|
| 357 | tag_COMPILE_FIRST(); |
|---|
| 358 | tag_FINAL() if (!$kdeopts{"nofinal"}); |
|---|
| 359 | |
|---|
| 360 | my $final_lines = "final:\n\t\$(MAKE) "; |
|---|
| 361 | my $final_install_lines = "final-install:\n\t\$(MAKE) "; |
|---|
| 362 | my $nofinal_lines = "no-final:\n\t\$(MAKE) "; |
|---|
| 363 | my $nofinal_install_lines = "no-final-install:\n\t\$(MAKE) "; |
|---|
| 364 | |
|---|
| 365 | foreach $program (@programs) { |
|---|
| 366 | my $lookup = $program . '_OBJECTS\s*=[ \t]*.*'; |
|---|
| 367 | my $new = ""; |
|---|
| 368 | my @list = split(/[\034\s]+/, $realObjs{$program}); |
|---|
| 369 | if (!$kdeopts{"nofinal"} && @list > 1 && $finalObjs{$program}) { |
|---|
| 370 | $new .= "$program\_final\_OBJECTS = " . $finalObjs{$program}; |
|---|
| 371 | $new .= "\n$program\_nofinal\_OBJECTS = " . $realObjs{$program}; |
|---|
| 372 | $new .= "\n\@KDE_USE_FINAL_FALSE\@$program\_OBJECTS = \$($program\_nofinal\_OBJECTS)"; |
|---|
| 373 | $new .= "\n\@KDE_USE_FINAL_TRUE\@$program\_OBJECTS = \$($program\_final\_OBJECTS)"; |
|---|
| 374 | |
|---|
| 375 | $final_lines .= "$program\_OBJECTS=\"\$($program\_final_OBJECTS)\" "; |
|---|
| 376 | $final_install_lines .= "$program\_OBJECTS=\"\$($program\_final_OBJECTS)\" "; |
|---|
| 377 | $nofinal_lines .= "$program\_OBJECTS=\"\$($program\_nofinal\_OBJECTS)\" "; |
|---|
| 378 | $nofinal_install_lines .= "$program\_OBJECTS=\"\$($program\_nofinal_OBJECTS)\" "; |
|---|
| 379 | } else { |
|---|
| 380 | $new = "$program\_OBJECTS = " . $realObjs{$program}; |
|---|
| 381 | } |
|---|
| 382 | if($MakefileData =~ m/\n$lookup/) { |
|---|
| 383 | substituteLine ($lookup, $new); |
|---|
| 384 | } |
|---|
| 385 | else { |
|---|
| 386 | appendLines("$new\n"); |
|---|
| 387 | } |
|---|
| 388 | } |
|---|
| 389 | appendLines($final_lines . "all-am\n"); |
|---|
| 390 | appendLines($final_install_lines . "install-am\n"); |
|---|
| 391 | appendLines($nofinal_lines . "all-am\n"); |
|---|
| 392 | appendLines($nofinal_install_lines . "install-am\n"); |
|---|
| 393 | |
|---|
| 394 | my $lookup = '(\@\S+\@)?DEP_FILES\s*=[ \t]*(.*)'; |
|---|
| 395 | if ($MakefileData =~ /\n$lookup/) { |
|---|
| 396 | my $condition = $1; |
|---|
| 397 | my $depfiles = $2; |
|---|
| 398 | my $workfiles; |
|---|
| 399 | |
|---|
| 400 | if ($dep_finals) { |
|---|
| 401 | # Add the conditions on every line, since |
|---|
| 402 | # there may be line continuations in the list. |
|---|
| 403 | $workfiles = "$dep_files $dep_finals $depfiles"; |
|---|
| 404 | $workfiles =~ s/\034/\034$condition\@KDE_USE_FINAL_TRUE\@\t/g; |
|---|
| 405 | $lines = "$condition\@KDE_USE_FINAL_TRUE\@DEP_FILES = $workfiles\n"; |
|---|
| 406 | $workfiles = "$dep_files $depfiles"; |
|---|
| 407 | $workfiles =~ s/\034/\034$condition\@KDE_USE_FINAL_FALSE\@\t/g; |
|---|
| 408 | $lines .= "$condition\@KDE_USE_FINAL_FALSE\@DEP_FILES = $workfiles"; |
|---|
| 409 | } else { |
|---|
| 410 | $workfiles = "$dep_files $depfiles"; |
|---|
| 411 | $workfiles =~ s/\034/\034$condition\t/g; |
|---|
| 412 | $lines = $condition . "DEP_FILES = $workfiles"; |
|---|
| 413 | } |
|---|
| 414 | substituteLine($lookup, $lines); |
|---|
| 415 | } |
|---|
| 416 | |
|---|
| 417 | # new recursive targets |
|---|
| 418 | $target_adds{ "nmcheck" } .= ""; # always create nmcheck target |
|---|
| 419 | $target_adds{ "nmcheck-am" } .= "nmcheck"; |
|---|
| 420 | $lookup = 'RECURSIVE_TARGETS\s*=[ \t]*(.*)'; |
|---|
| 421 | if ($MakefileData =~ /\n$lookup/) { |
|---|
| 422 | substituteLine($lookup, "RECURSIVE_TARGETS = $1 nmcheck-recursive bcheck-recursive"); |
|---|
| 423 | } |
|---|
| 424 | |
|---|
| 425 | $cvs_lines = "kde-rpo-clean:\n"; |
|---|
| 426 | $cvs_lines .= "\t-rm -f *.rpo\n"; |
|---|
| 427 | appendLines($cvs_lines); |
|---|
| 428 | $target_adds{"clean"} .= "kde-rpo-clean "; |
|---|
| 429 | |
|---|
| 430 | my %target_dels = ("install-data-am" => ""); |
|---|
| 431 | |
|---|
| 432 | # some strange people like to do a install-exec, and expect that also |
|---|
| 433 | # all modules are installed. automake doesn't know this, so we need to move |
|---|
| 434 | # this here from install-data to install-exec. |
|---|
| 435 | if ($MakefileData =~ m/\nkde_module_LTLIBRARIES\s*=/) { |
|---|
| 436 | # $target_adds{"install-exec-am"} .= "install-kde_moduleLTLIBRARIES "; |
|---|
| 437 | # don't use $target_adds here because we need to append the dependency, not |
|---|
| 438 | # prepend it. Fixes #44342 , when a module depends on a lib in the same dir |
|---|
| 439 | # and libtool needs it during relinking upon install (Simon) |
|---|
| 440 | my $lookup = "install-exec-am:([^\n]*)"; |
|---|
| 441 | if($MakefileData =~ /\n$lookup\n/) { |
|---|
| 442 | substituteLine("$lookup", "install-exec-am: $1 install-kde_moduleLTLIBRARIES"); |
|---|
| 443 | } |
|---|
| 444 | $target_dels{"install-data-am"} .= "install-kde_moduleLTLIBRARIES "; |
|---|
| 445 | $target_adds{"install-data-am"} .= " "; |
|---|
| 446 | } |
|---|
| 447 | |
|---|
| 448 | my $lines = ""; |
|---|
| 449 | |
|---|
| 450 | foreach $add (keys %target_adds) { |
|---|
| 451 | my $lookup = quotemeta($add) . ':([^\n]*)'; |
|---|
| 452 | if ($MakefileData =~ /\n$lookup\n/) { |
|---|
| 453 | my $newlines = $1; |
|---|
| 454 | my $oldlines = $lookup; |
|---|
| 455 | if (defined $target_dels{$add}) { |
|---|
| 456 | foreach $del (split(' ', $target_dels{$add})) { |
|---|
| 457 | $newlines =~ s/\s*$del\s*/ /g; |
|---|
| 458 | } |
|---|
| 459 | } |
|---|
| 460 | substituteLine($oldlines, "$add: " . $target_adds{$add} . $newlines); |
|---|
| 461 | } else { |
|---|
| 462 | $lines .= "$add: " . $target_adds{$add} . "\n"; |
|---|
| 463 | } |
|---|
| 464 | } |
|---|
| 465 | |
|---|
| 466 | appendLines($lines) if ($lines); |
|---|
| 467 | |
|---|
| 468 | $lines = join("\n", values %rule_adds); |
|---|
| 469 | appendLines($lines) if ($lines); |
|---|
| 470 | |
|---|
| 471 | my $found = 1; |
|---|
| 472 | |
|---|
| 473 | while ($found) { |
|---|
| 474 | if ($MakefileData =~ m/\n(.*)\$\(CXXFLAGS\)(.*)\n/) { |
|---|
| 475 | my $stuff_before = $1; |
|---|
| 476 | my $stuff_after = $2; |
|---|
| 477 | my $lookup = quotemeta("$1\$(CXXFLAGS)$2"); |
|---|
| 478 | my $replacement = "$1\$(KCXXFLAGS)$2"; |
|---|
| 479 | $MakefileData =~ s/$lookup/$replacement/; |
|---|
| 480 | $lookup =~ s/\\\$\\\(CXXFLAGS\\\)/\\\$\\\(KCXXFLAGS\\\)/; |
|---|
| 481 | $replacement = "$stuff_before\$(KCXXFLAGS) \$(KDE_CXXFLAGS)$stuff_after"; |
|---|
| 482 | next if ($stuff_before =~ /\$\(KDE_CXXFLAGS\)/ or $stuff_after =~ /\$\(KDE_CXXFLAGS\)/); |
|---|
| 483 | substituteLine($lookup, $replacement); |
|---|
| 484 | } else { |
|---|
| 485 | $found = 0; |
|---|
| 486 | } |
|---|
| 487 | } |
|---|
| 488 | |
|---|
| 489 | if($foreign_libtool == 0) { |
|---|
| 490 | $lookup = '(\n[^#].*\$\(LIBTOOL\) --mode=link) (\$\(CXXLD\).*\$\(KCXXFLAGS\))'; |
|---|
| 491 | |
|---|
| 492 | if ($MakefileData =~ m/$lookup/ ) { |
|---|
| 493 | $MakefileData =~ s/$lookup/$1 --tag=CXX $2/; |
|---|
| 494 | } |
|---|
| 495 | |
|---|
| 496 | $lookup = '(\n[^#].*\$\(LIBTOOL\) --mode=compile)\s+(\$\(CXX\)\s+)'; |
|---|
| 497 | if ($MakefileData =~ m/$lookup/ ) { |
|---|
| 498 | $MakefileData =~ s/$lookup/$1 --tag=CXX $2/; |
|---|
| 499 | } |
|---|
| 500 | } |
|---|
| 501 | |
|---|
| 502 | $MakefileData =~ s/\$\(KCXXFLAGS\)/\$\(CXXFLAGS\)/g; |
|---|
| 503 | |
|---|
| 504 | $lookup = '(.*)cp -pr \$\$/\$\$file \$\(distdir\)/\$\$file(.*)'; |
|---|
| 505 | if ($MakefileData =~ m/\n$lookup\n/) { |
|---|
| 506 | substituteLine($lookup, "$1cp -pr \$\$d/\$\$file \$(distdir)/\$\$file$2"); |
|---|
| 507 | } |
|---|
| 508 | |
|---|
| 509 | # Always update the Makefile.in |
|---|
| 510 | updateMakefile (); |
|---|
| 511 | return; |
|---|
| 512 | } |
|---|
| 513 | |
|---|
| 514 | #----------------------------------------------------------------------------- |
|---|
| 515 | |
|---|
| 516 | # Beware: This procedure is not complete. E.g. it also parses lines |
|---|
| 517 | # containing a '=' in rules (for instance setting shell vars). For our |
|---|
| 518 | # usage this us enough, though. |
|---|
| 519 | sub read_variables () |
|---|
| 520 | { |
|---|
| 521 | while ($MakefileData =~ /\n\s*(\S+)\s*=([^\n]*)/g) { |
|---|
| 522 | $varcontent{$1} = $2; |
|---|
| 523 | } |
|---|
| 524 | } |
|---|
| 525 | |
|---|
| 526 | # Check to see whether we should process this make file. |
|---|
| 527 | # This is where we look for tags that we need to process. |
|---|
| 528 | # A small amount of initialising on the tags is also done here. |
|---|
| 529 | # And of course we open and/or create the needed make files. |
|---|
| 530 | sub initialise () |
|---|
| 531 | { |
|---|
| 532 | if (! -r "Makefile.am") { |
|---|
| 533 | print STDOUT "found Makefile.in without Makefile.am\n" if ($verbose); |
|---|
| 534 | return 0; |
|---|
| 535 | } |
|---|
| 536 | |
|---|
| 537 | # Checking for files to process... |
|---|
| 538 | |
|---|
| 539 | open (FILEIN, $makefile) || die "Can't open $makefileDir/$makefile: $!\n"; |
|---|
| 540 | # perl bug in 5.8.0: in utf8 mode it badly screws up |
|---|
| 541 | binmode(FILEIN, ":bytes") if ($] >= 5.008); |
|---|
| 542 | # Read the file |
|---|
| 543 | # stat(FILEIN)[7] might look more elegant, but is slower as it |
|---|
| 544 | # requires stat'ing the file |
|---|
| 545 | seek(FILEIN, 0, 2); |
|---|
| 546 | my $fsize = tell(FILEIN); |
|---|
| 547 | seek(FILEIN, 0, 0); |
|---|
| 548 | read FILEIN, $MakefileData, $fsize; |
|---|
| 549 | close FILEIN; |
|---|
| 550 | print "DOS CRLF within $makefileDir/$makefile!\n" if($MakefileData =~ y/\r//d); |
|---|
| 551 | |
|---|
| 552 | # Remove the line continuations, but keep them marked |
|---|
| 553 | # Note: we lose the trailing spaces but that's ok. |
|---|
| 554 | # Don't mangle line-leading spaces (usually tabs) |
|---|
| 555 | # since they're important. |
|---|
| 556 | $MakefileData =~ s/\\\s*\n/\034/g; |
|---|
| 557 | |
|---|
| 558 | # If we've processed the file before... |
|---|
| 559 | restoreMakefile () if ($MakefileData =~ /$progId/); |
|---|
| 560 | |
|---|
| 561 | foreach $dir (@foreignfiles) { |
|---|
| 562 | if (substr($makefileDir,0,length($dir)) eq $dir) { |
|---|
| 563 | return 0; |
|---|
| 564 | } |
|---|
| 565 | } |
|---|
| 566 | |
|---|
| 567 | %kdeopts = (); |
|---|
| 568 | $kdeopts{"foreign"} = 0; |
|---|
| 569 | $kdeopts{"qtonly"} = 0; |
|---|
| 570 | $kdeopts{"noautodist"} = 0; |
|---|
| 571 | $kdeopts{"foreign-libtool"} = $foreign_libtool; |
|---|
| 572 | $kdeopts{"nofinal"} = !$use_final; # default |
|---|
| 573 | |
|---|
| 574 | read_variables(); |
|---|
| 575 | |
|---|
| 576 | if ($MakefileData =~ /\nKDE_OPTIONS\s*=[ \t]*([^\n]*)\n/) { |
|---|
| 577 | my $kde_options_str = $1; |
|---|
| 578 | local @kde_options = split(/[\034\s]+/, $kde_options_str); |
|---|
| 579 | if (grep(/^foreign$/, @kde_options)) { |
|---|
| 580 | push(@foreignfiles, $makefileDir . "/"); |
|---|
| 581 | return 0; # don't touch me |
|---|
| 582 | } |
|---|
| 583 | for $opt (@kde_options) { |
|---|
| 584 | if (!defined $kdeopts{$opt}) { |
|---|
| 585 | print STDERR "Warning: unknown option $opt in $printname\n"; |
|---|
| 586 | } else { |
|---|
| 587 | $kdeopts{$opt} = 1; |
|---|
| 588 | } |
|---|
| 589 | } |
|---|
| 590 | } |
|---|
| 591 | |
|---|
| 592 | # Look for the tags that mean we should process this file. |
|---|
| 593 | $metasourceTags = 0; |
|---|
| 594 | $metasourceTags++ while ($MakefileData =~ /\n[^=\#]*METASOURCES\s*=/g); |
|---|
| 595 | |
|---|
| 596 | my $pofileTag = 0; |
|---|
| 597 | $pofileTag++ while ($MakefileData =~ /\nPOFILES\s*=/g); |
|---|
| 598 | if ($pofileTag > 1) |
|---|
| 599 | { |
|---|
| 600 | print STDERR "Error: Only one POFILES tag allowed\n"; |
|---|
| 601 | $errorflag = 1; |
|---|
| 602 | } |
|---|
| 603 | |
|---|
| 604 | while ($MakefileData =~ /\n\.SUFFIXES:([^\n]+)\n/g) { |
|---|
| 605 | my $suffixes_str = $1; |
|---|
| 606 | my @list=split(' ', $suffixes_str); |
|---|
| 607 | foreach $ext (@list) { |
|---|
| 608 | if ($ext =~ /^\.$cppExt$/) { |
|---|
| 609 | $cxxsuffix = $ext; |
|---|
| 610 | $cxxsuffix =~ s/\.//g; |
|---|
| 611 | print STDOUT "will use suffix $cxxsuffix\n" if ($verbose); |
|---|
| 612 | last; |
|---|
| 613 | } |
|---|
| 614 | } |
|---|
| 615 | } |
|---|
| 616 | |
|---|
| 617 | tag_KDEINIT(); |
|---|
| 618 | |
|---|
| 619 | while ($MakefileData =~ /\n(\S*)_OBJECTS\s*=[\034 \t]*([^\n]*)\n/g) { |
|---|
| 620 | |
|---|
| 621 | my $program = $1; |
|---|
| 622 | my $objs = $2; # safe them |
|---|
| 623 | |
|---|
| 624 | my $ocv = 0; |
|---|
| 625 | |
|---|
| 626 | my @objlist = split(/[\034\s]+/, $objs); |
|---|
| 627 | foreach $obj (@objlist) { |
|---|
| 628 | if ($obj =~ /(\S*)\$\((\S+)\)/ ) { |
|---|
| 629 | my $pre = $1; |
|---|
| 630 | my $variable = $2; |
|---|
| 631 | if ($pre eq '' && exists($varcontent{$variable})) { |
|---|
| 632 | my @addlist = split(/[\034\s]+/, $varcontent{$variable}); |
|---|
| 633 | push(@objlist, @addlist); |
|---|
| 634 | } elsif ($variable !~ 'OBJEXT' && $variable !~ /am__objects_\d+/ ) { |
|---|
| 635 | $ocv = 1; |
|---|
| 636 | } |
|---|
| 637 | } |
|---|
| 638 | } |
|---|
| 639 | |
|---|
| 640 | next if ($ocv); |
|---|
| 641 | next if ($program =~ /^am_libkdeinit_/); |
|---|
| 642 | |
|---|
| 643 | $program =~ s/^am_// if ($program =~ /^am_/); |
|---|
| 644 | |
|---|
| 645 | my $sourceprogram = $program; |
|---|
| 646 | $sourceprogram =~ s/\@am_/\@/ if($sourceprogram =~ /^.*\@am_.+/); |
|---|
| 647 | |
|---|
| 648 | print STDOUT "found program $program\n" if ($verbose); |
|---|
| 649 | push(@programs, $program); |
|---|
| 650 | |
|---|
| 651 | $realObjs{$program} = $objs; |
|---|
| 652 | |
|---|
| 653 | if ($MakefileData =~ /\n$sourceprogram\_SOURCES\s*=[ \t]*(.*)\n/) { |
|---|
| 654 | $sources{$program} = $1; |
|---|
| 655 | } |
|---|
| 656 | else { |
|---|
| 657 | $sources{$program} = ""; |
|---|
| 658 | print STDERR "found program with no _SOURCES: $program\n"; |
|---|
| 659 | } |
|---|
| 660 | |
|---|
| 661 | my $realprogram = $program; |
|---|
| 662 | $realprogram =~ s/_/./g; # unmask to regexp |
|---|
| 663 | if ($MakefileData =~ /\n($realprogram)(\$\(EXEEXT\)?)?:.*\$\($program\_OBJECTS\)/) { |
|---|
| 664 | $realname{$program} = $1; |
|---|
| 665 | |
|---|