Including c files leads to undefined references - c

When I include c files, I start to get undefined references to other functions. Then, I have to start including the c files that contain the functions. How do I get around this? The undefined references are referenced in the c files that I include, but since I am not actually including those files, I get undefined references.

Generally one includes ".h" files, not ".c" files.
If you call a function declared in a .h file, it is not sufficient to compile the starting C file to get a complete program -- you also need to link in the object files associated with the code that implements the declared functions. These might be in a library, in which case you need to link with that library.

You need to either compile all the files at once (gcc *.c) or compile each .c file into a separate object file and then link them all into the executable:
gcc -c main.c -o main.o
gcc -c helper.c -o helper.o
gcc -c other.c -o other.o
gcc *.o -o main
And within each .c file you should only ever include .h files.

What do you mean by including? Including via the #include preprocessor directive, or including as in adding them to your project.
You cannot get around the fact that all of the functions that are called (or, generally, externals symbols that are referenced) in your program either have to be included in that program, or have to exist in a library that is linked to the program, explicitly or implicitly.
Just keep adding the source files that are needed until all the references are resolved.
If you can't do that, then you may have some problem with the program or build. Either the program is incomplete (missing source files), corrupt (missing parts of source files), or you have included an inappropriate source file into the build (e.g. a source file which is needed when the program is compiled for Unix, but you're building for Windows) or incorrectly configured (so it is conditionally compiling some code for the wrong platform) or the program is simply not ported to your system (makes references to library functions you don't have).

Related

How to write common functions for reusing in C

I was trying to write a common function for other files could reuse it, the example as following, I have three files:
The first file: cat test1.h
void say();
The second file: cat test1.c
void say(){
printf("This is c example!");
}
The third file: cat test2.c
include "test1.h"
void main(){
say();
}
but when I ran: gcc -g -o test2 test2.c
it threw error as:
undefined reference to `say'
Additionally: I knew this would work:gcc -g -o test2 test1.c test2.c
but I don't wanna do this, because the other team would use the server, and I hope them directly use my binary code not source code. I hope that just like we use printf() function, we just need include .
You can build yourself a library from the object files containing your useful functions, and store the header(s) that describe them in a convenient location. You and your colleagues then compile with the headers and link that library with any executables that use any of those functions. That's very much the same general mechanism that the C compiler uses to include the standard headers and automatically link with the standard C library.
The mechanics vary a bit depending on platform (Windows vs Unix being the primary distinction, though there are differences between Unix platforms too), and also on the type of library (static archive vs dynamic linked / loaded libraries — also known as shared objects or shared libraries).
In broad outline, for a Unix system with a static library, you'd:
Compile library object files libfile1.o, libfile2.o, … using (for example) gcc -c libfile1.c libfile2.c.
Create an archive from the object files — using for example ar r libname.a libfile1.o libfile2.o.
Copy the headers to a standard location such as /usr/local/include.
Copy the library to a standard location such as /usr/local/lib.
You'd compile any code that uses the library functions with -I/usr/local/include (if that is not already a standard compilation option).
You'd link the programs with -L/usr/local/lib -lname (you might not need to specify -L… but you would need to specify -lname).
Including a header file does not make a function available. It simply informs the compiler that the function will be provided at a later time.
You should compile the file with the function into a shareable object file (or a library if there is more than one function that you want to share). Mind the switch -c which tells gcc not to build an executable file:
gcc -o test1.o test1.c -c
Similarly, compile the main function into its own object file. Now you or anyone else can link the object file with their main program:
gcc -o test2 test2.o test1.o
The process can be automated using make.
Other programmers can use compiled object files (`*.o') in their programs. They need only to have a header file with function prototypes, extern data declarations and type definitions.
You can also wrap many object files into the library.
On many systems you can also create the dynamic linked libraries which do not have to be linked into the executable.
you also need to compile test1:
gcc -g -o test2 test1.c test2.c.

(Cygwin) C program linked to custom header file having memory problems when trying to execute

I am using Cygwin. I have two files in the same directory, test.c and iah202_graphics.h. test.c uses functions from the header file, where I have used #include "iah202_graphics.h". I have added the Cygwin directory to my Environment Variables (PATH) already.
However I receive these errors for every function call:
$ gcc -o test test.c
/cygdrive/c/Users/Matthew/AppData/Local/Temp/cclm2bNk.o:test.c:(.text+0x27): undefined reference to `draw_line'.
/cygdrive/c/Users/Matthew/AppData/Local/Temp/cclm2bNk.o:test.c:(.text+0x27): relocation truncated to fit:
R_X86_64_PC32 against undefined symbol `draw_line'.
/cygdrive/c/Users/Matthew/AppData/Local/Temp/cclm2bNk.o:test.c:(.text+0x4a): undefined reference to
`draw_line'.
collect2: error: ld returned 1 exit status.
It's having trouble linking to the header file even though I've simply stated which file to use in the local directory. I don't understand what I'm doing wrong?
Undefined reference to 'blah' is a linker error rather than a compiler error and is almost always caused by not including a needed library.
Including a header file in your source file does not usually link in the code required to provided the functions declared in that header.
For example, were you to prevent linking of the C runtime library, you could include stdio.h as many times as you wanted to, and still not be able to resolve printf.
Bottom line, you generally need two steps:
include the relevant header file in your source code so it knows about the declarations of things provided; and
link against the relevant library or object file so it has access to the definitions of the things provided.
That could be something as simple as:
gcc -o test -I/path/to/iah202includes test.c -L/path/to/iah202libs -liah202
where -I indicates where include files can be found, -L adjusts the search path for library files, and -l actually specifies the library file to use.
Even simpler is if you have the source file for the graphics stuff (which seems to be the case based on your comments). In that case no library is needed, you can simply use:
gcc -o test test.c iab202_graphics.c
and that will compile both those translation units then link them together.

GCC: undefined reference to xxx

I know that have been already asked a lot of time but I can't really solve it...
so I have a src folder where my main.c source is, an srclib where my lib.c file is stored and an include directory where my lib.h file is stored. now the makefile compiles the lib correctly and put the lib.a file in lib folder. the main.cincludes the lib like this:
#include "lib.h"
and it's compiled with -I ../include option, but when i compile it I get the undefined reference to xxx error for every function in the library
so what am I missing?
Nope. -I is for including the header files. You also need to link with the library using -l option.
Note: You may need to provide the path-to-library using -L option.
To quote the online gcc manual
-llibrary
Search the library named library when linking...... The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a. The linker then uses this file as if it had been specified precisely by name.
EDIT:
To quote the remaining part of the same manual
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.
So, you need to put the -l<libanme> at the last of your compilation statement, as s_echo.c uses functions defined in that particular library.

Why do I need to include .o files when compiling?

When I compiled my program and ran it, I got a a symbol lookup error. I was doing this:
$ gcc -o parts parts.c -lnettle
$ ./parts
$ ./parts: symbol lookup error: ./parts: undefined symbol: nettle_pbkdf2
My code included these header files:
#include <nettle/pbkdf2.h>
#include <nettle/hmac.h>
#include <pbkdf2-hmac-sha1.c>
I solved my problem by including the object files for the two included header files during gcc compilation.
$ gcc -o parts parts.c hmac.o pbkdf2.o -lnettle
The thing is, I don't understand what is going on and therefore why this works. Why must I include the .o files and not just the header files to avoid symbol lookup or undefined reference errors?
As Tobias mentioned, a header file tells the compiler what is done, the object file tells the compiler how it is done. You can see here what an object file is, but in reality it's just a precompiled version of a source file.
Truly, you were not actually getting compiler errors, but linker errors. It knew how to compile your source file, but it couldn't put everything together until it got the other object files.

Building object files that depends on other object files

EDITS: Including link to my makefile
I have a main program that calls a bunch of functions defined in other source files. This is not a problem because I am using cc -c functionSource.c functionHeader.h and generating object files before compiling my main program with cc main.c func1.o func2.o .... -o test.o
I am having problems when one of my functions depends on another function.
For example:
My main program calls an shuffle function which is defined in it's own source file and the shuffle function calls a swap function which in turn is defined in it's own source file.
When i try to generate the shuffle.o file for my main program using cc -c shuffle.o I get an undefined reference to swap error.
When I try to cc shuffle.c swap.o i get an undefined reference to main error.
Here is my makefile
How do I go about fixing this?
Found the problem. I had a swap function declared inside insertionSort.h and shuffle.h but no implementations.
Have a look to the man page: '-c' makes the compiler generating object files only (not trying to link).
Do the following:
cc -c insertionSort.c # => gives insertionSort.o
cc -c -c functionSource.c # => gives functionSource.o
cc insertionSort.o functionSource.o ...and-so-on... main.c -o test
It's not necessary to specify header files - it doesn't help.
BTW: If you have mor than one implementation file, it is rather useful
(a) to learn make
(b) stick to the convention that object files and programs should be named like th sources.
E.g:
foo.c => foo.o
bar.c => bar
etc - you get the picture.
This has nothing to do with make. You need to get a book on introductory C programming, that will explain how to use the preprocessor, and you need to examine the documentation for your compiler so you understand what the different compiler flags do (such as when you want to use the -c flag and when you don't, and what the difference is).
It's wrong to include header files (.h files) on the compile line. Only source files (.c) should be included on the command line when building object (.o) files. You should be adding the headers you need into your .c files using the #include directive: #include "insertionSort.h". If you're missing a reference to a function, then #include the header file that declares that function: #include "swap.h".

Resources