File indexing completed on 2024-04-21 05:41:55
0001 #!/usr/bin/perl 0002 0003 # Kevin Funk <kfunk@kde.org> (2015) 0004 # 0005 # Attempts to remove lines such as '#include "<basename>.moc"' from cpp files 0006 # 0007 # Automoc conventions: 0008 # - include moc_<basename>.cpp <=> Q_OBJECT/Q_GADGET inside header 0009 # - include <basename>.moc <=> Q_OBJECT/Q_GADGET inside source file 0010 # 0011 # Additionally, if K_PLUGIN_FACTORY is used, we'll *have* to use '<basename>.moc' 0012 # 0013 # Now, if <basename>.moc is included, and the source file does *not* need a moc run, 0014 # CMake's automoc still performs a moc run and moc will give warnings, such as: 0015 # "foo.cpp:0: Note: No relevant classes found. No output generated." 0016 # => Remove the include in this case 0017 # 0018 # More info: https://cmake.org/cmake/help/v3.0/manual/cmake-qt.7.html#automoc 0019 # 0020 # Usual invocation: 0021 # find -iname "*.cpp" | xargs kde-dev-scripts/kf5/convert-to-cmake-automoc.pl 0022 0023 use strict; 0024 use warnings; 0025 0026 use File::Basename; 0027 use lib dirname($0); 0028 use functionUtilkde; 0029 0030 foreach my $file (@ARGV) { 0031 open(my $FILE, "<", $file) or die "We can't open file $file:$!\n"; 0032 my $content = do { local $/; <$FILE> }; 0033 0034 my $regexRequiresMoc = qr/(Q_OBJECT|Q_GADGET|K_PLUGIN_FACTORY|EXPORT_KONTACT_PLUGIN|_WITH_JSON|K_EXPORT_PLASMA_)/; 0035 0036 my ($filenameWithoutExtension, $dirs,) = fileparse($file, qr/\.[^.]*/); 0037 0038 # In some cases, we cannot just get rid off the '#include <basename>.moc', 0039 # and need to include '#include moc_<basename>.cpp' 0040 # E.g. in case when the moc-generated file needs information about a class declared inside the .cpp file 0041 # Try to detect these cases and include '#include moc_<basename>.cpp' instead 0042 my $headerFile = $dirs . "$filenameWithoutExtension.h"; 0043 my $requiresHeaderMocInclude = (-e $headerFile) ? 0044 `grep Q_PRIVATE_SLOT -q $headerFile` : 0045 0; 0046 0047 my $sourceMocFilename = "$filenameWithoutExtension.moc"; 0048 my $requiresSourceMocInclude = ($content =~ /$regexRequiresMoc/); 0049 my $includesSourceMocInclude = ($content =~ /#include \"$sourceMocFilename\"/); 0050 0051 # rewrite file and fix moc includes 0052 if (!$requiresSourceMocInclude && $includesSourceMocInclude) { 0053 open (my $OUT, ">", $file); 0054 # TODO: Refactor, then use functionUtilkde::removeIncludeInFile? 0055 # Cannot use, because it a) only accepts <>-style includes and b) creates redundant newlines 0056 for (split /^/, $content) { 0057 # strip or replace unwanted includes 0058 if (/#include \"$sourceMocFilename\"/) { 0059 if ($requiresHeaderMocInclude) { 0060 print $OUT "#include \"moc_$filenameWithoutExtension.cpp\"\n"; 0061 } 0062 next; # remove line 0063 } 0064 0065 print $OUT $_; 0066 } 0067 close ($OUT); 0068 } 0069 } 0070 0071 functionUtilkde::diffFile( "@ARGV" );