How to use include in GNUmakefile - gnu-make

I have a makefile called test.mak and another one just called GNUmakefile
The way I execute the test.mak from command line is "make test.mak arg1". Now I would like to execute it in the GNUmakefile. I know I can use "include" so I did (in GNUmakefile)
"-include test.mak arg1" but the arg1 is treated like another makefile but how do I pass the argument to test.mak?
Thanks

I am guessing you just take the argument in GNUmakefile and since they share the same variable, test.mak should be getting the argument.

There are a few errors in your question that need to be cleared up:
First, to invoke make using test.mak, you should use
make -f test.mak arg1
the "-f" tells make the name of the makefile to use. Without it, make will try to use GNUmakefile, makefile, and Makefile (in that order).
Second, the "arg1" on your command line tells make which target you are trying to make. It is an argument to the make program, but not to the makefile itself. Because of that, it's not necessary to try to "pass" arg1 to test.mak on your include line. The "include" directive's parameters are the files to be included.
The line
include test.mak arg1
tries to include two files (named test.mak and arg1).
What you really want to do in GNUmakefile is just
include test.mak
which will allow you to type
make arg1
to create the "arg1" target using your implicitly-named GNUmakefile.

Related

zsh: create named file in place of argument?

realpath <<<'foo' fails "realpath: missing operand". I don't know what that means.
realpath <(<<<'foo') returns /proc/3443695/fd/pipe:[26244650] which I guess means it's creating a temporary pipe which will contain the string "foo".
Or maybe printf is more clear:
❯ printf "%q" <<<'foo' # no output
❯ printf "%q" <(<<<'foo')
/proc/self/fd/11%
The actual program I'm trying to call doesn't like either of those. I think I need an actual file.
I can do that in multiple commands by creating a file with mktemp and then writing to it, and then sending that off as the arg, but does zsh have any convenient syntax for doing this in-place? A 1-liner?
It looks like the =(list) process substitution should do what you want.
From the zshexpn man page:
If =(...) is used instead of <(...), then the file passed as an
argument will be the name of a temporary file containing the output
of the list process. This may be used instead of the < form for a
program that expects to lseek on the input file.
...
The temporary file created by the process substitution will be deleted when the function exits.
On my system, realpath =(<<<'foo') returns something like /private/tmp/zsh3YAdDx, i.e. the name of a temporary file that does indeed appear to be deleted after executing the command.
As a bonus, the documentation notes that in some cases the =(<<<...) form is optimized to execute completely in the current shell.

Augment makefile compilation switches for specific files

CFLAGS environment variable can be used to pass compilation switches to Makefile from the outside world without modifying the file itself. Is there a way to pass switches only for one specific source file?
In my case I'd like to suppress gcc warning for several files but not for all and the Makefile is automatically generated by IDE so I cannot edit it.
We can't answer this question given the lack of details.
However you can add NEW makefiles to be parsed along with the old makefiles, without changing the old makefiles. For example, you can run this:
make -f Makefile -f ExtraMakefile
and create your own ExtraMakefile that contains any extra makefile text you want and make will read them both, in that order.
Please find below way which will help you to pass extra compiler flags and assign value into it based on your conditions.
You can pass switches by creating a new variable , Ex: CCFLAGS_EXTRASWITCH and use this flag in CCFLAGS variable.
# Append CC_FLAGS with variable CCFLAGS_EXTRASWITCH which will be used to
# pass extra switches. Value of CCFLAGS_EXTRASWITCH you can assign
# to empty or some switches based on conditions/files that you have
CC_FLAGS = $(CCFLAGS_EXTRASWITCH) \
... \ # Other default compiler flags that already exists. Keep as it is

How does GNU make's "file" function work?

