Including a static library in makefile - makefile

I have a directory structure
trunk
--lib--libParser.a
--objs
--src
--Makefile
I have the following makefile
CRYPTOLIB_TARGET = cryptolib.a
LOCALLIBS = ./objs
LOCALLIBS_IMAGE = ./cryptolib.a
CC = gcc
AR = ar
DEBUG_FLAGS =
LDEFSECOM_LOG_VERSION = -DSECOM_LOG_VERSION
CMPL_TIME_MACROS = -DENBL_DEBUG_PRINTF $(LDEFSECOM_LOG_VERSION)
ALLWARN =
ALL_INCS = -I./src/INCLUDE
LIBS = -lrt -laio -lrt -lpthread -lm -lpq -ldl
LINK = $(CC) $(DEBUG_FLAGS) $(CMPL_TIME_MACROS) $(ALLWARN) $(ALL_INCS) $(LIBS) -c
default = CRYPTOLIB_TARGET
CRYPTOLIB_OBJ = \
$(LOCALLIBS)/AES_crypt.o \
$(LOCALLIBS)/bigdigits.o \
$(LOCALLIBS)/DataEncryption.o \
$(LOCALLIBS)/SiaEncryption.o
$(CRYPTOLIB_TARGET): $(CRYPTOLIB_OBJ)
$(AR) r $(CRYPTOLIB_TARGET) $(CRYPTOLIB_OBJ)
$(LOCALLIBS)/AES_crypt.o : \
src/AES_crypt.c
mkdir -p ./objs
$(LINK) src/AES_crypt.c -o $(LOCALLIBS)/AES_crypt.o
$(LOCALLIBS)/bigdigits.o : \
src/bigdigits.c
$(LINK) src/bigdigits.c -o $(LOCALLIBS)/bigdigits.o
$(LOCALLIBS)/DataEncryption.o : \
src/DataEncryption.c
$(LINK) src/DataEncryption.c -o $(LOCALLIBS)/DataEncryption.o
$(LOCALLIBS)/SiaEncryption.o : \
src/SiaEncryption.c
$(LINK) src/SiaEncryption.c -o $(LOCALLIBS)/SiaEncryption.o
clean:
rm -rf objs
rm -rf cryptolib.a
I want to include the libParser.a in the output library which I am creating but I am not sure how to do that. Can you please give me the pointers to so that I can include the library(libParser.a) and create cryptolib.a as a final output library.

from gcc online docs:
-llibrary
-l library
...(text removed)...
Normally the files found this way are library files—archive files
whose members are object files. The linker handles an archive file by
scanning through it for members which define symbols that have so far
been referenced but not defined. But if the file that is found is an
ordinary object file, it is linked in the usual fashion. The only
difference between using an -l option and specifying a file name is
that -l surrounds library with ‘lib’ and ‘.a’ and searches several
directories.
So... you could specify the library include folder:
-L./lib
and put the libParser.a in the list of libraries (subracting 'lib' and '.a'):
-lParser -lrt -laio ...

Related

Problem when passing argument to Makefile

