gmake: преобразовать все %.c и %.cxx в переменной в lib%.a lib%.so

#gnu-make

#gnu-make

Вопрос:

Мой makefile создает несколько небольших библиотек по .a и .so форме из отдельных .c и .cxx файлов. Например, если SmallLibSrc включает a foo.c , я хочу SmallLibs включить libfoo.a libfoo.so . Аналогично, если SmallLibSrc включает a bar.cxx , я хочу SmallLibs включить libbar.a libbar.so .

Я могу заставить это работать в два этапа, используя фиктивную переменную, такую как:

 SmallLibsDummyA  = $(SmallLibSrc:%.c=lib%.a)
SmallLibsDummySO = $(SmallLibSrc:%.c=lib%.so)
SmallLibs        = $(SmallLibsDummyA:%.cxx=lib%.a) $(SmallLibsDummySO:%.cxx=lib%.so)
  

Но по какой-то причине выполнить это в одной переменной не удается. Я думаю, что я чего-то не понимаю в синтаксисе этих замен. Есть ли другой однострочный подход, который бы сработал? Обратите внимание, что я частично прошу о более чистом решении, но в основном для того, чтобы узнать больше о $ ().

 SmallLibs = $($(SmallLibSrc:%.cxx=lib%.a):%.c=lib%.a) $($(SmallLibSrc:%.cxx=lib%.so):%.c=lib%.so)
  

Ответ №1:

Это не сработает:

 SmallLibSrc = foo.cxx bar.c

$($(SmallLibSrc:%.cxx=lib%.a):%.c=lib%.a)
  

потому что формат переменных подстановки такой, $(NAME:...) где NAME это имя переменной. В вашем примере сначала расширяется внутренняя переменная, и вы получаете:

 SmallLibSrc = foo.cxx bar.c

$(libfoo.a bar.c:%.c=lib%.a)
  

Он попытается расширить переменную make с именем libfoo.a bar.c , которая явно не существует.

Вы не можете использовать эту форму; вам придется использовать более универсальную функцию, например, эту:

 $(foreach base,$(basename $(SmallLibSrc)),lib$(base).a lib$(base).so)