Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
692 views
in Technique[技术] by (71.8m points)

gnu make - Check if a program exists from a Makefile

How can I check if a program is callable from a Makefile?

(That is, the program should exist in the path or otherwise be callable.)

It could be used to check for which compiler is installed, for instance.

E.g. something like this question, but without assuming the underlying shell is POSIX compatible.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Sometimes you need a Makefile to be able to run on different target OS's and you want the build to fail early if a required executable is not in PATH rather than to run for a possibly long time before failing.

The excellent solution provided by engineerchuan requires making a target. However, if you have many executables to test and your Makefile has many independent targets, each of which requires the tests, then each target requires the test target as a dependency. That makes for a lot of extra typing as well as processing time when you make more than one target at a time.

The solution provided by 0xf can test for an executable without making a target. That saves a lot of typing and execution time when there are multiple targets that can be built either separately or together.

My improvement to the latter solution is to use the which executable (where in Windows), rather than to rely on there being a --version option in each executable, directly in the GNU Make ifeq directive, rather than to define a new variable, and to use the GNU Make error function to stop the build if a required executable is not in ${PATH}. For example, to test for the lzop executable:

 ifeq (, $(shell which lzop))
 $(error "No lzop in $(PATH), consider doing apt-get install lzop")
 endif

If you have several executables to check, then you might want to use a foreach function with the which executable:

EXECUTABLES = ls dd dudu lxop
K := $(foreach exec,$(EXECUTABLES),
        $(if $(shell which $(exec)),some string,$(error "No $(exec) in PATH")))

Note the use of the := assignment operator that is required in order to force immediate evaluation of the RHS expression. If your Makefile changes the PATH, then instead of the last line above you will need:

        $(if $(shell PATH=$(PATH) which $(exec)),some string,$(error "No $(exec) in PATH")))

This should give you output similar to:

ads$ make
Makefile:5: *** "No dudu in PATH.  Stop.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...