My Makefile looks like this:
OBJ = $(SRC:.c=.c.o) #yes it it should be renamed to .c.o, not .o
LIBS = -lchecl -lchecs -lchengine-dev -lglfw -lm -lGL -lGLEW -lcheio -lopenal -lfreetype
EXE = test
VER = -std=c99
MODE = -g
OPT = -O0
ERR = -Wall -Wuninitialized -Werror=implicit-function-declaration -Wextra -Wno-unused-parameter -Wno-incompatible-pointer-types -Werror=int-conversion -Wduplicated-cond -Wlogical-op -Wrestrict -Wnull-dereference -Wjump-misses-init -Wdouble-promotion -Wshadow -Wformat=2
LFLAGS = -o
CFLAGS = $(ERR) $(VER) $(OPT) -c $(MODE) `pkg-config --cflags freetype2`
run: $(EXE)
./$(EXE)
$(EXE): $(OBJ)
gcc $(LFLAGS) $(EXE) $(OBJ) $(LIBS)
%.o: %.c
gcc -c $(CFLAGS) $*.c
mv "$$(basename $*.o)" "$$(dirname $*)"
cleanall:
rm $(OBJ)
rm $(SRC)
And I am passing the SRC variable like this:
files=$(find . -type f -name '*.c.c')
make run SRC="$files"
But this gives the the following error:
make: *** No rule to make target 'src/setup.c
./states/mainMenuState.c
...
(a list of all source files)'
However if I manually copy the value of $files into the Makefile, writing SRC = and then the source files, it compiles just fine. If I write instead of OBJ = $(SRC:.c.c=.c.o) OBJ = $($(SRC):.c.c=.c.o) it seems to compile but not link correctly, because then I get this error:
//usr/local/lib/libchengine-dev.so: undefined reference to `vector_find'
//usr/local/lib/libchengine-dev.so: undefined reference to `che_init'
//usr/local/lib/libchengine-dev.so: undefined reference to `vector_destruct'
SRC is used in the definition of OBJ. But this can't be your real makefile, because it won't work. So something must be different about your real makefile versus what you've shown us, and that difference is critical to the problem you're having. As Renaud says, please provide a MCVE.
I created a simple makefile:
OBJS := $(SRC:.c=.c.o)
all: $(OBJS)
%.c.o : %.c
: $< $#
then ran it:
files=$(find -name \*.c)
make SRC="$files"
and it worked just fine:
: foo.c foo.c.o
: bar.c bar.c.o
: biz.c biz.c.o
: baz.c baz.c.o
You can work around the problem in GNU make 4.1 by not including newlines in the $files variable. For example you can change how you set it to this:
files=$(find . -type f -name '*.c.c' -printf '%p ')
so it uses space separators instead of newlines.

