gnu-make

How should I invoke recursive make across ssh into a local vm?


Typically, I recurse normally:

recipe-X:
  $(MAKE) recipe-Y

However, on MacOS I recurse differently:

recipe-X:
ifeq ($(shell uname -s),Darwin)
  colima ssh -- make $@
else
  <recipe script>
endif

Should I use $(MAKE), or is this a case where I should really make? I am not clear on the differences between the two modes in this context, and how they will interact. My understanding is that $(MAKE) is a macro that propagates parallelism, environment and other concerns to the sub-make... but I am having some trouble.

What I have noticed is that $(MAKE) may break commands that would otherwise access the network within the vm by propagating the environment variables. But I have not had success with the network-based commands using ordinary make..commands which do work when I ssh into the vm and invoke via the cli.

So before diving in and doing something too clever, I figured there might be a special way that make is expecting me to use it for this purpose.


Solution

  • $(MAKE) does three things:

    1. It ensures that you're using the same binary in the submake as the parent (for example if the parent runs /my/special/make/bin/make but /my/special/make/bin is not on the PATH before /usr/bin, then using simple make to recurse would give the wrong make binary).
    2. It tells make that the recipe should be invoked even if running in -n (don't build) mode. You usually want this else your make -n doesn't tell you what will really be built.
    3. It ensures that the sub-make receives the correct form of the MAKEFLAGS environment variable so it can participate in the jobserver (parallel build control) facility.

    If you are going to run make on a remote system, then you definitely don't want #3 as the jobserver is local only: it is not network-aware.

    It's not clear if you want #1 or not: that's up to you and your environment. This is especially true on MacOS, which ships a very old and very broken version of GNU Make as it's "normal" version, which no one should ever use.

    You also may or may not want #2, depending on what these recipes actually do, but you want this you can get the same behavior without using $(MAKE) if you prefix your recipe with +.

    In short, you probably don't want to use $(MAKE) in this situation. But you may have to do something to emulate the parts of it that you DO want.