tags:

views:

32

answers:

3

I need to invoke make (build a makefile) in a directory different from the one I'm in, from inside a Python script. If I simply do:

build_ret = subprocess.Popen("../dir1/dir2/dir3/make",
                     shell = True, stdout = subprocess.PIPE)

I get the following: /bin/sh: ../dir1/dir2/dir3/make: No such file or directory

I've tried:

build_ret = subprocess.Popen("(cd ../dir1/dir2/dir3/; make)",
                     shell = True, stdout = subprocess.PIPE)

but the make command is ignored. I don't even get the "Nothing to build for" message.

I've also tried using "communicate" but without success. This is running on Red Hat Linux.

A: 

Try to use the full path, you can get the location of the python script by calling

sys.argv[0]

to just get the path:

os.path.dirname(sys.argv[0])

You'll find quite some path manipulations in the os.path module

Fabian
Be careful when just using `os.path.dirname`. It returns an empty string when given just a file name. Calling `os.path.abspath(os.path.dirname(sys.argv[0]))` will always get you the the full path.
unholysampler
+2  A: 

Use the cwd argument, and use the list form of Popen:

subprocess.Popen(["make"], stdout=subprocess.PIPE, cwd="../dir1/dir2/dir3")

Invoking the shell is almost never required and is likely to cause problems because of the additional complexity involved.

Philipp
The python docs say the following:If cwd is not None, the child’s current directory will be changed to cwd before it is executed. Note that this directory is not considered when searching the executable, so you can’t specify the program’s path relative to cwd.So I'm not sure if that will work.
Fabian
The `make` program should be in the search path, of course. I'm pretty sure that this works (unless I made some silly typo) because I'm using it all the time.
Philipp
Of course, in this case this is correct. I got a bit confused.
Fabian
+2  A: 

I'd go with @Philipp's solution of using cwd, but as a side note you could also use the -C option to make:

make -C ../dir1/dir2/dir3/make

-C dir, --directory=dir

Change to directory dir before reading the makefiles or doing anything else. If multiple -C options are specified, each is interpreted relative to the previous one: -C / -C etc is equivalent to -C /etc. This is typically used with recursive invocations of make.

John Kugelman