Why while using makefile I receive undefined reference error? - c

I created the following makefile:
assembler: main.o first_pass.o second_pass.o helpers.o data_array.o symbol_table.o
gcc -Wall -ansi -pedantic main.o first_pass.o second_pass.o helpers.o data_array.o symbol_table.o -o assembler
main.o: main.c header.h
gcc -Wall -ansi -pedantic main.c -o main.o
first_pass.o: first_pass.c header.h
gcc -Wall -ansi -pedantic first_pass.c -o first_pass.o
second_pass.o: second_pass.c header.h
gcc -Wall -ansi -pedantic second_pass.c -o second_pass.o
helpers.o: helpers.c header.h data.h
gcc -Wall -ansi -pedantic helpers.c -o helpers.o
data_array.o: data_array.c header.h data.h
gcc -Wall -ansi -pedantic data_array.c -o data_array.o
symbol_table.o: symbol_table.c header.h data.h
gcc -Wall -ansi -pedantic symbol_table.c -o symbol_table.o
In my 'main.c' file I have #include "header.h". Where in 'header.h' I have the declarations of all the functions.
But I receive the following error:
gcc -Wall -ansi -pedantic main.c -o main.o
/tmp/cc3dP7hx.o: In function `main':
main.c:(.text+0x257): undefined reference to `first_pass`
main.c:(.text+0x2e4): undefined reference to `second_pass'
main.c:(.text+0x37f): undefined reference to build_obj_file
main.c:(.text+0x3a9): undefined reference to build_ent_file
main.c:(.text+0x427): undefined reference to free_all_data
main.c:(.text+0x436): undefined reference to free_all_symbols
main.c:(.text+0x44d): undefined reference to free_all_words
collect2: error: ld returned 1 exit status
makefile:4: recipe for target 'main.o' failed
make: *** [main.o] Error 1

The problem is that your command doesn't create object files, but attempt to build executable programs:
gcc -Wall -ansi -pedantic main.c -o main.o
You need the -c option to create object files:
gcc -Wall -pedantic main.c -c -o main.o
A better idea would be to rely on the make implicit rules so you don't have to explicitly list all commands:
CC = gcc
LD = gcc
CFLAGS = -Wall -pedantic
LDFLAGS =
assembler: main.o first_pass.o second_pass.o helpers.o data_array.o symbol_table.o
You might want to add rules for the header-file dependencies, or figure out some way to auto-generate them (it's possible). Other than that the above Makefile should be enough to build all object files and then link them together into the assembler executable program.
Note that I have removed the -ansi flag, as it's mostly obsolete these days.

Related

error: cannot specify -o when generating multiple output files

How to fix this error?
I am trying to compile the C project, but I get such error
Alekseys-MBP:mmn14 aleksey$ make
gcc -Wall -ansi -pedantic -c -o assembler.o assembler.c
gcc -Wall -ansi -pedantic -c -o utils.o utils.c
gcc -Wall -ansi -pedantic -c -o symbol_table.o symbol_table.c
gcc -Wall -ansi -pedantic -c -o file_scan.o file_scan.c
file_scan.c:323:2: warning: no newline at end of file [-Wnewline-eof]
}
^
1 warning generated.
gcc -Wall -ansi -pedantic -c -o data_block.o data_block.c
gcc -Wall -ansi -pedantic -c -o commands.o commands.c
gcc -Wall -ansi -pedantic assembler.o utils.o symbol_table.o file_scan.o utils.h data_block.o commands.o -o assembler
clang: error: cannot specify -o when generating multiple output files
make: *** [assembler] Error 1
there is my makefile
EXEC_FILE = assembler
C_FILES = assembler.c utils.c symbol_table.c file_scan.c utils.h data_block.c commands.c
H_FILES = common.h symbol_table.h data_block.h commands.h file_scan.h
O_FILES = $(C_FILES:.c=.o)
all: $(EXEC_FILE)
$(EXEC_FILE): $(O_FILES)
gcc -Wall -ansi -pedantic $(O_FILES) -o $(EXEC_FILE)
%.o: %.c $(H_FILES)
gcc -Wall -ansi -pedantic -c -o $# $<
clean:
rm -f *.o $(EXEC_FILE)
What am I doing wrong?
This list of C files:
C_FILES = assembler.c utils.c symbol_table.c file_scan.c utils.h data_block.c commands.c
contains a header, file utils.h.
When this statement:
O_FILES = $(C_FILES:.c=.o)
constructs the list of object files, the substitution .c=.o does not alter utils.h, which results in O_FILES containing a header file. Then this build command:
gcc -Wall -ansi -pedantic $(O_FILES) -o $(EXEC_FILE)
asks GCC to do its default actions with the files, which is to link the object files and write an executable file and to “precompile” (analyze) the header file and write a “precompiled header” data file. Thus, you have two output files.
To fix this, remove utils.h from C_FILES and put it in H_FILES.

undefined reference for inline function [duplicate]

