makefile: how to perform “ranlib” operation correctly - c++

I downloaded a third party lib( Library link) which installs and compiles properly. It creates multiple object file (*.o), rather than creating executable, it's using gnu libtool to do some scripting. I plan to make some changes in some function; however, given I am new to linux, I thought to avoid libtool and just create executable.
I wrote a small makefile to link multiple object files and libraries and create an executable. All object files already exists. One library is as archive file (libtaucs.a). Based on online resouce, I came to know that I have to perform "ranlib" utlity as suggested here link. However, I get the following error:
$ make
make: *** No rule to make target `ranlib', needed by `test_me_DKU'. Stop.
Here is my makefile which I am using to link already existing object file (disclaimer: I barely understand makefile;so, you may find lots of error)
# Here is a simple Make Macro.
LINK_TARGET = test_me_DKU
# Here is a Make Macro that uses the backslash to extend to multiple lines.
##OBJS = tsnnls_test.o
OBJS = libtsnnls_la-taucs_malloc.o libtsnnls_la-taucs_ccs_order.o \
libtsnnls_la-taucs_ccs_ops.o libtsnnls_la-taucs_vec_base.o \
libtsnnls_la-taucs_complex.o libtsnnls_la-colamd.o \
libtsnnls_la-amdbar.o libtsnnls_la-amdexa.o \
libtsnnls_la-amdtru.o libtsnnls_la-genmmd.o \
libtsnnls_la-taucs_timer.o libtsnnls_la-taucs_sn_llt.o \
libtsnnls_la-taucs_ccs_base.o libtsnnls_la-tlsqr.o \
libtsnnls_la-tsnnls.o libtsnnls_la-lsqr.o \
tsnnls_test.o
# Here is a Make Macro defined by two Macro Expansions.
# A Macro Expansion may be treated as a textual replacement of the Make Macro.
# Macro Expansions are introduced with $ and enclosed in (parentheses).
REBUILDABLES = $(OBJS) $(LINK_TARGET)
clean :
rm -f $(REBUILDABLES)
echo Clean done
all : $(LINK_TARGET)
echo All done
RANLIB = ranlib
LIBTARGET= /usr/local/lib/taucs_full/lib/linux/libtaucs.a
tsnnls_test_LDADD = $(LDADD)
LIBS = -largtable2 -llapack -lblas -lquadmath $? $(RANLIB) $(LIBTARGET) -lm
# Here is a Rule that uses some built-in Make Macros in its command:
# $# expands to the rule's target, in this case "test_me.exe".
# $^ expands to the rule's dependencies, in this case the multiple files
# defined in OBJS (*.o)
$(LINK_TARGET) : $(OBJS) $(tsnnls_test_LDADD) $(LIBS)
g++ -g -o $# $^
Also, can someone please also explain this command ?
g++ -g -o $# $^

Your error is that you put $(tsnnls_test_LDADD) and $(LIBS) in the prerequisites line. That isn't correct. You want those on the linking line. They are flags to the linker.
You also don't want ranlib in LIBS because it is a command that needs to be run and not a flag to the linker.
That all being said you don't appear to be creating a static library (.a file) so you shouldn't need ranlib at all. Alternatively, since you probably do want to be making a library and not an executable (binary). You need to run ranlib on the .a file as indicated in the question/answer you linked.

Related

How to force GNU make to recompile the same object file used in two targets with different FLAGS

