Library linkage in makefile using gfortran - linux

I have a fortran code (pardiso_1.f) and it needs some libraries (BLAS, lapack and Pardiso libraries) to be compiled. When I try to compile it, I link libraries before compilation and I write this line in linux terminal:
gfortran pardiso_1.f -L/home/behnam/Pardiso -lpardiso412-GNU450-X86-64 -L/usr/lib -lblas -llapack -fopenmp
and it works perfectly.
However I have to run the code using makefile. I am so new in writing makefiles and I do not know how to do the linkage. I have written this makefile. could anyone help me to find out what is wrong with that?
FC = gfortran
OPT = -O2
PROGRAMS = pardiso_1
all: $(PROGRAMS)
FFLAGS = -fopenmp
#### BLAS, LAPACK and PTHREAD libraries
LBLAS = /usr/lib/
###location of pardiso file
LIBMKL = /home/behnam/PS2/
#### Series of libraries
LIBRARIES= -llapack -lblas -lpthread -lm -lpardiso412-GNU430-X86-64
PATHFC = /usr/bin/
nlace: ${PATHFC}${FC} ${OPT} ${FFLAGS} -I${PROGRAMS} -o nlace.exe \
-L${LIBMKL} -lpardiso412-GNU430-X86-64\
-L${LBLAS} ${LIBRARIES}
clean:
rm -f *.o *.exe fort.* *~ *.mod
veryclean: clean
rm -f *~ $(PROGRAMS)
The errors are:
behnam#meen-392430:~/testing$ make
make: Warning: File `Makefile' has modification time 23 s in the future
gfortran -fopenmp pardiso_1.f -o pardiso_1
/tmp/ccYNexaH.o: In function `MAIN__':
pardiso_1.f:(.text+0xb3): undefined reference to `pardisoinit_'
pardiso_1.f:(.text+0x2ae): undefined reference to `pardiso_chkmatrix_'
pardiso_1.f:(.text+0x36e): undefined reference to `pardiso_chkvec_'
pardiso_1.f:(.text+0x44c): undefined reference to `pardiso_printstats_'
pardiso_1.f:(.text+0x5ae): undefined reference to `pardiso_'
pardiso_1.f:(.text+0x860): undefined reference to `pardiso_'
pardiso_1.f:(.text+0xb78): undefined reference to `pardiso_'
pardiso_1.f:(.text+0xe00): undefined reference to `pardiso_'
collect2: ld returned 1 exit status
make: *** [pardiso_1] Error 1

Your makefile does not contain the -L/home/behnam/Pardiso part of your command line.

Your rule for PROGRAMS does not contain a recipe that includes the library calls. I presume you want something like your nlace rule, but right now, make is not calling any of your -L switches as part of its operation.

Related

Link a C .o file before a shared .so in Rust

My Rust main function depends on a C object file foo.o, which depends on a C shared library libbar.so.
I need to link foo.o before libbar.so in Rust,
I tried rust-link-lib=foo. It only works for libraries that begin with lib and end with .so or .a.
I tried rust-link-arg=foo.o and rust-link-lib=bar. It puts foo.o after -lbar, which results in an undefined reference error.
Compile the C .o and .so files,
gcc -c foo.c
gcc -fPIC -shared -o libbar.so bar.c
Linking in gcc succeeds,
gcc main.c -o main foo.o -L./ -lbar
LD_LIBRARY_PATH=./ ./main
Linking in rust
cargo run
failed with
= note: /usr/bin/ld: foo.o: in function `foo':
foo.c:(.text+0x10): undefined reference to `bar'
collect2: error: ld returned 1 exit status
Sample code here.
Thank you for your help.

Cliclock CC Build Error 'undefined reference' [duplicate]

I'm trying to compile my project and I use the lib ncurse. And I've got some errors when compiler links files.
Here is my flags line in Makefile:
-W -Wall -Werror -Wextra -lncurses
I've included ncurses.h
Some layouts :
prompt$> dpkg -S curses.h
libslang2-dev:amd64: /usr/include/slcurses.h
libncurses5-dev: /usr/include/ncurses.h
libncurses5-dev: /usr/include/curses.h
prompt$> dpkg -L libncurses5-dev | grep .so
/usr/lib/x86_64-linux-gnu/libncurses.so
/usr/lib/x86_64-linux-gnu/libcurses.so
/usr/lib/x86_64-linux-gnu/libmenu.so
/usr/lib/x86_64-linux-gnu/libform.so
/usr/lib/x86_64-linux-gnu/libpanel.s
And here are my erros :
gcc -W -Wall -Werror -Wextra -I./Includes/. -lncurses -o Sources/NCurses/ncurses_init.o -c Sources/NCurses/ncurses_init.c
./Sources/NCurses/ncurses_init.o: In function `ncruses_destroy':
ncurses_init.c:(.text+0x5): undefined reference to `endwin'
./Sources/NCurses/ncurses_init.o: In function `ncurses_write_line':
ncurses_init.c:(.text+0xc5): undefined reference to `mvwprintw'
./Sources/NCurses/ncurses_init.o: In function `ncurses_init':
ncurses_init.c:(.text+0xee): undefined reference to `initscr'
collect2: error: ld returned 1 exit status
Thanks a lot
You need to change your makefile so that the -lncurses directive comes after your object code on the gcc command line, i.e. it needs to generate the command:
gcc -W -Wall -Werror -Wextra -I./Includes/. -o Sources/NCurses/ncurses_init.o -c Sources/NCurses/ncurses_init.c -lncurses
This is because object files and libraries are linked in order in a single pass.
In C++ , I fixed it just by linking the ncurses library .
Here is the command :
g++ main.cpp -lncurses
I got flags to correct order by using LDLIBS variable:
ifndef PKG_CONFIG
PKG_CONFIG=pkg-config
endif
CFLAGS+=-std=c99 -pedantic -Wall
LDLIBS=$(shell $(PKG_CONFIG) --libs ncurses)
man gcc | grep -A10 "\-l library"
-l library
Search the library named library when linking. (The second alternative with the library as a separate argument is only for POSIX
compliance and is not recommended.)
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.

