I am getting the below error when i try to compile my code. The code is not complete since i am yet to add functions in my header and source files. But only with definitions i am having these errors.
Error:
'Building target: UART_example.elf'
'Invoking: ARM gcc linker'
arm-xilinx-eabi-gcc -Wl,-T -Wl,../src/lscript.ld -L../../test_bsp/ps7_cortexa9_0/lib -o "UART_example.elf" ./src/helloworld.o ./src/platform.o ./src/uart_new.o -Wl,--start-group,-lxil,-lgcc,-lc,--end-group
./src/uart_new.o:(.data+0x0): multiple definition of `uart_fifo_rxptr'
./src/helloworld.o:(.data+0x0): first defined here
./src/uart_new.o:(.data+0x4): multiple definition of `uart_rxbuf'
./src/helloworld.o:(.data+0x4): first defined here
./src/uart_new.o:(.data+0x8): multiple definition of `uart1_tx'
./src/helloworld.o:(.data+0x8): first defined here
./src/uart_new.o:(.data+0xc): multiple definition of `uart2_tx'
./src/helloworld.o:(.data+0xc): first defined here
collect2.exe: error: ld returned 1 exit status
make: *** [UART_example.elf] Error 1
My uart_new.c source file just contains the include of uart_new.h header.
Content of uart_new.h is shown below
#ifndef UART_NEW_H_
#define UART_NEW_H_
#include "xparameters.h"
// address offset for the UART Peripheral
#define BASE_UART_BUFFER 0x4800
#define BASE_UART_REGS 0x4C00
unsigned *uart_fifo_rxptr = XPAR_SIGNAL_CONNECTOR_0_S00_AXI_BASEADDR + BASE_UART_REGS*4; // register 0
unsigned *uart_rxbuf = XPAR_SIGNAL_CONNECTOR_0_S00_AXI_BASEADDR + BASE_UART_BUFFER*4 ; // dual-port RAM
//--UART1 and UART2 transmit byte at registers 1 and 2
unsigned *uart1_tx = XPAR_SIGNAL_CONNECTOR_0_S00_AXI_BASEADDR + (BASE_UART_REGS +1)*4; // register 1
unsigned *uart2_tx = XPAR_SIGNAL_CONNECTOR_0_S00_AXI_BASEADDR + (BASE_UART_REGS +2)*4; // register 2
#endif /* UART_NEW_H_ */
And my main contains as shown below
#include <stdio.h>
#include "platform.h"
#include "uart_new.h"
void print(char *str);
int main()
{
//code
}
Please let me know if i am making any mistake somewhere.
I am assuming the error is linker related but cannot solve.
Thanks for help in advance!!
You've defined some global variables in a header file. These global variables will subsequently be defined in each source file (compilation unit) that includes the header file, resulting in multiple definitions.
To fix, change your definitions to declarations in the header file:
unsigned *uart_fifo_rxptr, *uart_rxbuf, *uart1_tx, *uart2_tx;
and put the definitions in only one source file.
Related
below is the code:
//test.h
...
extern int globalVariable;
...
//test.c
#include "test.h"
...
int globalVariable = 2020;
...
//main.c
#include <stdio.h>
#include "test.h"
int main()
{
printf("Value is %d", globalVariable);
}
let's say in a scenario, there are hundreds of variables are declared in test.h and globalVariable is just one of them.
since there are two many variables, I easily makes a typo error in test.c as:
#include "test.h"
int globalVariables = 2020; //extra 's' in the name which contradicts the declaration of its counterpart in test.h
if I compile(only compile,not linking them) test.c, test.h and main.c, it compiles and shows no error. the unresolved error will only occur when linker involved in the linking stage.
But in a large application, I might just write some modules without the need of linking all existing to an executable file, so it would be better the compiler throw an error in the compile stage to indicate the error so I can correct them asap, so how can I let the compiler force the source file implement definition for a header file?
You could also use the preprocessor
test.h:
#ifndef TEST_C_IMPLEMENTATION
#define DEFINE_AND_INIT_VARIABLE(type, name, value) \
extern type name;
#else
#define DEFINE_AND_INIT_VARIABLE(type, name, value) \
type name = value;
#endif
DEFINE_AND_INIT_VARIABLE(int, globalVariable, 2020);
test.c:
#define TEST_C_IMPLEMENTATION
#include "test.h"
This technique can be taken even further - there are small utility libraries that are shipped as a single include file; you're just to set a macro in one of the translation units to force the implementation to be compiled in there.
The declaration extern int globalVariable; says that the variable exists somewhere, but not necessarily in the current translation unit. So any source file that includes the header containing this declaration will know that the variable exists without needing the full definition.
When you then get to the linking stage is when you'll get the error regarding glovalVariable being undefined. Since the variables is declared in test.h, convention would dictate that the definition would be in test.c. Upon inspecting that file, you would then find that no such variable exists and could then either add it or find the typo and fix it.
I have static library file(lib_XXX.a) with global variable defined in it. I am trying to access the global variable in my executable(exe_XXX.o).
Linker error is coming. Any help would be thankful.
Languae : c
OS : Ubuntu gcc compiler
Sample as follows
exe_xxx.o module has 2 files resource.h and main.c
resource.h code as follows :
#ifndef RESOURCE_H
#define RESOURCE_H
#define APL
extern const StructTest g_AplObjDef;
const StructTest g_AplObjDef = {
abc, def, ghi,
....
};
#endif //APL
main.c code as follows:
#include "resource.h"
....
....
....
lib_xxx.a has another main.c in it. Its sample code as follows:
#include "resource.h"
int main()
{
#if defined(APL)
fun1(g_AplObjDef);
#endif
}
I suspect the reason is because resource.h included in both the main.c files.
I couldn't way to get rid of this. Can anyone help ?
Error details:
/lib_XXX.a(lib_XXX_a-main.o):(.data.rel.ro.local+0x40): `g_AplObjDef' が重複して定義されています
/exe_xxx-main.o:(.data.rel.ro.local+0x260): ここで最初に定義されています
Above error is in Japanese.. 1st line says "Duplicate is defined". 2nd line says "Here it is defined"
This part:
const StructTest g_AplObjDef = {
abc, def, ghi,
....
};
is a definition, and should not be in a header. Move it to
a .c file.
The reason for this is that header files are textually inserted, so if a header has a definition, and is included from multiple translation units, the symbol will be defined multiple times, which is an error.
Here you are defining a variable in the header
const StructTest g_AplObjDef =
You should only declare, which you did the line before.
This definition should go into a code file, accessing it will be possible by the knowledge provded by the declaration in the header. But the definition in the header will be done in each code file which includes it, which causes the redundant definition mentioned in the error message.
Moving the definition (as you now have it in the header, including the {...} into the libs code file should help.
Note that having two main() will probably get you into trouble, I only focus this answer on the double definition of the variable.
I've inherited some code* which declares and defines a struct in a header file (a_A.h). This struct is in the top file of an include hierarchy tree which symbolically looks like:
file: t_T.h (#includes "c_C.h") //defines a struct
file: c_C.h (#includes "h_H.h")
file: h_H.h (#includes "a_C.h")
file: a_C.h (#includes <stdio.h>)
Each header has the appropriate header guards and appear to be non-recursive when looked at as a flat collection of files. However, files c_C.h and a_C.h reside in the same library. While h_H.h resides in a different library. From a library perspective this symbolically appears as:
t_T.h (includes a file from Lib_C)
Lib_C: (includes a file from Lib_H)
Lib_H (includes a file from Lib_C)
which is recursive and is the likely cause of redefinition problems when I compile the code (the linker complains that the struct in file a_C.h is redefined).
1) Did I correctly identify the issue?
2) If so, why? I am guessing that linked objects in a library appear flat to the linker (i.e. they've lost their hierarchy context). And if guessed somewhat correctly then:
3) Should I consider header guards to be limited to the scope of their respective library?
Below is the error statement from the problems window:
symbol "ov5642_1280x960_RAW" redefined: first defined in "./TakePhoto.obj"; redefined in "./ArduCam/ov5642_Config.obj"
Header in ./TakePhoto:
#ifndef TAKEPHOTO_H
#define TAKEPHOTO_H
#include "ov5642_Config.h"
#include "HAL_ArduCAM.h"
...
#endif /* TAKEPHOTO_H_ */
Header in ./ArduCAM/ov5642_Config.h:
#ifndef ARDUCAM_OV5642_CONFIG_H_
#define ARDUCAM_OV5642_CONFIG_H_
#include "HAL_ArduCAM.h"
#include "ov5642_Sensor_Values.h"
....
#endif /* ARDUCAM_OV5642_CONFIG_H_ */
Header in HAL_ArduCAM
#ifndef HAL_ArduCAM_h
#define HAL_ArduCAM_h
#include <stdint.h>
#include "driverlib.h"
....
#endif /* HAL_ArduCAM_h */
ov5642_Sensor_Values.h has the following
#ifndef ARDUCAM_OV5642_SENSOR_VALUES_H_
#define ARDUCAM_OV5642_SENSOR_VALUES_H_
#include <stdint.h>
const struct sensor_reg ov5642_1280x960_RAW[] =
{
{0x3103,0x93},
{0x3008,0x02},
{0x3017,0x7f},
.....
#endif /* ARDUCAM_OV5642_SENSOR_VALUES_H_ */
It seems that the contents of OV5642_Sensor_Values is copied twice, once for TakePhoto and once again for ovV5642_Config despite their header guards. My original thought was that there was a recursive dependencies but didn't find it.
Ok, I've made an example pasted below. There are five files in this example, three files (bar.h, foo.h, foo.c reside in a library), the other two files (foo1.h, foo1.c) do not. Notice that foo.h includes bar.h and that foo1 includes both foo.h and bar.h.
I am conjecturing that the guard headers of bar.h are not preserved when the pre-processor copies into foo.h. Thus when foo1 includes bar.h and foo.h the symbol redefinition arises. So to answer my own question, no, it is not a library issue. Not preserving the header guard seems the likely cause of my problem.
They are pasted below.
/*
* bar.h
*
*/
#ifndef ARDUCAM_BAR_H_
#define ARDUCAM_BAR_H_
#include <stdint.h>
typedef struct regStruct {
uint16_t reg;
uint8_t val;
} regStruct;
const struct regStruct regArray[] =
{
{0x3103,0x03},
{0x3104,0x03},
{0x3008,0x82},
{0xffff,0xff},
};
const struct regStruct tinyArray[] =
{
{0x3106,0x03},
{0x3003,0x82},
{0xffff,0xff},
};
#endif /* ARDUCAM_BAR_H_ */
/*
* foo.h
*
*
*/
#ifndef ARDUCAM_FOO_H_
#define ARDUCAM_FOO_H_
#include <stdint.h>
#include <stdio.h>
#include "bar.h" //including this file causes redefinition
typedef struct Init_Parameters {
//! Select sensor resolution
//! options.
//! \n Valid values are:
//! - \b big
//! - \b small
//! - \b tiny
uint8_t size;
} Init_Parameters;
uint8_t Sensor_Init(Init_Parameters *param);
typedef enum {
small=0,
big,
tiny
} select_size;
#endif /* ARDUCAM_FOO_H_ */
/*
* foo.c
*
*
*/
#include "foo.h"
uint8_t Sensor_Init(Init_Parameters *param)
{
switch(param->size)
{
case big:
break;
case small:
break;
case tiny:
break;
}
return 0x01;
}
/*
* foo1.h
*
* Created on: Feb 28, 2019
* Author: jnadi
*/
#ifndef FOO1_H_
#define FOO1_H_
#include "foo.h"
#include "bar.h"
#endif /* FOO1_H_ */
/*
* foo1.c
*
* Created on: Feb 28, 2019
* Author: jnadi
*/
#include "foo1.h"
void Camera_Init(){
Init_Parameters setParams; //create instance
setParams.size=big;
Sensor_Init(&setParams);
}
The physical locations of header files affect C source compilation only via the include-file search path. Headers have to be in one of the directories that are searched, and if there is more than one with the same name, then the search path order determines which is used. The association, if any, between a given header and a library is not known to the compiler, and it does not affect compilation, unless indirectly via the search path.
Your claim that
the linker complains that the struct in file a_C.h is redefined
(emphasis added) makes sense only if by "the struct" you mean an object of a structure type. The linker may complain if a variable with external linkage is defined in more than one translation unit, which will likely happen if a header contains a definition of that variable (as opposed to merely a declaration).
If instead the issue is that the structure type is redefined, then that would be diagnosed by the compiler, not the linker, and it would tend to contradict your conclusion that
Each header has the appropriate header guards
. Proper header guards are exactly what would prevent such a type redefinition issue.
1) Did I correctly identify the issue?
Not with any specificity, for sure. That there are header dependencies in both directions between headers associated with different libraries reflects poor design, but it would not inherently cause compilation or linking to fail.
2) If so [...]
N/A
3) Should I consider header guards to be limited to the scope of their
respective library?
No. Header guards are relevant at the compilation stage only, and C compilation knows nothing about libraries. All header files processed by the compiler in the course of translating a single translation unit are on equal footing. In fact, the main risk in this area is in the opposite direction: a collision of header guards.
That answers the question as posed. As for what the true nature of your build issue may be, you have not given us enough information to do more than speculate. My own speculations are already conveyed above.
Using the five files posted above and commenting out an #includes bar.h in foo.h, I believe I found the answer to my problem.
The simple answer is that header guards are not preserved once it is included into the header of another file.
When bar.h is included into another header file, its header guards are superseded by the header guards of its new host (foo.h). Thus symbol redefinition issues arise when foo1.h includes both bar.h and foo.h
Header guards only prevent a .h file from including its contents twice or more within one top-level translation unit. They are to deal with cases like this, where two or more headers need to include the same set of common definitions:
// A.h
struct A { int x, y, z; };
// B.h
#include "A.h"
struct B { struct A aye; float f, g; };
// C.h
#include "A.h"
struct C { struct A aye; long l, m; };
// main.c
#include "B.h"
#include "C.h" // error, redefinition of struct A
But each translation unit starts out with a clean macro environment, so if you include a header file in two different top-level translation units, that header's declarations are made visible (once) to each. And that's what you want. (Think about standard library headers. You wouldn't want stdio.h not to declare printf in bar.c just because there existed foo.c in the same project that also included stdio.h.)
Now, your problem is that ov5642_Sensor_Values.h defines a data object (not a type), ov5642_1280x960_RAW, and this header is included into two different top-level translation units (.c source files). Each translation unit produces an object file containing a definition of ov5642_1280x960_RAW, and you get a multiple definition error from the linker when you try to combine them.
The bug causing this problem is not that ov5642_Sensor_Values.h's header guards are ineffective. The bug is that ov5642_Sensor_Values.h should not be making any global definitions. Header files should only declare things (with rare exceptions that you shouldn't worry about until you encounter them).
To fix the bug, change ov5642_Sensor_Values.h to declare ov5642_1280x960_RAW but not define it, like this:
#ifndef ARDUCAM_OV5642_SENSOR_VALUES_H_
#define ARDUCAM_OV5642_SENSOR_VALUES_H_
#include <stdint.h>
#include "sensor_reg.h"
extern const struct sensor_reg ov5642_1280x960_RAW[];
#endif
and create a new file named ov5642_Sensor_Values.c that contains the initialized definition:
#include "ov5642_Sensor_Values.h"
extern const struct sensor_reg ov5642_1280x960_RAW[] =
{
{0x3103,0x93},
{0x3008,0x02},
{0x3017,0x7f},
.....
};
and add that file to your link.
thank you everyone especially John, Zwoi. I was up against a deadline (this was inherited code) but was able to calm myself down enough to figure out what John was saying. I moved the struct definition into a c file and used an extern pointer in the header which is similar to zwoi's declaration. I am also relieved that what I did matched zwoi's example (thank you so much!).
extern const struct sensor_reg * ov5642_1280x960_RAW;
I am programming a game in C using Code::Blocks. I am using the most recent version of C and of Code::Blocks. I am still learning the language.
All of my past programs have been contained in one huge source file, so I decided to branch out and try putting my code in multiple files. I know that the proper way to do it is to have source files containing code definitions and such and a header file containing prototypes for other source files to use. This has worked out horribly for me and I either can't get the files to work together properly or it simply doesn't work period.
I have a single function in a source file called process.c and a function prototype in a file called process.h. I also have a main.h and a main.c containing all the rest of the code. The main issue is that I have a typedef struct Game in my main.h file and I can't get the 'Game' struct type I created to work in my process.c. Every function in my game needs the Game type in order to work. However, when I give process.c access to main.h (the file that Game is declared in) I get issues.
My code works fine when it's in one file. My header files are protected from duplication and are properly included in the program. The problem is, I need to include main.h in both main.c and process.c. And I have to include process.h in both 'main.c' and 'process.c'. I have tried every configuration and nothing works.
In some #include configurations I get no errors, but I get this weird message that says "It seems your project has not been built yet; would you like to build it now?" and when I click "Yes" nothing happens.
My compiler works fine and there is nothing wrong with the projects settings. What the heck is going on here? How do I get main.h and process.h to work together?
EDIT: Source code:
main.c:
#include <stdio.h>
#include "main.h"
#include "process.h"
void initGame(Game *thisGame)
{
variable = 10;
number = 5;
letter = 'c';
}
int main()
{
Game thisGame;
initGame(&thisGame);
displayData(&thisGame);
return 0;
}
main.h:
#ifndef _MAIN_H_
#define _MAIN_H_
typedef struct
{
int variable, number;
char letter;
}
#endif
process.c:
#include <stdio.h> //not sure if this should be here or not, it doesn't seem to effect my code
#include "main.h"
#include "process.h"
void displayData(Game *thisGame)
{
printf("%i, %i, %c", thisGame.variable, thisGame.number, thisGame.letter);
}
process.h:
#ifndef _MAIN_H_
#define _MAIN_H_
void displayData(Game *thisGame);
#endif
Error message
-------------- Build: Debug in FishKiller (compiler: GNU GCC Compiler)---------------
mingw32-g++.exe -L..\deps\lib -L..\SDLFILES\lib -o bin\Debug\FishKiller.exe obj\Debug\main.o obj\Debug\process.o -lmingw32 -lSDL2main -lSDL2 -lSDL2_image
obj\Debug\process.o:process.c:(.rdata+0x0): multiple definition of `SCREEN_WIDTH'
obj\Debug\main.o:main.c:(.rdata+0x0): first defined here
obj\Debug\process.o:process.c:(.rdata+0x4): multiple definition of `SCREEN_HEIGHT'
obj\Debug\main.o:main.c:(.rdata+0x4): first defined here
obj\Debug\process.o:process.c:(.rdata+0x8): multiple definition of `GAMESTATE_MENU'
obj\Debug\main.o:main.c:(.rdata+0x8): first defined here
obj\Debug\process.o:process.c:(.rdata+0xc): multiple definition of `GAMESTATE_GAME'
obj\Debug\main.o:main.c:(.rdata+0xc): first defined here
obj\Debug\process.o:process.c:(.rdata+0x10): multiple definition of `GAMESTATE_GAMEOVER'
obj\Debug\main.o:main.c:(.rdata+0x10): first defined here
collect2.exe: error: ld returned 1 exit status
Process terminated with status 1 (0 minute(s), 0 second(s))
0 error(s), 0 warning(s) (0 minute(s), 0 second(s))
Issues are address file by file below. Once these issues are corrected in your source, the executable will build.
1)
In process.h you have the wrong header blocks:
#ifndef _MAIN_H_
#define _MAIN_H_
//Change to:
#ifndef _PROCESS_H_
#define _PROCESS_H_
Also change:
void displayData(Game *thisGame);(see notes in main.h for explanation)
To:
void displayData(GAME *thisGame);
2) In process.c you have;
#include "main.h"
It does not hurt anything, but since we are analyzing everything, it is not needed to support current architecture.
You also have:
printf("%i, %i, %c", thisGame.variable, thisGame.number, thisGame.letter);
Because the thisGame is passed in as a pointer, you need to use struct pointer operator: ->
printf("%i, %i, %c", thisGame->variable, thisGame->number, thisGame->letter);
Also, the function protocol in the same file is incorrect. You are attempting to instantiate a variable type that does not exist: (see notes for main.h)
Change:
void displayData(Game *thisGame){...}
To:
void displayData(GAME *thisGame){...}//uses typedef struct GAME
3) in main.h you have a malformed struct:
typedef struct
{
int variable, number;
char letter;
}//no ";" statement terminator to indicate to your compiler _end of struct_
And with this definition, there is no struct name with which to reference or instantiate it in any other file. Change it to the following:
typedef struct
{
int variable;
int number;//style point , put each member on its own line
char letter;
}GAME;//note struct type name and terminator ";"
With the struct type name, in this case GAME, you can create instances of this struct in any file that #includes this file.
extern GAME Game;// using the extern modifier, create an instance of GAME
// that can be referenced in any file of the
//project, once initialized. (See the line GAME Game; in main.c)
4) in main.c you have variables in the function initGame that need to be referenced differently. Change this:
void initGame(Game *thisGame)
{
variable = 10;
number = 5;
letter = 'c';
}
To:
void initGame(GAME *thisGame)
{
thisGame->variable = 10;
thisGame->number = 5;
thisGame->letter = 'c';
}
There is Code::Blocks information here that may help you to set up your environment to get the error messages that will help you to debug your code.
This question already has answers here:
Multiple definition of ... linker error
(3 answers)
Closed 8 years ago.
I am developing a program to read NFC cards, and I have a header file, source.h, holding all the variables for use in it's related source code, source.c. A sample is as shown below:
#ifdef __cplusplus
extern "C" {
#endif
int SDA_SUPPORT_PRESENT = 0;
int DDA_SUPPORT_PRESENT = 0;
int CDA_SUPPORT_PRESENT = 0;
int CARDHOLDER_VERIFICATION_PRESENT = 0;
...
The source code, source.c, holds the methods utilizing the above defined variables. A sample is as shown:
#include <source.h>
extern void translateError(uint8 error, int slot) //one of the methods
{
TP_DbgSerialPrn("\n\rDevice Error: ");
switch(error)
{
...
I also have a source file, CardReader.c, which calls the methods included in source.c, and which has a related header file, CardReader.h. The issue is, when I include the source.h file in the CardReader.h file, i get the following error:
../CardReader.o:(.bss+0x12b4): first defined here
../source.o:(.bss+0x12b8): multiple definition of `SLOT_NUMBER'
../CardReader.o:(.bss+0x12b8): first defined here
../source.o:(.data+0x49): multiple definition of `LISTED_APPLICATION_IDS'
../CardReader.o:(.data+0x49): first defined here
../source.o:(.data+0xc9): multiple definition of `LISTED_APPLICATION_IDS_LENGTH'
All the rest of the error messages are of the same type. The source.h file is included as indicated in CardReader.h:
#include <TPCardReader.h>
#include <source.h>
#ifdef __cplusplus
extern "C" {
#endif
...
with the path variables set properly, so it can be found, and then called the CardReader.h file as usual in CardReader.c. My question is why is that error coming up, yet I have only defined each of the specified variables once in source.h? Is there something am missing or not doing or do I not understand the error?
The variables should not be defined in the header file.
Instead in the header file you should have
extern int SDA_SUPPORT_PRESENT;
Then in the source (.c) file you should have
int SDA_SUPPORT_PRESENT = 0;
This will ensure you only have one definition of the variable
But then again global variables are a bad idea