2016-05-01 2 views
3

Я пишу небольшую операционную систему для микроконтроллеров в C (не C++, поэтому я не могу использовать шаблоны). Он сильно использует некоторые функции gcc, одним из наиболее важных из которых является удаление неиспользуемого кода. ОС не загружает ничего во время выполнения; программа пользователя и источник ОС скомпилированы вместе, чтобы сформировать единый двоичный файл.Проверка времени компиляции, если функция оптимизирована

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

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

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

  • Есть пользователь явно включить модули, они должны (используя #define), а также использовать #if включать только им поддержку в консоль отладки, если она включена. Мне не нравится этот метод, потому что в настоящее время пользователь не должен этого делать, и я бы предпочел сохранить его таким образом.

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

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

  • Выполните тест во время компиляции в коде отладки, например:

    if(i2cInit is used) { 
        debugShowi2cStatus(); 
    } 
    

Последний метод кажется идеальным, но возможно ли это?

+0

@quantdev спасибо за фиксации фрагмента кода. Не уверен, почему 4 пробела было недостаточно. – Rena

ответ

1

Это похоже на интересную проблему. Вот идея, хотя это не идеально:

Двухпроходный компиляции.

Что вы можете сделать, это сначала, скомпилируйте программу с флагом, как FINDING_DEPENDENCIES=1. Оберните все проверки зависимостей с помощью #if s для этого (я предполагаю, что вы не так обеспокоены добавлением дополнительных ifs там).

Затем, когда компиляция выполнена (без каких-либо дополнительных функций), используйте nm или аналогичные для определения использования функций/функций в программе (например, i2cInit) и форматирования этой информации в файл .h.

#ifndef FINDING_DEPENDENCIES 
#include "dependency_info.h" 
#endif 

Теперь известны дополнительные зависимости.

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

Теоретически это может не увеличить время сборки, особенно если вы использовали временный файл для сгенерированного h, а затем заменили его только в том случае, если он был другим. Однако вам нужно использовать разные объекты.

Кроме того, это может помочь (до полосы, конечно): How can I view function names and parameters contained in an ELF file?

Смежные вопросы