Поиск по сайту:

Необычные, но полезные параметры командной строки GCC


На этой странице

  1. Просмотр промежуточных результатов на каждом этапе компиляции.
  2. Подготовьте отладку и профилирование кода
  3. Заключение

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

Показательный пример: компиляторы. Хороший компилятор языка программирования всегда предлагает множество опций, но пользователи обычно знают и используют только ограниченный набор. В частности, если вы разработчик языка C и используете Linux в качестве платформы для разработки, весьма вероятно, что вы используете компилятор gcc, который предлагает бесконечный список параметров командной строки.

Знаете ли вы, что при желании вы можете попросить gcc сохранять вывод на каждом этапе процесса компиляции? Знаете ли вы, что параметр -Wall, который вы используете для создания предупреждений, не распространяется на некоторые конкретные предупреждения? Есть много параметров командной строки gcc, которые обычно не используются, но могут быть чрезвычайно полезны в определенных сценариях, например, при отладке кода.

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

Но прежде чем мы двинемся дальше, имейте в виду, что все примеры, команды и инструкции, упомянутые в этом руководстве, были протестированы на Ubuntu 16.04 LTS, а версия gcc, которую мы использовали, — 5.4.0.

 

Смотрите промежуточный вывод на каждом этапе компиляции

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

Но предположим, если при отладке требуется посмотреть, как выглядел код, скажем, на этапе препроцессинга. Тогда что бы вы сделали? Хорошо, что компилятор gcc предлагает параметр командной строки, который вы можете использовать в своей стандартной команде компиляции, и вы получите те промежуточные файлы, которые в противном случае будут удалены компилятором. Опция, о которой мы говорили, это -save-temps.

Вот что говорит об этом параметре справочная страница gcc:

           Store the usual "temporary" intermediate files permanently; place
           them in the current directory and name them based on the source
           file.  Thus, compiling foo.c with -c -save-temps produces files
           foo.i and foo.s, as well as foo.o.  This creates a preprocessed
           foo.i output file even though the compiler now normally uses an
           integrated preprocessor.

           When used in combination with the -x command-line option,
           -save-temps is sensible enough to avoid over writing an input
           source file with the same extension as an intermediate file.  The
           corresponding intermediate file may be obtained by renaming the
           source file before using -save-temps.

Ниже приведен пример команды, которая даст вам представление о том, как вы можете использовать эту опцию:

gcc -Wall -save-temps test.c -o test-exec

И вот как я убедился, что все промежуточные файлы действительно были созданы после выполнения вышеупомянутой команды:

Как вы можете видеть на снимке экрана выше, файлы test.i, test.s и test.o были созданы <-save-temps. Эти файлы соответствуют этапам предварительной обработки, компиляции и компоновки соответственно.

Подготовьте отладку и профилирование кода

Существуют специальные инструменты, позволяющие отлаживать и профилировать исходный код. Например, gprof — популярный инструмент для профилирования. Но знаете ли вы, что есть специальные параметры командной строки, которые предлагает gcc, чтобы подготовить ваш код к отладке и профилированию?

Начнем с отладки. Чтобы иметь возможность использовать gdb для отладки кода, вам необходимо скомпилировать свой код с помощью параметра командной строки -g, предоставляемого компилятором gcc. Эта опция в основном позволяет gcc производить отладочную информацию, которая требуется gdb для успешной отладки вашей программы.

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

           GCC allows you to use -g with -O.  The shortcuts taken by optimized
           code may occasionally produce surprising results: some variables
           you declared may not exist at all; flow of control may briefly move
           where you did not expect it; some statements may not be executed
           because they compute constant results or their values are already
           at hand; some statements may execute in different places because
           they have been moved out of loops.

           Nevertheless it proves possible to debug optimized output.  This
           makes it reasonable to use the optimizer for programs that might
           have bugs.

Не только gdb, компиляция кода с использованием параметра -g также открывает возможность использования инструмента проверки памяти Valgrind в полном объеме. Для тех, кто не знает, memcheck используется программистами для проверки утечек памяти (если таковые имеются) в их коде. Вы можете узнать больше об этом инструменте здесь.

Двигаясь дальше, чтобы иметь возможность использовать gprof для профилирования кода, вы должны скомпилировать свой код с помощью параметра командной строки -pg. Это позволяет gcc генерировать дополнительный код для записи информации профилирования, которая требуется gprof для анализа кода. \Вы должны использовать эту опцию при компиляции исходных файлов, о которых вы хотите получить данные, а также использовать ее при связывании\, – это специальное руководство на нашем веб-сайте.

Примечание. Использование параметров -g и -pg аналогично использованию параметра -save-temps в предыдущем разделе.

Заключение

Если вы не являетесь профессионалом gcc, я уверен, что вы узнали что-то новое из этой статьи. Попробуйте эти варианты и посмотрите, как они работают. А пока ждите следующей части этой серии руководств, в которой мы обсудим другие интересные и полезные параметры командной строки gcc.