Undefined reference to `compress2' and other functions in the HDF5 library

I am trying to make a code called iPIC3D and it has some prerequisite libraries such as HDF5, H5hut etc. I did everything as instructed. One has to install all the prerequisites and then run the "make" command. But while running the make command, I get a series of errors such as
/usr/local/hdf5/1.8.11-par/lib/libhdf5.a(H5Zdeflate.o): In function `H5Z_filter_deflate':
H5Zdeflate.c:(.text+0xf1): undefined reference to `compress2'
H5Zdeflate.c:(.text+0x1af): undefined reference to `inflateInit_'
H5Zdeflate.c:(.text+0x1c9): undefined reference to `inflate'
H5Zdeflate.c:(.text+0x27a): undefined reference to `inflateEnd'
H5Zdeflate.c:(.text+0x2dc): undefined reference to `inflateEnd'
H5Zdeflate.c:(.text+0x3de): undefined reference to `inflateEnd'
collect2: error: ld returned 1 exit status
make: *** [main] Error 1
Here is a copy of my makefile for reference
PIC_HOME = $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
## SECTION THAT DEPENDS ON THE SYSTEM
# -- Modify this variables according
# -- to your system options.
# -- Possible flags:
# -DPARALLEL_IO Use parallel HDF5
# -DUSEH5HUT Use H5hut (must include also -DPARALLEL_IO)
# -DBATSRUS Coupling with BATS-R-US
CXX = mpicxx
HDF5_HOME = /usr/local/hdf5/1.8.11-par
H5HUT_HOME = /usr/local/H5hut/1.8.11
IPIC_FLAGS = "-DUSEH5HUT -DPARALLEL_IO"
## END OF SECTION
OPTIM = -O3
HDF5_LIB = $(HDF5_HOME)/lib/libhdf5_hl.a $(HDF5_HOME)/lib/libhdf5.a
H5HUT_LIB = $(H5HUT_HOME)/lib/libH5hut.a
H5HUTIO_LIB = $(IPIC_HOME)/H5hut-io/libH5hut-io.a
INC_DIR = ./include
INC_H5HUT = $(H5HUT_HOME)/include
INC_H5HUTIO = $(IPIC_HOME)/H5hut-io/include
INC_HDF5 = $(HDF5_HOME)/include
.SUFFIXES:
.SUFFIXES: .cpp .o .h
SRC = \
$(IPIC_HOME)/grids/Grid3DCU.cpp \
$(IPIC_HOME)/fields/BCStructure.cpp \
$(IPIC_HOME)/fields/EMfields3D.cpp \
$(IPIC_HOME)/inputoutput/phdf5.cpp \
$(IPIC_HOME)/inputoutput/Restart3D.cpp \
$(IPIC_HOME)/inputoutput/ParallelIO.cpp \
$(IPIC_HOME)/inputoutput/Collective.cpp \
$(IPIC_HOME)/performances/Timing.cpp \
$(IPIC_HOME)/PSKOutput3D/PSKhdf5adaptor.cpp \
$(IPIC_HOME)/bc/BcParticles.cpp \
$(IPIC_HOME)/bc/BcFields3D.cpp \
$(IPIC_HOME)/mathlib/EllipticF.cpp \
$(IPIC_HOME)/solvers/CG.cpp \
$(IPIC_HOME)/solvers/GMRES.cpp \
$(IPIC_HOME)/ConfigFile/src/ConfigFile.cpp \
$(IPIC_HOME)/main/iPic3Dlib.cpp \
$(IPIC_HOME)/particles/Particles3Dcomm.cpp \
$(IPIC_HOME)/particles/Particles3D.cpp \
$(IPIC_HOME)/communication/ComNodes3D.cpp \
$(IPIC_HOME)/communication/ComParser3D.cpp \
$(IPIC_HOME)/communication/ComInterpNodes3D.cpp \
$(IPIC_HOME)/communication/ComParticles3D.cpp \
ALLOBJ = $(subst .cpp,.o,$(SRC))
IPIC3D_EXE = $(IPIC_HOME)/iPic3D
IPIC3D_LIB = $(IPIC_HOME)/libiPic3Dlib.a
LDLIBS = $(IPIC3D_LIB) $(H5HUTIO_LIB) $(H5HUT_LIB) $(HDF5_LIB) -ldl
all : io lib main
io :
CXX=$(CXX) HDF5_HOME=$(HDF5_HOME) H5HUT_HOME=$(H5HUT_HOME) IPIC_FLAGS=$(IPIC_FLAGS) $(MAKE) -C $(IPIC_HOME)/H5hut-io
lib : $(ALLOBJ)
$(AR) sr $(IPIC3D_LIB) $(ALLOBJ)
ranlib $(IPIC3D_LIB)
main : iPic3D.o
$(CXX) $(LDFLAGS) -I$(INC_DIR) -I$(INC_HDF6) iPic3D.cpp -o $(IPIC3D_EXE) $(LDLIBS)
clean : cleanio
$(RM) $(ALLOBJ)
$(RM) $(IPIC3D_LIB)
$(RM) iPic3D.o
$(RM) $(IPIC3D_EXE)
cleanio :
$(MAKE) -C $(IPIC_HOME)/H5hut-io clean
%.o : %.cpp
echo " Compiling " $#
$(CXX) $(CXXFLAGS) $(OPTIM) $(IPIC_FLAGS) -I$(INC_DIR) -I$(INC_H5HUTIO) -I$(INC_H5HUT) -I$(INC_HDF5) -c $< -o $#
I am unable to understand what exactly is causing this problem.
I would say you are missing linking in the libz library as this is where the compress2 function should come from. Try adding -lz to your LDLIBS.

Makefile is always 'up to date' while files have been changed

