What is wrong with this makefile and how to fix it? - makefile

I have got 4 files: pass1.c , pass2.c, main.c and header1.h.
Each of these files, include the file header.h
I wrote the following makefile:
assembler: pass1.o pass2.o main.o
gcc pass1.o pass2.o -o assembler
pass1.o: pass1.c
gcc -c -ansi -Wall -pedantic pass1.c -o pass1.o
pass2.o: pass2.c
gcc -c -ansi -Wall -pedantic pass2.c -o pass2.o
main.o: main.c
gcc -c -ansi -Wall -pedantic main.c -o main.o
When I did make, I got the following error:
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
makefile:2: recipe for target 'assembler' failed
make: *** [assembler] Error 1
Note that I didn't write a function called 'start'.
What is the problem here and how can I fix it?

gcc pass1.o pass2.o -o assembler
should be
gcc main.o pass1.o pass2.o -o assembler
Rename main.c to assembler.c and your entire makefile can be condensed to
CFLAGS := -ansi -Wall -pedantic
objects := assembler.o pass1.o pass2.o
assembler: $(objects)
$(objects): header.h
assuming that cc on your system is a symlink to gcc.

Related

How do I link a archive file with C code?

I'm trying to link a static library archive file (libx/libx.a) with a C code. The library requires 2 flags (-lx -lpthread). After linking the static library my ultimate goal is to create a shared library. I have the following Make file,
rsa-engine: rsa/rsa.c rsa/bignum.c rsa/aes.c rsa/x509parse.c rsa/pem.c
gcc -fPIC -o rsa/rsa.o -c rsa/rsa.c
gcc -fPIC -o rsa/bignum.o -c rsa/bignum.c
gcc -fPIC -o rsa/aes.o -c rsa/aes.c
gcc -fPIC -o rsa/x509parse.o -c rsa/x509parse.c
gcc -fPIC -o rsa/pem.o -c rsa/pem.c
gcc -fPIC rsa-engine.c libx/libx.a -L.libx/ -lx -lpthread -o rsa-engine.o
gcc -shared -o librsa_engine.so -lcrypto rsa-engine.o rsa/rsa.o rsa/bignum.o rsa/aes.o rsa/x509parse.o rsa/pem.o
clean:
rm -f *.o rsa/*.o *.so rsa-engine
After using the make command it produces the following output,
/usr/bin/ld: cannot find -lx
collect2: error: ld returned 1 exit status
Makefile:2: recipe for target 'rsa-engine' failed
make: *** [rsa-engine] Error 1
I found similar questions here. But that did not help. Seems like I can't make the link work. Any help with what I'm doing wrong?
I would like to achieve the same result generated by the following command,
CC := gcc
CFLAGS := -Wall -g -MD -O2 -I ../
LDFLAGS := -lx -lpthread
tests_files := hello
all: $(tests_files)
hello: hello.o ../libx/libx.a
$(CC) $(CFLAGS) -static $(<) -L../libx/ $(LDFLAGS) -o $(#)
It seems that your libx.a is located in libx, yet -L references .libx directory. Anyway, since you reference libx/libx.a directly, you may skip both -L.libx/ -lx and it should link just fine.

script-file Not found by linker

when running a makefile, which includes a usage of
a script-file, I receive an error saying the linker doesn't find the script file.
When running the make file the output is as follows:
arm-none-eabi-gcc -g -Wall -Werror -c -o main.o main.c
arm-none-eabi-gcc -g -Wall -Werror -c -o misc.o misc.c
arm-none-eabi-gcc main.o misc.o misc.h -g -Wall -Werror -Wl,-Map=HOST.map -T=msp432p401r.lds -o HOST
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: cannot open linker script file =msp432p401r.lds: No such file or directory
collect2: error: ld returned 1 exit status
make: *** [Makefile:11: HOST] Error 1
The makefile content is:
#---- Variables (machine depending) --------
TARGET = HOST
CC = arm-none-eabi-gcc #gcc
CFLAGS = -g -Wall -Werror # compiler flags
LDFLAGS = -Wl,-Map=$(TARGET).map -T=msp432p401r.lds # linker flag
SOURCE = main.c misc.c misc.h
OBJS = $(SOURCE:.c=.o) # replace all c with o
#---- Targets -----------
$(TARGET): $(OBJS)
$(CC) $(OBJS) $(CFLAGS) $(LDFLAGS) -o $#
I have searched a lot for a solution for this issue, and tried various fixes, with no success.
The script file is located at the same location as the source files.
What can be the reason for not finding the file?
Thanks

Makefile Not Recognizing Object Make Directive

I am having issues getting my Makefile to compile a very simple main function, and I can't seem to find the issue. Here is my Makefile:
main: main.o Recursion.o
gcc -Wall -o main main.o Recursion.o
main.o: main.c Recursion.c
gcc -Wall -c main.c
Recursion.o: Recursion.c Recursion.h
gcc -Wall -c Recursion.c
clean:
rm main *.o
When I enter the make command in the UNIX terminal, this is the result I get:
-bash-4.2$ make
cc -c -o main.o main.c
cc -c -o Recursion.o Recursion.c
gcc -Wall -o main main.o Recursion.o
main.o: main.c Recursion.c
make: main.o:: Command not found
make: *** [Makefile:3: main] Error 127
-bash-4.2$
I cannot figure out what's wrong. It is generating the executable main, but I'm not sure what exactly the issue is on the command line. Any suggestions?
Makefiles are indentation-sensitive.
Try this:
main: main.o Recursion.o
gcc -Wall -o main main.o Recursion.o
main.o: main.c Recursion.c
gcc -Wall -c main.c
Recursion.o: Recursion.c Recursion.h
gcc -Wall -c Recursion.c
clean:
rm main *.o

how to build g++ Makefile

Last time i asked sth about how to use CLAPACK.
Using CLAPACK undefined reference error
After that i tried to separate everything for a larger project.
Now I have "blitzLA.cpp" "InterfaceCLAPACK.cpp" "InterfaceCLAPACK.hpp"
I could successfully make it work just by calling
g++ -Wall -g InterfaceCLAPACK.cpp blitzLA.cpp -llapack -lblas -lf2c -o blitzLA
But if I do the Makefile, it gives me some errors.. My makefile is shown below.
CC = g++
CFLAGS = -Wall -g
linker = -llapack -lblas -lf2c
blitzLA: blitzLA.o InterfaceCLAPACK.o
${CC} ${CFLAGS} InterfaceCLAPACK.o blitzLA.o -o blitzLA
blitzLA.o: blitzLA.cpp InterfaceCLAPACK.hpp
${CC} ${CFLAGS} ${linker} -c blitzLA.cpp
InterfaceCLAPACK.o: InterfaceCLAPACK.cpp InterfaceCLAPACK.hpp
${CC} ${CFLAGS} ${linker} -c InterfaceCLAPACK.cpp
clean:
rm -rf *.o blitzLA
I guess the problem is where do i leave "-llapack -lblas -lf2c"..Now i get the errors shown below.
g++ -Wall -g -llapack -lblas -lf2c -c blitzLA.cpp
g++ -Wall -g -llapack -lblas -lf2c -c InterfaceCLAPACK.cpp
g++ -Wall -g InterfaceCLAPACK.o blitzLA.o -o blitzLA
InterfaceCLAPACK.o: In function `quantfin::interfaceCLAPACK::SolveLinear(blitz::Array<double, 2>
bunch of things here..
/home/baozi/Dropbox/Linux/LinearAlgebra/InterfaceCLAPACK.cpp:64: undefined reference to `dgttrf_'
/home/baozi/Dropbox/Linux/LinearAlgebra/InterfaceCLAPACK.cpp:67: undefined reference to `dgttrs_'
collect2: error: ld returned 1 exit status
make: *** [blitzLA] Error 1
Where do i go wrong.. Help plz

Linking C program with C++ library (GCC 4.5+)

I was using gcc/g++ 4.4 to build my project, and now i'm trying to switch to gcc 4.5, but getting odd "undefined reference" errors when linking C program with C++ library. Here is my testcase:
source.c
#ifdef LIBRARY
extern "C" int one() {
return 1;
}
#else
#include <stdio.h>
int one();
int main() {
printf ("%i\n", one());
return 0;
}
#endif
Makefile
all: clean program
program: source.c library.so
$(CC) -L. -lrary -o $# $<
library.so: source.c
$(CXX) -shared -DLIBRARY -fPIC -o $# $<
.PHONY: clean
clean:
rm -f program library.so
Everything works fine while using GCC 4.4:
$ CXX=g++-4.4 CC=gcc-4.4 make
rm -f program library.so
g++-4.4 -shared -DLIBRARY -fPIC -o library.so source.c
gcc-4.4 -L. -lrary -o program source.c
But not working while using GCC 4.5:
$ CXX=g++-4.5 CC=gcc-4.5 make
rm -f program library.so
g++-4.5 -shared -DLIBRARY -fPIC -o library.so source.c
gcc-4.5 -L. -lrary -o program source.c
/tmp/ccC4kNHP.o: In function `main':
source.c:(.text+0xa): undefined reference to `one'
collect2: ld returned 1 exit status
make: *** [program] Error 1
Or GCC 4.6:
$ CXX=g++-4.6 CC=gcc-4.6 make
rm -f program library.so
g++-4.6 -shared -DLIBRARY -fPIC -o library.so source.c
gcc-4.6 -L. -lrary -o program source.c
/tmp/ccxNRNSS.o: In function `main':
source.c:(.text+0xa): undefined reference to `one'
collect2: ld returned 1 exit status
make: *** [program] Error 1
Anyone can shed a light on this issue?
PS: This one was built using 4.6:
$ nm -D library.so
w _Jv_RegisterClasses
0000000000201010 A __bss_start
w __cxa_finalize
w __gmon_start__
0000000000201010 A _edata
0000000000201020 A _end
00000000000005a8 T _fini
0000000000000458 T _init
000000000000055c T one
It is because of linker's --as-needed option being used i.e. the library is not linked until a symbol is actually found in the source which is part of the library. You should move your source files before linking in the compilation command. You could try changing your Makefile rule program from $(CC) -L. -lrary -o $# $< to $(CC) $< -L. -lrary -o $#. Or alternatively, you could pass --no-as-needed to the linker i.e. $(CC) -Wl,--no-as-needed -L. -lrary -o $# $<. The first method is better suited to be used.
Hope this helps!

Resources