I am thinking I may need to use the file function in GNU make, and just can not follow the example they give. I have looked online, but don't see any post with more explanation. Here is the example they give:
program: $(OBJECTS)
$(file >$#.in,$^)
$(CMD) $(CMDFLAGS) #$#.in
#rm $#.in
I think I know what it is doing at a high level as it is explained in the manual.
$#.in
is a list of all the target files
$^
is a list of the source files
I am not sure how #$#.in is used on the third line or what there is an # sign at the beginning. What does that mean please? What does it supposed to do?
The key to the operation of that recipe is given in the prose immediately preceding it in the manual:
Many commands use the convention that an argument prefixed with an # specifies a file containing more arguments. Then you might write your recipe in this way:
program: $(OBJECTS)
$(file >$#.in,$^)
$(CMD) $(CMDFLAGS) #$#.in
#rm $#.in
$# is the target file (there is only one of those in any given recipe)
$#.in is the target file with .in added to the end of the name.
$^ is the "list" of the all the prerequisites of the target.
#$#.in is the name of the target with .in at the end and # at the start.
So the $(file ...) call in that recipe writes the list of prerequisites of the target into a file called program.in in "overwrite" mode and then passes that file name to the $(CMD) command using the #filename convention that was mentioned.

How to manually call another target from a make target?

I would like to have a makefile like this:
cudaLib :
# Create shared library with nvcc
ocelotLib :
# Create shared library for gpuocelot
build-cuda : cudaLib
make build
build-ocelot : ocelotLib
make build
build :
# build and link with the shared library
I.e. the *Lib tasks create a library that runs cuda directly on the device, or on gpuocelot respectively.
For both build tasks I need to run the same build steps, only creating the library differs.
Is there an alternative to running make directly?
make build
Kind of a post-requisite?
Note: This answer focuses on the aspect of a robust recursive invocation of a different target in a given makefile.
To complement Jack Kelly's helpful answer, here's a GNU makefile snippet that demonstrates the use of $(MAKE) to robustly invoke a different target in the same makefile (ensuring that the same make binary is called, and that the same makefile is targeted):
# Determine this makefile's path.
# Be sure to place this BEFORE `include` directives, if any.
THIS_FILE := $(lastword $(MAKEFILE_LIST))
target:
#echo $# # print target name
#$(MAKE) -f $(THIS_FILE) other-target # invoke other target
other-target:
#echo $# # print target name
Output:
$ make target
target
other-target
Using $(lastword $(MAKEFILE_LIST)) and -f ... ensures that the $(MAKE) command uses the same makefile, even if that makefile was passed with an explicit path (-f ...) when make was originally invoked.
Note: While GNU make does have features for recursive invocations - for instance, variable $(MAKE) specifically exists to enable them - their focus is on invoking subordinate makefiles, not on calling a different target in the same makefile.
That said, even though the workaround above is somewhat cumbersome and obscure, it does use regular features and should be robust.
Here is the link to the manual section covering recursive invocations ("sub-makes"):
Recursive Use of make
Most versions of make set a variable $(MAKE) that you can use for recursive invocations.
As you have written it, the build target will need to do something different depending on whether you have just done an ocelot or cuda build. That's another way of saying you have to parameterise build in some way. I suggest separate build targets (much like you already have), with associated variables. Something like:
build-cuda: cudaLib
build-ocelot: ocelotLib
build-cuda build-ocelot:
shell commands
which invoke ${opts-$#}
On the command-line you type make build-cuda (say). Make first builds cudaLib, then it carries out the recipe for build-cuda. It expands the macros before calling the shell. $# in this case is build-cuda, thus ${opts-$#} is first expanded to ${opts-build-cuda}. Make now goes on to expand ${opts-build-cuda}. You will have defined opts-build-cuda (and of course its sister opts-build-ocelot) elsewhere in the makefile.
P.S. Since build-cuda et. al. are not real files, you had better tell make this (.PHONY: build-cuda).

Parameter for rule in Makefile

I need to make a Makefile, and it should have a run rule. However, the run requires some parameters.
Does anyone have any idea how I can pass arguments in when running a rule in a Makefile? I want to be able to run the run rule with arguments by typing make run foo bar.
I tried this, but it didn’t work:
run:
make compile
./scripts/runTrips $1 $2 $PLACES $OUT $VERS
The parameters I want supplied are the first and the second.
When passing parameters to a make command, reference them like you would other internal make variables.
If your makefile looks like:
run:
script $(param1) $(param2)
You can call it with the following syntax:
$> make run param1=20 param2=30
and make should call the script like:
script 20 30
Make itself doesn't provide passing arguments like for scripts. Usually make is used in the following way: you configure project than run just simple 'make'. Configuring can be done by running shell script 'configure'. This script is the one that you can pass parameters to. For example:
./configure param1 param2
make run
configure script must parse parameters and write them out to config.mk. config.mk must contain the following:
PARAM1 = val1
PARAM2 = val2
Your Makefile must include config.mk:
TOP = .
include $(TOP)/config.mk
run:
make compile
./scripts/runTrips $(PARAM1) $(PARAM2) $(PLACES) $(OUT) $(VERS)
In your 'configure' script you can also check parameters for correctness and make other checks and calculations.

Resources