In CINCLUDE path in my make file there are two headers with same name.
I cannot remove one of them . How can I instruct makefile to give priority to header files in a specific folder.
This is usually something specified by the compiler. For example with gcc, you can create the following files:
qq.c:
#include <qq.h>
int main (void) {
return 0;
}
1/qq.h:
#error file number 1
2/qq.h:
#error file number 2
Then, when you compile them:
pax> gcc -I1 -I2 -o qq qq.c
In file included from qq.c:1:
1/qq.h:1:2: #error file number 1
pax> gcc -I2 -I1 -o qq qq.c
In file included from qq.c:1:
2/qq.h:1:2: #error file number 2
In other words, it's the order in which the include paths are specified (with -I) which dictates the order of search (there are other things such as whether headers are named the same as system headers but they need not concern us here).
Related
I'm attempting to build some code using a temporary version of an include file in my local ../include/records directory. The orignal lives in /home/apps/include/records. I have my gcc command set to search ../include before /home/apps/include, but it's still picking up the original module from /home/apps/include and reporting errors. If I rename the original in /home/apps/include, then gcc picks up my local edited copy and it compiles clean. So, what's up with the include order...? This 'local include first' logic has always worked for me in the past, but this may be the first time I've used it since migrating from AIX to Linux.
Is there something beyond the order of the -I command-line options that could be overriding the requested include order?
The source module include statment is:
#include "records/novarec.h"
and the gcc command line looks like this:
$make
gcc -DLINUX64 -c -g -I. -I../include -I/home/apps/include -I/home/apps/include/em -I/home/apps/include/odbc -Wno-implicit-function-declaration -Wno-implicit-int -Wno-format-security -Wno-format-truncation -Wno-discarded-qualifiers novaget.c
The compiler complains about an undefined value that's in my local copy of novarec.h, but not in the production /home/apps/include/records/novarec.h:
novaget.c: In function ‘calcComscoreDemoV1’:
novaget.c:2651:15: error: ‘CSCD_W21_49’ undeclared (first use in this function); did you mean ‘CSCD_W25_49’?
fval = *(dm+CSCD_W21_49);
^~~~~~~~~~~
It seems like the answer is this:
My module called in 2 include files. The first one also includes the second one - and the first one lives in /home/apps/include. That seems to make gcc search there for the second include file - even though /home/apps/include is not the first include directory in my path.
When I reverse the 2 include statements in my .c file, the correct path is followed for novarec.h. i.e. when I code:
#include "spottvdemos.h" (this modules has a #include "records/novarec.h")
#include "records/novarec.h"
novarec.h gets picked up from /home/apps/include, but when I code:
#include "records/novarec.h"
#include "spottvdemos.h"
novarec gets picked up from ../include, which is what I wanted.
I would like to understand how the preprocessor inlines includes into the code in Fortran. With C, it's pretty simple:
Test.c:
#include <stdio.h>
int main(void) {
return 0;
}
Then I compile using:
gcc -E test.c
Then it displays the content generated by the C preprocessor, as expected.
Now assume I have this Fortran code:
Test.f:
program test
include "mpif.h"
call mpi_init
call mpi_finalize
end
Then I run:
gfortran -E -cpp test.f // For some reason I need -cpp when using -E in Fortran
But I won't have the expected result, which is the generated include embedded into the code.
Instead, I have this:
# 1 "test.f"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.f"
program test
include 'mpif.h'
call mpi_init
call mpi_finalize
end
What am I doing wrong here?
Fortran has its own include directive which must not be confused with the preprocessor directive #include. As far as I understand it, the included code is not embedded into the master file, but the compiler instead continues to compile from the include file, and returns to the master file at the end of that file. From here:
The INCLUDE statement directs the compiler to stop reading statements
from the current file and read statements in an included file or text
module.
Also, included files are not preprocessed further, while #included ones are.
Note, that there is also a naming convention that enables the preprocessor only on files with capital suffixes *.F and *.F90. If you want to preprocess *.f or *.f90 files, you need to specify that in a compile option, e.g. -cpp for gfortran, and -fpp for ifort.
I've got a working project that I need to take parts from it without changing it's code and just write new main() for it.
My directory structure:
[main_dir]/[main.cpp]
[main_dir]/[dir1]/[child1]/file1.h
[main_dir]/[dir2]/[child2]/file2.h
in main.cpp I have: include "dir1/child1/file1.h"
In file1.h I have: include "dir2/child2/file2.h"
I'm compiling:
g++ main main.cpp
I'm getting "dir2/child2/file2.h" no such file or directory.
I can't change file1 to do: include "../../dir2/child2/file2.h"
Somehow in the original project something in the makefile to search for all include path relative to the [main_dir] so the include from file1.h can be found.
What should I add to the makefile in order to do it as well?
When using double-quotes to include a header file, as in
#include "dir2/child2/file2.h"
then the compiler will use the directory of the current file to search for the header file.
If you have it in your file1.h then the compiler will look for the header file [main_dir]/dir1/child1/dir2/child2/file2.h. Which isn't correct.
You can solve it by telling the compiler to add [main_dir] to the list of standard include search paths. This is done with the -I (upper-case i) option:
g++ -I [main_dir] main.cpp
Then when the compiler fails to find dir2/child2/file2.h in its first search, it will continue with the list of standard include search paths, and it should be found.
You need to manage CPPFLAGS in your Makefile.
CPPFLAGS="-I[main_dir]"
And compile application with receipt like this:
g++ $(CPPFLAGS) main.cpp -o main
Also it's recommended to read make style guides to write a good one Makefile. You can meet there tips for include folders declaration.
as a part of build process I need to process some files with m4. These files are given an '.in' extension and are located not only in the top-level dir, but also in subdirs.
I locate them using find and process them in a shell loop.
Is there some makefile syntax magic to write simpler rule to process them save the output into a file (the '.in' extension stripped) in the same directory as the input file?
This is what I have in my makefile now:
PROCESS_FILES=$(shell find . -name \*.in)
WORK_FILES=$(subst .in,,$(PROCESS_FILES))
$(WORK_FILES): $(PROCESS_FILES)
for file in $(PROCESS_FILES); \
do \
m4 $$file > $${file%.*};\
done
You could write a set of rules to convert files with the suffix .in to files without that suffix.
In the classic notation, that would be something like:
# Not functional — see discussion
.SUFFIXES: .in # Add .in as a suffix
M4 = m4
M4FLAGS =
M4SCRIPT = xyz.m4
.in:
${M4} ${M4FLAGS} ${M4SCRIPT} $< > $*
This adds .in as a recognized suffix, and says that you convert the file with a .in suffix to the file without it using the command specified by the three macros. The $< is the name of the file with the .in extension; the $* is the name of the file without the extension.
Unfortunately though, that notation only works when the files to be converted have names such as xyz.in and need to be converted to xyz. It does not work for a case where xyz.h.in needs to be converted to xyz.h.
It would be possible to specify that the suffixes are .h.in and .h, but then the rule for converting between the two starts with .h.in.h: and make gets confused.
However, GNU make has an alternative notation for defining suffix rules which can accommodate this:
.SUFFIXES: .h.in .h # Add .h.in and .h as suffixes
M4 = m4
M4FLAGS =
M4SCRIPT = xyz.m4
%.h: %.h.in
${M4} ${M4FLAGS} ${M4SCRIPT} $< > $*.h
The %.h: %.h.in line is able to deal with the suffix with two dots. The only nuisance is that for each extension such as .c.in or .y.in or .mk.in, you have to provide similar mappings.
(Tested on Mac OS X 10.7.4. If that makefile is xyz.mk, you can create an empty file xyz.h.in and then run make -n -f xyz.mk xyz.h and you'll see the build would run the command m4 xyz.m4 xyz.h.in > xyz.h.)
If you have a source file path/to/file.in, a rule for making % from %.in, and a dependency on the output file path/to/file, that should be all you need.
Perhaps you want to express your dependencies in terms of the output from find. In GNU Make this is easy; in other dialects, perhaps you want to generate and include something like find -name '*.in' | sed 's/\.in$//' >make.dep
To quote the iOS Documentation on Wrapper Headers:
#include_next does not distinguish between <file> and "file" inclusion, nor does it check that the file you specify has the same
name as the current file. It simply looks for the file named, starting
with the directory in the search path after the one where the current
file was found.
The use of `#include_next' can lead to great confusion. We recommend
it be used only when there is no other alternative. In particular, it
should not be used in the headers belonging to a specific program; it
should be used only to make global corrections along the lines of
fixincludes.
So, two questions, what is #include_next, and why would you ever need to use it?
It is used if you want to replace a default header with one of your own making, for example, let's say you want to replace "stdlib.h". You would create a file called stdlib.h in your project, and that would be included instead of the default header.
#include_next is used if you want to add some stuff to stdlib.h rather than replace it entirely. You create a new file called stdlib.h containing:
#include_next "stdlib.h"
int mystdlibfunc();
And the compiler will not include your stdlib.h again recursively, as would be the case with plain a #include, but rather continue in other directories for a file named "stdlib.h".
It's handy if you're supporting multiple versions of something. For example, I'm writing code that supports PostgreSQL 9.4 and 9.6. A number of internal API changes exist, mostly new arguments to existing functions.
Compatibility headers and wrapper functions
I could write compatibility headers with static inline wrapper functions with new names for everything, basically a wrapper API, where I use the wrapper name everywhere in my code. Say something_compat.h with:
#include "something.h"
static inline something*
get_something_compat(int thingid, bool missing_ok)
{
assert(!missing_ok);
return get_something(thingid);
}
but it's ugly to scatter _compat or whatever suffixes everywhere.
Wrapper header
Instead, I can insert a compatibility header in the include path when building against the older version, e.g. compat94/something.h:
#include_next "something.h"
#define get_something(thingid, missing_ok) \
( \
assert(!missing_ok), \
get_something(thingid) \
)
so the rest of the code can just use the 9.6 signature. When building against 9.4 we'll prefix -Icompat94 to the header search path.
Care is required to prevent multiple evaluation, but if you're using #include_next you clearly don't mind relying on gcc. In that case you can also use statement expressions.
This approach is handy when the new version is the "primary" target, but backward compatibility for an older version is desired for some limited time period. So you're deprecating the older versions progressively and trying to keep your code clean with reference to the current version.
Alternatives
Or be a sensible person, use C++, and use overloaded functions and template inline functions :p
include_next is used as a preprocessor directive to tell the compiler to exclude the search paths up to and including filename file.h from resolving to this header file. The typical need is when two header files of the same name need to be used. Use such features sparingly and only when absolutely necessary.
For example:
source file.c contents with the usual file.h from path 1:
#include <file.h>
int main() {
printf("out value: %d", out_val);
exit 0;
}
file.h header file in path 1 contents with file.h from path 2 included:
include_next instructs that path 1 sub directory not be used as search path for file.h and instead use path 2 sub directory as search path. This way you can have 2 files of the same name without the fear of invoking a circular reference to itself.
# include_next <file.h>
int out_val = UINT_MAX - INT_MAX;
file.h in path 2 contents
#define INT_MAX 1<<63 - 1
#define UINT_MAX 1<<64 - 1