Заголовки конфигурации для конкретной платформы
У меня была бы система для генерации специфичной для платформы конфигурации в заголовок, который используется во всех сборках. Имя AutoConf - «config.h»; Вы можете увидеть «platform.h» или «porting.h» или «port.h» или другие варианты темы. Этот файл содержит информацию, необходимую для построения платформы. Вы можете сгенерировать файл, скопировав вариант, зависящий от версии, в стандартное имя. Вы можете использовать ссылку вместо копирования. Или вы можете запустить конфигурационные сценарии, чтобы определить его содержимое на основе того, что сценарий найден на компьютере.
Значения по умолчанию для параметров конфигурации
Код:
#if (DAN==YES)
char MasterSkipFile[MAXSTR] = "/home/dp120728/tools/testarea/MasterSkipFile";
#endif
#if (UNIX==YES)
char MasterSkipFile[MAXSTR] = "/home/tregrp/tre1/tretools/MasterSkipFile";
#endif
#if (LINUX==YES)
char MasterSkipFile[MAXSTR] = "/ptehome/tregrp/tre1/tretools/MasterSkipFile";
#endif
Лучше бы заменить на:
#ifndef MASTER_SKIP_FILE_PATH
#define MASTER_SKIP_FILE_PATH "/opt/tretools/MasterSkipFile"
#endif
const char MasterSkipFile[] = MASTER_SKIP_FILE_PATH;
Те, кто хочет построить сборку в другом месте, могут установить местоположение с помощью:
-DMASTER_SKIP_FILE_PATH='"/ptehome/tregtp/tre1/tretools/PinkElephant"'
Обратите внимание на использование одинарных и двойных кавычек; старайтесь не делать этого в командной строке с обратными слешами в пути. Вы можете использовать подобный механизм по умолчанию для всех видов вещей:
#ifndef DEFAULTABLE_PARAMETER
#define DEFAULTABLE_PARAMETER default_value
#endif
Если вы выберете свои значения по умолчанию, это может сэкономить много энергии.
Перемещаемое программное обеспечение
Я не уверен насчет дизайна программного обеспечения, которое может быть установлено только в одном месте. В моей книге вы должны иметь возможность установить на машину старую версию 1.12 продукта одновременно с новой версией 2.1, и они должны работать независимо друг от друга. Жестко заданное имя пути побеждает это.
Параметризация по функции, а не по платформе
Ключевое различие между инструментами AutoConf и средней альтернативной системой заключается в том, что конфигурация выполняется на основе функций, а не на платформах. Вы параметризуете свой код, чтобы определить функцию, которую вы хотите использовать. Это очень важно, поскольку функции, как правило, появляются на платформах, отличных от оригинала. Я смотрю после кода, где есть такие строки, как:
#if defined(SUN4) || defined(SOLARIS_2) || defined(HP_UX) || \
defined(LINUX) || defined(PYRAMID) || defined(SEQUENT) || \
defined(SEQUENT40) || defined(NCR) ...
#include <sys/types.h>
#endif
Было бы намного лучше иметь:
#ifdef INCLUDE_SYS_TYPES_H
#include <sys/types.h>
#endif
А затем на платформах, где это необходимо, сгенерировать:
#define INCLUDE_SYS_TYPES_H
(Не воспринимайте этот пример заголовок слишком буквально; это концепция, которую я пытаюсь преодолеть.)
Рассматривайте платформу как набор функций
В качестве следствия к предыдущему пункту вам необходимо определить платформу и определить функции, применимые к этой платформе. Здесь у вас есть специфичный для платформы заголовок конфигурации, который определяет функции конфигурации.
Функции продукта должны быть включены в заголовок
( Развивая комментарий, который я сделал к другому ответу. )
Предположим, у вас есть несколько функций в продукте, которые необходимо включить или исключить условно. Например:
KVLOCKING
B1SECURITY
C2SECURITY
DYNAMICLOCKS
Соответствующий код включается при установке соответствующего определения:
#ifdef KVLOCKING
...KVLOCKING stuff...
#else
...non-KVLOCKING stuff...
#endif
Если вы используете инструмент анализа исходного кода, например cscope , то будет полезно, если он покажет вам, когда определен KVLOCKING. Если единственное место, где он определен, находится в некоторых случайных файлах Makefile, разбросанных по системе сборки (предположим, что в этом документе используется сотня подкаталогов), трудно сказать, по-прежнему ли используется код на любом из ваши платформы. Если определения находятся где-то в заголовке - в заголовке для конкретной платформы или, возможно, в заголовке выпуска продукта (поэтому версия 1.x может иметь KVLOCKING, а версия 2.x может включать C2SECURITY, но 2.5 включает B1SECURITY и т. Д.), Тогда вы можете увидеть, что Код KVLOCKING все еще используется.
Поверьте мне, после двадцати лет разработки и текучести кадров люди не знают, используются ли функции по-прежнему или нет (потому что он стабилен и никогда не вызывает проблем - возможно, потому, что он никогда не используется). И если единственное место, где можно узнать, определен ли еще KVLOCKING, находится в файлах Makefile, то такие инструменты, как cscope, менее полезны, что делает изменение кода более подверженным ошибкам при попытке очистки позже.