I want to copy all prerequisites into a folder to then process them there. I have tried a shell for loop, but the syntax seems to be different
for f in $^; do cp $f some/folder/; done
I also tried the foreach loop from GNU make
$(foreach f,$^,cp $f some/folder/)
I have found this explanation, but I don't really understand it
make: execute an action for each prerequisite
Here is my recipe
CURRENT := $(PWD)
IMAGE_TREE_SOURCE := ./device/layer/kernelFitImage.its
FIT_PREREQUISITES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/arch/$(TARGET_KERNEL_ARCH)/boot/Image \
$(PRODUCT_OUT)/ramdisk-recovery.img \
$(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/arch/$(TARGET_KERNEL_ARCH)/boot/dts/freescale/imx8mm-gpv-distec.dtb \
$(IMAGE_TREE_SOURCE)
FIT_IMAGE_TARGET := $(PRODUCT_OUT)/boot/fitImage
$(FIT_IMAGE_TARGET): $(FIT_PREREQUISITES)
echo "Creating FIT image"
mkdir -p $(dir $@)
# for f in $^; do $$f $(PRODUCT_OUT)/boot; done
cd $(PRODUCT_OUT)/boot
cp $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/arch/$(TARGET_KERNEL_ARCH)/boot/Image .
cp $(PRODUCT_OUT)/ramdisk-recovery.img .
cp $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/arch/$(TARGET_KERNEL_ARCH)/boot/dts/freescale/imx8mm-gpv-distec.dtb .
cp $(IMAGE_TREE_SOURCE) .
mkimage -f kernelFitImage.its $@
rm ./Image
rm ./ramdisk-recovery.img
rm ./imx8mm-gpv-distec.dtb
rm ./kernelFitImage.its
cd $(CURRENT)
I am trying to substitute all the copy statements to clean this recipe up a bit.
CodePudding user response:
You don't need a loop; why can't you just use cp $^ $(PRODUCT_OUT)/boot
? However, the for loop DOES work. If you go look in the directory after the failure, don't you see the files you copied there? If something is failing you'll have to look for some other problem.
I will point out that unless you're setting oneshell in your makefile, this can't work:
cd $(PRODUCT_OUT)/boot
cp $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/arch/$(TARGET_KERNEL_ARCH)/boot/Image .
...
Every individual logical line in a recipe is run in a separate shell. So after each line is complete, the shell exits (so make knows what its exit code is and whether it failed or not). When that happens all context local to the shell which includes environment variables and the working directory, are thrown away.
So, the cd ...
line above is a no-op: it will change to the directory in a subshell, then the subshell exits and you're back where you started. The next shell will still be in the original directory.
You have to turn this into a single logical line, by adding semicolons and backslashes:
cd $(PRODUCT_OUT)/boot; \
cp $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/arch/$(TARGET_KERNEL_ARCH)/boot/Image .; \
...