Как лучше всего использовать разные CFLAGS для одних и тех же исходных файлов? - PullRequest
7 голосов
/ 25 марта 2010

мне нужно построить одно и то же дерево исходного кода дважды,

1 - с обычными флагами для сборки двоичного файла проекта
2 - cflags плюс -fPIC для создания статической библиотеки, которая будет своего рода SDK для разработки динамических модулей проекта.

Каков наилучший подход для достижения этой цели, используя только один Makefile?

Было бы неплохо сделать что-то вроде:

all: $(OBJECTS)

lib_rule: $(OBJECTS)
   CFLAGS += -fPIC

.cpp.o: 
   $(CC) -c $< -o $@ $(CFLAGS)

Но, очевидно, это не может быть сделано.

Спасибо

Ответы [ 4 ]

12 голосов
/ 25 марта 2010

Одна вещь, которую я использовал в прошлом, это другое расширение:

.cpp.o:
    $(CC) -c $< -o $@ $(CFLAGS)

.cpp.lo:
    $(CC) -c $< -o $@ $(CFLAGS) $(EXTRA_CFLAGS)

Затем вы собираете статическую библиотеку из файлов .lo, а двоичный файл из файлов .o:

prog: a.o b.o

libsdk.a: a.lo b.lo

Предполагая, что вы используете GNU Make, вы можете использовать некоторые встроенные функции, чтобы вести список объектов только один раз:

OBJS = a.o b.o
LOBJS = $(patsubst %.o, %.lo, $(OBJS))
7 голосов
/ 27 марта 2010

GNU make предлагает также «Значения переменных, специфичных для цели». Рассмотрим следующий Makefile:

# Makefile  
CFLAGS := My Cflags

all: $(OBJECTS)  
        @echo "$@ CFLAGS is: " $(CFLAGS)  

lib_rule: CFLAGS += extended by -fPIC  
lib_rule: $(OBJECTS)  
        @echo "$@ CFLAGS is: " $(CFLAGS)  

# Makefile - end.

$ сделать все
все CFLAGS это: Мои Cflags
$ make lib_rule
lib_rule CFLAGS: Мои флаги расширены с помощью -fPIC
$
(Обратите внимание: если вы копируете и вставляете пример, не забудьте повторно добавить табуляторы перед командной строкой. Я всегда зацикливаюсь на этом.)

2 голосов
/ 25 марта 2010

Вместо того, чтобы помещать скомпилированные файлы .o в один каталог с исходным кодом, я создаю их в помеченных подкаталогах.В вашем случае файлы статической библиотеки могут быть созданы как source_dir/lib/*.o, а ваши обычные файлы - как source_dir/bin/*.o.В разных целях сборки после настройки уникального CFLAGS просто сгенерируйте значение DIR_NAME, содержащее имя соответствующей подпапки.Эту переменную можно использовать при создании путей, которые компилятор будет использовать при сборке и при компоновке.

0 голосов
/ 25 марта 2010

В другом инструменте make, таком как CMake, вы можете выразить нечто подобное гораздо проще.

Например, вы могли бы сделать

set(sources ABC.cpp DEF.cpp XYZ.cpp)
ADD_LIBRARY(mylib STATIC ${sources})
add_executable(myExecutable  ${sources} main.cpp)

Или вы можете многократно создавать один и тот же каталог с разными флагами, включая его несколько раз из логического родителя каталога, т.е.

set(MyTweakFlag 2)
add_subdirectory("libDir" "libDir2")
set(MyTweakFlag 3)
add_subdirectory("libDir" "libDir3")

... и затем используйте if() или еще много чего в дочернем каталоге, чтобы установить правильные флаги.

В частности, если у вас много таких конфигураций, использование make становится довольно хрупким; make не сможет правильно найти транзитивное закрытие рекурсивных зависимостей make (и, конечно, не сможет правильно найти зависимость от самого make-файла - скажем, если вы измените флаги), так что если вы собираетесь делать сложную магию make-файла: сделайте это с лучший инструмент!

(CMake просто оказывается тем, чем я заменил, с помощью make, но, конечно, возможны и другие замены)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...