Есть ли инструмент или опция компилятора для gcc, которая считает «строки скомпилированного кода»? - PullRequest
0 голосов
/ 19 февраля 2019

Для сравнения времени компиляции ядра Linux было бы очень полезно, если бы впоследствии было число для (фактически) скомпилированных строк кода.Выполнение 'cloc' для исходного кода ядра до компиляции является лишь частью решения, потому что это значение будет равно для любой конфигурации ядра, независимо от того, настроено ли оно, например, как tinyconfig или allyesconfig или localmodconfig.

Добавлен запрос в список рассылки gcc, который может поддержать этот вопрос
(https://gcc.gnu.org/ml/gcc-help/2019-03/msg00057.html)

Редактировать (из комментария ниже ответа от Майка Кингхана 03/09/2019):
"Это число должно быть нормализующим фактором для сравнения времени компиляции для разных версий ядер Linux для предыдущих версий и в последующие годы."

1 Ответ

0 голосов
/ 09 марта 2019

Похоже, вы хотите посчитать строки кода, потребленные компилятором после предварительной обработки.Именно то, что подразумевается под этим можно поспорить, но я предполагаю, что разумный способ подсчета будет достаточно для ваших целей.GNU Make make-файл, такой как:

Makefile

%.o: %.c    # Cancel built-in rule
%.o: %.i
    $(CC) $(CFLAGS) -c $< -o $@
    @loc=$$(wc -l $<); echo "Compiled $${loc%% *} LOC from $<"

%.i: %.c
    $(CC) $(CPPFLAGS) -E -P $< > $@

иллюстрирует способ сделать это: -

  • Предварительная обработка исходного файлаfirst.
  • Подсчет строк предварительно обработанного вывода.
  • Компиляция предварительно обработанного вывода.

Makefile позволяет избежать бесполезной предварительной обработки исходного кода дважды, поскольку gcc распознаетрасширение .i как , обозначающее файл уже предварительно обработанного источника C , и не будет предварительно обрабатывать его снова.Также нет необходимости очищать промежуточные файлы .i, потому что GNU make распознает их как промежуточные и автоматически удаляет их.Пример:

$ cat foo.c
#ifdef FOO

/* A
 * B
 * C
 */
int foo(int x, int y)
{
    while(x < y) {
        if (++x == y) {
            return y;
        }
        --y;
    }
    while(y < x) {
        if (++y == x) {
            return x;
        }
        --x;
    }
    return y;
}

#else

/* D */
int bar(int x) {
    return x * x;
}

#endif

$ make foo.o
cc  -E -P foo.c > foo.i
cc  -c foo.i -o foo.o
Compiled 3 LOC from foo.i
rm foo.i

$ rm foo.o
$ make CPPFLAGS=-DFOO foo.o
cc -DFOO -E -P foo.c > foo.i
cc  -c foo.i -o foo.o
Compiled 16 LOC from foo.i
rm foo.i

Возможно, вы захотите передать опцию -P на этапе предварительной обработки, как показано, для подавления вывода с маркировкой строки, которая будет раздувать строку-сосчитать.Например, вы, вероятно, не хотите, чтобы foo.i было:

$ cc -DFOO -E foo.c > foo.i
$ cat foo.i
# 1 "foo.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "foo.c"






int foo(int x, int y)
{
    while(x < y) {
        if (++x == y) {
            return y;
        }
        --y;
    }
    while(y < x) {
        if (++y == x) {
            return x;
        }
        --x;
    }
    return y;
}

, а скорее хотите, чтобы оно было:

$ cc -DFOO -E -P foo.c > foo.i
$ cat foo.i
int foo(int x, int y)
{
    while(x < y) {
        if (++x == y) {
            return y;
        }
        --y;
    }
    while(y < x) {
        if (++y == x) {
            return x;
        }
        --x;
    }
    return y;
}

Очевидно, для системы make, которая скомпилировала много исходных файлов, вы бы изобрели больше или иной аппарат, чем добавление отчетов LOC для каждого файла.

...