I would apreciate any insights to a couple of linker and compiler issues I have
I have main.c file
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "assemble.h"
char *fileName;
FILE *file;
int main(int argc, char *argv[]){
char inputFile[MAX_INPUT];
int i, flag = TRUE;
for(i=1; i<argc; i++){
fileName = argv[i];
strcpy(inputFile,argv[i]);
file = fopen(inputFile,"r");
}
flag = assemble(file, fileName); //****this is the problam line****
if(!flag)
printf("Errors found, compilation aborted\n");
else
printf("File %s compiled\n", fileName);
fclose(file);
return 0;
}
In the header assemble.h I have the decleration:
int assemble(FILE *file, char *fileName);
The first issue is in main.c I get undefined referance to 'assemble', id returned 1 exit status
The second issue is in assemble.h I get FILE was not declared in this scope.
Does anyone know what causes these errors and what is the fix?
Thanks in advance
[EDIT]: the makefile.
assembler: main.o assemble.o functions.o
gcc -Wall -ansi -pedantic main.o assemble.o functions.o -o assembler -lm
main.o: main.c assemble.c
gcc -Wall -ansi -pedantic -c main.c assemble.c -lm
assemble.o: assemble.c
gcc -Wall -ansi -pedantic -c assemble.c -lm
functions.o: functions.c
gcc -Wall -ansi -pedantic -c functions.c -lm
clean:
rm -f assembler
rm -f *.o
You need to compile both files and link them together.
gcc main.c assemble.c
Or compile them separately to object files and link them.
gcc -c main.c
gcc -c assemble.c
gcc main.o assemble.o
Related
In my project, I have two libraries and one program.
Lib1.c and Lib1.h are two files of first library(Lib1.so).
Lib2.c and Lib2.h are two files of second library(Lib2.so).
prog.c is the main file of program(prog).
The program(prog) is linked only to the second library(Lib2.so) and the second library(Lib2.so) is linked to the first library(Lib1.so).
In Lib1.c, I have a declaration of global variable (int var = 0;) and in Lib1.h, I have a declaration (extern int var;).
In Lib2.h, I have a declaration (extern int var;) in order to use var variable in main program.
In main() function, I include the Lib2.h in prog.c file and I have a declaration (var = 5;)
Lib1.c :
#include <stdio.h>
#include "Lib1.h"
int var = 0;
int funct(void)
{
printf("hello world \n");
return 0;
}
Lib1.h :
extern int var;
int funct(void);
Lib2.c :
#include <stdio.h>
#include "Lib2.h"
int funct2(void)
{
printf("Library 2 \n");
funct();
return 0;
}
Lib2.h :
#include "Lib1.h"
extern int var;
int funct2(void);
prog.c :
#include <stdio.h>
#include "Lib2.h"
int main()
{
var = 5;
printf("===>var=%d\n", var);
funct2();
return 1;
}
Commands :
gcc -c -Wall -Werror -fpic Lib1.c
gcc -shared -o Lib1.so Lib1.o
gcc -c -Wall -Werror -fpic Lib2.c
gcc -shared -o Lib2.so Lib2.o -ldl /home/test/Lib1.so
gcc prog.c -o prog -ldl /home/test/Lib2.so
When I try to compile the program(prog.c), I get an error in the link step as below.
/usr/bin/ld: /tmp/ccKaq16a.o: undefined reference to symbol 'var'
/home/test/Lib1.so: error adding symbols: DSO missing from command line
Is there a way to use var variable in the main function when its defined in the first library?
You link your program against Lib2 but not Lib1. You need to add that as well. You also don't need to explicitly link Lib1 when you create Lib2
gcc -c -Wall -Werror -fpic Lib1.c
gcc -shared -o Lib1.so Lib1.o
gcc -c -Wall -Werror -fpic Lib2.c
gcc -shared -o Lib2.so Lib2.o
gcc prog.c -o prog /home/test/Lib2.so /home/test/Lib1.so
After a certain attempt to write a simple program with a main and one function,
I ask for your help to find the bug. I include the 3 files that are in action:
the main function in base.c
the function in fun.c
the makefile
The compiler says that the function is called in a bad way in the main:
undefined reference to `fun'
base.c
#include <stdio.h>
int fun(char c);
main()
{
printf("please enter a single char\n");
char c=getchar();
fun(c);
return 0;
}
fun.c
#include <stdio.h>
int fun(char c)
{
printf("%d3 is the value of your char!\n", 'c');
return 0;
}
makefile
charprint: base.o fun.o
gcc -g -Wall -ansi base.o fun.o -o charprint
base.o: base.c
gcc -g -Wall -ansi base.c -o base.o
fun.o: fun.c
gcc -g -Wall -ansi fun.c -o fun.o
The compilation problem is that you forgot the -c flags in the compiler line for base.o and fun.o. One obvious simple (but not very good) way to fix that is:
charprint: base.o fun.o
gcc -g -Wall -ansi base.o fun.o -o charprint
base.o: base.c
gcc -c -g -Wall -ansi base.c -o base.o
fun.o: fun.c
gcc -c -g -Wall -ansi fun.c -o fun.o
Interestingly, the simplest fix would be to delete the two compiler command for the two object files — make knows how to compile C files to object files. You could set CFLAGS += -Wall (or CFLAGS = -Wall) to get the (very important) -Wall flag included. Adding -Werror too would be good.
CFLAGS += -Wall -Werror -g -std=c11
charprint: base.o fun.o
${CC} ${CFLAGS} base.o fun.o -o $#
base.o: base.c
fun.o: fun.c
In the code for fun(), your argument to printf() should be just c and not 'c'. You probably also mean %3d rather than %d3 though that 'works'; it just doesn't do what you expect. Note that you should use an explicit int main(void) { … }. And you should probably create a header fun.h containing:
extern int fun(char c);
and #include "fun.h" in both source files, and add fun.h after the source file name in the dependency lines in the makefile:
CFLAGS += -Wall -Werror -g -std=c11
charprint: base.o fun.o
${CC} ${CFLAGS} base.o fun.o -o $#
base.o: base.c fun.h
fun.o: fun.c fun.h
In fact, you don't need to list the source files as dependencies for the object files; make will infer that dependency automatically. But you do need to specify the header file dependency.
There are 4 files:
helper.h //contains the signatures of functions in helper.c
helper.c //implements the signatures in helper.h
file.h //has all the includes needed to run file.h
file.c //this file includes file.h and helper.h
In file.c, I need to use the function that is defined in helper.c in my main function. However, file.c is saying that there is an undefined reference to 'func_found_in_helper.c'
Is this structure correct?
Yes, provided file.c contains
#include "helper.h"
and when building your program you link together helper.o and file.o.
You also need to ensure you compile each of the files with -c so that the compiler only compiles (and not links); do the link later with all the object files.
Here's a working example (I don't actually need a main.h but if you have one of those, #include it from main.c):
main.c
#include <stdio.h>
#include <stdlib.h>
#include "helper.h"
int
main (int argc, char **argv)
{
test ();
exit (0);
}
helper.c
#include <stdio.h>
void
test ()
{
printf ("Hello world\n");
}
helper.h
void test ();
To compile
gcc -Wall -Werror -c -o main.o main.c
gcc -Wall -Werror -c -o helper.o helper.c
To link
gcc -Wall -Werror -o test main.o helper.o
In a Makefile
test: main.o helper.o
gcc -Wall -Werror -o test main.o helper.o
%.o: %.c
gcc -c -Wall -Werror -o $# $<
clean:
rm -f *.o test
To run
$ ./test
Hello world
It's a bit difficult to tell what else might be wrong without the program; my guess is you simply forgot the -c flag to gcc, or forgot to link in helper.o.
undefined reference to 'func_found_in_helper.c'
That's a little odd, as it suggests you have tried to call the function using the '.c' extension, rather than just the function name. Maybe the '.' is just a typo in the question ?
Also a linker will flag an undefined symbol, so it may also be that you have not told the linker where to find helper.o ( the helper.c file compiled to the an object file ). The compiler will start the linker automatically. Did you compile helper.c first ?
I've been confused as to why this specific error is coming up.
The function being called looks the same so I don't think it is a type/case-sensitive error. I've included my makefile, the header in question, and the code snippet of the C file using the header + calling the function.
If anything else would be relevant I could supply it.
Thanks to anyone that helps!
game_state.h
#ifndef GAME_STATE_H
#define GAME_STATE_H
typedef struct Game_Condition_struct {
bool vertical_win;
bool down_diag_win;
bool up_diag_win;
char* player_char;
} GAME;
void Game_Over(BOARD* board);
void Win_Check(BOARD* board, GAME* game_condition);
#endif
moves.c snippet
#include "game_state.h"
... // other code above
else {
Make_Move(board, user_move, player_char);
Print_Board(board);
// IF-ELSE to change the player turn
if (*player_char == 'X') {
*player_char = 'O';
}
else {
*player_char = 'X';
}
Game_Over(board);
}
game_state.c
void Game_Over(BOARD* board) {
GAME game_condition;
Win_Check(board, &game_condition);
}
makefile
connectn.out: board.o main.o read_args.o moves.o game_state.o
gcc -g -Wall -o connectn.out board.o main.o read_args.o moves.o
main.o: board.h read_args.h moves.h game_state.h main.c
gcc -g -Wall -c -o main.o main.c
board.o: board.h board.c
gcc -g -Wall -c -o board.o board.c
read_args.o: read_args.h read_args.c
gcc -g -Wall -c -o read_args.o read_args.c
moves.o: moves.h board.h game_state.h moves.c
gcc -g -Wall -c -o moves.o moves.c
game_state.o: game_state.h board.h game_state.c
gcc -g -Wall -c -o game_state.o game_state.c
clean:
rm *.o *.out
The code works as I expect if I don't include the Game_Over(board) call, so I'm confused as to why it's not defined.
BOARD is a struct I made, similar to GAME.
You didn't link game_state.o into connectn.out. Add game_state.o to the end of the 2nd line of Makefile.
This is a sample program i was trying to compile this below c program to know about the
make file.
main.c
#include<stdio.h>
#include "reciprocal.h"
int main(int argc,char **argv){
int i;
i=atoi(argv[1]);
printf("The Reciprocal of %d is %f\n ",i,reciprocal(i));
return 0;
}
reciprocal.c
#include<stdio.h>
#include<assert.h>
#include "reciprocal.h"
double reciprocal(int i){
assert(i!=0);
return 1.0/i;
}
reciprocal.h
#include<stdio.h>
#ifdef __cplusplus
extern "C"{
#endif
extern double reciprocal(int i);
#ifdef __cplusplus
}
#endif
makefile
CFLAGS:=-o2
reciprocal: reciprocal.o main.o
gcc $(CFLAGS) -o reciprocal.o main.o
main.o: main.c reciprocal.h
gcc $(CFLAGS) -c main.c -I ../include
reciprocal.o: reciprocal.c reciprocal.h
gcc $(CFLAGS) -c reciprocal.c -I ../include
clean:
rm -f *.o reciprocal
when compiled as below it throws an error.
% make
gcc -o2 -c reciprocal.c -I ../include gcc -o2 -c main.c -I ../include
gcc -o2 -o reciprocal.o main.o main.o: In function main':
main.c:(.text+0x25): undefined reference toreciprocal' collect2: ld
returned 1 exit status make: * [reciprocal] Error 1
Please help me understand what is the reason for this error.
Change your makefile:
reciprocal: reciprocal.o main.o
gcc $(CFLAGS) -o reciprocal reciprocal.o main.o
^^^^^^^^^^
Alternatively:
reciprocal: reciprocal.o main.o
gcc $(CFLAGS) -o $# $^
You have an insidious typo:
CFLAGS:=-o2
That should have been -O2 with a capital O, this way you redirect the output of every compilation to the file 2.