I am getting a really odd error from GCC 4.8.1 with inline functions.
I have two near-identical inline functions defined in header files (debug.h and error.h) in src/include/, with the only difference being what they print - one prefixes DEBUG: to the message, and the other %s: error: %s (program name, error message). When defining the functions both inline, and compiling a debug build (so it sets the macro DEBUG=1), I get lots of undefined reference errors:
src/main_debug.o
gcc -osrc/main_debug.o src/main.c -c -Wall -Wextra -Wpedantic -std=gnu11 -march=native -Og -g -DCC="\"gcc\"" -DCFLAGS="\"-Wall -Wextra -Wpedantic -std=gnu11 -march=native -Og -g\"" -DDEBUG=1 -DBTCWATCH_VERSION="\"0.0.1\""
src/lib/btcapi_debug.o
gcc -osrc/lib/btcapi_debug.o src/lib/btcapi.c -c -Wall -Wextra -Wpedantic -std=gnu11 -march=native -Og -g -DCC="\"gcc\"" -DCFLAGS="\"-Wall -Wextra -Wpedantic -std=gnu11 -march=native -Og -g\"" -DDEBUG=1
src/lib/libbtcapi_debug.a
ar rc src/lib/libbtcapi_debug.a src/lib/btcapi_debug.o
ranlib src/lib/libbtcapi_debug.a
src/lib/cmdlineutils_debug.o
gcc -o src/lib/cmdlineutils_debug.o src/lib/cmdlineutils.c -c -Wall -Wextra -Wpedantic -std=gnu11 -march=native -Og -g -DCC="\"gcc\"" -DCFLAGS="\"-Wall -Wextra -Wpedantic -std=gnu11 -march=native -Og -g\"" -DDEBUG=1
src/lib/libcmdlineutils_debug.a
ar rc src/lib/libcmdlineutils_debug.a src/lib/cmdlineutils_debug.o
ranlib src/lib/libcmdlineutils_debug.a
debug
gcc -obtcwatch-debug src/main_debug.o -Lsrc/lib/ -lbtcapi_debug -lcmdlineutils_debug -lcurl -ljansson
src/main_debug.o: In function `main':
/home/marcoms/btcwatch/src/main.c:148: undefined reference to `debug'
src/main_debug.o:/home/marcoms/btcwatch/src/main.c:185: more undefined references to `debug' follow
collect2: error: ld returned 1 exit status
make: *** [debug] Error 1
But changing debug()'s definition to static inline removes the errors. But I have never received any errors from error()'s definition, although its defenition is inline, and not static inline.
The definitions are all in headers (i.e. not prototyped)
According to the manual, passing -std=gnu11 enables C99 instead of GNU inline semantics.
This means inline, static inline and extern inline all behave differently. In particular, inline expects an external definition in a separate translation unit (which you can provide without duplicating the definition - see this answer).

Makefile Giving Duplicate Error C

I have created a makefile to run 9 programs simultaneously.
The names of the 9 programs are init_aim.c, register.c, sort.c, schedule.c, add.c, class_schedule.c, class_list.c, grade.c, and report.c.
In each of the files I have implemented the code:
#include "aim.h"
int main(){
return 0;
}
I also have a header file with the code
#ifndef AIM_H
#define AIM_H
#endif
My only goal is to get my makefile working. And also add the "all:" rule. My current makefile looks like this.
AIS: init_aim.o register.o sort.o schedule.o add.o class_schedule.o
class_list.o grade.o report.o
gcc -Wall -ansi -pedantic init_aim.o register.o sort.o
schedule.o add.o class_schedule.o class_list.o grade.o report.o -o AIS
init_aim.o: init_aim.c aim.h
gcc -Wall -ansi -pedantic -c init_aim.c -o init_aim.o
register.o: register.c aim.h
gcc -Wall -ansi -pedantic -c register.c -o register.o
sort.o: sort.c aim.h
gcc -Wall -ansi -pedantic -c sort.c -o sort.o
schedule.o: schedule.c aim.h
gcc -Wall -ansi -pedantic -c schedule.c -o schedule.o
add.o: add.c aim.h
gcc -Wall -ansi -pedantic -c add.c -o add.o
class_schedule.o: class_schedule.c aim.h
gcc -Wall -ansi -pedantic -c class_schedule.c -o
class_schedule.o
class_list.o: class_list.c aim.h
gcc -Wall -ansi -pedantic -c class_list.c -o class_list.o
grade.o: grade.c aim.h
gcc -Wall -ansi -pedantic -c grade.c -o grade.o
report.o: report.c aim.h
gcc -Wall -ansi -pedantic -c report.c -o report.o
Please keep in mind the spacing does not look proper on here because there is too much code.
When I run make I get:
gcc -Wall -ansi -pedantic -c init_aim.c -o init_aim.o
gcc -Wall -ansi -pedantic -c register.c -o register.o
gcc -Wall -ansi -pedantic -c sort.c -o sort.o
gcc -Wall -ansi -pedantic -c schedule.c -o schedule.o
gcc -Wall -ansi -pedantic -c add.c -o add.o
gcc -Wall -ansi -pedantic -c class_schedule.c -o class_schedule.o
gcc -Wall -ansi -pedantic -c class_list.c -o class_list.o
gcc -Wall -ansi -pedantic -c grade.c -o grade.o
gcc -Wall -ansi -pedantic -c report.c -o report.o
gcc -Wall -ansi -pedantic init_aim.o register.o sort.o schedule.o add.o
class_schedule.o class_list.o grade.o report.o -o AIS
clang: warning: argument unused during compilation: '-ansi' [-Wunused-
command-line-argument]
duplicate symbol _main in:
init_aim.o
register.o
duplicate symbol _main in:
init_aim.o
sort.o
duplicate symbol _main in:
init_aim.o
schedule.o
duplicate symbol _main in:
init_aim.o
add.o
duplicate symbol _main in:
init_aim.o
class_schedule.o
duplicate symbol _main in:
init_aim.o
class_list.o
duplicate symbol _main in:
init_aim.o
grade.o
duplicate symbol _main in:
init_aim.o
report.o
ld: 8 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see
invocation)
make: *** [AIS] Error 1
If anyone knows how to solve the duplicate error and add the "all:" command please let me know.
You have defined main() in each code file.
main() is the "start here" point for the executable you are trying to create.
The build fails because of multiple "start here" points.
To put it differently:
You can only have a single main() in a single executable.
You might be thinking of multithread programming.
In that case you need to do some research on the topic.
You might be thinking of running multiple programs from shell.
In that case you need to create multiple executables and start them separatly with the appropriate shell features, e.g. for background execution.
If you are writing nine separate programs you shouldn't try to link them all together at the end. I think this is what you want
all: init_aim register sort schedule add class_schedule class_list grade report
init_aim: init_aim.c aim.h
gcc -Wall -ansi -pedantic init_aim.c -o init_aim
register: register.c aim.h
gcc -Wall -ansi -pedantic register.c -o register
...
I removed -c, removed .o and added the all rule.

C makefile errors

I have a custom header file example.h which has prototypes for a few functions. There is a .C file example.c that I implemented which "includes" (#include "example.h") and has the implementations of the functions that has prototype in example.h. Now, I have another function test.c that calls the functions that are prototyped in example.h and defined in example.c.
My make file is as follows
test: test.o
gcc -o test -g test.o
test.o: test.c example.c example.h
gcc -g -c -Wall test.c
gcc -g -c -Wall example.c
clean:
rm -f *.o test
I get following message for the functions that are defined in example.c
Undefined first referenced
symbol in file
function1 test.o
function2 test.o
function3 test.o
function4 test.o
ld: fatal: Symbol referencing errors. No output written to test
collect2: ld returned 1 exit status
* Error code 1
make: Fatal error: Command failed for target `test'
Any help is most appreciated.
%.o: %.c
gcc -c -g -o $# $^
test: test.o example.o
gcc -o -g $# $^
%.o: %.c This means any *.o file should be builded from its equivalen from c files.
example test.o should be builded from test.c and example.o should be builded from example.c
First of all, you must include the example.o file when generating the executable file : gcc -o test example.o test.o. Then, the dependencies you wrote for target test.o are incorrect. You should split it like this :
test: test.o example.o
gcc -o test test.o example.o
test.o: test.c
gcc -c -Wall test.c
example.o: example.c
gcc -c -Wall example.c
Then, consider the use of variables to store the names of your object files, the flags you want to pass to the linker/compiler etc... This would make your life much easier.
test.o: test.c example.c example.h
gcc -g -c -Wall test.c
gcc -g -c -Wall example.c
as per your code test.o target is calling test.c example.c example.h target which i am not able to see.

