Инструмент для компиляции автоматически всего ifdef / ifndef [закрытые] директивы

6
задан Brian Tompsett - 汤莱恩 20 February 2016 в 22:14
поделиться

8 ответов

Вот Perl скрипт, который делает хаккую работу по разбору #ifdef записей и собирает список символов, используемых в конкретном файле. Затем он распечатывает Декартовый продукт всех возможных комбинаций включения или выключения этого символа. Это работает для моего проекта на C++, и может потребовать незначительной доработки для вашей установки.

#!/usr/bin/perl

use strict;
use warnings;

use File::Find;

my $path = $ENV{PWD};

my $symbol_map = {};
find( make_ifdef_processor( $symbol_map ), $path );

foreach my $fn ( keys %$symbol_map ) {
   my @symbols = @{ $symbol_map->{$fn} };

   my @options;
   foreach my $symbol (@symbols) {
      push @options, [
         "-D$symbol=0",
         "-D$symbol=1"
      ];
   }

   my @combinations = @{ cartesian( @options ) };
   foreach my $combination (@combinations) {
      print "compile $fn with these symbols defined:\n";
      print "\t", join ' ', ( @$combination );
      print "\n";
   }
}

sub make_ifdef_processor {
   my $map_symbols = shift;

   return sub {
      my $fn = $_;

      if ( $fn =~ /svn-base/ ) {
         return;
      }

      open FILE, "<$fn" or die "Error opening file $fn ($!)";
      while ( my $line = <FILE> ) {
         if ( $line =~ /^\/\// ) { # skip C-style comments
            next;
         }

         if ( $line =~ /#ifdef\s+(.*)$/ ) {
            print "matched line $line\n";
            my $symbol = $1;
            push @{ $map_symbols->{$fn} }, $symbol;
         }
      }
   }
}

sub cartesian {
   my $first_set = shift @_;
   my @product = map { [ $_ ] } @$first_set;

   foreach my $set (@_) {
      my @new_product;
      foreach my $s (@$set) {
         foreach my $list (@product) {
            push @new_product, [ @$list, $s ];
         }
      }

      @product = @new_product;
   }

   return \@product;
}

Это определенно не сработает с комментариями в стиле C /* */, так как я не потрудился их эффективно разобрать. Другая вещь, о которой стоит подумать, это может не иметь смысла для всех комбинаций символов, которые будут тестироваться, и вы можете встроить это в скрипт или ваш тестовый сервер. Например, у вас могут быть взаимоисключающие символы для указания платформы:

-DMAC
-DLINUX
-DWINDOWS

Тестирование комбинаций включаемых и выключаемых символов на самом деле не имеет смысла. Одно из быстрых решений - это просто скомпилировать все комбинации и быть уверенным, что некоторые из них выйдут из строя. Тогда вашим тестом на корректность может стать то, что компиляция всегда завершается неудачно и удается с одними и теми же комбинациями.

