Gnu-Make fails to include a makefile - c

From the docs:
The include directive tells make to suspend reading the current
makefile and read one or more other makefiles before continuing. The
directive is a line in the makefile that looks like this:
include FILENAMES...
FILENAMES can contain shell file name patterns.
Now, given a Makefile:
# we define 'include' from the command-line.
ifdef include
# We create the included Makefile
$(shell echo 'all : ;' >makefile.include)
# And we include it.
# The docs say: "FILENAMES can contain shell file name patterns."
include *.include
else
endif
Running, we get:
$ rm -rf makefile.include && make include=1
makefile:6: *.include: No such file or directory
So, what happened here? We clearly had:
Created a Makefile to be included, in:
$(shell echo 'all : ;' >makefile.include)
And later included this makefile, given that we can using "shell file name patterns", as quoted above from the documentation - and thus, we have in the makefile:
include *.include
So, why did Gnu-Make failed to find this newly-created makefile?

The problem you are facing is not of inclusion, but of order of execution.
make is not a procedural language, but instead a declarative one, so order-of-execution sometimes gets a bit tricky.
In your specific case, make will parse the entire Makefile in the first pass, including the include statements, resulting in an erroneous Makefile, since there is no makefile.include yet.
It will then execute the shell command to create the makefile.include (but again it is too late: inclusion would have happened before).
A second run of make will then correctly include the makefile.include.
Note:
The same is true for both directly using include *.include and include $(wildcard *.include) but only the former will result in an error (since the latter will expand the *.include to an empty set which will then (not) be included, whereas the former will try to include the literal *.include - similar to a stray cat *.nonexistent on the shell).

Related

autoconf configure results in C std lib header related compile errors

I am attempting to build a project that comes with an automake/autoconf build system. This is a well-used project, so I'm skeptical about a problem with the configure scripts, makefiles, or code as I received them. It is likely some kind of environment, path, flag, etc problem - something on my end with simply running the right commands with the right parameters.
The configuration step seems to complete in a satisfactory way. When I run make, I'm shown a set of errors primarily of these types:
error: ‘TRUE’ undeclared here (not in a function)
error: ‘struct work’ has no member named ‘version’
error: expected ‘)’ before ‘PRIu64’
Let's focus on the last one, which I have spent time researching - and I suspect all the errors are related to missing definitions. Apparently the print-friendly extended definitions from the C standard library header file inttypes.h is not being found. However, in the configure step everything is claimed to be in order:
configure:4930: checking for inttypes.h
configure:4930: /usr/bin/x86_64-linux-gnu-gcc -c -g -O2 conftest.c >&5
configure:4930: $? = 0
configure:4930: result: yes
All the INTTYPES flags are set correctly if I look in confdefs.h, config.h, config.log Output Variables, etc:
HAVE_INTTYPES_H='1'
#define HAVE_INTTYPES_H 1
The problem is the same whether doing a native build, or cross-compiling (for arm-linux-gnueabihf, aka armhf).
The source .c file in question does have config.h included as you'd expect, which by my understanding via the m4 macros mechanic should be adding an
#include <inttypes.h>
line. Yes, as you may be inclined to ask, if I enter this line myself into the .c file it appears to work and the PRIu64 errors go away.
I'm left with wondering how to debug this type of problem - essentially, everything I am aware of tells me I've done the configure properly, but I'm left with a bogus make process. Aside from trying every ./configure tweak and trick I can find, I've started looking at the auto-generated Makefile.in itself, but nothing so far. Also looking into how I can get the C pre-processor to tell me which header files it's actually inserting.
EDIT: I've confirmed that the -DHAVE_CONFIG_H mechanic looks good through configure, config.log, Makefile, etc.
autoconf does not automatically produce #include directives. You need to do that on your own based on the HAVE_* macros. So you'll have to add something like this:
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif
If these lines show up in confdefs.h, a temporary header file used by configure scripts, this does excuse your application from performing these #includes. If configure writes them to confdefs.h, this is solely for the benefit of other configure tests, and not for application use.
First, run make -n for the target that failed. This is probably some .o file; you may need some tweaking to get its path correctly.
Now you have the command used to compile your file. If you don't find the problem by meditating on this command, try to run it, adding the -E to force preprocessor output text instead of invoking the compiler.
Note that now the .o file will be text, and you must rebuild it without -E later.
You may find some preprocessor flags useful to get more details: -dM or -dD, or others.

