I have to include some of the macros from .h in .S file. .h includes c declarations as well. Hence I took the defines out using
gcc -E -dM header.h > generated_header.h
generated_header.h has all predefined macros and standard symbols also.
Now gcc -Iinclude/ asm.S -o asm.o gives number of following warnings
warning: "__GCC_ATOMIC_LLONG_LOCK_FREE" redefined
warning: "__GCC_ATOMIC_SHORT_LOCK_FREE" redefined
warning: "__STDC__" redefined etc...
This is because we are redefining same macros again by including generated_header.h in asm.S
I checked all the preprocessor options for extracting only local defines. But nothing helped. Is there any other way to solve this. Is there any other way to make asm.S to be aware of those macros?.
Related
Here's my header file.
#ifndef P6_H
#define P6_H
#include <stdio.h>
void FoundationC();
void StructureC();
void PlumbingC();
void ElectricC();
void HVACC();
void SheatingC();
extern int DAYS;
#endif
I'm using a makefile to do all compilation. It's able compile the individual .o files file but when it tries turn those into a single executable it says that there multiple definitions of the variable DAYS even though that is extern and declared and initialized in each individually. I got this to work before but can't figure out why it's not working now.
Oh and here's my makefile code
all:
gcc -c P6.c
gcc -c foundations.c
gcc -c structure.c
gcc -c plumbing.c
gcc -c electric.c
gcc -c hvac.c
gcc -c sheating.c
gcc P6.h P6.o foundations.o structure.o plumbing.o electric.o hvac.o sheating.o -o P6
I realize P6.h probably doesn't have to be include in the command but the include guards should make it not matter no?
Also I'm sorry if this question is a dupe but I did previously look for answers and this issue is driving me crazy on a personal level despite the fact that's it's for school.
Here are the errors I get.
gcc -c P6.c
gcc -c foundations.c
gcc -c structure.c
gcc -c plumbing.c
gcc -c electric.c
gcc -c hvac.c
gcc -c sheating.c
gcc P6.h P6.o foundations.o structure.o plumbing.o electric.o hvac.o sheating.o -o P6
structure.o:(.data+0x0): multiple definition of `DAYS'
foundations.o:(.data+0x0): first defined here
plumbing.o:(.data+0x0): multiple definition of `DAYS'
foundations.o:(.data+0x0): first defined here
electric.o:(.data+0x0): multiple definition of `DAYS'
foundations.o:(.data+0x0): first defined here
hvac.o:(.data+0x0): multiple definition of `DAYS'
foundations.o:(.data+0x0): first defined here
sheating.o:(.data+0x0): multiple definition of `DAYS'
foundations.o:(.data+0x0): first defined here
collect2: error: ld returned 1 exit status
make: *** [all] Error 1
To help you understand, the following is an extension of #FUZxxl's answer, which is correct. If you have the following in your compilation unit (a compilation unit is the .c source file plus all included .h files):
extern int DAYS;
...
int DAYS = 1;
then the second declaration of DAYS overrides the first declaration which stated it is an extern. So, the variable is now no longer an extern and if you do this in more than one source file you now consequently have multiple definitions and the linker complains.
If you must initialize DAYS, then you can do that in one place, preferably in the main file.
initialized in each individually.
There's your mistake. What do you think is supposed to happen if you initialize the same variable in different translation units? What do you think happens if these use different values?
You can only define a variable once in your program, multiple declarations are fine though. From all but one translation unit, remove the definition of DAYS to fix this problem.
First of all,remove P6.h from the last command in the makefile.-o option in gcc is used for compiling and linking multiple source files.So,this doesn't make any sense.
Secondly define DAYS as "int DAYS" in a .c file,you could declare it as extern in the corresponding .h file and include this .h file in all other source .c files.This will resolve this issue of multiple definitions.
Example:Define days as "int DAYS" in A.c and you declare it as "extern int DAYS" in A.h.Now,you could include this A.h in rest other source files like B.c , C.c ,D.c and so on.
I have a number of .c files, i.e. the implementation files say
main.c
A.c
B.c
Where functions from any of the files can call any function from a different files. My question being, do I need a .h i.e. header file for each of A and B's implementation where each header file has the definition of ALL the functions in A or B.
Also, main.c will have both A.h and B.h #included in it?
If someone can finally make it clear, also, how do I later compile and run the multiple files in the terminal.
Thanks.
Header contents
The header A.h for A.c should only contain the information that is necessary for external code that uses the facilities defined in A.c. It should not declare static functions; it should not declare static variables; it should not declare internal types (types used only in A.c). It should ensure that a file can use just #include "A.h" and then make full use of the facilities published by A.c. It should be self-contained, idempotent (so you can include it twice without any compilation errors) and minimal. You can simply check that the header is self-contained by writing #include "A.h" as the first #include line in A.c; you can check that it is idempotent by including it twice (but that's better done as a separate test). If it doesn't compile, it is not self-contained. Similarly for B.h and B.c.
For more information on headers and standards, see 'Should I use #include in headers?', which references a NASA coding standard, and 'Linking against a static library', which includes a script chkhdr that I use for testing self-containment and idempotency.
Linking
Note that main.o depends on main.c, A.h and B.h, but main.c itself does not depend on the headers.
When it comes to compilation, you can use:
gcc -o program main.c A.c B.c
If you need other options, add them (most flags at the start; libraries at the end, after the source code). You can also compile each file to object code separately and then link the object files together:
gcc -c main.c
gcc -c A.c
gcc -c B.c
gcc -o program main.o A.o B.o
You must provide an header file just if what is declared in a .c file is required in another .c file.
Generally speaking you can have a header file for every source file in which you export all the functions declared or extern symbols.
In practice you won't alway need to export every function or every variable, just the one that are required by another source file, and you will need to include it just in the required file (and in the source paired with the specific header file).
When trying to understand how it works just think about the fact that every source file is compiled on its own, so if it's going to use something that is not declared directly in its source file, then it must be declared through an header file. In this way the compiler can know that everything exists and it is correctly typed.
It would depend on the compiler, but assuming you are using gcc, you could use something like this:
gcc -Wall main.c A.c B.c -o myoutput
Look at http://www.network-theory.co.uk/docs/gccintro/gccintro_11.html (first google answer) for more details. You could compile it into multiple object files/ libraries:
gcc -c main.c
gcc -c A.c
gcc -c B.c
gcc -o mybin main.o A.o B.o
You want to use
gcc -g *.c -lm
It saves typing and will allow you to link all your c files in your project.
I have three files.
trees.h
// a bunch of typedefs and function prototypes
#include <trees.c>
trees.c
// a bunch of function bodies
main.c
#include <trees.h>
This isn't right, because every function in trees.c is giving me "undefined type" errors about the type defined in trees.h. I've tried every configuration I can think of - include trees.c from main and include trees.h from trees.c, include trees.c at the end of trees.h, include it at the beginning of trees.h... Every combination of includes I could think of, and each one gives a different set of errors. Sometimes it's multiple defines, sometimes it's undefined functions...
So how exactly does this work? What do I put in which files, and which files do I include and where?
Like this:
trees.h
// a bunch of typedefs and function declarations (prototypes)
trees.c
#include <trees.h>
// a bunch of function definitions (bodies)
main.c
#include <trees.h>
Explanation:
#include is basically the same as copying the entire included file to this file (where you put the #include).
So including trees.h in main.c allows that file to know about functions in trees.c.
Including trees.h in trees.c allows functions lower down in trees.c to be usable and this is also where defines, etc. used in trees.c is specified.
You also may not know about creating multiple objects and linking them, refer to Joachim Pileborg's answer.
The (very ugly) alternative is:
trees.h
// a bunch of typedefs and function declarations (prototypes)
trees.c
#include <trees.h>
// a bunch of function definitions (bodies)
main.c
#include <trees.c>
Then you just need to compile main. But for any project of a few .c files, this becomes impractical.
You compile each source file into object files, then link these object files together to form the final executable. If you use e.g. GCC and compile on the command line you can put both source files in the command line and GCC will handle it for you:
$ gcc main.c tree.c -o tree
The above command tells gcc to compile and link the files main.c and tree.c, and name the output executable tree. You can also compile the source file separately into object files, and then manually link them together:
$ gcc -c main.c -o main.o
$ gcc -c tree.c -o tree.o
$ gcc main.o tree.o -o tree
In the above commands, the -c option tells gcc to create an object file, and the -o option tells gcc what to name that object file. The last command takes these object files and create the final executable and names it (with the -o option) tree.
In the source files, you include the header(s) needed, not the other way around.
The reason it's not working is because you have to use 'extern' to define a variable or function that is declared in a different include file to the standard ones. You should also save all header files as *.h. So, assuming you had defined the struct 'tree' in tree.h:
#include <tree.h>
int main() {
extern tree; /* Get variable 'tree' declared in tree.h */
extern make_tree(void); /* Get function make_tree() declared in tree.h */
make_tree(); /* Call function */
return (0); /* End */
}
Begin with not including implementation (.c) files. Only include header (.h) files. Include them whenever you need the types or functions declared in them. To avoid multiple declarations, use include guards (whatever they are - just google it).
The way to go is including your header file trees.h in trees.c and then including trees.c within main.c
Have a look at this thread here
One of my questions, as I'm pretty new to C is about ways to avoid getting the duplication error. Basically, when I build the project in Netbeans if I have the file in the project and also include it, I get that error.
Defining the functions static, is a correct way to avoid it? What other solutions are there? Thanks
.c/.cpp files shouldn't be included.
Move declarations to a common header file and include that.
As K. Horvath says, you shouldn't be including one c file in another. This means you have to provide an .h for each .c, compile the .c files into object files, then include the .h files as necessary and compile all the objects together with the .c containing main(). You can still end up with duplication in the .h declarations, however, which is where include guards come in.
#ifndef MY_HEADER
#define MY_HEADER
// all your type definitions, function prototypes, etc
#endif
WRT compiling each .c first, here's an example for gcc: you have a util.c file with various functions you want to use in main.c; util.c should then have a corresponding util.h you #include in main.c. Then:
gcc -Wall -g -c util.c
"-Wall" enable compiler warnings
"-g" include debugger symbols
"-c" will produce a .o (unlinked intermediate object) file instead of a normal executable.
Now:
gcc -Wall -g util.o main.c
This compiles main.c and includes the stuff from util.c which was compiled into util.o.
Since you're using netbeans, this may be theoretical -- generally IDE's do all that for you. However, understanding the fundamental process may make it easier to understand your IDE ;)
I have a c-library which I use in gcc. The library has the extension .lib but is always linked as a static library. If i write a program which uses the library as c-code, everything as a-ok. If I however rename the file to .cpp (doing simple stuff that works in both c/c++) I get undefined reference. These are simple small programs I write for testing purposes so no fancy stuff. I compile using:
gcc -g -Wall -I <path to custom headers> -o program main.c customlibrary.lib -lm -lpthread
The above works like a charm. However:
g++ -g -Wall -I <path to custom headers> -o program main.cpp customlibrary.lib -lm -lpthread
or
gcc -g -Wall -I <path to custom headers> -o program main.cpp customlibrary.lib -lm -lpthread -lstdc++
results in undefined reference to any function in customlibrary.lib. I tried creating a symbolic link named customlibrary.a but no luck.
Why won't g++ find recognize my library. Unfortunately I have no access to the source code of the libraries but linking a c-lib to c++ should not be a problem right?
Your library appears to have an API that assumes it will be called from C, not C++. This is important because C++ effectively requires that the symbols exported from a library have more information in them than just the function name. This is handled by "name mangling" the functions.
I assume your library has an include file that declares its public interface. To make it compatible with both C and C++, you should arrange to tell a C++ compiler that the functions it declares should be assumed to use C's linkage and naming.
A likely easy answer to test this is to do this:
extern "C" {
#include "customlibrary.h"
}
in your main.cpp instead of just including customlibrary.h directly.
To make the header itself work in both languages and correctly declare its functions as C-like to C++, put the following near the top of the header file:
#ifdef __cplusplus
extern "C" {
#endif
and the following near the bottom:
#ifdef __cplusplus
}
#endif
The C++ compiler performs what is known as name-mangling - the names that appear in your code are not the same ones as your linker sees. The normal way round this is to tell the compiler that certain functions need C linkage:
// myfile.cpp
extern "C" int libfun(); // C function in your library
or do it for a whole header file:
// myfile.cpp
extern "C" {
#include "mylibdefs.h" // defs for your C library functions
}
Does your header file have the usual
#ifdef __cplusplus
extern "C" {
#endif
// ...
#ifdef __cplusplus
} /* extern "C" */
#endif
to give the library functions C linkage explicitly.
.cpp files are compiled with C++ linkage i.e. name mangling by default.