Другое, что следует помнить - не все комбинации корректны, потому что многие из них не вложены. Я думаю, что компиляция относительно дешева, но количество комбинаций может расти очень быстро, если не быть внимательным. Можно заставить скрипт разобрать, какие символы находятся в одной и той же структуре управления (например, вложенные #ifdefs), но это гораздо сложнее реализовать, и я этого здесь не делал.

2
ответ дан 17 December 2019 в 22:13
поделиться

Извините, я не знаю никаких инструментов, которые могли бы вам помочь, но если бы мне пришлось это сделать, я бы пошла с простым сценарием, который делает это: - Скопируйте все исходные файлы в другое место, - Добавьте в начале каждой строки бегущий номер (в комментарии, очевидно) (первая строка кода первого файла = 1, не сбрасывайте между файлами), - Выполните препроцессирование, используя все предопределенные конфигурации, и проверьте, какие строки были включены, а какие нет, - Проверьте, какие строки были включены, а какие отсутствуют.

Не должно занять больше пары дней, чтобы запустить это с помощью, например, Perl или Python. Требуется файл, содержащий строку с конфигурациями. Это должно быть достаточно быстро, чтобы сделать это с помощью этого скрипта. Просто проверьте, какие строки уже не включены в конфигурации, и отредактируйте файл до тех пор, пока каждая строка не будет включена. Затем просто выполняйте это время от времени, чтобы убедиться, что нет новых путей.

Анализ исходного текста, как вы хотите, будет гораздо более сложным скриптом, и я не уверен, стоит ли это делать.

.
0
ответ дан 17 December 2019 в 22:13
поделиться
[

]Может, вам нужен grep?[

]?
-3
ответ дан 17 December 2019 в 22:13
поделиться

Можно использовать Hudson с проектом матрицы . (Обратите внимание, что Хадсон - это не просто инструмент для тестирования Java, а очень гибкий сборочный сервер, который может собирать практически все, включая C/C++ проекты). Если вы настроите проект матрицы, то получите возможность создать одну или несколько осей. Для каждой оси можно указать на одну руду больше значений. Затем Хадсон запустит вашу сборку, используя все возможные комбинации значений переменных. Например, если вы укажете

os=windows,linux,osx
wordsize=32,64

Хадсон построит шесть комбинаций; 32- и 64-битные версии для каждого окна, linux и osx. При сборке "проекта в свободном стиле" (т.е. при запуске внешнего скрипта сборки) конфигурации задаются с помощью переменных окружения. В приведенном выше примере в качестве переменных окружения будут указаны "os" и "windows".

Хадсон также имеет поддержку фильтрации комбинаций, чтобы избежать сборки определенных недопустимых комбинаций (например, windows 64-bit можно убрать, а все остальные оставить).

(Отредактировано сообщение для предоставления более подробной информации о матричных проектах)

.
-1
ответ дан 17 December 2019 в 22:13
поделиться

Хм, я изначально думал, что униформа Def может быть полезна, но если посмотреть дальше, о чем вы просите, то нет, это не принесет немедленной пользы.

-2
ответ дан 17 December 2019 в 22:13
поделиться

Я не знаю ни одного инструмента для выполнения того, что вы хотите делать. Но, глядя на вашу проблему, я думаю, что все, что вам нужно, это сценарий, который скомпилирует исходный код со всеми возможными комбинациями символов препроцессора.

Например, если у вас есть ..

#ifdef A 
    CallFnA();
#ifdef B
    CallFnB();
#endif
    CallFnC();
#endif

Вам нужно будет запустить сборку со следующими комбинациями

  1. A и B оба определены
  2. A не определены и B определены (здесь не имеет смысла, но требуется для всего модуля)
  3. A определен, а B не определен
  4. A и B оба не определены

Хотелось бы увидеть какой-нибудь сценарий, который grep исходный код и производит комбинации. Что-то вроде

find ./ -name '* .cpp' -exec egrep -h '^ # ifdef' {} \; | awk '{print $ 2}' | сортировать | uniq

С заменой * .cpp любыми файлами, которые вы хотите найти.

4
ответ дан 17 December 2019 в 22:13
поделиться

Другое решение - скомпилировать все функции и провести тестирование конфигурации этих функций во время выполнения. Это крутой «трюк», поскольку он позволяет маркетингу продавать различные конфигурации и экономит время разработки, просто устанавливая значения в файле конфигурации.

В противном случае я предлагаю язык сценариев для построения всех конфигураций.

0
ответ дан 17 December 2019 в 22:13
поделиться

Вы можете использовать UniFDEF -S , чтобы получить список всех символов препроцессора, используемых в условиях препроцессора. Исходя из дискуссии вокруг других ответов, это явно не совсем необходимая информация, но если вы также используете опцию -d, вывод отладки включает в себя уровень вложенности. Для фильтрации вывода должно быть довольно просто, чтобы вывести комбинации символов, которые вы хотите.

1
ответ дан 17 December 2019 в 22:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: