I have a autotool project where part of the source code is downloaded dynamically from the net (because of IP rights preventing direct redistribution) and then built.
I have a Makefile.am that works but I'm not happy about some of it's aspects.
Here it is:
INCLUDES = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
AM_CFLAGS = -fPIC -Wall ${SYMBOL_VISIBILITY}
LIBVERSION=0:0:0
REFSRC_PATH=refsrc
REFSRC_SRC=refsrc/dtx.c refsrc/globdefs.c refsrc/host.c refsrc/mathhalf.c refsrc/sp_enc.c refsrc/sp_rom.c refsrc/vad.c refsrc/err_conc.c refsrc/homing.c refsrc/mathdp31.c refsrc/sp_dec.c refsrc/sp_frm.c refsrc/sp_sfrm.c
${REFSRC_PATH}/.downloaded:
./fetch_sources.py "${REFSRC_PATH}"
for f in `ls -1 "${REFSRC_PATH}"/*.{c,h}`; do \
sed -i -e"s/round/round_l2s/" "$$f"; \
done
touch $#
${REFSRC_PATH}/dtx.c: ${REFSRC_PATH}/.downloaded
lib_LTLIBRARIES = libgsmhr.la
libgsmhr_la_SOURCES = libgsmhr.c $(REFSRC_SRC)
clean-local:
-rm -rf ${REFSRC_PATH}
So essentially, libgsmhr.c is my main wrapper, then I download the source code in a refsrc/ subdirectory and patch it a little.
First problem is that in REFSRC_SRC I would have loved to use a $(addprefix ...) instead of repeating refsrc/ in front of each .c file. But that doesn't seem to work and autoreconf complains a little.
Failure details (when removing the refsrc/ prefix from REFSRC_SRC= and using $(addprefix ${REFSRC_PATH}/, ${REFSRC_SRC}) on the dependency list):
bash$ autoreconf -i
libgsmhr/Makefile.am:19: addprefix ${REFSRC_PATH}/, ${REFSRC_SRC}: non-POSIX variable name
libgsmhr/Makefile.am:19: (probably a GNU make extension)
(configure works fine)
bash$ make
...
make[2]: Entering directory `/tmp/ram/gapk.build/libgsmhr'
CC libgsmhr.lo
CCLD libgsmhr.la
make[2]: Leaving directory `/tmp/ram/gapk.build/libgsmhr'
...
(So as you see it didn't include any of the downloaded .c files, didn't even download them at all. The compile works because libgsmhr.c is a stub that doesn't use the symbols in those file yet)
Second problem is this rule:
${REFSRC_PATH}/dtx.c: ${REFSRC_PATH}/.downloaded
I have to explicitely list the first file (dtx.c) instead of using a wildcard like:
${REFSRC_PATH}/%.c: ${REFSRC_PATH}/.downloaded
If I try to use the wildcard, then autoreconf complains and also it just doesn't work ... (pattern doesn't match somehow).
Failure detail:
bash$ autoreconf -i
libgsmhr/Makefile.am:16: `%'-style pattern rules are a GNU make extension
(configure works fine)
bash$ make
...
make[2]: *** No rule to make target `refsrc/dtx.c', needed by `dtx.lo'. Stop.
...
Sylvain
You seem to be writing a makefile in GNUMake style, but actually running some other version of Make. If it's not obvious what autoreconf is calling, you could insert a rule in the makefile:
dummy:
#echo using $(MAKE)
$(MAKE) -v
If this theory proves correct, you can either persuade autoconf to use GNUMake, or write for the version it's using.
Related
i have been trying to make a correct makefile for a while now but i keep getting the error "make: *** No rule to make target `all'. Stop."
i have one main program: mpasswdsort.c
and the c file wich is used by mpasswdsort, it comes with a header as well:
list.c and list.h
my makefile:
CC=gcc
CFLAGS=-Wall -pedantic -ansi
all: mpasswdsort
server: mpasswdsort.o list.o
$(CC) mpasswdsort.o list.o -o mpasswdsort
mpasswdsort.o: mpasswdsort.cpp
$(CC) $(CFLAGS) mpasswdsort.cpp
list.o: list.cpp
$(CC) $(CFLAGS) list.cpp
clean:
rm -f server client *.o core
I am unsure if its wrong in the makefile or if the makefil isnt supposed to be a .txt file.
The error message you present indicates that make does not see any rule for building target "all". It is exactly the same diagnostic that GNU make emits when there is no makefile at all. Since the makefile contents you present do contain a rule for target "all", I conclude that make is not seeing them.
That may be because the makefile is in a different directory, because its name is different from the ones make tries by default (Makefile or makefile is conventional; GNU's version of make also checks for GNUmakefile), or because an access-control issue prevents make from reading the file. Since you remark
I am unsure if its wrong in the makefile or if the makefil isnt
supposed to be a .txt file.
, the most likely conclusion is that (at least) the filename is wrong. Makefiles are text files, but text file names don't necessarily end with ".txt". In fact, on Linux and other UNIXes, most of them don't. Makefiles shouldn't have such an extension, though, technically, you can use the -f option to tell make the name of the makefile to use.
For me, quite simply, I was initiating the make init command outside of the target directory that I wished to create the makefile. Hope this helps someone.
I'm using a MAC so renaming the "MakeFile" to "Makefile" did the trick for me.
And one more thing, I got this error after fixing the previous one:
Makefile:3: *** missing separator. Stop.
Replacing the four spaces with tabs solved this problem for me! Simply just delete the space before the commands in your "Makefile" and put a tab behind them.
Say I have the following gnu makefile.
TOP := $(dir $(lastword $(MAKEFILE_LIST)))
all : graphics
graphics :
pushd $(TOP)../graphics; \
$(TOP)../tools/autotools_gen.sh; \
./configure; \
$(MAKE) clean all; \
$(TOP)../tools/autotools_clr.sh; \
popd;
inside a folder called build and I call it from one directory up, in the following manner:
make --file ./build/Makefile all
and I get the following message from make:
make: Nothing to be done for `all'.
Why is it complaining that there is nothing to be done for all?
The problem you run into is that because you have a directory graphics (I took this from the question comments) in the working directory, when make encounters the target
graphics :
as a prerequisite for all, it sees that graphics already exists, that none of its prerequisites are newer than it (because it doesn't have any), and so considers it up to date and does nothing to build it. Since all doesn't have a recipe of its own, make then doesn't find anything to do for it either and just tells you that there's nothing to do.
The solution is to declare graphics and all as phony targets:
.PHONY: all graphics
Then they will be run even if files or directories called all or graphics exist/are newer than their dependencies.
The intent of phony targets is to make rules that don't produce a file work properly even if such a file accidentally appears in the directory of the Makefile, so it is commonly used for targets all, clean, install and suchlike. Your graphics target doesn't produce a file graphics, so it falls into this category.
See also this section in the GNU make manual (which also applies to other makes).
I have two GNUmakefiles in my directory as follows,
GNUmakefile &
GNUmakefile2
Could someone please let me know the command I have to use, if I have to let the "make" command to process "GNUmakefile2" instead of "GNUmakefile".
I used the below command,
make -f GNUmakefile2
but in that case, I am getting the following errors,
This is gnustep-make 2.6.1. Type 'make print-gnustep-make-help' for help.
make[1]: ** No rule to make target `internal-master-tool-all'. Stop.*
make: ** [internal-all] Error 2*
I think it is considering GNUmakefile as makefile (when I use make with -f command), so it is checking for rules in GNUmakefile.
At present what I am doing is I am renaming the required file (which I want, make command to execute) to "GNUmakefile". And I am not getting any errors while executing "make" command, but I don't think this is the correct solution.
Please let me know which command I need to use for this scenario. Thanks for your help.
After checking Beta's solution (i.e.,but that makefile is invoking Make a second time, and the second Make process is probably reading GNUmakefile) what I have done is I renamed existing "GNUmakefile" to "GNUmakefile3".
So at present in my directory the following makefiles are present:- "GNUmakefile2" & "GNUmakefile3".
And then I executed the following command:- $ make -f GNUmakefile2
I recieved the below errors,
This is gnustep-make 2.6.1. Type 'make print-gnustep-make-help' for help.
make[1]: GNUmakefile: No such file or directory
make[1]: * No rule to make target `GNUmakefile'. Stop.
make: * [internal-all] Error 2
Please let me know what is the problem here
Your makefile includes two huge makefiles from the FSF. The second, library.make, contains this rule:
ifeq ($(GNUSTEP_MAKE_PARALLEL_BUILDING), no)
# Standard building
...
else
# Parallel building. ...
internal-library-all_:: $(GNUSTEP_OBJ_INSTANCE_DIR) $(OBJ_DIRS_TO_CREATE)
$(ECHO_NOTHING_RECURSIVE_MAKE)$(MAKE) -f $(MAKEFILE_NAME) ...
endif
and the first, common.make contains this assignment:
# The default name of the makefile to be used in recursive invocations of make
ifeq ($(MAKEFILE_NAME),)
MAKEFILE_NAME = GNUmakefile
endif
So try either make -f GNUmakefile2 GNUSTEP_MAKE_PARALLEL_BUILDING=no or make -f GNUmakefile2 MAKEFILE_NAME=GNUmakefile2, and see if that solves the problem.
I was experimenting with GNU make. Suppose, I have 3 C files with the following structure:
hellomake.c
|
|---------------------
| |
V V
hellofunc.c hellomake.h
makefile:
hellomake: hellomake.c hellofunc.c
gcc -o hellomake hellomake.c hellofunc.c -I.
When I type make for the 1-st time, it creates a program hellomake. When I run it for the 2-nd time, it prints:
make: `hellomake' is up to date.
Everything is working correctly.
I tried to use make for compiling LaTeX files. Suppose, I have 2 TeX files:
1.tex
|
V
1_data.tex
1_data is included into 1.tex internally.
Makefile:
COMMAND = pdflatex
all: 1.tex 1_data.tex
$(COMMAND) 1.tex
But it recompiles 1.tex every time I type make. Even if none of the files were modified.
What's wrong?
makesimply looks at whether or not all exists. Since it doesn't, it attempts to create it (but doesn't even notice that your commands do not create the file!)
Assuming pdflatex really creates a file somewhere, use the file name as the target name. Then it will be recreated only if it is older than the dependencies.
To recapitulate, a Makefile declares a mapping of target files, their dependencies, and how to create them from the dependencies. When a target is missing or out of date with respect to its dependencies, Make runs the commands for recreating it.
(My first attempt at articulating this answer mentioned .PHONY: targets as an aside, but that's not really useful in this context; if you declared .PHONY: all it would run the recipe even if a file named all existed, so that's the opposite behavior of what you are looking for.)
I'm new to using makefiles and trying to produce a basic makefile as part of an exercise for university. I have two source code files, chello.c and writeexit.s, which have to be compiled/assembled and then linked to produce chello.
This is the code I have so far for the makefile:
chello: chello.o writeexit.o
ld -N chello.o writeexit.o -o chello
chello.o: chello.c
gcc -c chello.c -o chello.o
writeexit.o: writeexit.s
as writeexit.s -o writeexit.o
The whitespace before ld, gcc and as are all tabs, so I think the whitespacing is fine. When I call 'make makefile', it returns 'make: Nothing to be done for `makefile'.' However, if I change the dependencies of chello, like chello.c, the same message is returned and chello's behaviour is not modified.
From man make:
make executes commands in the makefile to update one or more target
names, where name is typically a program. If no -f option is present,
make will look for the makefiles GNUmakefile, makefile, and Makefile,
in that order.
make makefile will actually execute your "makefile" (because it is listed among the default names in the man page) file, trying to build the "makefile" target (because of the argument you are passing), which already exists
What you need is to build the "chello" binary, so you have to type:
make chello
Or alternatively:
make -f makefile chello
Alternative account here, it seems to work fine if I just call "make" instead of "make makefile". This question can be ignored.