Suppose you have have a makefile containing two targets as in the following:
# targetA
X86CPPTARGET += targetA
targetA,SRCS = FILEA.cpp FILEB.cpp commonFile.cpp
targetA.so,DEPSOL = libUsedByCommon1.cpp
targetA,CPPFLAGS += -Ifakeinclude -std=c++11
# tartargetBgetA
X86CPPTARGET += targetB
targetB,SRCS = FILEC.cpp FILED.cpp commonFile.cpp
targetA.so,DEPSOL = libUsedByCommon2.cpp
targetB,CPPFLAGS += -std=c++11
targetA and targetB share a file, namely, commonFile.cpp which contains a number of #included headers.
commonFile.o is created only once by GNU make and reused during the compilation of targetB.
The CPPFLAGS present in targetA makes the compiler use an include that contains more symbols that the one that is in the default include directory. libUsedByCommon2 does not export all the additional symbols that are contained in the header in the fakeinclude directory and at link time, this results in undefined reference.
The workaround I am usingat the moment is to create a symbolic link to commonFile.cpp and use that in my makefile in only one of the target.
# targetA
X86CPPTARGET += targetA
targetA,SRCS = FILEA.cpp FILEB.cpp commonFile.cpp
targetA.so,DEPSOL = libUsedByCommon1.cpp
targetA,CPPFLAGS += -Ifakeinclude -std=c++11
# tartargetBgetA
X86CPPTARGET += targetB
targetB,SRCS = FILEC.cpp FILED.cpp **commonFile_symbolic_link.cpp**
targetA.so,DEPSOL = libUsedByCommon2.cpp
targetB,CPPFLAGS += -std=c++11
Is there a cleaner solution to this problem?
Is there a way to force GNU make to recompile commonFile.cpp when a different include path is being used?
You could create two new targets who are dependent on the same C file with different build commands like the following example...
commonFileA.o: commonFile.cpp
$(CC) -o $# $^ -FlagsA
commonFileB.o: commonFile.cpp
$(CC) -o $# $^ -FlagsB
You can then use "commonFileA.o" as a dependency to link in the version with those particular flags etc...
You should probably try to compile the same source file but with two different output object files:
a0.o: MYFLAGS := foo bar
a0.o: a.c
a1.o: MYFLAGS := baz cux
a1.o: a.c
And then, for the depending targets, use either a0.o or a1.o as prerequisite.
One way I have done this is to set a variable and then recursively call make with a specific target. One advantage of this method is you can specify your targets only once.
This is an incomplete extract to show the technique:
all: debug release
debug:
#echo -e "\n====== BUILDING DEBUG PROGRAM ======\n"
#FLAGS="$(CXXFLAGS_DBG)" SUFFIX="-debug" $(MAKE) general
release:
#echo -e "\n====== BUILDING RELEASE PROGRAM ======\n"
#FLAGS="$(CXXFLAGS_REL)" $(MAKE) general
general: $(PROGRAM)$(SUFFIX)
$(PROGRAM)$(SUFFIX): $(SRC)/program.cpp
$(CXX) $(FLAGS) -o $# $^

How to merge two Makefiles (each builds scripts with certain environment variables set) into a single Makefile?

