What does #$ mean in the below make recipe ?
#$(OBJCOPY) -S --set-section-flags .bss=alloc,contents -O binary $(BINARY).elf $(BINARY).bin
Thanks
The # sign in the beginning of the recipe command means "do not echo the command".
The $(OBJCOPY) in your recipe command means "substitute here the value of the OBJCOPY variable".
For more info about recipe echoing, please refer to https://www.gnu.org/software/make/manual/make.html#Echoing
Related
I'm trying to resolve an issue with my project. In short, I have a variable in my makefile containing the names of .o files to be linked. The variable has gotten too big, and is now causing an Argument list too long error. The offending line in my makefile reads:
#arm-none-eabi-ld -T layout.ld -o #$ $^
The problem is the variable $^ expands to be too large, and I get an error stating that "arm-none-eabi-ld: Argument list too long".
What I'm trying to do to resolve the issue is to pass the arguments as a file, but I'm not sure how.
What I've tried is:
#arm-none-eabi-ld -T layout.ld -o #$ <$^
#arm-none-eabi-ld -T layout.ld -o #$ | xargs `cat $^`
and also tried:
#echo $^ >temp.txt
#arm-none-eabi-ld -T layout.ld -o #$ <temp.txt
that last one I think has potential, but says "no input files".
I found a solution:
#echo "INPUT($^)" > $(TEMP_LD)
#$(LD) $(LDFLAGS) -o $# -T $(TEMP_LD)
I have to compile some mysql c api code and tired of writing all this in command line:
gcc main.c -o main `mysql_config --cflags --libs`
I wrote a shell script in bash and pass positional parameter in bash:
gcc $1 -o ${"$1":0:2} 'mysql_config --cflags --libs' but this doesn't work. I get error message: ./compile: line 2: ${"$1":0:-2}: bad substitution. Can someone please tell me what I am doing wrong?
The only way I got this to work is by assigning a new variable:
filename=$1;
gcc $filename -o ${filename:0:-2} `mysql_config --cflags --libs`
Is this the only way to do it or is there a way to fix what I am doing wrong in the first case?
You almost had it:
${1:0:2}
You don't need another reference to $1 inside the brackets since everything in it will be interpreted as the name of the variable, as in the case of ${filename:0:-2}.
In response to the comments under the question, here's an example makefile for this situation:
MSQL_FLAGS := $(shell mysql_config --cflags)
MSQL_LIBS := $(shell mysql_config --libs)
main : main.c
gcc $(MSQL_FLAGS) -o $# $< $(MSQL_LIBS)
This is a simple question for a starter like me, but what can I do to do like the following
all: run
run:
DIR=bin/
$(CC) $(LIBRARY) $(INCLUDE) run.o -o $(DIR)$#
Thanks.
Why not go like this?
DIR=bin/
all: $(DIR)/run
$(DIR)/run:
$(CC) $(LIBRARY) $(INCLUDE) run.o -o $#
As written, you have an assignment to the shell variable DIR on one command line. On the next line, you have the expansion of a make variable DIR. This doesn't work because the two lines are executed by different shells, and in any case, make expands $(DIR) before running the shell and DIR is not a make variable.
You could make it work like this:
all: run
run:
DIR=bin/; \
$(CC) $(LIBRARY) $(INCLUDE) run.o -o $${DIR}$#
The backslash means the two lines are treated as one (so much so that the semicolon is needed). The $${DIR} notation is expanded by make to ${DIR} (more precisely, $$ expands to $ and make ignores the {DIR}), and then the shell expands ${DIR} from the value set previously. You could, of course, omit the braces.
However, the answer by BeSerK is probably what you're looking for.
I'd like for my makefile output to be color-coded.
But I can't get the ANSI color codes to work on this terminal. It should be possible though, ls --color gives me colorful output, and my shell prompt is also colored:
$ echo $PS1
\[\033]0;$MSYSTEM:\w\007 \033[32m\]\u#\h \[\033[33m\w\033[0m\] $
I suspect maybe the first section puts the terminal in a special mode so that it will accept color codes. Can somebody explain?
I solved it.
The command to use is echo -e.
So, in the makefile:
foo.o: foo.c
#echo -e "\033[32mCompiling foo.c\033[0m"
$(CC) $(CFLAGS) -c -o $# $<
I would imagine this works just fine in bash as well.
I have a Makefile building many C files with long long command lines and we've cleaned up the output by having rules such as:
.c${MT}.doj:
#echo "Compiling $<";\
$(COMPILER) $(COPTS) -c -o $# $<
Now this is great as the # suppresses the compilation line being emitted.
But when we get an error, all we get is the error message, no command line.
Can anyone think of a "neat" way to emit the command line?
All I can think of doing is echoing it to a file and have a higher level make catch the error and cat the file. Hacky I know.
Tested and it worked (GNU make in Linux):
.c${MT}.doj:
#echo "Compiling $<";\
$(COMPILER) $(COPTS) -c -o $# $< \
|| echo "Error in command: $(COMPILER) $(COPTS) -c -o $# $<" \
&& false
This question is pretty old, but for those of you Googling, I think what I’ll do in this situation is alias make to make -s (silent mode) in my shell, and only put the # prefix before lines where echo or other diagnostic commands are being invoked. When I want the full output from make, I will override my alias by calling it as \make.
Also note that in this situation that you’ll need to do the typical thing and put the #echo on its own line, with the actual rule commands on separate lines and without #’s.
A simple solution would be to use a simple script abc like the following:
#!/bin/bash
$#
code=$?
if (( code )); then
echo error running $#
fi
exit $code
Then you can write abc $(COMPILER) $(COPTS) -c -o $# $< in your Makefile. Do note that this does not work when you have pipes or redirects (as they will be applied to abc instead of the command you want to run).
You can also just put similar code directly in the Makefile if that's preferable.
I recently used a utility called logtext for the likes of tracking what output had occurred during the course of a bat file executing. Check it out, you may find this pretty useful if you want to know what error occurred where.