1. 12
    1. 1

      Override PWD so that it’s always based on the location of the file and NOT based on where the shell is when calling make. This is useful if make is called like make -C <some path>

      make -C already changes directory before doing anything else, so this is unnecessary.

      1. 1

        Hi! Author here. make -C changes the directory to find the Makefile, but the make variable $(PWD) points to where you call make from. To reproduce:

        # create root folder
        mkdir level1
        cd level1
        # create nested folder
        mkdir level2
        # Create makefile inside level2 with the contents:
        # t:
        # 	@echo $(PWD)
        echo -e "t:\n\t@echo \$(PWD)" > level2/Makefile
        # run make
        make -C level2
        # Output:
        # <your path>/level1

        The script will print level1, which is the location from where you call make. It will not print level2, the location of the Makefile.

        In any case, I like overriding $(PWD) to make sure I can reference paths starting from the location of the Makefile, regardless of what the caller does.

        1. 2

          You’re right of course - PWD is inherited from the caller in most makes. Are you using GNU make?

          I think what you want is CURDIR (which will even be standardised in POSIX 202x).

          1. 1

            Aha! I think I had read about CURDIR but kind of forgot it existed, that’s exactly what I need. I try to avoid some “modern-GNU-only” features so that the makefiles also work with the version shipped by macOS (3.81 in my case), but I see CURDIR works in that version too[^1]. I’ll update the post with a link to your comment, thanks!

            [^1]: Out of curiosity, it seems CURDIR was added in 1998.

    2. 1

      I was interested in the .venv/ path trick, but it didn’t work on Linux, which seems to store envs in $(HOME)/.cache/pypoetry/virtualenvs/. (I think python is single-handedly responsible for half of my gray hairs.)

      edit: This seems to work for all 3 cases, and uses shell instead of $$ so it only gets eval’d once:

      PYTHON ?= $(shell if $(POETRY) --help >/dev/null 2>&1; then echo $(POETRY) run python; else if [ -d $(PWD)/'.venv' ]; then echo $(PWD)/".venv/bin/python3"; else echo "python3"; fi; fi)

      1. 1

        I think python is single-handedly responsible for half of my gray hairs.

        I’m a broken record, but: every time I hear this and dig into it, it ends up not being Python’s standard tooling, but instead some alternative/third-party thing.

        For example, it’s clear from the rest of your comment that you’re using Poetry. Maybe you’re happy with it most of the time, even. But Python has clear standard default package tooling (setuptools to define packages; pip to install and manage them; venv to isolate projects’ dependencies from each other) and Poetry is not part of that. And I have found, through long years of experience, that the pain and suffering mostly comes from using a third-party thing, and then having to introduce yet another tool or workaround when that doesn’t quite do what’s needed, and then one day I wake up with a rickety Jenga tower of half-assed stuff.

        Meanwhile, when I stick to a workflow using the standard tools – even though they’re a bit low-level and manual to work with – I don’t end up there, and have a far happier and easier time.

        1. 1

          Yeah, that argument has come up many times before (on here and other places). The short answer is: The reason tools like poetry exist is that the combined knowledge required to do things “the right way” without any tooling is too complicated for the casual user (like me). If python fixes the common cases, these tools would probably wither away.