I have a Makefile to compile several fortran files, most of which are module files. Whenever I changed the module file and initiate make command, the make says:
make: `PRM' is up to date.
PRM is the executable name. No such problem when I changed the main file. Another problem is that sometimes I also get:
make: m2c: Command not found
error. My makefile looks like:
.SUFFIXES: .f90
F90 = pgf90
NETCDF_DIR = /opt/netcdf
F90_FLAGS = -Mbackslash -Mlarge_arrays
LIBS = -L$(NETCDF_DIR)/lib -lnetcdff -lnetcdf
INCLUDE_MODULES = -I$(NETCDF_DIR)/include
VPATH = /path/FORTRAN
util_module = \
precmod.o \
strings.o
EXEC = PRM
OBJS = \
${util_module} \
mo_date.o \
mo_utils.o \
module_metcro_lib.o \
module_plumerise1.o \
module_finn_lib.o \
main_plm.o
${EXEC} : ${OBJS}
${F90} -o $# ${OBJS} ${LIBS}
.f90.o:
${F90} -c ${F90_FLAGS} ${INCLUDE_MODULES} $<
clean:
rm -f ${EXEC} ${OBJS} *.mod
thanks for answering!

makefile implicit rule -- confused

I am working on a project where makefile is used to make an target.
Here i am confused how makefile is generating .o files from the .cpp file.
Like file clientthread_level1_unix.o have to be generated from clientthread_level1_unix.cpp file.
But no where it is specified to use *.cpp file for it.
EXTRALIBS = -pthread -lz -ldl -lm
OPENGLLIBS =
LDFLAGS_GL =
LDLIBS = ${APPEXTRALIBS} ${top_builddir}/lib/libwx_based-2.6.a ${EXTRALIBS}
# Compiler used
CXX = c++
CC = gcc
CANALOBJS = ../../common/listenthread_unix.o ../../common/clientthread_level1_unix.o ../../common/devicethread_unix.o \
../../common/canalshmem_level1_unix.o ../../common/clientlist.o ../../common/controlobject.o \
../../common/devicelist.o ../../common/udpreceivethread_unix.o ../../../vscp/common/vscp.o \
../../common/clientthread_level2_unix.o ../../common/canalshmem_level2_unix.o \
../../common/tcplistenthread.o
CANALHDRS = ../../common/clientlist.h ../../common/controlobject.h ../../common/devicelist.h \
../../common/canal.h ../../common/canaldlldef.h \
../../common/version.h ../../common/canal_unix_ipc.h ../../common/CanalShMem_level1_unix.h \
../../common/CanalShMem_level2_unix.h ../../common/clientthread_level1_unix.h ../../common/clientthread_level2_unix.h
PROJOBJS = ../../../common/dllist.o ../../../common/configfile.o ../../../common/crc.o
PROJHDRS = ../../../common/dllist.h ../../../common/configfile.h
OBJS = canald.o
HDRS = canald.h
all: canald
# Build the Linux executable
canald: $(OBJS) $(HDRS) $(CANALOBJS) $(CANALHDR) $(PROJOBJS) $(PROJHDRS)
$(CXX) $(OBJS) $(CANALOBJS) $(PROJOBJS) -o canald $(LIBS) $(LDLIBS)
If we use the Implicit rule then also, then also canald target is not as per that.
http://www.gnu.org/software/make/manual/make.html#make-Deduces
http://www.gnu.org/software/make/manual/make.html#Implicit-Rules
Please sugest how is this line working to produce canald ?
$(CXX) $(OBJS) $(CANALOBJS) $(PROJOBJS) -o canald $(LIBS) $(LDLIBS)
The line
$(CXX) $(OBJS) $(CANALOBJS) $(PROJOBJS) -o canald $(LIBS) $(LDLIBS)
will approximately (I skipped not defined variables) be translated into:
c++ canald.o ../../common/listenthread_unix.o ../../common/clientthread_level1_unix.o ../../common/devicethread_unix.o \
../../common/canalshmem_level1_unix.o ../../common/clientlist.o ../../common/controlobject.o \
../../common/devicelist.o ../../common/udpreceivethread_unix.o ../../../vscp/common/vscp.o \
../../common/clientthread_level2_unix.o ../../common/canalshmem_level2_unix.o \
../../common/tcplistenthread.o \
../../../common/dllist.o ../../../common/configfile.o ../../../common/crc.o \
-o canald /lib/libwx_based-2.6.a -pthread -lz -ldl -lm
i.e., a "normal" compiler call. Since there is an explicit rule for canald, there is no need to search for implicite ones. In addition, it is the target rule in the Makefile, thus it is the default target.
Howerver, for objects canald depends on, no explicit rule exist, thus the implicit rules are used.
If you want to know, which implicit rules exist, call make -p and search in the output for the pattern, e.g. in your case for %.cpp.

makefile-compiling-back-and-forth - follow up

In continuation with my earlier question
Makefile - compiling back and forth
I made an attempt in creating a single Makefile. The two subdirectories are HAM-src and GFS-src. However, I am still unable to build it. I paste my Makefile below:
export
SHELL = /bin/sh
top_srcdir=./Temp
objdir=$(top_srcdir)/obj
bindir=${exec_prefix}/bin
cfssrcdir=${top_srcdir}/GFS-src
hamsrcdir=${top_srcdir}/HAM-src
incdir=${top_srcdir}/include
exec=${bindir}/esm_gfs-ham_v0
PROG=$(exec)
LDR = mpxlf90_r -qsmp=noauto
FFLAG90 = $(OPTS90) $(FINCS) -qfree=f90 -NS2048 -qmoddir=$(objdir) -I$(objdir)
FFLAGM = -NS2048 -qfixed -qmoddir=$(objdir) -I$(objdir)
F77 = mpxlf95
F90 = mpxlf95
F90_x = xlf90_r
F90_r = mpxlf95_r
SRCHAM = $(hamsrcdir)/ham_control.f90 $(hamsrcdir)/mo_filename.f90 \
$(hamsrcdir)/ham_namelist.f90 $(hamsrcdir)/ham_submodel.f90 \
$(hamsrcdir)/ham_submodel_diag.f90 $(hamsrcdir)/ham_ham.f90
SRCGFS_MOD=$(cfssrcdir)/machine.f $(cfssrcdir)/resol_def.f \
$(cfssrcdir)/omegas.f $(cfssrcdir)/cnvcld_v.f
OBJGFS_MOD = $(patsubst $(cfssrcdir)/%.f,$(objdir)/%.o,$(SRCGFS_MOD))
OBJHAM = $(patsubst $(hamsrcdir)/%.f90,$(objdir)/%.o,$(SRCHAM))
.SUFFIXES: $(SUFFIXES) .f90 .f .o
all: $(PROG)
$(PROG): $(OBJHAM) $(OBJGFS_MOD)
$(LDR) $(CFS_LDFLAGS) -o $# $(OBJGFS_MOD) $(OBJHAM) $(CFS_LIBS) -L$(LDFLAGS)
$(objdir)/%.o: $(cfssrcdir)/%.f
$(F77) $(FFLAGS) -c $< -o $#
$(objdir)/%.o: $(hamsrcdir)/%.f90
$(F90_r) $(F90FLAGS) -c $< -o $#
########## dependencies for $(hamsrcdir) ###########
ham_filename.o: ham_control.o
ham_namelist.o: ham_control.o ham_filename.o
ham_submodel.o: ham_control.o ham_namelist.o $(objdir)/resol_def.o
ham_submodel_diag.o: ham_submodel.o
########## dependencies for $(cfssrcdir) ###########
$(objdir)/omegas.o: $(cfssrcdir)/omegas.f
$(F77) $(FFLAGM) -c $(cfssrcdir)/omegas.f -o $#
$(objdir)/cnvcld_v.o: $(cfssrcdir)/cnvcld_v.f
$(F77) $(FFLAGM) -c $(cfssrcdir)/cnvcld_v.f -o $#
The error:
mpxlf95_r -q64 -O3 -qstrict -qMAXMEM=-1 -qarch=auto -qtune=auto -qcache=auto -qfloat=fltint -qsuffix=cpp=f90 -lessl_r -lmass -lmassv -I./Temp/include -I./Temp/HAM-src -qmoddir=./Temp/obj -I./Temp/obj -c ./Temp/HAM-src/ham_namelist.f90 -o ./Temp/obj/ham_namelist.o
** ham_namelist === End of Compilation 1 ===
1501-510 Compilation successful for file ham_namelist.f90.
mpxlf95_r -q64 -O3 -qstrict -qMAXMEM=-1 -qarch=auto -qtune=auto -qcache=auto -qfloat=fltint -qsuffix=cpp=f90 -lessl_r -lmass -lmassv -I./Temp/include -./Temp/HAM-src -qmoddir=./Temp/obj -I./Temp/obj -c ./Temp/HAM-src/ham_submodel.f90 -o ./Temp/obj/ham_submodel.o
"./Temp/HAM-src/ham_submodel.f90", line 425.7: 1514-219 (S) Unable to access module symbol file for module resol_def. Check path and file permissions of file. Use association not done for this module.
1501-511 Compilation failed for file ham_submodel.f90.
gmake: *** [/gpfs1/home/cccrmod/ham_expt_dec11/regrid_test/CFS-HAM/SORC_CFS-HAM/Temp/obj/ham_submodel.o] Error 1
Why makefile does not compile the resol_def.f module on encountering the dependency?
Another issue - my makefile is not working properly. It goes in a sequence in which the sources are defined.
This is difficult to untangle (a minimal, complete example really would help), but I'd suggest you change this
ham_submodel.o: ham_control.o ham_namelist.o $(objdir)/resol_def.o
to this
$(objdir)/ham_submodel.o: ham_control.o ham_namelist.o $(objdir)/resol_def.o
and see if that solves the first problem. I don't understand the last line of your question ("Another issue...").

Resources