function in one shared library calling a function in another shared library

I have a shared library say libfile2.so (which contains print2() function definition). Now I create a libfile1.so (which contains print1() function definition which in turn calls print2() function in libfile2.so). Now I create a main.c file which contains main() function which calls print1() by dynamically linking libfile1.so.
But I am getting the following error:
./libfile1.so: undefined reference to `print2'**
The following are the commands that I am using:
gcc -c -fpic file1.c
gcc -shared -o libfile1.so file1.o
gcc -c -fpic file2.c
gcc -shared -o libfile2.so file2.o
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
gcc -I. -L. -o main main.c -lfile1
If you have called only print1 in your main.c. Then set the path of the libfile2.so in the LD_LIBRARY_PATH. Because it will try to find the dependencies of libfile1.so while linking with main.c.
gcc -o file1.o -c file.c
gcc -o file2.o -c file.c
gcc -o libfile2.so file2.o -shared
gcc -o libfile1.so file1.o -L. -lfile2 -shared
gcc -o main.o -c main.c
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
gcc -o main.exe main.o -L. -lfile1
If you have called both print1 and print2 in main.c then link both libfile1.so and libfile2.so like below.
gcc -o main.o -c main.c
gcc -o main.exe main.o -L$YOUR_LIB_PATH -lfile1 -lfile2
Because all the symbol used in main.c needs to be resolved while generating executable.

Resources