Search code examples
shellmakefilegnu

use of variables in gnu makefile


This is a GNU make question. Maybe a simple one, but I did search some textbooks before and didn't find the answer.

Short description of what I want to do:

  1. copy a range of bytes from a file in a temporary file
  2. calculate the checksum of this file with crc32 utility
  3. just print the checksum in the build process for now
  4. delete the temporary file

The problem I see is that every command is done in a separate shell, but I need a way to get input from the previous command to execute the next one.

eg:

/opt/rtems-4.11/bin/arm-rtems4.11-nm -a px_pmc.elf | grep bsp_section_start_begin | awk '{print $$1}'
/opt/rtems-4.11/bin/arm-rtems4.11-nm -a px_pmc.elf | grep _Check_Sum | awk '{print $$1}'

These commands will print in shell the limits of the range of bytes I want, but how do I store them in two variables, say low_limit/high_limit so I can copy that range in the temp file in the next make command ?

dd if=px_pmc.bin skip=low_limit bs=(high_limit-low_limit) count=1 of=temp.bin

(in C you can do this with a simple variable, I'm looking for the equivalent here)

regards, Catalin


Solution

  • You can chain all your shell commands such that they are all executed in the same shell:

    cmd1; cmd2; cmd3
    

    If you prefer one command per line you can also use the line continuation (\):

    cmd1; \
    cmd2; \
    cmd3
    

    (be careful, no spaces after the \). And you can assign the output of a shell command to a shell variable:

    a="`cmd1`"
    

    So, the only subtlety here is that make will expand the recipe before passing it to the shell and this will eat all $ signs. If you want to preserve them such that they are passed to the shell, you must double them ($$):

    a="`cmd1`"; \
    b="`cmd2`"; \
    cmd3 "$$a" "$$b"
    

    In your case you can try this (untested):

    target:
        low_limit="`/opt/rtems-4.11/bin/arm-rtems4.11-nm -a px_pmc.elf | grep bsp_section_start_begin | awk '{print $$1}'`"; \
        high_limit="`/opt/rtems-4.11/bin/arm-rtems4.11-nm -a px_pmc.elf | grep _Check_Sum | awk '{print $$1}'`"; \
        bs="`expr "$$high_limit" - "$$low_limit"`"; \
        dd if=px_pmc.bin skip="$$low_limit" bs="$$bs" count=1 of=temp.bin
    

    I added the computation of high_limit-low_limit using expr. This should be more or less compatible with the bourne shell which is the default shell make uses.