я должен создать то же исходное дерево дважды,
1 - с нормальным cflags для создания двоичного файла проекта
2 - с cflags плюс-fPIC для создания статической библиотеки, которая была бы своего рода SDK для разработки динамических модулей проекта.
Используя только один Make-файл, что лучший подход должен выполнить это?
Было бы хорошо сделать своего рода:
all: $(OBJECTS)
lib_rule: $(OBJECTS)
CFLAGS += -fPIC
.cpp.o:
$(CC) -c $< -o $@ $(CFLAGS)
Но очевидно это не может быть сделано.
Спасибо
Раньше я использовал другое расширение:
.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))
Вместо того, чтобы помещать скомпилированные файлы .o
в тот же каталог, что и исходный код, я создаю их в помеченных подкаталогах. В вашем случае вы можете создать файлы статической библиотеки как source_dir / lib / *. O
, а ваши обычные файлы - как source_dir / bin / *. O
. В различных целях сборки после настройки уникального CFLAGS
просто сгенерируйте значение DIR_NAME
, содержащее имя соответствующей подпапки. Вы можете использовать эту переменную при создании путей, которые компилятор будет использовать при построении и при компоновке.
В другой инструмент 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")
... и затем использовать , если ()
или еще много чего в дочернем каталоге, чтобы установить правильные флаги.
В частности, если у вас много таких конфигураций, использование make становится весьма уязвимым; make не сможет правильно найти транзитивное закрытие рекурсивных зависимостей make (и, конечно же, не сможет правильно найти зависимость от самого make-файла - например, если вы измените флаги), поэтому, если вы собираетесь совершить сложную магию make-файла: сделайте это с лучший инструмент!
(Я просто заменил make на CMake, но, конечно, возможны и другие замены)
GNU предлагает также «Целевые значения переменных». Рассмотрим следующий файл 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.
$ make all
все CFLAGS - это: My Cflags
$ make lib_rule
lib_rule CFLAGS is: My Cflags расширен -fPIC
$
(Обратите внимание: если вы скопируете и вставите пример, не забудьте повторно добавить табуляторы перед командными строками. Я всегда получаю поймано этим.)