I'm trying to figure out how to create a makefile that will create object files and then compile them into an executable but when I try to make an object file that uses a variable that was declared in another file it won't compile to an object file. In other words if I have main.c that has a global variable var and I have another file called other.c which uses var but doesn't declare it like main.c did. Is there a way to compile them both to object files and link them so other.c sees the declaration of var in main.c? I was under the impression there was but I can't figure it out because when I do gcc -c other.c I get an error about var. (I know you can make var extern to fix this issue but I need to able to do this without doing that)
Here's the error messages I get.
foundations.c: In function ‘FoundationC’:
foundations.c:2:2: error: ‘DAYS’ undeclared (first use in this function)
DAYS=DAYS+10;
^
foundations.c:2:2: note: each undeclared identifier is reported only once for each function it appears in
foundations.c:3:2: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
printf("The FoundationC Contractor completed the project - DAY %d\n",DAYS );fflush(stdout);
^
foundations.c:3:85: error: ‘stdout’ undeclared (first use in this function)
printf("The FoundationC Contractor completed the project - DAY %d\n",DAYS );fflush(stdout);
So DAYS is a variable that was declared in main.c not foundations.c
EDIT: Solved I added the needed stl header file and global variable to the other file and then it was able to compile as an object file. Sorry about this question. I made it thinking that object file linking had the ability which would make that unnecessary but I guess not.
...but when I try to make an object file that uses a variable that was declared in another file it won't compile to an object file.
This has nothing to do with a makefile. Commands in the makefile will for example start the compiler on a .c file to produce an object file. Either this compilation succeeds, or it does not in which case the compiler gives you one or more error messages.
The problem you describe of a variable declared in another .c file will NOT halt the compiler; it will just compile the .c file and will at most give warning messages that a variable is not declared. But it will produce an object file.
At link time, the linker must be given all object files so produced (a command in the makefile starts the linker with the list of names on the command line) and then will produce an executable. If now the variable cannot be found in the object files, the link process will fail and no executable is produced. But all object files will have been produced (if there aren't errors in the compilation step).
Maybe his helps to re-formulate your question.
Related
This is my current workspace. I have the Headers in the same folder with the otp.c but whenever I compile and run it it returns an error telling me that hmac-sha1 is undefined. Hope someone can help me.
Short Background
Including a header file enables you to compile the source file into an object file by declaring the function.
However, to get an executable, you need to link the object files together whereby one function used in one object file may be defined (i.e. implemented) in another object file. When listing the objects for the linker, they must be arranged in order of dependency, e.g if a depends on b the a should appear before b on the command line (in case of circular dependencies please find a post on it).
Solution
The way you run gcc makes it first compile the sources into object files and link them. otp.c requires the function hmac_sha1 is probably in hmac-sha1.c (I am guessing from the header file name) and so you should run:
gcc otp.c hmac-sha1.c -o otp
Note that otp.c depends on hmac-sha1.c hence the order.
I'm trying to run make on an Ubuntu machine to compile a RoT MUD, but the farthest I've gotten is when I get a collect2: error: ld returned 1 exit status.
This is what comes immediately before the error in the terminal (along with a lot of other similar errors):
/usr/bin/ld: obj/wizlist.o:/home/lucas/Projects/R2b5/src/merc.h:3355: multiple definition of `bllmax'; obj/act_comm.o:/home/lucas/Projects/R2b5/src/merc.h:3355: first defined here
From what I've gathered this means that the header files have variable declarations in them, and that using static is an easy fix, however, I haven't been able to figure out where I should put that keyword in the code to fix this issue. The following is the only mention of bllmax in merc.h:
int bllmax, crbmax, crnmax, srpmax, mngmax;
Here is the program I'm trying to compile.
You need to learn the difference between declaration and definition. A declaration is telling the compiler that the symbol exists somewhere but possibly not here. A definition is telling the compiler that the symbol exists here.
The line you show (without any context) is defining the variables, which means they will be defined in each source file that includes the header file.
What it should do is to declare the variables, which can be done by making them extern:
extern int bllmax, crbmax, crnmax, srpmax, mngmax;
Then in a single source file define the variables (without extern).
Why does the compiler sometimes not give line number of the error? Where is the use case of that "undefined reference". I've already included everything as header files I myself wrote so it needs to give a specific line number. It is not closed source. Have I changed some setting of the compiler by accident or is it another thing whatever that another thing is?
D:\Projects\DanceOfPixels\GLEW>gcc main.c glad.c -IC:\mingw_dev_lib\include\SDL2 -LC:\mingw_dev_lib\lib -lmingw32 -lopengl32 -lSDL2main -lSDL2 -lSDL2_image -o main.exe -ansi -std=c89 -pedantic -w
C:\Users\user\AppData\Local\Temp\ccMooHZm.o:main.c:(.text+0x126ce): undefined reference to `drawImagePartScaledHW'
collect2.exe: error: ld returned 1 exit status
Edit: I have solved the problem. I have included two different versions of the draw.h, one coming from software renderer, other from OpenGL renderer. Since they use same
#ifndef DRAW_H
#define DRAW_H
...
#endif
structure for both files; the compiler didn't include the second. Once I've changed the DRAW_H to DRAW_HW I managed to compile and run the application.
That error comes from the "linker" (ld), not the compiler proper.
Typically, the compiler compiles each source file into its own, individual object file, containing just the code and data from that source file. Then, the linker combines one or more object files together, and also links in any needed library functions.
Crucially, there's no problem if a single source file (a single object file) calls an undefined function -- that's normal, if the definition of the function is in another source file, or a library. So that's why it's the linker (not the compiler) that finally discovers that there's not a definition for a function anywhere, that it's truly undefined.
But since the linker is working with object files, typically it doesn't know which source file line numbers the functions were originally called on.
(Some C compilers work more closely with their linkers, so that these "undefined external" error messages can, more usefully, contain actual source file line numbers, but that's a relatively recent innovation. For this to work it may be important to compile with debugging enabled, e.g. by using the -g flag, so that the compiler includes source line number information in its object files.)
When I include "stdio.h" and try to use "printf" it works fine.
In the same way when I use "krb5.h", its function "krb5_get_init_creds_password" does not get resolved by its own.
Error faced :
bash-4.1$ gcc krb.c
krb.c: In function ‘main’:
krb.c:6: warning: incompatible implicit declaration of built-in function ‘printf’
/tmp/ccTK4DJM.o: In function main':
krb.c:(.text+0x53): undefined reference tokrb5_get_init_creds_password'
collect2: ld returned 1 exit status
I had to compile using -lkrb5 which resolved the issue.
Can someone let me know why do I need to use gcc option "-lkrb5" to get that krb5 function resolved ?
I am using C.
The header file you include only contains the declaration of the function, the actual function definition (the implementation) is in the actual library (usually a file named (using your example) libkrb5.a or libkrb5.so).
The option you pass to the linker is -l (lower-case L) which tells the linker to find and use whatever library you pass as argument to the -l option.
If you have create programs consisting of multiple source files yourself, then this should not have been much of a surprise really. If you have two source files a.c and b.c, where in a.c you call a function defined in b.c you need to declare the function for it to be available in a.c. And then when you link the executable program you need to link with the object file created by b.c to be able to find the definition.
Using a library is really not much different from that.
anyone can help me?? my board is LPC1768 and the sensor is BMP180
Rebuild target 'Target 1'
compiling BMP180.c...
compiling I2C.c...
assembling startup_LPC17xx.s...
compiling system_LPC17xx.c...
compiling GPIO_LPC17xx.c...
compiling PIN_LPC17xx.c...
linking...
.\Objects\asdsa.axf: Error: L6218E: Undefined symbol main (referred from __rtentry2.o).
Not enough information to list image symbols.
Finished: 1 information, 0 warning and 1 error messages.
".\Objects\asdsa.axf" - 1 Error(s), 0 Warning(s).
Target not created.
I found the solution is easy, but before going deeper into the solution, keep in mind that C compilation unit (C Compiler and Assembler at least) compiles each pure C source file after resolving necessary pre-processor directives, and generates a relocatable object file as a result of compilation.
After the compilation unit does its job, there is another unit that is responsible for combining individually every source file that is compiled successfully into the relocatable form of one big object file for all. This unit is called Linker and the operation is called Linking
A very important feature in relocatable object file is that what is called variable, function will be noted as symbol so far. The linker has to solve the symbols, defining what is originally defined in an object file, reference what is being used in another to their original object file.
After this motivation, now we can call main() function as main() symbol.
I Found that the problem is because the source file that contains the main() function was not compiled. As a result, there is no a relocatable object file that contains the symbol corresponding to main() function. Hence, the compiler is complaining: you asked me to use (reference) a symbol you guaranteed to be found (defined) in another file but I found no such symbol!
The solution:
For Kiel IDE, to queue a source file for a compilation; you gotta shortlist it in the category "Source Group",by clicking right, either adding new files to group, or existing files to group. It will result in something like the following figure:
Now we have a main function, is turned (defined) to main symbol later, and found by the linker to reference it to whatever use it in any other relocatable object files.
I solved this problem with the following steps;
Delete your old project and create new project
Choose true library from Manage Run Time Environment like so:
Configure "Options for Target" segment. Define symbol USE_STDPERIPH_DRIVER and define project path like so:
Test your configuration. Please write the following code:
#include "stm32f10x.h" // Device header
int main() {
}
I had the same issue. The problem was that the function name in .c file had a different name with the one in the .h file, and I didn't know.
just add your c file (ex: 'main.c') to the source group (ex: 'source group 1') by expanding the target then right click on the source group, choose add existing files to group 'your source group', then choose the main.c file.
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/14222.html
This should help.
Just create a dummy main() or main.c file. Linker can't find it in your pjt.
For solution only add this file C to driver folder and translate it,
Solved: This "Target Not Created" Issue was Resolved by the setting of Run Time Environment as shown in below(url) image.https://i.stack.imgur.com/kJ4IL.jpg ( consisting of CMSIS and Device supporting components in Run time environment)
{ compiling TransformFunctions.c...
linking...
Program Size: Code=768 RO-data=320 RW-data=4 ZI-data=612
FromELF: creating hex file...
".\Objects\LPC1768_B_T.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:07
}