Can someone let me know what these two flags do in this makefile? I've googled 'till my fingures hurt, but cannot find any info. The GNU documentation doesn't seem have this info.
Thanks!
(-ln) and (-fs)
$(MAKE) -C wiringPi $#
$(MAKE) -C devLib $#
-ln -fs libwiringPiDev.so.2.0 devLib/libwiringPiDev.so
-ln -fs libwiringPi.so.2.0 wiringPi/libwiringPi.so
$(MAKE) -C gpio 'INCLUDE=-I../devLib -I../wiringPi' 'LDFLAGS=-L../devLib -L../wiringPi' $#
The ln -fs foo bar command creates a link named bar pointing to file foo. The -f option forces the creation: if a bar already exists it is overwritten (except if it is a directory). The -s option tells ln to create a symbolic link instead of the default hard link. See man ln to know more about this command.
The - on front of the command tells make that it should not abort if the command fails. If you are using GNU make see the make manual section about errors in recipes.
Thanks Eugene. Without the '-' I was able to find more info.
So I think the ln with the (-fs) is checking, then removing a existing file (if there is one) then making a symbolic link. cool.
I'm sure this was / is obvious to the experienced out there.
Thanks,
oc.
Related
I have a makefile that uses a source file from the internet. There are two locations where the file resides, neither of which I consider very dependable, so I also keep a local copy. So the relevant lines of my makefile look like:
src.c:
wget -nv http://location.com/$# || wget -nv http://otherplace.com/$# || cp local/$# .
src.o: src.c
$(CC) -o $# $<
Is this the "right way" to do this? What if there are multiple steps in each different way of creating the target - how do I tell make "Try A. If A fails, try B. If B fails, ..."?
The right thing to do is this:
.PHONY: phony
src.c: phony
if (wget -nv http://location.com/$# -O $#.temp) && ! diff $#.temp $# >/dev/null; then \
mv $#.temp $#; \
fi
I shortened your command to a single wget but you can put whatever you want there, including a sequence of ||s to achieve "try this, if not, try that etc". Just make sure it outputs to a temporary file (and does not hang indefinitely !) .
It is in fact important to use phony here, and not only .PHONY. Can you see why?
Also, with this method, there is no longer a need to keep another "local" copy and/or use cp. Your target src.c is your "local copy" - the latest one you were able to successfully get from the Internet.
I'm having trouble using the ln command in a makefile.
This is a part of my makefile for creating a dynamic library:
NAME := Net
DDIR := dynamic_library
DLIB := $(DDIR)/lib$(NAME).so
MAJOR := 1
MINOR := 0
VERSION := $(MAJOR).$(MINOR)
$(DLIB).$(VERSION): $(OBJD)
g++ -shared -Wl,-soname,$(DLIB).$(MAJOR) $^ -o $#
$(DLIB): $(DLIB).$(VERSION)
ln -sf $(DLIB).$(VERSION) $(DLIB)
ln -sf $(DLIB).$(VERSION) $(DLIB).$(MAJOR)
OBJD are my .o files.
I'm trying to create the links next to libNet.so.1.0 which is in dynamic_library/ .
The ln commands create broken links with incomplete target addresses but in the correct destination.
I've tried adding ./ and / before the sources but they don't work.
Any help would be appreciated
EDIT
found the answer through trial and error
apparently we're supposed to add ../ before the sources. I have no idea why though.
if anybody has a better way, please answer.
Some of the variations of ln command are:
ln -s abs_path_to_link_target rel_path_from_current_dir_to_link_source
ln -s rel_path_from_link_src_to_target rel_path_from_current_dir_to_link_source
But the following, which you were trying to use, is not one of them:
ln -s rel_path_from_current_dir_to_link_target ...
Your makefile has another subtle error, namely, the link source, does not depend on the changes to the link target, it only depends on the existence of the link target.
And another problem, is that you have a "side effect", when you are making $(DLIB) target. I am guessing you are a software eng, so you know that side effects are bad for parallelism, cause race conditions, and make code hard to read.
Also, one should always use automatic variables such as $#, and depend everything on the Makefile.
Finally, I am hoping that you know why you are using -f. Some of the responses above, including mine :), do not use it. It is very important in the Makefile context, don't drop it.
Bearing these points in mind, the cleanest and correct way to do this would be:
$(DLIB) $(DLIB).$(MAJOR): Makefile | $(DLIB).$(VERSION)
ln -sf $(abspath $|) $#
g++ -shared -Wl,-soname,$(DLIB).$(MAJOR) $^ -o $#
Isn't it supposed to be -Wl,-soname,$(DLIB).$(VERSION)?
ln -s creates a link at the destination location with a link target of your source path (not the full path the path you give the ln command). If your link destination is a directory below your source directory and you aren't using full paths to the source then you need the ../ so that the link target is ../source.file instead of source.file as that would make the link point to a file in the same directory.
Compare:
$ ln -s bar foo
$ readlink foo
bar
$ readlink -f foo
/tmp/bar
$ ln -s ../bar foo
$ readlink foo
../bar
$ readlink -f foo
/foo
$ ln -s /tmp/bar foo
$ readlink foo
/tmp/bar
$ readlink -f foo
/tmp/bar
I'm trying to modify a makefile to cross-compile binaries. The command in question is below:
# GNU Make solution makefile autogenerated by Premake
# Type "make help" for usage help
ifndef config
config=debug
endif
export config
PROJECTS := json openjaus openjaus-core openjaus-environment openjaus-mobility openjaus-manipulator openjaus-ugv Base Managed PingTest LargeMessageTest PdDemo GposDemo GposClientDemo StillImageSensorDemo StillImageClientDemo
.PHONY: all clean help $(PROJECTS)
all: $(PROJECTS)
json:
#echo "==== Building json ($(config)) ===="
#${MAKE} --no-print-directory -C .build -f json.make
As can be seen the makefile has several targets. They all have the same structure as the 'json' target. The command in question in question is
#${MAKE} --no-print-directory -C .build -f json.make
The '${MAKE}' variable = make (I have verified this with echo)
What does the -C do?
What does the .build do?
I'm good with -f json.make
Also, when I run make the json.make file gets created compiles file and deletes it self, so I do not have access to that file.
The error I receive when I modify the command in question is
==== Building json (debug) ====
make[1]: Nothing to be done for `/home/botbear/openwrt/trunk/staging_dir/toolchain- arm_v6k_gcc-linaro_uClibc-0.9.32_eabi/bin/arm-openwrt-linux-c++'.
The command after modifications looks like:
#${MAKE} /home/botbear/openwrt/trunk/staging_dir/toolchain-arm_v6k_gcc-linaro_uClibc-0.9.32_eabi/bin/arm-openwrt-linux-c++ --no-print-directory -C .build -f json.make
Any help is appreciated!
you can use man make to understand the parameters for make:
-C dir, --directory=dir
Change to directory dir before reading the makefiles or doing any-
thing else. If multiple -C options are specified, each is inter-
preted relative to the previous one: -C / -C etc is equivalent to
-C /etc. This is typically used with recursive invocations of
make.
-f file, --file=file, --makefile=FILE
Use file as a makefile.
so -C .build changes to the directory .build.
and i don't understand the part of your question about modifying the command.
Try to find where json.make lives. It seems that it's that makefile which creates & deletes the directory you were talking about.
From the command line it seems that make changes directory to .build and executes the json.make. Not sure how json.make ends up there. Is .build the directory which is created and then deleted?
I'm not sure if it's gmake or gcc that I don't understand here.
I'm using the -MM and -MD options to generate dependency rules for the Unit Testing framework I'm using. Specifically:
$(TEST_OBJ_DIR)/%.d: $(TEST_SRC_DIR)/%.cpp
#$(CPPC) -MM -MD $< -o $#
#sed -i -e 's|\(.*\)\.o:|$(OBJ_DIR)/\1.o $(TEST_OBJ_DIR)/\1.d $(TEST_OBJ_DIR)/\1.o:|' $#
-include $(TEST_DEP_FILES)
When I run make, after all binaries are linked (properly), I see the following extra (unexplained) line before make exits
rm test/obj/dice.d test/obj/regex.o test/obj/inventoryContainer.d test/obj/color-string.d test/obj/dice.o test/obj/inventoryContainer.o test/obj/color-string.o test/obj/regex.d
From whence is that rm command coming? The only place - anywhere - that I have an rm command in my makefile is in the clean directive
test-clean:
rm -f $(TEST_BIN_FILES)
rm -f $(TEST_OBJ_DIR)/*.{a,d,o}
Any ideas?
make will automatically create intermediate files if necessary to chain two rules together, but it will delete them at the end of the build. You can use the .PRECIOUS special target to prevent it from removing them
One helpful option for debugging these kind of problems is the -n switch:
make -n {TARGET}
It will show you the commands it would run but won't actually run them. This lets you see what rules are firing but doesn't give you all the extra output that makes it difficult to diagnose the problem.
The -d debug flag can also be useful but be sure to run it in a context where you can scroll around easily, you'll be getting a lot of output. I usually use emacs shell mode as it has good searching functionality and saves the buffer.
I'm wondering how I can avoid some echo in a Makefile :
clean:
rm -fr *.o
this rule will print:
$>make clean
rm -fr *.o
$>
How can I avoid that?
To start with: the actual command must be on the next line (or at least that is the case with GNU Make, it might be different with other Make's - I'm not sure of that)
clean:
rm -rf *.o
(note, you need a TAB before rm -rf *.o as in every rule)
Making it silent can be done by prefixing a #:
so your makefile becomes
clean:
#rm -rf *.o
If there are no *.o files to delete, you might still end up with an error message. To suppress these, add the following
clean:
-#rm -rf *.o 2>/dev/null || true
2>/dev/null pipes any error message to /dev/null - so you won't see any errors
the - in front of the command makes sure that make ignores a non-zero return code
In fact I was looking for something else, adding this line to the Makefile :
.SILENT:clean
while execute every step of the "clean" target silently.
Until someone point some drawback to this, I use this as my favourite solution!
I'm responding to this ancient topic because it comes up high in search and the answers are confusing. To do just what the user wants,all that is needed is:
clean:
#rm -f *.o
The # means that make will not echo that command.
The -f argument to rm tells rm to ignore any errors, like there being no *.o files, and to return success always.
I removed the -r from the OPs example, because it means recursive and here we are just rming .o files, nothing to recurse.
There's no need for the 2>&1 >/dev/null because with the -f there will be no errors printed.
.SILENT: clean
works in place of the #, but it isn't at the same place in the Makefile as the command that it affects, so someone maintaining the project later might be confused. That's why # is preferred. It is better locality of reference.
If you put an # in front of the command, it doesn't echo onto the shell. Try changing rm to #rm. (Reference)
From the manual: .SILENT is essentially obsolete since # is more flexible.
Much worse is that make prints far too much information. Warning/error/private messages are buried in the output. On the other hand -s (.SILENT) suppresses just anything. Especially the "nothing to be done" and "up to date" messages can be a pain. There is no option to suppress them. You have to filter them out actively or use something like colormake. Here is a solution for grep:
make | egrep -hiv 'nothing to be done|up to date'
But the output will have line numbers. The Perl solution is therefore better, because it suppresses line numbers and flushes stdout immediately:
make | perl -ne '$|=1; print unless /nothing to be done|up to date/i'
Make's a flawed tool. "What’s Wrong With GNU make?" explains this better than I can.
There's a great article on using .SILENT that explains how to conditionally activate it.
I have used that information to put this in my Makefile:
# Use `make V=1` to print commands.
$(V).SILENT:
# Example rule, only the #echo needs to be added to existing rules
*.o: %.c
#echo " [CC] $<"
gcc ...
What this does is if you run make normally, normal output is silenced and instead the echo commands work:
$ make
[CC] test.c
[CC] test2.c
But it allows you to debug problems by passing the V=1 parameter, which still shows the [CC] messages as it helps break up the output, but the traditional Makefile output is also visible:
$ make V=1
[CC] test.c
gcc ...
[CC] test2.c
gcc ...