Home > Net >  Calling a GNU ar script in Makefile
Calling a GNU ar script in Makefile

Time:09-22

I'm having some trouble using GNU ar script from a Makefile. Specifically, I'm trying to follow an answer to How can I combine several C/C libraries into one?, but ar scripting isn't well supported by make, as most Makefiles use the ar command-line interface and not a script. ar needs each line to be terminated by a new line (\n). This is not the same as multiple shell commands which can use a semicolon as a separator.

The ar commands are:

ar -M <<CREATE libab.a
    ADDLIB liba.a
    ADDLIB libb.a
    SAVE
    END
ranlib libab.a

I'm trying to merge the libraries because I'm creating a static library in a Makefile which depends on another static library, but the second one is created with CMake.

foo.a: foo.o
    $(AR) $(ARFLAGS) $@ $^

final_lib.c: foo.a the_cmake_library.a
    $(AR) -M <<CREATE $@
        ADDLIB foo.a
        ADDLIB the_cmake_library.a
        SAVE
        END
    ranlib $@

The above doesn't work because make is interpreting the ar commands as its own, so I'm getting a

make: CREATE: Command not found

If these were bash commands, I could use something like this answer, but that doesn't work:

ar -M <<CREATE libab.a; ADDLIB liba.a; ADDLIB libb.a; SAVE; END

ar doesn't have a command-line version of the ADDLIB command.

My current solution is:

final_lib.c: foo.a the_cmake_library.a
    $(shell printf "EOM\nCREATE $@\nADDLIB foo.a\nADDLIB the_cmake_library.a\nSAVE\nEND\nEOM\n" > ARCMDS.txt)
    $(AR) -M < ARCMDS.txt
    ranlib $@

I find that very clumsy. Does anyone know of a better way to handle ar scripts in a Makefile? Thanks!

CodePudding user response:

You don't need to use the shell function and you don't need to write it to a file. ar is taking from stdin anyway so why not just use a pipe?

Either:

final_lib.c: foo.a the_cmake_library.a
        printf "EOM\nCREATE $@\nADDLIB foo.a\nADDLIB the_cmake_library.a\nSAVE\nEND\nEOM\n" | $(AR) -M
        ranlib $@

Or something like:

final_lib.c: foo.a the_cmake_library.a
        (echo EOM; \
         echo "CREATE $@"; \
         echo ADDLIB foo.a; \
         echo ADDLIB the_cmake_library.a; \
         echo SAVE; \
         echo END; \
         echo EOM) \
            | $(AR) -M
        ranlib $@
  • Related