How can I see the location of a header included with #include?

I'd like to be able to see which header is actually included when I compile. For example, I have two very different check.h files (one is a linux-header thing, the other from the unit test system).
Is there a setting in gcc or some language command/macro that would show where header files are being included from?
You can use the -E flag.
gcc -E source.c
This will show you the “annotated” preprocessed source, including the absolute paths of headers included using <> and relative paths of headers included using "". Keep in mind that it will be a lot to trudge through, especially if you include a lot of system headers (which in turn include implementation-specific headers etc.).
Using grep, you could filter these results with:
gcc -E source.c | grep '^# 1 '
The # n is an annotation describing the line number of the currently-included file, which is always # 1 at the beginning of a file.
You can try adding -MD to your compilation command. This generates a dependency file (suitable for Make) which will tell you all of the include files that your source code depends on.
This can be added to an existing compile command without fear of breaking the compilation, since it generates the dependency file as a side effect of normal compilation.

How to stop make (in makefile) after "No such file or directory" error?

So, most of the times I'm testing if every include is correct on a given C/C++ code, I have a makefile with a gcc/g++ call with proper -I option for searching headers on specific directories (like every program) when I'm compiling sources to headers.
However, if the included directory is not correct and an undefined header appears (e.g. foo.h has #include and was not found), the gcc/g++ will just spit a bunch of errors for every include I have of that foo.h header for all other sources I'm compiling afterwards (and I'm already using -Werror -Wfatal-errors to make gcc/g++ to stop).
So, my question is simple: how can I tell makefile stop after the first error of the type "No such file or directory" it finds? It is really annoying it continue to compile sources and sources, giving me hundreds of errors just for a repeated error I already understood.
It probably continues because you told it to. See the following two options of GNU make:
-k, --keep-going Keep going when some targets can't be made.
-S, --no-keep-going, --stop
Turns off -k.
Put the header files into a variable and use that variable as a dependency. The following snippet will not build anything until the specified headers exist.
HEADERS=test.h other.h /usr/include/special.h
all: $(HEADERS) $(BINPROGS)
[... all other rules go here as usual ...]
*.h:
echo found $#
The ".h:" simply prints out each header that is found before any building even starts. The makefile itself stops if a header cannot be found (and it will stop before trying to compile anything).
I believe that that is what you wanted?
you can write a shell script to check for error conditions before running the make script.

purpose of creating DEPENDENCIES_OUTPUT file while compiling c program

gcc -MD file.c creates a dependency output file named file.d. But I dont understand the need of creating this file ( dependency file ), because when error comes while compilation, no dependency file is generated. So can anyone throw some light when he/she has used this dependency file or some usefulness of this file / feature of gcc.
The file.d file can be understand by make. You often first generate the .d files, include them into your Makefile and then compile the c-files only if one of the included headers has changed.
Don't bother about if you don't use make.
GCC documentation says:
Instead of outputting the result of preprocessing, output a rule suitable for make describing the dependencies of the main source file. The preprocessor outputs one make rule containing the object file name for that source file, a colon, and the names of all the included files, including those coming from -include or -imacros command line options.

how to "execute" make file

I tried to use a make file in code::blocks but I am doing it wrong. I have the version installed with the compilers included. http://sourceforge.net/projects/codeblocks/files/Binaries/10.05/Windows/codeblocks-10.05mingw-setup.exe/download. What do I do with the make file? It starts with:
CC=gcc
best, US
You don't tend to execute the make file itself, rather you execute make, giving it the make file as an argument:
make -f pax.mk
If your make file is actually one of the standard names (like makefile or Makefile), you don't even need to specify it. It'll be picked up by default (if you have more than one of these standard names in your build directory, you better look up the make man page to see which takes precedence).
As paxdiablo said make -f pax.mk would execute the pax.mk makefile, if you directly execute it by typing ./pax.mk, then you would get syntax error.
Also you can just type make if your file name is makefile/Makefile.
Suppose you have two files named makefile and Makefile in the same directory then makefile is executed if make alone is given. You can even pass arguments to makefile.
Check out more about makefile at this Tutorial : Basic understanding of Makefile

Resources