Error compiling with gfortran/gcc: crt1.o: In function `_start'

I'm executing this makefile to compile a Fortran code using gfortran, gcc, netcdf and mpich2 libraries.
When the make script executes the following command,
gfortran -O3 -I/home/santiago/Install/mpich2_sam/include -I/home/santiago/Install/netcdf_sam/include /home/santiago/Modeling/SAM6.8.2/SRC/fft.f
I get the following message:
/usr/lib/gcc/x86_64-redhat-linux/4.8.3/../../../../lib64/crt1.o: In
function _start': (.text+0x20): undefined reference tomain'
collect2: error: ld returned 1 exit status
I have found similar error messages in forums, but I didn't saw how to apply the solutions in my problem.
Could someone please guide me solving this problem?
If you are building a library, you might need -c flag in
.f.o:
${FF77} ${FFLAGS} $<
i.e.
.f.o:
${FF77} ${FFLAGS} -c $<
The same applies for
.f90.o:
${FF90} ${FFLAGS} -c $<
.c.o:
${CC} ${CFLAGS} -I$(SAM_SRC)/TIMING $(NOTIMERS) -c $<

strange g++ linking behavior depending on arguments order

I was trying to compile a simple opengl program on msys using g++. To my surprise the linker was complaining on undefined references:
$ g++ -mwindows -lopengl32 glut_md2.cpp
C:\Users\...\cceQtYAy.o:glut_md2.cpp:(.text+0x67a): undefined reference to `glGenTextures#8'
C:\Users\...\cceQtYAy.o:glut_md2.cpp:(.text+0x696): undefined reference to `glBindTexture#8'
....
After googling for a while I found that the problem was in g++ arguments order:
$ g++ glut_md2.cpp -mwindows -lopengl32
--- all ok! ---
The interesting thing is that the correct argument orders in g++ is in the first example. That is:
$ g++ --help
Usage: g++.exe [options] file...
....
Am I missing something? Why moving options after the file argument makes a compilation success? I never had this issue when compiling natively on linux...
I bumped into this problem once or twice, you should put -L and -l at the end of command line. g++ doesn't link, it invokes ld and pass arguments, ld man:
The linker will search an archive only once, at the location where it
is specified on the command line. If the archive defines a symbol
which was undefined in some object which appeared before the archive
on the command line, the linker will include the appropriate file(s)
from the archive. However, an undefined symbol in an object appearing
later on the command line will not cause the linker to search the
archive again.
ld -o /lib/crt0.o hello.o -lc

How to include all objects of an archive in a shared object?

When compiling our project, we create several archives (static libraries), say liby.a and libz.a that each contains an object file defining a function y_function() and z_function(). Then, these archives are joined in a shared object, say libyz.so, that is one of our main distributable target.
g++ -fPIC -c -o y.o y.cpp
ar cr liby.a y.o
g++ -fPIC -c -o z.o z.cpp
ar cr libz.a z.o
g++ -shared -L. -ly -lz -o libyz.so
When using this shared object into the example program, say x.c, the link fails because of an undefined references to functions y_function() and z_function().
g++ x.o -L. -lyz -o xyz
It works however when I link the final executable directly with the archives (static libraries).
g++ x.o -L. -ly -lz -o xyz
My guess is that the object files contained in the archives are not linked into the shared library because they are not used in it. How to force inclusion?
Edit:
Inclusion can be forced using --whole-archive ld option. But if results in compilation errors:
g++ -shared '-Wl,--whole-archive' -L. -ly -lz -o libyz.so
/usr/lib/libc_nonshared.a(elf-init.oS): In function `__libc_csu_init':
(.text+0x1d): undefined reference to `__init_array_end'
/usr/bin/ld: /usr/lib/libc_nonshared.a(elf-init.oS): relocation R_X86_64_PC32 against undefined hidden symbol `__init_array_end' can not be used when making a shared object
/usr/bin/ld: final link failed: Bad value
Any idea where this comes from?
You could try (ld(2)):
--whole-archive
For each archive mentioned on the command line after the --whole-archive option, include every object file in the
archive in the link, rather than searching the archive for the required object files. This is normally used to turn
an archive file into a shared library, forcing every object to be included in the resulting shared library. This
option may be used more than once.
(gcc -Wl,--whole-archive)
Plus, you should put -Wl,--no-whole-archive at the end of the library list. (as said by Dmitry Yudakov in the comment below)

Resources