I have two different directories with two different C++ source codes each of them execute different program. Directories have their own Makefiles each of them builds scripts with certain environment variables set.
Now, I want to put both directories' contents into a single directory as I want to mix both C++ source codes in order to develop a new C++ source code that utilizes both programs capabilities.
So far, I placed all files in a single directory, and I can successfully build each of the original source codes when I place the corresponding Makefile. Now, I want to have a single Makefile that allows me to build each of the original source codes (without replacing the Makefile), and hopefully this would allow me to build the new mixed C++ source file...
I tried a trivial solution and I placed the contents of both Makefiles into a single Makefile and this didn't work ...
I think it is useful to post my two Makefiles
Here is the first one
# A simple $(MAKE)file to cause make to go look in the top directory. A simple
# convenience.
all: lib
$(MAKE) -C .. examples
lib:
$(MAKE) -C .. lib/libAria.so
%.so: ../lib/libAria.so %.cpp
$(MAKE) -C .. examples/$#
%: ../lib/libAria.so %.cpp
$(MAKE) -C .. examples/$#
%Static: ../lib/libAria.a %.cpp
$(MAKE) -C .. examples/$#
clean:
$(MAKE) -C .. cleanExamples
../lib/libAria.so: FORCE
$(MAKE) -C .. dirs lib/libAria.so
../lib/libAria.a: FORCE
$(MAKE) -C .. dirs lib/libAria.a
FORCE:
.PHONY: all FORCE clean lib
And the second Makefile is
LDLIBS = -lm
CXXFLAGS = -O3 -finline-functions -I. -I./qpoases/INCLUDE -I./qpoases/SRC
CFLAGS = -O3
CC = g++
OBJECTS = \
./qpoases/SRC/QProblemB.o \
./qpoases/SRC/Bounds.o \
./qpoases/SRC/Constraints.o \
./qpoases/SRC/SubjectTo.o \
./qpoases/SRC/Indexlist.o \
./qpoases/SRC/CyclingManager.o \
./qpoases/SRC/Utils.o \
./qpoases/SRC/MessageHandling.o \
./qpoases/solver.o \
integrator.o \
condensing.o \
gauss_newton_method.o
.PHONY: all
all: test libacado_exported_rti.a
test: ${OBJECTS} test.o
./qpoases/solver.o : ./qpoases/solver.hpp
integrator.o : acado.h
condensing.o : acado.h
gauss_newton_method.o : acado.h ./qpoases/solver.hpp
test.o : acado.h ./qpoases/solver.hpp
libacado_exported_rti.a: ${OBJECTS}
ar r $# $?
${OBJECTS} : ./qpoases/solver.hpp
.PHONY : clean
clean :
-rm -f *.o *.a ./qpoases/SRC/*.o ./qpoases/SRC/*.a test
I check all stackoverflow questions related to my question and the only closest situation to mine is a question titled (multiple makefiles in one directory);however, this is not exactly what I want to do...
Thanks a lot !
Why would you want to merge your source directories? I assume they are seperated for a reason. Instead, I'd leave them be and create a new make file in the directory above them that calls each of the sub makes files below it - either via includes or via shelling directly to each makefile. I would not mix the code just to make it "easier" to get inheritance or whatever working.
BTW, here's a link for you:Stack Overflow shows you how

syntax error near unexpected token `newline'

After compiling some code using a Makefile I get this when I try to run it:
$ ./libbookgui.a
./libbookgui.a: line 1: syntax error near unexpected token `newline'
./libbookgui.a: line 1: `!<arch>'
The Makefile has the following contents.
INCLUDES = -I"$(FLTK)"
LIBS = -lstdc++
CXXFLAGS = $(INCLUDES) -Wall -time -O3 -DNDEBUG -Wno-deprecated
LIBFLAGS =
AR = ar
.SUFFIXES: .cpp .o
# Create a list of source files.
SOURCES = $(shell ls *.cpp)
# Create a list of object files from the source file lists.
OBJECTS = ${SOURCES:.cpp=.o}
# Create a list of targets.
TARGETS = libbookgui.a
# Build all targets by default
all: $(TARGETS)
%.a: $(OBJECTS)
$(AR) rcs $# $(OBJECTS)
# A rule to build .o file out of a .cpp file
%.o: %.cpp
$(CXX) $(CXXFLAGS) -o $# -c $<
# A rule to clean all the intermediates and targets
clean:
rm -rf $(TARGETS) $(OBJECTS) *.out *.stackdump
I see that it has the line TARGETS = libbookgui.a and the compiler doesn't return any errors it just creates the .a file.
Any ideas?
libbookgui.a is a static library (that aggregates several object files in it).
You are supposed to run executables, not libraries. Link this library into some executable and run that.
I suggest you read this article.
You need to update your post to show the changes you made to the makefile to get the link line added. Without that we can't really help you with that part of the problem.
Based on the errors my suspicion is that you're not using the right tool for linking: you're either using "gcc" (C compiler front-end) or trying to invoke the linker directly. When you link your application you should use the C++ compiler (in your case, $(CXX)). You also don't need to specify -lstdc++, since the C++ front-end will automatically add that to the link line.

Implicit Build Rules: GNU Make Multiple Makefiles Multiple Directories

I have the following directory structure:
.
..
./Graphic/
./Graphic/SymbolXLib
There are several other directories in this project but I won't list them for simplicities sake.I want a main makefile that drives the build of other Makefiles stored in their own directories. There are several project comming together, so I can't just move source around.
The main makefile is defined as:
[mehoggan#hogganz400 Core]$ cat ./Makefile
CORE_LIBS_DIR = libs
OBJS_DIR = obj/symb_obj
include ./Graphic/SymbolXLib/Makefile
The Graphic makefile is defined as:
#
# make BUILD_MODE={release|debug} OS_ARCH={32|64}
#
# default is 32-bit release build
#
BUILD_MODE = release
OS_ARCH = 64
OBJS_DIR = $(BUILD_MODE)$(OS_ARCH)
SRC = \
./Graphic/SymbolXLib/CartoCursor.cpp \
...
./Graphic/SymbolXLib/TextureConversion.cpp \
$(NULL)
CC = gcc -fPIC
OBJS = $(SRC:%.cpp=$(OBJS_DIR)/%.o)
COPTS = -m$(OS_ARCH) -O2
CDEFS = -DLINUXx86 \
-I../../../SharedArcGIS/Include/GraphicsPipeline/Display/SymbolX/SymbolXLib \
-I../../../SharedArcGIS/Include/System/Geometry/GeometryXLib \
-I../../../ArcSDE/pe/include \
-I../../../ArcSDE/shape/include
CFLAGS = $(COPTS) $(CDEFS) $(CINCS)
TARGET = libSymbolXLib.a
all : $(OBJS_DIR) $(OBJS_DIR)/$(TARGET)
$(OBJS_DIR) :
mkdir -p $(OBJS_DIR)
$(OBJS_DIR)/$(TARGET) : $(OBJS)
ar qc $# $^
$(OBJS_DIR)/%.o : %.cpp
$(CC) -c $(CFLAGS) -o $# $<
The response at the previous post (Previous Post) helped only if I moved alot of things around. I can't do this. So the question still remains, how do I get make to recognize the implicit build in a subdirectory from the main Makefile?
The error I am getting is
make: *** No rule to make target `release64/./Graphic/SymbolXLib/CartoCursor.o', needed by `release64/libSymbolXLib.a'. Stop.
I have to think you'd have far better success if you avoided include and instead use recursive make. In the top-level Makefile, something like:
graphic:
$(MAKE) -C Graphic
And the Makefile in Graphic/Makefile can have its sub-projects:
symbolxlib:
$(MAKE) -C SymbolXLib
and so on. You might need to add each of the targets to a default target or something similar to hang them all together on a single execution. You could give each of these targets an actual dependency (they should be .PHONY: if they don't have a dependency...) to rebuild them only when necessary or when commanded to by an upper-level target that touch(1)es "command files".
Alternatively, this paper recommends a different approach to avoid recursive make, but I've not yet read it -- and have found recursive make works well enough in projects I've been a part of that I don't mind recommending it.
Does this gnumake documentation help you?

Makefile Syntax: Static library lib$(library).a($objects)

I'm updating some Makefiles to move from Make 3.81 to 3.82. In multiple places, the original author used something like this to build static libs:
all: lib$(library).a($objects)
This seems to build each .o file in turn and insert it into the .a using ar:
g++ -O2 <snip> -o some_obj.o some_cpp.cpp
ar rv libsome_lib.a some_obj.o
etc...
This new make version, though, chokes with:
*** No rule to make target 'libsome_lib.a()', needed by 'all'
Am I safe to replace this shortcut with the way I'm used to doing this:
lib$(library).a: $(objects)
ar -rs lib$(library).a $objects
Thanks.
EDIT
Looks like I need a better Makefile education. Here's a larger excerpt from the original Makefile:
CXXFLAGS += -O2 -g -Wall -Wunused-parameter \
`pkg-config --cflags gthread-2.0 glibmm-2.4 gtkmm-2.4`
libs += `pkg-config --libs gthread-2.0 glibmm-2.4` -lc
%.d: %.cpp
$(SHELL) -ec '$(CXX) -M $(CPPFLAGS) $(CXXFLAGS) $< \
| sed '\''s/\($*\)\.o[ :]*/\1.o $# : /g'\'' > $#; \
[ -s $# ] || rm -f $#'
%.d: %.c
$(SHELL) -ec '$(CXX) -M $(CPPFLAGS) $(CXXFLAGS) $< \
| sed '\''s/\($*\)\.o[ :]*/\1.o $# : /g'\'' > $#; \
[ -s $# ] || rm -f $#'
from_sources = $(patsubst %.c,$(2),$(filter %.c, $(1))) $(patsubst %.cpp,$(2),$(filter %.cpp, $(1)))
sources = $(shell cat sources.inc)
objects = $(call from_sources,$(sources),%.o)
depends = $(call from_sources,$(sources),%.d)
library = some_lib
.PHONY: all clean fresh
all: lib$(library).a($(objects))
clean:
<SNIP>
if neq($(MAKECMDGOALS),clean)
include $(depends)
endif
When this runs under 3.81, I get all the .d dependences created, then make starts g++ing the obj files. Under 3.82, I get the .d files but no .o and make fails with "***No rule to make..."
This is the "archive member" syntax supported in gnu make. It's a bit too intimate with the tools for my tastes, but there it is. The original error may be caused by $(objects) being empty. But I'm really not sure. Here's some documentation:
http://www.gnu.org/software/make/manual/make.html#Archive-Members
11.1 Archive Members as Targets
An individual member of an archive file can be used as a target or
prerequisite in make. You specify the member named member in archive
file archive as follows:
archive(member)
This construct is available only in targets and prerequisites, not in recipes! Most programs that you might use in
recipes do not support this syntax and cannot act directly on archive
members. Only ar and other programs specifically designed to operate
on archives can do so. Therefore, valid recipes to update an archive
member target probably must use ar. For example, this rule says to
create a member hack.o in archive foolib by copying the file hack.o:
foolib(hack.o) : hack.o
ar cr foolib hack.o
In fact, nearly all archive member targets are updated in just this way and there is an implicit rule to
do it for you. Please note: The ‘c’ flag to ar is required if the
archive file does not already exist.
Your way looks good, but there must be more to the old makefile if the old way worked at all.
Oh, and just for good form I'd suggest this:
lib$(library).a: $(objects)
ar -rs $# $^
EDIT
Don't feel bad about not understanding Make very well; it has quite a learning curve.
There is still not quite enough to go on here, but if sources.inc isn't too huge, you could try the following in 3.81 and 3.82 and look for differences:
experiment:
#echo sources: $(sources)
#echo objects: $(objects)
#echo depends: $(depends)
The evidence so far is that objects is empty under 3.82, but if the .d files are being rebuilt under 3.82 that suggests that depends is not empty, which is very strange.
Possibly, but you have no explicit rule for converting something like xyz.cpp to xyz.o, which you may need for your sources before trying to inject their objects into the library. There may be a suitable implicit rule for this so check first.
The first question I'd be asking is: what happened to $objects that caused you to try and target libsome_lib.a() (i.e., with nothing between the parentheses) in the first place?
To be honest, I tend to avoid these encompassing rules as much as possible, preferring explicit statements of dependencies (unless there are a lot of dependencies, of course). Yes, I know it makes the makefiles larger and marks me as at least a partial luddite, but I prefer to have things that just work over things that work cleverly.
Cut'n'paste is one of the strongest tools in my toolbox :-)