2015-04-02 2 views
0

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

Упрощая, скажем, у меня есть модуль A, который управляет всеми опциональные части прошивки, каждый закодированный в модуле (B, C, D, и т.д. ...)

в модуле использования AI #ifdef статьи:

#ifdef USE_B 
    #include "B.h" 
#endif 

#ifdef USE_C 
    #include "C.h" 
#endif 

... 

И затем поверх этого я просто #define ключевое слово для модуля, который я хочу включить.

У меня есть некоторые глобальные переменные в файле Z.c, которые должны оставаться там. Поскольку моя цель свести к минимуму использование памяти, я прилагаю свою декларацию в #ifdef, а

#ifdef USE_B 
    uint8_t usedonlybyb; 
#endif 

#ifdef USE_C 
    uint8_t usedonlybyc; 
#endif 

... 

Что происходит, что даже если файл B и файл C полностью отключен от остальной части проекта во время компиляции, на конец компиляции. Я получаю ошибки «Undefined symbol» для внешних переменных «usedonlybyx», которые недоступны для отключенных модулей.

Я хотел бы сохранить переменные usedonlybyx, объявленные в модуле Z, потому что это общий модуль настроек.

Есть ли элегантный способ подавить эти ошибки и по-прежнему сможет преуспеть в моем объеме?

Должен ли я просто вложить все модули B, C, ... внутри #ifdef/#endif?

+0

Если вы скомпилированы с 'USE_C', не будет ли бинарный файл перезаписывать те, которые были скомпилированы ранее, с' USE_B'? Может ли это быть причиной, по которой символы не найдены? –

+0

Вы упомянули, что не хватает места для компиляции всех модулей одновременно. Затем предложите разбить некоторые файлы в подфайлах. Используйте файл make, который не является многопоточным. скомпилируйте файлы один за другим. затем выполните заключительный шаг ссылки, чтобы связать их все вместе. – user3629249

+0

Я думаю, что мое утверждение не было ясным, у меня нет проблем с компиляцией всего проекта, но я не могу запустить «полный» проект на целевом ЦП. Мне в основном нужно адаптировать функции, которые я хочу скомпилировать, в соответствии с моделью процессора и запросами клиентов. Но я хочу сохранить уникальный проект, потому что это более практично. – Vitomakes

ответ

2

Легче решение вложить всю реализацию и декларации внутри b.h и b.c файлов внутри #ifdef USE_B и #endif. То же самое для других модулей. Таким образом, вся условная компиляция для одного модуля изолирована и не обязательно должна быть в другом коде, где используется #include "b.h".

// b.h 
#ifdef USE_B 
// declarations and include guards 
#endif 

// b.c 
#ifdef USE_B 
// definitions 
#endif 

// a.c 
#include "b.h" // <- no USE_B needed here 
0

Вы могли бы попытаться расколоть B и модули C на отдельные компоненты библиотеки, убедившись, что все Глобал используемых этих библиотеками, содержатся в них. Для этого может потребоваться переместить объявления переменных extern в файлы интерфейса библиотеки или, при необходимости, предоставить методы доступа.

В качестве альтернативы, если вы используете GCC, компилятор имеет расширение языка в виде __attribute__((weak)), которое объявит версию переменной «just-in-case-it -s-not-defined-where-else» что будет держать компоновщика счастливым.

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