Reputation: 20569
I have a complex logic for detecting path for Makefile variable. I gave up on doing this in make language, so I coded it in Python, and want to embed the code into Makefile to set variable. However, this doesn't work:
define DETECT_SDK
import os
locations = [
"../google_appengine",
"/usr/local/google_appengine",
"../.locally/google_appengine",
]
for path in locations:
if os.path.exists(path):
print(path)
break
else:
print(".")
endef
SDK_PATH ?= $(shell python -c $(DETECT_SDK))
default:
python -c 'import sys; print(sys.argv)' $(SDK_PATH)
UPDATE: Updated multiline definition from Is it possible to create a multi-line string variable in a Makefile
Previously it was failing with Makefile:2: *** missing separator. Stop.
. Now it fails with another error:
/bin/sh: 1: Syntax error: "(" unexpected
python -c 'import sys; print(sys.argv)'
['-c']
Upvotes: 2
Views: 3181
Reputation: 20569
Due to some make
bug, which tried to execute multiline strings, the following worked for me:
define NEWLINE
endef
define DETECT_SDK
import os
locations = [
"../google_appengine",
"/usr/local/google_appengine",
"../.locally/google_appengine",
]
for path in locations:
if os.path.exists(path):
print(path)
break
endef
SDK_PATH ?= $(shell echo '$(subst $(NEWLINE),@NEWLINE@,${DETECT_SDK})' | sed 's/@NEWLINE@/\n/g' | python -)
default:
@echo 'SDK Path Detected: $(SDK_PATH)'
Upvotes: 1
Reputation: 101081
You have to quote the string you pass to Python:
SDK_PATH ?= $(shell python -c '$(DETECT_SDK)')
Otherwise the shell will be confused trying to parse the Python script.
EDIT:
I don't understand your Python script though. Either your indentation is wrong, so the else
is supposed to be attached to the if (grrr...) or else you're missing a break
statement... or possibly the else
is just useless. As it's written, it will generate a newline-separated list of paths that exist, plus ".". If you describe what you're really trying to do, rather than just say you gave up, we can help.
For example, if what you want to do is print the first existing path in that list or "." if none exist (that is, your Python loop is missing a break
after the print
), then you can easily do this in GNU make:
SDK_PATH_LIST = ../google/appengine /usr/local/google_appengine ../.locally/google_appengine
SDK_PATH ?= $(firstword $(wildcard $(SDK_PATH_LIST:%=%/.)) .)
Upvotes: 2