[Edit: The question is flawed, the file I described as "main.c" was actually "main.cpp" and that it why I was having an issue, calling a C function from a C++ file. The question is thus incorrect and doesn't have an answer, but if you have this undefined symbol issue, also think about checking you're not mixing C & C++.]
I'm using uVision 5 to develop a firmware, however I can't get the linker to find one of my functions.
main.c :
#include "Test.h"
int main()
{
return three();
}
Test.h :
#ifndef TEST_H
#define TEST_H
int three();
#endif
Test.c
#include "Test.h"
int three()
{
return 3;
}
All those files are at the root of my project, I know they get compiled as if I introduce a syntax error in them, compiler reports an error.
Also looking at the map file produced, I see that three() was removed:
Removing test.o(i.three), (4 bytes).
For testing purposes, I had --no_remove to linker command line, map file now contains:
0x0002ba76 0x00000004 Code RO 1 i.three test.o
So obviously, the linker is well aware of my function, and will or won't remove it depending on flags.
Regardless, it reports:
.\build\uvision5\test.axf: Error: L6218E: Undefined symbol three() (referred from main.o).
Not enough information to list image symbols.
Flawed question, it was actually a case of mixing C/C++, in which case you'll get a symbol missing if you call a C function from C++ without declaring it extern C.
Related
Just a simple program, but I keep getting this compiler error. I'm using MinGW for the compiler.
Here's the header file, point.h:
//type for a Cartesian point
typedef struct {
double x;
double y;
} Point;
Point create(double x, double y);
Point midpoint(Point p, Point q);
And here's point.c:
//This is the implementation of the point type
#include "point.h"
int main() {
return 0;
}
Point create(double x, double y) {
Point p;
p.x = x;
p.y = y;
return p;
}
Point midpoint(Point p, Point q) {
Point mid;
mid.x = (p.x + q.x) / 2;
mid.y = (p.y + q.y) / 2;
return mid;
}
And here's where the compiler issue comes in. I keep getting:
testpoint.c: undefined reference to 'create(double x, double y)'
While it is defined in point.c.
This is a separate file called testpoint.c:
#include "point.h"
#include <assert.h>
#include <stdio.h>
int main() {
double x = 1;
double y = 1;
Point p = create(x, y);
assert(p.x == 1);
return 0;
}
I'm at a loss as to what the issue could be.
How are you doing the compiling and linking? You'll need to specify both files, something like:
gcc testpoint.c point.c
...so that it knows to link the functions from both together. With the code as it's written right now, however, you'll then run into the opposite problem: multiple definitions of main. You'll need/want to eliminate one (undoubtedly the one in point.c).
In a larger program, you typically compile and link separately to avoid re-compiling anything that hasn't changed. You normally specify what needs to be done via a makefile, and use make to do the work. In this case you'd have something like this:
OBJS=testpoint.o point.o
testpoint.exe: $(OBJS)
gcc $(OJBS)
The first is just a macro for the names of the object files. You get it expanded with $(OBJS). The second is a rule to tell make 1) that the executable depends on the object files, and 2) telling it how to create the executable when/if it's out of date compared to an object file.
Most versions of make (including the one in MinGW I'm pretty sure) have a built-in "implicit rule" to tell them how to create an object file from a C source file. It normally looks roughly like this:
.c.o:
$(CC) -c $(CFLAGS) $<
This assumes the name of the C compiler is in a macro named CC (implicitly defined like CC=gcc) and allows you to specify any flags you care about in a macro named CFLAGS (e.g., CFLAGS=-O3 to turn on optimization) and $< is a special macro that expands to the name of the source file.
You typically store this in a file named Makefile, and to build your program, you just type make at the command line. It implicitly looks for a file named Makefile, and runs whatever rules it contains.
The good point of this is that make automatically looks at the timestamps on the files, so it will only re-compile the files that have changed since the last time you compiled them (i.e., files where the ".c" file has a more recent time-stamp than the matching ".o" file).
Also note that 1) there are lots of variations in how to use make when it comes to large projects, and 2) there are also lots of alternatives to make. I've only hit on the bare minimum of high points here.
I had this issue recently. In my case, I had my IDE set to choose which compiler (C or C++) to use on each file according to its extension, and I was trying to call a C function (i.e. from a .c file) from C++ code.
The .h file for the C function wasn't wrapped in this sort of guard:
#ifdef __cplusplus
extern "C" {
#endif
// all of your legacy C code here
#ifdef __cplusplus
}
#endif
I could've added that, but I didn't want to modify it, so I just included it in my C++ file like so:
extern "C" {
#include "legacy_C_header.h"
}
(Hat tip to UncaAlby for his clear explanation of the effect of extern "C".)
I think the problem is that when you're trying to compile testpoint.c, it includes point.h but it doesn't know about point.c. Since point.c has the definition for create, not having point.c will cause the compilation to fail.
I'm not familiar with MinGW, but you need to tell the compiler to look for point.c. For example with gcc you might do this:
gcc point.c testpoint.c
As others have pointed out, you also need to remove one of your main functions, since you can only have one.
Add the "extern" keyword to the function definitions in point.h
I saw here that this question
In c programming language, i keep getting this error
has been answered here so the thread seems closed for answers.
I disagree. It is different code.
The answer should be that we don't know what is in custom header file "functions.h".
Also, we don't know what are
MAPA m;
POSICAO heroi;
Are these functions, constants?
If these were some constants, one should expect #define in front of them, and no semicolon e.g.
#define MAPA m
#define POSICAO heroi
If You intended to prototype the function, since there's is semicolon behing, than You did not insert the parentheses ().
In that case MAPA and POSICAO are some custom-type functions, whose content should be determined in "Functions.h"
Also, there's a possibilty that You wanted to import the functions or variable or constant from some other directory, and in that case You're missing the word
extern MAPA m;
I had a similar problem running a bunch of .c files in a directory all linking to one header file with custom function prototypes.
I ran:
$gcc -Wall -Werror -Wextra -pedantic -std=gnu89 *.c
Getting these errors:
/usr/bin/ld: /tmp/ccovH4zH.o: in function `_puts': 3-puts.c:(.text+0x2f): undefined reference to `_putchar'
/usr/bin/ld: 3-puts.c:(.text+0x51): undefined reference to `_putchar'
/usr/bin/ld: /tmp/ccGeWRqI.o: in function `main': _putchar.c:(.text+0xe): undefined reference to `_putchar'
/usr/bin/ld: _putchar.c:(.text+0x18): undefined reference to `_putchar'
/usr/bin/ld: _putchar.c:(.text+0x22): undefined reference to `_putchar'
/usr/bin/ld: /tmp/ccGeWRqI.o:_putchar.c:(.text+0x2c): more undefined references to `_putchar' follow
collect2: error: ld returned 1 exit status
Note: All files were linked to the same header file with all the function declarations.
I manage to compile successfully after adding -c option to the gcc compiler like:
$gcc -Wall -Werror -Wextra -pedantic -std=gnu89 -c *.c
This run successfully.
Just in case anyone comes across the same.
Just a simple program, but I keep getting this compiler error. I'm using MinGW for the compiler.
Here's the header file, point.h:
//type for a Cartesian point
typedef struct {
double x;
double y;
} Point;
Point create(double x, double y);
Point midpoint(Point p, Point q);
And here's point.c:
//This is the implementation of the point type
#include "point.h"
int main() {
return 0;
}
Point create(double x, double y) {
Point p;
p.x = x;
p.y = y;
return p;
}
Point midpoint(Point p, Point q) {
Point mid;
mid.x = (p.x + q.x) / 2;
mid.y = (p.y + q.y) / 2;
return mid;
}
And here's where the compiler issue comes in. I keep getting:
testpoint.c: undefined reference to 'create(double x, double y)'
While it is defined in point.c.
This is a separate file called testpoint.c:
#include "point.h"
#include <assert.h>
#include <stdio.h>
int main() {
double x = 1;
double y = 1;
Point p = create(x, y);
assert(p.x == 1);
return 0;
}
I'm at a loss as to what the issue could be.
How are you doing the compiling and linking? You'll need to specify both files, something like:
gcc testpoint.c point.c
...so that it knows to link the functions from both together. With the code as it's written right now, however, you'll then run into the opposite problem: multiple definitions of main. You'll need/want to eliminate one (undoubtedly the one in point.c).
In a larger program, you typically compile and link separately to avoid re-compiling anything that hasn't changed. You normally specify what needs to be done via a makefile, and use make to do the work. In this case you'd have something like this:
OBJS=testpoint.o point.o
testpoint.exe: $(OBJS)
gcc $(OJBS)
The first is just a macro for the names of the object files. You get it expanded with $(OBJS). The second is a rule to tell make 1) that the executable depends on the object files, and 2) telling it how to create the executable when/if it's out of date compared to an object file.
Most versions of make (including the one in MinGW I'm pretty sure) have a built-in "implicit rule" to tell them how to create an object file from a C source file. It normally looks roughly like this:
.c.o:
$(CC) -c $(CFLAGS) $<
This assumes the name of the C compiler is in a macro named CC (implicitly defined like CC=gcc) and allows you to specify any flags you care about in a macro named CFLAGS (e.g., CFLAGS=-O3 to turn on optimization) and $< is a special macro that expands to the name of the source file.
You typically store this in a file named Makefile, and to build your program, you just type make at the command line. It implicitly looks for a file named Makefile, and runs whatever rules it contains.
The good point of this is that make automatically looks at the timestamps on the files, so it will only re-compile the files that have changed since the last time you compiled them (i.e., files where the ".c" file has a more recent time-stamp than the matching ".o" file).
Also note that 1) there are lots of variations in how to use make when it comes to large projects, and 2) there are also lots of alternatives to make. I've only hit on the bare minimum of high points here.
I had this issue recently. In my case, I had my IDE set to choose which compiler (C or C++) to use on each file according to its extension, and I was trying to call a C function (i.e. from a .c file) from C++ code.
The .h file for the C function wasn't wrapped in this sort of guard:
#ifdef __cplusplus
extern "C" {
#endif
// all of your legacy C code here
#ifdef __cplusplus
}
#endif
I could've added that, but I didn't want to modify it, so I just included it in my C++ file like so:
extern "C" {
#include "legacy_C_header.h"
}
(Hat tip to UncaAlby for his clear explanation of the effect of extern "C".)
I think the problem is that when you're trying to compile testpoint.c, it includes point.h but it doesn't know about point.c. Since point.c has the definition for create, not having point.c will cause the compilation to fail.
I'm not familiar with MinGW, but you need to tell the compiler to look for point.c. For example with gcc you might do this:
gcc point.c testpoint.c
As others have pointed out, you also need to remove one of your main functions, since you can only have one.
Add the "extern" keyword to the function definitions in point.h
I saw here that this question
In c programming language, i keep getting this error
has been answered here so the thread seems closed for answers.
I disagree. It is different code.
The answer should be that we don't know what is in custom header file "functions.h".
Also, we don't know what are
MAPA m;
POSICAO heroi;
Are these functions, constants?
If these were some constants, one should expect #define in front of them, and no semicolon e.g.
#define MAPA m
#define POSICAO heroi
If You intended to prototype the function, since there's is semicolon behing, than You did not insert the parentheses ().
In that case MAPA and POSICAO are some custom-type functions, whose content should be determined in "Functions.h"
Also, there's a possibilty that You wanted to import the functions or variable or constant from some other directory, and in that case You're missing the word
extern MAPA m;
I had a similar problem running a bunch of .c files in a directory all linking to one header file with custom function prototypes.
I ran:
$gcc -Wall -Werror -Wextra -pedantic -std=gnu89 *.c
Getting these errors:
/usr/bin/ld: /tmp/ccovH4zH.o: in function `_puts': 3-puts.c:(.text+0x2f): undefined reference to `_putchar'
/usr/bin/ld: 3-puts.c:(.text+0x51): undefined reference to `_putchar'
/usr/bin/ld: /tmp/ccGeWRqI.o: in function `main': _putchar.c:(.text+0xe): undefined reference to `_putchar'
/usr/bin/ld: _putchar.c:(.text+0x18): undefined reference to `_putchar'
/usr/bin/ld: _putchar.c:(.text+0x22): undefined reference to `_putchar'
/usr/bin/ld: /tmp/ccGeWRqI.o:_putchar.c:(.text+0x2c): more undefined references to `_putchar' follow
collect2: error: ld returned 1 exit status
Note: All files were linked to the same header file with all the function declarations.
I manage to compile successfully after adding -c option to the gcc compiler like:
$gcc -Wall -Werror -Wextra -pedantic -std=gnu89 -c *.c
This run successfully.
Just in case anyone comes across the same.
Just a simple program, but I keep getting this compiler error. I'm using MinGW for the compiler.
Here's the header file, point.h:
//type for a Cartesian point
typedef struct {
double x;
double y;
} Point;
Point create(double x, double y);
Point midpoint(Point p, Point q);
And here's point.c:
//This is the implementation of the point type
#include "point.h"
int main() {
return 0;
}
Point create(double x, double y) {
Point p;
p.x = x;
p.y = y;
return p;
}
Point midpoint(Point p, Point q) {
Point mid;
mid.x = (p.x + q.x) / 2;
mid.y = (p.y + q.y) / 2;
return mid;
}
And here's where the compiler issue comes in. I keep getting:
testpoint.c: undefined reference to 'create(double x, double y)'
While it is defined in point.c.
This is a separate file called testpoint.c:
#include "point.h"
#include <assert.h>
#include <stdio.h>
int main() {
double x = 1;
double y = 1;
Point p = create(x, y);
assert(p.x == 1);
return 0;
}
I'm at a loss as to what the issue could be.
How are you doing the compiling and linking? You'll need to specify both files, something like:
gcc testpoint.c point.c
...so that it knows to link the functions from both together. With the code as it's written right now, however, you'll then run into the opposite problem: multiple definitions of main. You'll need/want to eliminate one (undoubtedly the one in point.c).
In a larger program, you typically compile and link separately to avoid re-compiling anything that hasn't changed. You normally specify what needs to be done via a makefile, and use make to do the work. In this case you'd have something like this:
OBJS=testpoint.o point.o
testpoint.exe: $(OBJS)
gcc $(OJBS)
The first is just a macro for the names of the object files. You get it expanded with $(OBJS). The second is a rule to tell make 1) that the executable depends on the object files, and 2) telling it how to create the executable when/if it's out of date compared to an object file.
Most versions of make (including the one in MinGW I'm pretty sure) have a built-in "implicit rule" to tell them how to create an object file from a C source file. It normally looks roughly like this:
.c.o:
$(CC) -c $(CFLAGS) $<
This assumes the name of the C compiler is in a macro named CC (implicitly defined like CC=gcc) and allows you to specify any flags you care about in a macro named CFLAGS (e.g., CFLAGS=-O3 to turn on optimization) and $< is a special macro that expands to the name of the source file.
You typically store this in a file named Makefile, and to build your program, you just type make at the command line. It implicitly looks for a file named Makefile, and runs whatever rules it contains.
The good point of this is that make automatically looks at the timestamps on the files, so it will only re-compile the files that have changed since the last time you compiled them (i.e., files where the ".c" file has a more recent time-stamp than the matching ".o" file).
Also note that 1) there are lots of variations in how to use make when it comes to large projects, and 2) there are also lots of alternatives to make. I've only hit on the bare minimum of high points here.
I had this issue recently. In my case, I had my IDE set to choose which compiler (C or C++) to use on each file according to its extension, and I was trying to call a C function (i.e. from a .c file) from C++ code.
The .h file for the C function wasn't wrapped in this sort of guard:
#ifdef __cplusplus
extern "C" {
#endif
// all of your legacy C code here
#ifdef __cplusplus
}
#endif
I could've added that, but I didn't want to modify it, so I just included it in my C++ file like so:
extern "C" {
#include "legacy_C_header.h"
}
(Hat tip to UncaAlby for his clear explanation of the effect of extern "C".)
I think the problem is that when you're trying to compile testpoint.c, it includes point.h but it doesn't know about point.c. Since point.c has the definition for create, not having point.c will cause the compilation to fail.
I'm not familiar with MinGW, but you need to tell the compiler to look for point.c. For example with gcc you might do this:
gcc point.c testpoint.c
As others have pointed out, you also need to remove one of your main functions, since you can only have one.
Add the "extern" keyword to the function definitions in point.h
I saw here that this question
In c programming language, i keep getting this error
has been answered here so the thread seems closed for answers.
I disagree. It is different code.
The answer should be that we don't know what is in custom header file "functions.h".
Also, we don't know what are
MAPA m;
POSICAO heroi;
Are these functions, constants?
If these were some constants, one should expect #define in front of them, and no semicolon e.g.
#define MAPA m
#define POSICAO heroi
If You intended to prototype the function, since there's is semicolon behing, than You did not insert the parentheses ().
In that case MAPA and POSICAO are some custom-type functions, whose content should be determined in "Functions.h"
Also, there's a possibilty that You wanted to import the functions or variable or constant from some other directory, and in that case You're missing the word
extern MAPA m;
I had a similar problem running a bunch of .c files in a directory all linking to one header file with custom function prototypes.
I ran:
$gcc -Wall -Werror -Wextra -pedantic -std=gnu89 *.c
Getting these errors:
/usr/bin/ld: /tmp/ccovH4zH.o: in function `_puts': 3-puts.c:(.text+0x2f): undefined reference to `_putchar'
/usr/bin/ld: 3-puts.c:(.text+0x51): undefined reference to `_putchar'
/usr/bin/ld: /tmp/ccGeWRqI.o: in function `main': _putchar.c:(.text+0xe): undefined reference to `_putchar'
/usr/bin/ld: _putchar.c:(.text+0x18): undefined reference to `_putchar'
/usr/bin/ld: _putchar.c:(.text+0x22): undefined reference to `_putchar'
/usr/bin/ld: /tmp/ccGeWRqI.o:_putchar.c:(.text+0x2c): more undefined references to `_putchar' follow
collect2: error: ld returned 1 exit status
Note: All files were linked to the same header file with all the function declarations.
I manage to compile successfully after adding -c option to the gcc compiler like:
$gcc -Wall -Werror -Wextra -pedantic -std=gnu89 -c *.c
This run successfully.
Just in case anyone comes across the same.
This question already has answers here:
What is the difference between a definition and a declaration?
(27 answers)
Closed 5 years ago.
I have two .c files, one of them has the definition of x, and the other file is using x, as follows:
file1.c:
int x;
//other code...
main.c:
int main(void)
{
printf("%d", x);
}
Now, when I compile this code, I get the following compilation error message:
In function 'main':
error: 'x' undeclared (first use in this function)
So, if a global variable (in this case x) is 'extern' by default, then why can't main.c file see x?
When I now go to main.c and define x, so that main.c now looks like:
int x=9; //This line was added.
int main(void)
{
printf("%d",x);
}
And also initialize x in file1.c, the program doesn't compile and I get the following error message:
error: ld returned 1 exit status
So, if main.c can't see x that is in file1.c, then this time what is the problem?
Is this a linking error?
Note that when I add
extern int x;
in main.c, the problem disappears.
Each compilation unit (in this case your individual .c files) is compiled separately. The compiler needs to know the storage class of x in order to handle it, so your first error (undeclared) comes from the compiler not knowing what x is. The compiler does not need to know where x lives.
When you then link your compiled objects together, the linker resolves any external names (including x in main.c if you've marked it extern) and the final executable will then have all its variables in known places. If it finds 2 extern symbols with the same name, then it will fail, giving you your second error (error: ld returned 1 exit status).
You must declare you variable in main.c, so the compiler knows about it: extern int x. The compiler said it to you: error: 'x' undeclared
You added the second definition of x in main.c, the first definition you did in file1.c. The linker informed you about ambiguity between two definitions. You could read the error above the line error: ld returned 1 exit status
Just a simple program, but I keep getting this compiler error. I'm using MinGW for the compiler.
Here's the header file, point.h:
//type for a Cartesian point
typedef struct {
double x;
double y;
} Point;
Point create(double x, double y);
Point midpoint(Point p, Point q);
And here's point.c:
//This is the implementation of the point type
#include "point.h"
int main() {
return 0;
}
Point create(double x, double y) {
Point p;
p.x = x;
p.y = y;
return p;
}
Point midpoint(Point p, Point q) {
Point mid;
mid.x = (p.x + q.x) / 2;
mid.y = (p.y + q.y) / 2;
return mid;
}
And here's where the compiler issue comes in. I keep getting:
testpoint.c: undefined reference to 'create(double x, double y)'
While it is defined in point.c.
This is a separate file called testpoint.c:
#include "point.h"
#include <assert.h>
#include <stdio.h>
int main() {
double x = 1;
double y = 1;
Point p = create(x, y);
assert(p.x == 1);
return 0;
}
I'm at a loss as to what the issue could be.
How are you doing the compiling and linking? You'll need to specify both files, something like:
gcc testpoint.c point.c
...so that it knows to link the functions from both together. With the code as it's written right now, however, you'll then run into the opposite problem: multiple definitions of main. You'll need/want to eliminate one (undoubtedly the one in point.c).
In a larger program, you typically compile and link separately to avoid re-compiling anything that hasn't changed. You normally specify what needs to be done via a makefile, and use make to do the work. In this case you'd have something like this:
OBJS=testpoint.o point.o
testpoint.exe: $(OBJS)
gcc $(OJBS)
The first is just a macro for the names of the object files. You get it expanded with $(OBJS). The second is a rule to tell make 1) that the executable depends on the object files, and 2) telling it how to create the executable when/if it's out of date compared to an object file.
Most versions of make (including the one in MinGW I'm pretty sure) have a built-in "implicit rule" to tell them how to create an object file from a C source file. It normally looks roughly like this:
.c.o:
$(CC) -c $(CFLAGS) $<
This assumes the name of the C compiler is in a macro named CC (implicitly defined like CC=gcc) and allows you to specify any flags you care about in a macro named CFLAGS (e.g., CFLAGS=-O3 to turn on optimization) and $< is a special macro that expands to the name of the source file.
You typically store this in a file named Makefile, and to build your program, you just type make at the command line. It implicitly looks for a file named Makefile, and runs whatever rules it contains.
The good point of this is that make automatically looks at the timestamps on the files, so it will only re-compile the files that have changed since the last time you compiled them (i.e., files where the ".c" file has a more recent time-stamp than the matching ".o" file).
Also note that 1) there are lots of variations in how to use make when it comes to large projects, and 2) there are also lots of alternatives to make. I've only hit on the bare minimum of high points here.
I had this issue recently. In my case, I had my IDE set to choose which compiler (C or C++) to use on each file according to its extension, and I was trying to call a C function (i.e. from a .c file) from C++ code.
The .h file for the C function wasn't wrapped in this sort of guard:
#ifdef __cplusplus
extern "C" {
#endif
// all of your legacy C code here
#ifdef __cplusplus
}
#endif
I could've added that, but I didn't want to modify it, so I just included it in my C++ file like so:
extern "C" {
#include "legacy_C_header.h"
}
(Hat tip to UncaAlby for his clear explanation of the effect of extern "C".)
I think the problem is that when you're trying to compile testpoint.c, it includes point.h but it doesn't know about point.c. Since point.c has the definition for create, not having point.c will cause the compilation to fail.
I'm not familiar with MinGW, but you need to tell the compiler to look for point.c. For example with gcc you might do this:
gcc point.c testpoint.c
As others have pointed out, you also need to remove one of your main functions, since you can only have one.
Add the "extern" keyword to the function definitions in point.h
I saw here that this question
In c programming language, i keep getting this error
has been answered here so the thread seems closed for answers.
I disagree. It is different code.
The answer should be that we don't know what is in custom header file "functions.h".
Also, we don't know what are
MAPA m;
POSICAO heroi;
Are these functions, constants?
If these were some constants, one should expect #define in front of them, and no semicolon e.g.
#define MAPA m
#define POSICAO heroi
If You intended to prototype the function, since there's is semicolon behing, than You did not insert the parentheses ().
In that case MAPA and POSICAO are some custom-type functions, whose content should be determined in "Functions.h"
Also, there's a possibilty that You wanted to import the functions or variable or constant from some other directory, and in that case You're missing the word
extern MAPA m;
I had a similar problem running a bunch of .c files in a directory all linking to one header file with custom function prototypes.
I ran:
$gcc -Wall -Werror -Wextra -pedantic -std=gnu89 *.c
Getting these errors:
/usr/bin/ld: /tmp/ccovH4zH.o: in function `_puts': 3-puts.c:(.text+0x2f): undefined reference to `_putchar'
/usr/bin/ld: 3-puts.c:(.text+0x51): undefined reference to `_putchar'
/usr/bin/ld: /tmp/ccGeWRqI.o: in function `main': _putchar.c:(.text+0xe): undefined reference to `_putchar'
/usr/bin/ld: _putchar.c:(.text+0x18): undefined reference to `_putchar'
/usr/bin/ld: _putchar.c:(.text+0x22): undefined reference to `_putchar'
/usr/bin/ld: /tmp/ccGeWRqI.o:_putchar.c:(.text+0x2c): more undefined references to `_putchar' follow
collect2: error: ld returned 1 exit status
Note: All files were linked to the same header file with all the function declarations.
I manage to compile successfully after adding -c option to the gcc compiler like:
$gcc -Wall -Werror -Wextra -pedantic -std=gnu89 -c *.c
This run successfully.
Just in case anyone comes across the same.