gmake компилируют все файлы в каталоге

Существует простой прием для этой проблемы:

bool IsPowerOfTwo(ulong x)
{
    return (x & (x - 1)) == 0;
}

Примечание, эта функция сообщит true для [1 112], который не является питанием [1 113]. Если Вы хотите исключить это, вот то, как:

bool IsPowerOfTwo(ulong x)
{
    return (x != 0) && ((x & (x - 1)) == 0);
}

Объяснение

Прежде всего поразрядный двоичный файл & оператор из определения MSDN:

Двоичный файл & операторы предопределены для целочисленных типов и bool. Для целочисленных типов, & вычисляет логическое поразрядное И его операндов. Для bool операндов, & вычисляет логическое И его операндов; то есть, результат верен, если и только если оба его операнда верны.

Теперь позволяют нам смотреть на то, как это все теряет значение:

функция возвращает булевскую переменную (верный / ложь) и принимает один входящий параметр типа, неподписанного длинный (x, в этом случае). Давайте ради простоты предположим, что кто-то передал значение 4 и вызвал функцию как так:

bool b = IsPowerOfTwo(4)

Теперь мы заменяем каждое возникновение x с 4:

return (4 != 0) && ((4 & (4-1)) == 0);

Хорошо мы уже знаем это 4! = 0 evals к истинному, пока неплохо. Но что относительно:

((4 & (4-1)) == 0)

Это переводит в это, конечно:

((4 & 3) == 0)

, Но что точно 4&3?

двоичное представление 4 равняется 100, и двоичное представление 3 равняется 011 (помните & берет двоичное представление этих чисел). Таким образом, мы имеем:

100 = 4
011 = 3

Воображают эти значения сложенными во многом как элементарное дополнение. & оператор говорит, что, если оба значения равны 1 тогда, результат равняется 1, иначе это 0. Так 1 & 1 = 1, 1 & 0 = 0, 0 & 0 = 0, и 0 & 1 = 0. Таким образом, мы делаем математику:

100
011
----
000

результат просто 0. Таким образом, мы возвращаемся и смотрим на то, во что теперь переводит наш оператор возврата:

return (4 != 0) && ((4 & 3) == 0);

, Который переводит теперь в:

return true && (0 == 0);
return true && true;

Все мы знаем, что true && true просто true, и это показывает, что для нашего примера, 4 питание 2.

13
задан squelart 28 August 2009 в 04:05
поделиться

2 ответа

Показанный вами синтаксис на языке GNU make называется шаблонным правилом, и он является краеугольным камнем вашего решения. Все, что вам нужно, это добавить способ динамического получения списка файлов .C. Другие показали решения, в которых для этого используется $ (shell) , но это совершенно неэффективно. Я предлагаю вам вместо этого использовать $ (подстановочный знак), который является встроенной функцией GNU make, разработанной именно для этой цели:

SRCS = $(wildcard *.C)
OBJS = $(patsubst %.C,%.o,$(SRCS))
foo: $(OBJS)
        $(CC) -o $@ $^

%.o: %.C
        $(CC) $(CPFLAGS)  -c  $<

Если вы ищете что-то более сжатое, то подойдет и следующее:

foo: $(patsubst %.C,%.o,$(wildcard *.C))

Это просто устраняет переменных и использует тот факт, что GNU make предоставляет шаблонное правило %. o:% .C по умолчанию, а также правило по умолчанию для связывания исполняемого файла из набора объектов. Лично я бы использовал более подробную версию, так как мне легче читать и поддерживать,

22
ответ дан 1 December 2019 в 22:07
поделиться

Это пример шаблонного правила , он должен нормально работать в gmake . Для очень простых сборок, подобных этой, вы в основном можете полагаться на неявные правила . Главное, что вы должны указать в цели, которую вы хотите построить, и ее зависимостях:

CXXFLAGS:=-g -O -Iincludes
LDFLAGS:=-lm

SRCS:=$(shell ls *.C)          # select all .C files as source
OBJS:=$(substr .C,.o,$(SRCS)   # list the corresponding object files

foo : $(OBJS)

Обратите внимание на использование просто оператора присваивания расширенной переменной (: = ) вместо рекурсивного оператор присваивания ( = ), который может уменьшить объем повторной обработки make в более сложных сборках.

1
ответ дан 1 December 2019 в 22:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: