68

I have a Makefile from which I want to call another external bash script to do another part of the building. How would I best go about doing this?

2240
  • 1,547
  • 2
  • 12
  • 30
Matthew FL
  • 1,612
  • 3
  • 18
  • 22

5 Answers5

66

Just like calling any other command from a makefile:

target: prerequisites
    shell_script arg1 arg2 arg3

Regarding your further explanation:

.PHONY: do_script

do_script: 
    shell_script arg1 arg2 arg3

prerequisites: do_script

target: prerequisites 
Carl Norum
  • 219,201
  • 40
  • 422
  • 469
16

Perhaps not the "right" way to do it like the answers already provided, but I came across this question because I wanted my makefile to run a script I wrote to generate a header file that would provide the version for a whole package of software. I have quite a bit of targets in this package, and didn't want to add a brand new prerequisite to them all. Putting this towards the beginning of my makefile worked for me

$(shell ./genVer.sh)

which tells make to simply run a shell command. ./genVer.sh is the path (same directory as the makefile) and name of my script to run. This runs no matter which target I specify (including clean, which is the downside, but ultimately not a huge deal to me).

yano
  • 4,827
  • 2
  • 23
  • 35
13

Each of the actions in the makefile rule is a command that will be executed in a subshell. You need to ensure that each command is independent, since each one will be run inside a separate subshell.

For this reason, you will often see line breaks escaped when the author wants several commands to run in the same subshell:

targetfoo:
    command_the_first foo bar baz
    command_the_second wibble wobble warble
    command_the_third which is rather too long \
        to fit on a single line so \
        intervening line breaks are escaped
    command_the_fourth spam eggs beans
bignose
  • 30,281
  • 14
  • 77
  • 110
12

Currently using Makefile, I can easily call the bash script like this:

dump:
    ./script_dump.sh

And call:

make dump

This also works like mentioned in the other answer:

dump:
    $(shell ./script_dump.sh)

But the downside is that you don't get the shell commands from the console unless you store in a variable and echo it.

Brother
  • 2,150
  • 1
  • 20
  • 24
0

Not sure if this is best practice, but the most straightforward approach I've found is to simply use bash, if your terminal has it:

run_file:
    bash ./scripts/some_shell_script.sh

This negates the need to alter the permissions of the file first then by executing directly i.e. via ./scripts/some_shell_script.sh. Alternately to source the command in the spawned make process, the following 2 methods below will also work (the ./ is optional).

run_file_source:
    source ./scripts/some_shell_script.sh

run_file_source_alt:
    . ./scripts/some_shell_script.sh

Within your terminal, the following can then be run.

$ make run_file

An extended make entry to run a python file after running a shell script to activate the virtual environment to run it in (by chaining commands with &&):

run-python:
    @bash -c "source ./scripts/python/activate_env.sh && \
    python src/python_scripts/main.py"

run-python-alt:
    @source ./scripts/python/activate_env.sh && \
    python src/python_scripts/main.py
decoder247
  • 134
  • 2
  • 12