Search code examples
makefilegnu-make

Start and kill background process within one Makefile recipe


Within one make recipe, I am trying to:

  1. Run a server process in the background
  2. Run a command that uses the server, in the foreground
  3. Kill the background server process after foreground task completes

The below is where I am at (inspired by https://stackoverflow.com/a/30171236), but it doesn't quite work because SERVER_PID is currently empty (possibly related to this empty PID: Getting last process' PID in Makefile).

run-server: ## Run the server in the foreground.
    run server

run-kill-server:    ## Run the server while using it.
    @$(MAKE) run-server&
    export SERVER_PID=$! && cmd-that-uses-server && kill $(SERVER_PID)

Makefile run processes in background is also related, except I believe it "leaks" the background processes, the recipes there don't try to kill spawned background processes


Solution

  • Within one make recipe, I am trying to:

    1. Run a server process in the background
    2. Run a command that uses the server, in the foreground
    3. Kill the background server process after foreground task completes

    But you're not doing all that in one recipe. You're using two.

    Bringing it all into one recipe would be a step in the right direction, though It will not in itself provide a complete solution.

    SERVER_PID is currently empty

    Yes, because your recipe is setting shell variable SERVER_PID, but trying to reference a make variable of that name. And also trying to reference a make variable named !, where you appear to want the shell variable of that name. You need to escape your $ by doubling it when you want to pass it through to the shell.

    Additionally, each logical line of your recipe runs in a separate shell. In the one where you define and later user SERVER_PID, no background process is ever run.

    You probably want something more like this:

    run-job:
            run server & export SERVER_PID=$$!; cmd-that-uses-server; kill $${SERVER_PID}