Условная компиляция исходного файла, который должен быть включен только в отладочные сборки - PullRequest
0 голосов
/ 03 июня 2019

Я читал лучшие практики для условной компиляции, но я не нашел пример ситуации, которая у меня есть.

У меня есть проект C, целевой платформой которого является конкретное устройство (отличное от ПК).).У меня есть исходный файл, который содержит только функции для тестирования интеграции и тому подобное.Я хочу, чтобы этот файл компилировался и связывался только в DEBUG сборках, а не в RELEASE.

У меня вопрос, какой из следующих вариантов лучше: *Файл 1009 *

A *.c, подобный следующему:

Tests.c
---------
#ifndef NDEBUG
// All testing functions
...
#endif

И включите этот файл в сборки DEBUG и RELEASE.

Или

Проверка того, определено ли NDEBUG из Makefile / CMakeLists.txt проекта и, следовательно, включая указанный исходный файл.

Ответы [ 3 ]

6 голосов
/ 03 июня 2019

Мое личное мнение (!) По этому поводу:

Первый подход - #ifndef NDEBUG - предпочтительнее.

В начале было cc *.c.

Затем последовало добавление соответствующих опций.

Затем появились системы сборки, которые выяснили, какие из этих *.c файлов действительно требовали перекомпиляции, и освободили вас от запоминания, какие соответствующие опции были .

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

Со временем системы сборки стали умнее, и может содержать значительную логику. Тем не менее, я чувствую, что этот интеллект должен оставаться сосредоточенным на их основной функции (см. Выше), и что - в конце концов - cc *.c все еще должен выполнять свою работу.

Системы сборки устарели или заменены. Следующий парень может даже не знать, какую систему сборки вы выбрали; он все еще должен быть в состоянии сделать из головы ваш проект, не разбираясь и в логике вашей системы сборки.

Установка / проверка NDEBUG - это C, и любой, кто немного знаком с языком (и <assert.h>), сразу же узнает, что вы собираетесь там делать.

Выяснение того, почему конкретный исходный файл должен быть включен только в определенный тип сборки, но не в другие, из вашей системы сборки, не так интуитивно понятно и может вообще потеряться, когда кто-то подойдет, выбросит ваш CMakeLists.txt потому что он любит джем больше и строит это с нуля. Этот человек может в конечном итоге задаться вопросом, почему все эти тесты загромождают его код выпуска и почему вы не достаточно умны, чтобы делать их только для отладки (не осознавая, что сделал в своей системе сборки).

1 голос
/ 03 июня 2019

На самом деле, я не понимаю, почему выбрать только один? На мой взгляд, оба варианта могут и должны использоваться вместе.

Если какой-то файл совершенно не нужен в сборке релиза, то у вас есть прекрасная причина полностью исключить его из процесса сборки. Но наличие некоторой защиты препроцессора в исходном коде (будь то #ifdef или #error), безусловно, очень полезно.

0 голосов
/ 03 июня 2019

Я считаю, что первый подход (#ifndef NDEBUG) лучше, почему?

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

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

...