Including custom header files (ANSI C) - compilation

I have made some header files and placed them in the same folder as the main program, but the compilation command gcc -ansi -Wall *.c cannot find those files. Do I have to include the full directory path of the header files or am I doing something else wrong?

First of all you have to include the header files into the relevant C-files if you haven't already done so as such:
#include "path/to/file.h"
You also have to tell the compiler to compile the .h-files so if your .h-files are in the same foder as you .c-files and you want to include all the present .h-files your compiler command would look like this:
gcc -ansi -Wall *.h *.c

Related

Including a header from a parent directory

I have a situation where I am given a link to source directory which goes under the parent dir. The contents of the link cannot be modified. The link has a header and .c file. The header file includes a "Config.h" file. The Config.h can only reside in the parent dir because I cannot modify anything under the link. I have to use the sources in the link and compile the parent dir. Here is the directory structure.
ParentDir
|-TestSrc.c
|-TestSrc.h
|-Config.h
|-Makefile
|-LinkToSrcDir
|-Src.c
|-Src.h(#include "Config.h")
My makefile is very straightforward
CC = gcc
INC_DIR = -IParentDir -IParentDir/LinkToSrcDir
CFLAGS = -Wall -Wextra $(INC_DIR)
all: mybin
mybin: TestSrc.o Src.o
$(CC) $(CFLAGS) -o TestSrc.o Src.o
TestSrc.o: TestSrc.c
$(CC) $(CFLAGS) -c TestSrc.c
--- similar code for Src.o ----
Phony: clean (all the usual rm -f)
My problem is, since I cannot modify src.h, the make always complains that Config.h is not found(tried a few different ways). How do I write the Makefile to make src.h look for Config.h in parent dir?
The simplest way is to use a fully-qualified path for the compiler flags:
INC_DIR = -I$(CURDIR)/ParentDir -I$(CURDIR)/ParentDir/LinkToSrcDir
Just to be clear, when the compiler searches for header files using a relative path it always starts with the directory the source file appears in. It doesn't start with the working directory where the compiler is invoked.
From the GCC manual for example:
the preprocessor looks for header files included ... first relative to the directory of the current file
In your case, the current file is LinkToSrcDir/Src.h so all paths will be expanded relative to the directory LinkToSrcDir.
When you say a link above I assume you mean a symbolic link. In that case you may not be able to use something like -I.. because that will give you the parent of the directory linked to.
You pretty much have no alternative but to use a fully-qualified path in your -I options.

How to include *project root* headers compiling with GCC C++ compiler?

How to include headers located in project root compiling with GCC C++ compiler?
I want to tell GCC compiler to search for some header files in project root.
I do NOT want to make changes in code and use relative paths in #include directives - e.g. #include "../../myheader.h"
I compile source code I do not own and I do not want to maintain own version.
I do NOT want to specify absolute include path e.g. g++ -c -IC:\root_project_folder .. for obvious reasons.
I have tried: g++ -c -I .., g++ -c -I/ .. and g++ -c -I"/" .. but it does not work.
Please advise.
root_project_folder
|--myheader.h
|--src_folder
|-prog.cpp
The symbol for the current directory is ..
You're looking for -I.

C++ makefile with relative include path to parent

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.

gfortran include files ignored even with -I options

I am trying to compile using gfortran using the following:
$ gfortran -I/usr/local/include -O3 -Wall -Wno-uninitialized -fbounds-check -g alignparts_lmbfgs.f90 /home/vincent/test/lmbfgs/Lbfgsb.3.0/lbfgsb.f /home/vincent/test/lmbfgs/Lbfgsb.3.0/linpack.f /home/vincent/test/lmbfgs/Lbfgsb.3.0/blas.f /home/vincent/test/lmbfgs/Lbfgsb.3.0/timer.f /home/vincent/test/lmbfgs/minimal_libraries/imlib2010.a /home/vincent/test/lmbfgs/minimal_libraries/genlib.a -o alignparts_lmbfgs.exe -lfftw3 -lm
but it gave me the error
alignparts_lmbfgs.f90:105: Error: Can't open included file '/usr/include/fftw3.f'
even though I specified the -I opitions where the fftw3.f resides.
What am I doing wrong? I don't have root privileges so I can't just move the files from /usr/local/include to /usr/inlcude
I am a noob in compiling. I am only compiling because this is the only way I am getting the executable. Please be as noob-proof as possible when explaining. Thank you so much!
The compiler reports:
alignparts_lmbfgs.f90:105: Error: Can't open included file '/usr/include/fftw3.f'
This means that your source file alignparts_lmbfgs.f90 contains
a line #105 like:
INCLUDE '/usr/include/fftw3.f'
which tells the compiler to copy the file /usr/include/fftw3.f in place
of that line #105. But there is no such file.
You have passed the compiler option -I/usr/local/include which
tells the compiler to search for included files in /usr/local/include,
and you say:
I specified the -I options where the fftw3.f resides.
So probably there is such a file as /usr/local/include/fftw3.f?
In that case, can change:
INCLUDE '/usr/include/fftw3.f'
to:
INCLUDE '/usr/local/include/fftw3.f'
However, if you do that, then the compiler option:
-I/usr/local/include
is pointless, because /usr/local/include/fftw3.f is an absolute filename:
it either exists or it doesn't.
If you want the program to be compilable independently of the absolute location
of fftw3.f - which is emphatically the best practice - then replace line #105 with:
INCLUDE 'fftw3.f'
Then, if fftw3.f is in fact located in /usr/local/include, you can compile
the program with the option -I/usr/local/include, and in general if the file
is located in directory /look/here/for/headers, you can compile the program
with the option -I/look/here/for/headers.

how to gcc compile with #define in multiple files

I have a project with multiple files.. I want to compile it using gcc from command line.
the directory looks like this
lib/
Comp/ contains .cpp files
Decomp/ contains .cpp files
Globals.cpp
include/
Comp/ contains .h files
Decomp/ contains .h files
Globals.h
some of these .h files are not paired with .cpp files
to compile this i use something like this :
g++ lib/Comp/* lib/Decomp/* lib/Globals.cpp -std=c++0x -o TEST
the problem is,I have to add some #defines for each .h file and i have to do it through command line. how to do this ??
also if i had to compile each file on its own and then link them. what would be the appropriate order for doing this ?
The dirtiest ugliest way is that you want to use something like:
g++ -Iinclude lib/Comp/*.cpp lib/Decomp/*.cpp lib/Globals.cpp -o test
Your .cpp files should #include <Comp/foo.h> or whatever
The correct way to manage this is to use a makefile to build each object file and then link them together:
Makefile
Create a a file called Makefile and put the following in it:
CXX=g++
CPPFLAGS=-Iinclude -DFOO -DBAR=1 -DSOME_STRING=\"My Name\"
CXXFLAGS=-O2 -g
SOURCES=lib/Comp/file1.cpp \
lib/Comp/file2.cpp \
lib/Comp/file3.cpp \
lib/Decomp/file1.cpp \
lib/Decomp/file2.cpp \
...
OBJ=$(SOURCES:%.cpp=%.o)
default: test
test: $(OBJ)
<tab> $(CXX) -o $# $(OBJ)
%.o: %.cpp
<tab> $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
NOTES
Replace file1.cpp etc. with the actual filenames in your project. DO NOT include headers in SOURCES only your .cpp or .cc files
If you are using sub-paths like #include <Comp/foo.h> or #include "Comp/foo.h" in your source files then you only need to use -Iinclude in CPPFLAGS but if you are doing something like "foo.h" and foo.h is actually in include/Comp/ then add -Iinclude/Comp and -Iinclude/Decomp to the CPPFLAGS
Where it says <tab> make sure you use the TAB key to insert a tab (don't type the word '')
Before using this Makefile blindly . Know that it will NOT work as is you have to correct the entries. It is offered as a starting point... Read up on writing Makefiles ... http://frank.mtsu.edu/~csdept/FacilitiesAndResources/make.htm has a good introduction
Defines can be provided on the compiler command line using -DVAR=VALUE (on Windows, presumably /DVAR=VALUE). Note that you can not provide different defines for different headers as in:
compiler -DX=one first.h -DX=two second.h third.cc -o third.o
In such a case, my compiler spews warning and uses the last value of X for all source code.
Anyway, in general you should not list header files on the compilation line; prefer to include them from the implementation files (.cc/.cpp or whatever) that need them.
Be careful too - if you're changing defines to modify class definitions, inline function implementation etc. you can end up with technically and/or practically undefined behaviour.
In terms of how best to decide which objects to create and link - you probably want one object per .cc/.cpp file. You can link those objects then specify them on the command line when compiling the file containing main().

Resources