writing a cygwin makefile for ubuntu - c++

I am trying to compile the open-source AAM-library. I have tried in Visual Studio, and although it compiled, it had a run-time error. Now I'm trying to compile it in Ubuntu 11.04 using G++. The only makefile provided is a cygwin makefile. I am trying to use this to compile in Ubuntu. (I have included the makefile below). The problem I am having is near the bottom in the lines:
libaamlibrary.dll.a: $(OBJS)
g++ -fPIC -shared $(OBJS) $(LIBS) -o cygaamlibrary-2.dll -Wl,--enable-auto-image-base -Xlinker --out-implib -Xlinker libaamlibrary.dll.a
"--enable-auto-image-base" is not a recognised option. I am trying to rewrite these 3 lines to a form that does the same thing but works in Ubuntu, but I am struggling, because I don't really understand what the lines are doing (e.g., I don't understand Xlinker and how it should be used). Any advice would be much appreciated... Here is the full makefile for reference:
CPPFLAGS = -I. -I/home/andrew/MscProject/OpenCV-2.3.0/include/opencv -O2 -Wall -g -MD -fPIC
PROGRAMS = libaamlibrary.dll.a libaamlibrary.a fit build
LIBS = -L/usr/local/lib -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml -lopencv_video -lopencv_features2d -lopencv_calib3d -lopencv_objdetect -lopencv_contrib -lopencv_legacy -lopencv_flann
OBJS = AAM_Util.o VJfacedetect.o AAM_Shape.o AAM_CAM.o AAM_PAW.o AAM_PDM.o AAM_TDM.o AAM_MovieAVI.o AAM_Basic.o AAM_IC.o
all: $(PROGRAMS)
AAM_Util.o: AAM_Util.cpp AAM_Util.h
g++ $(CPPFLAGS) -c -o AAM_Util.o AAM_Util.cpp
AAM_Shape.o: AAM_Shape.cpp AAM_Shape.h
g++ $(CPPFLAGS) -c -o AAM_Shape.o AAM_Shape.cpp
AAM_TDM.o: AAM_TDM.cpp AAM_TDM.h
g++ $(CPPFLAGS) -c -o AAM_TDM.o AAM_TDM.cpp
AAM_PDM.o: AAM_PDM.cpp AAM_PDM.h
g++ $(CPPFLAGS) -c -o AAM_PDM.o AAM_PDM.cpp
AAM_PAW.o: AAM_PAW.cpp AAM_PAW.h
g++ $(CPPFLAGS) -c -o AAM_PAW.o AAM_PAW.cpp
AAM_CAM.o: AAM_CAM.cpp AAM_CAM.h
g++ $(CPPFLAGS) -c -o AAM_CAM.o AAM_CAM.cpp
VJfacedetect.o: VJfacedetect.cpp VJfacedetect.h
g++ $(CPPFLAGS) -c -o VJfacedetect.o VJfacedetect.cpp
AAM_MovieAVI.o: AAM_MovieAVI.cpp AAM_MovieAVI.h
g++ $(CPPFLAGS) -c -o AAM_MovieAVI.o AAM_MovieAVI.cpp
AAM_Basic.o: AAM_Basic.cpp AAM_Basic.h
g++ $(CPPFLAGS) -c -o AAM_Basic.o AAM_Basic.cpp
AAM_IC.o: AAM_IC.cpp AAM_IC.h
g++ $(CPPFLAGS) -c -o AAM_IC.o AAM_IC.cpp
demo_build.o: train.cpp
g++ $(CPPFLAGS) -c -o demo_build.o train.cpp
demo_fit.o: fit.cpp
g++ $(CPPFLAGS) -c -o demo_fit.o fit.cpp
libaamlibrary.a: $(OBJS)
ar cru libaamlibrary.a $(OBJS)
ranlib libaamlibrary.a
libaamlibrary.dll.a: $(OBJS)
g++ -fPIC -shared $(OBJS) $(LIBS) -o cygaamlibrary-2.dll -Wl,--enable-auto-image-base -Xlinker --out-implib -Xlinker libaamlibrary.dll.a
fit: demo_fit.o
g++ -o fit demo_fit.o libaamlibrary.dll.a $(LIBS)
build: demo_build.o
g++ -o build demo_build.o libaamlibrary.dll.a $(LIBS)
clean:
rm -f *.o $(PROGRAMS)

I agree that you should not use a .dll.a or .dll extension (I believe .a and .so are appropriate), but it seems you can't do without libaamlibrary[.dll].a.
Since '--enable-auto-image-base' is prefixed with -Wl, this makes it a linker (ld) option.
I searched 'man ld' and came up with this:
--enable-auto-image-base
Automatically choose the image base for DLLs, unless one is
specified using the "--image-base" argument. By using a hash
generated from the dllname to create unique image bases for each
DLL, in-memory collisions and relocations which can delay program
execution are avoided. [This option is specific to the i386 PE
targeted port of the linker]
What is your platform? It is not available to non i386 architectures as I understand, and maybe not needed? So can you try compiling without it?
By the way I recommend using the excellent Autotools package (automake/autoconf/libtool).
Regarding --out-implib it is also not available on amd64.
--out-implib file
The linker will create the file file which will contain an import
lib corresponding to the DLL the linker is generating. This import
lib (which should be called ".dll.a" or ".a" may be used to link
clients against the generated DLL; this behaviour makes it possible
to skip a separate "dlltool" import library creation step. [This
option is specific to the i386 PE targeted port of the linker]
Sorry but I don't know what an import lib is.

Practical approach: first try building without all the .dll and .dll.a stuff; just remove the lines that refer to such targets.
It seems .dll.a files are static archives containing position-independent code (PIC), which are necessary in advanced linking scenarios, i.e. if you're developing shared libraries yourself. (Even if you want such a thing, you shouldn't call it .dll.a on Linux.)

Related

how to import opencv lib into other lib using g++

How can I set properly the makefile to import some OpenCV lib into the libmat.o?
this is the make file:
# Define a variable for classpath
CLASS_PATH = ../bin
# Debug: -g3=compile with extra debugg infos. -ggdbg3=include things like macro defenitions. -O0=turn off optimizations.
DEBUGFLAGS = -g3 -ggdb3 -O0
CFLAGS = $(DEBUGFLAGS)
# Define a virtual path for .class in the bin directory
vpath %.class $(CLASS_PATH)
all : libMat.so
# $# matches the target, $< matches the first dependancy
libMat.so : libMat.o
g++ $(CFLAGS) -W -shared -o $# $<
# $# matches the target, $< matches the first dependancy
libMat.o : Mat2Image.cpp Mat2Image.h
g++ $(CFLAGS) -fPIC -I/usr/lib/jvm/jdk1.8.0_111/include -I/usr/lib/jvm/jdk1.8.0_111/include/linux -c $< -o $# -L/usr/local/lib
# $* matches the target filename without the extension
# manually this would be: javah -classpath ../bin HelloJNI
HelloJNI.h : Mat2Image.class
javah -classpath $(CLASS_PATH) $*
clean :
rm -f Mat2Image.h libMat.o libMat.so
i need some OpenCV lib located in /usr/local/lib
for example libopencv_imgproc.so
I think what you want to do is get (e.g.) libopencv_imgproc.so,
located in /usr/local/lib, to be linked with your shared library libMat.so.
The way you are trying to do this in your makefile is by "linking"
libopencv_imgproc.so with the object file libMat.o by the recipe:
libMat.o : Mat2Image.cpp Mat2Image.h
g++ $(CFLAGS) -fPIC -I/usr/lib/jvm/jdk1.8.0_111/include \
-I/usr/lib/jvm/jdk1.8.0_111/include/linux -c $< -o $# \
-L/usr/local/lib
You think that -L/usr/local/lib at the end will in some way let the linker
know you want to link libopencv_imgproc.so and do so.
That won't work for more than one reason:
-L/usr/local/lib will just tell the linker that /usr/local/lib is
a directory where you want it search for libraries that you ask it to
link. It doesn't ask it to link any libraries from there, and if you
don't tell it to, it won't. To tell the linker
to search for libraries in /usr/local/lib and ask it to link
libopencv_imgproc.so you would use:
`-L/usr/local/lib -lopencv_imgproc
But you don't need to tell it to search for libraries in /usr/local/lib,
because that is one of the directories the linker searches for libraries
by default. So -lopencv_imgproc is all you would need.
But more important than that,
g++ $(CFLAGS) -fPIC -I/usr/lib/jvm/jdk1.8.0_111/include \
-I/usr/lib/jvm/jdk1.8.0_111/include/linux -c $< -o $# \
-L/usr/local/lib
is the command that simply compiles libMat.o from Mat2Image.cpp. It
doesn't do any linkage. It is not possible and does not make sense to "link"
anything with an object file. So adding any linkage options to your
compile command is pointless. The compiler will ignore them. This command is
effectively no different from:
g++ $(CFLAGS) -fPIC -I/usr/lib/jvm/jdk1.8.0_111/include \
-I/usr/lib/jvm/jdk1.8.0_111/include/linux -c $< -o $#
and that's what it should be.
The recipe that does your linkage is:
libMat.so : libMat.o
g++ $(CFLAGS) -W -shared -o $# $<
So this is where you have to tell the linker that you want libopencv_imgproc.so
to be linked:
libMat.so : libMat.o
g++ $(CFLAGS) -W -shared -o $# $< -lopencv_imgproc
With this, libMat.so will be linked containing libMat.o and a runtime
dependency on the shared library libopencv_imgproc.so - that is, an
instruction to the runtime loader that it must load libopencv_imgproc.so
into the same process when it loads libMat.so.
Your makefile has various other faults but what I've said is enough to
explain and fix the particular problem I think you're asking about. You
can learn how to write a better makefile, if you want, by searching for tutorials
and ariticles about GNU Make and studying the documentation
I'll just point out one other fault that is serious. Your recipe:
clean:
rm -f Mat2Image.h libMat.o libMat.so
is going to delete the header file Mat2Image.h when you run
make clean. That header file is one of your original source files. It
isn't generated by this makefile - like libMat.o and libMat.so - unless
you've ommitted some bits of the real makefile. So
if you delete it you'll have to recover it from you source-control system; and
if its not under a source-control system, you'll have to rewrite it. So
I think you just want:
clean:
rm -f libMat.o libMat.so

Undefined reference to function when using shared library in Linux

I have some problems to use a custom shared library, since I get undefined reference errors for some functions from two of many other source files.
If I compile the whole project with main file (release:), everything works just fine. But if I create a shared library (lib:) and use this library with the main file (all:), those compile time errors occur.
Here is a snippet of my makefile
release:
$(CC) -Wall -s -w $(INCLUDES) $(LIBRARY) $(SRC) mainfile.cpp $(OCV) $(BOOST) $(GLOG) $(GFLAGS) -o test.exe
lib:
$(CC) -fPIC $(INCLUDES) $(LIBRARY) -c $(SRC) $(OCV) $(BOOST) $(GLOG) $(GFLAGS)
mv *.o obj/
$(CC) -shared -o libOutput.so obj/*.o
all:
$(CC) -Wall -s -w $(INCLUDES) $(LIBRARY) mainfile.cpp -L/path/to/lib/ -lOutput $(OCV) $(BOOST) $(GLOG) $(GFLAGS) -o project.exe
Since there is no error during compilation using the release-option, I'm assuming that there is a linker specific problem.
I inspected the specific object files using GNU Binary Utilities
nm -C obj/specific.o | grep functionName
with no results. I did the same for the shared library, but this time with the following result,
U functionName(std::vector<int>)
which means that the function is unknown.
Do you have any suggestions, how to fix this issue?

Trouble compiling/linking C and C++ files

I have tried searching around other questions here on SO, but have still been unable to get my newly created C++ and .h linked to my main C file correctly. My implementation of my loader.cpp and loader.h are based off of this SO question.
My loader.cpp has no main function as I just want to use the C++ functions there. My shift.c file is where my int main() is located. Here is the basic structure of my loader.cpp file.
loader.cpp
#include "loader.h"
...
// Class Declaration
...
// Class implementation
I have been trying to compile with the following.
g++ loader.cpp -o obj -lGLU -lGL -lglut
The error I am getting here is...
(.text+0x20): undefined reference `to main'
So my two questions are, how do I get my cpp file to compile properly, and then what do I need to add to my Makefile to link them properly?
Makefile (for reference)
CC = gcc
CXX = g++
EXE = shift gears
# Main target
all: $(EXE)
CFLG=-O3 -Wall
LIBS=-lglut -lGLU -lGL -lm
CLEAN=rm -f $(EXE) *.o *.a
# Dependencies
gears.o: gears.c
shift.o: shift.c CSCIx229.h
fatal.o: fatal.c CSCIx229.h
loadtexbmp.o: loadtexbmp.c CSCIx229.h
print.o: print.c CSCIx229.h
project.o: project.c CSCIx229.h
errcheck.o: errcheck.c CSCIx229.h
object.o: object.c CSCIx229.h
# Create archive
CSCIx229.a:fatal.o loadtexbmp.o print.o project.o errcheck.o object.o
ar -rcs $# $^
# Compile rules
.c.o:
gcc -c $(CFLG) $<
.cpp.o:
g++ -c $(CFLG) $<
# Link
shift:shift.o CSCIx229.a
gcc -O3 -o $# $^ $(LIBS)
gears:gears.o
gcc -O3 -o $# $^ $(LIBS)
# Clean
clean:
$(CLEAN)
If you want g++ to compile an object module without linking it into a complete program then you must give it the -c option:
g++ -c loader.cpp -o loader.o
Note that that compilation command also assigns a conventional name to the generated object file, and that if you're not linking it into an executable then you don't need to specify libraries to link it to. Your Makefile is already set up for this.
If you add loader.o to the dependencies of CSCIx229.a then that should be enough to persuade make to build it from loader.cpp and to include the object file in your library (which will make it available for linking into your executables). You may also need to add some or all of -lGLU -lGL -lglut to your LIBS variable. It might also be appropriate to add loader.o's dependencies to the makefile if they include more than just loader.cpp itself (e.g. if they include CSCIx229.h).
Add the -c option to compile only. When you are ready to link the final application, then include all the object files and the list of libraries.
g++ -c loader.cpp -o loader.o
g++ loader.o (and the rest of your object files) -lGLU -lGL -lglut
Try adding this to your makefile:
shift:shift.o CSCIx229.a loader.o
gcc -O3 -o $# $^ $(LIBS)

Simple makefile for compiling a shared object library file

I need a very simple makefile to compile a shared object library file (*.so). I also need to know how to pass optimization parameters like -O2 and -O3. I tried to search for simple examples using google, but all examples are twisted.
I don't need to create any version like *.so.1.0 but only a simple *.so file. My project would have multiple files, so I need an example which compiles multiple files.
The simplest makefile that I can think of that does what you want:
CXXFLAGS += -fPIC
CXXFLAGS += -O3
x.so: x.o y.o
g++ -shared $^ -o $#
In the alternative, you may want to use more of make's built-in rules and variables:
CXXFLAGS += -fPIC
CXXFLAGS += -O3
x.so: x.o y.o
$(LINK.cc) -shared $^ $(LOADLIBES) $(LDLIBS) -o $#

GCC Shared Library Problems

I'm trying to create a shared library on ubuntu using gcc
I just have one simple class(shared.h and shared.cpp) and one client to use it (main.cpp)
This is my makefile and I'm still not able to to get the program to compile.
all:
#compile object(fPIC: creates position independent code)
gcc -fPIC -Wall -g -c shared.cpp
#compile shared library
gcc -shared -Wl,-soname,libshared.so.1 -o libshared.so.1.0.1 shared.o -lc
#link shared library
gcc -g -o main main.cpp -L. -lshared
I'm confident the first line is correct
I am unsure what "-lc" does. I think it passes something to the linker?
I don't want to install the library, I just want to be able to link it from the current directory. I have tried: export LD_LIBRARY_PATH=.
but it does not seem to make a difference. Everything is in the current directory.
ERROR: /usr/bin/ld: cannot find -lshared
how do I get the compiler to check the current directory for my library?
The problem is not that it's not looking in the directory, the problem is that you've named the library "libshared.so.1.0.1". When you use -lshared, it's looking for a file named 'libshared.so' or 'libshared.a' in the library search path.
Most of the time, when using versioned system libraries, you'll provide a link to the latest one as 'libshared.so', even if you have installed 'libshared.so.1' or 'libshared.so.1.0.1'.
In your case, if you continue to leave the file named 'libshared.so.1.0.1', you'll want to create 2 symbolic links:
libshared.so - So that the library can be found using ld
libshared.so.1 - Since you declared the SO name as libshared.so.1 when building it, you need to provide this link, otherwise, the executable will not be able to find the proper shared library at runtime.
You don't write any dependencies, which is the purpose of Makefile-s. And you probably need to force the run path Perhaps something like
.PHONY: all clean
CXX=g++
CXXFLAGS=-g -Wall
all: main
main: main.o libshared.so
$(LINK.cpp) -o $# $< -Wl,-rpath,. -L. -lshared
libshared.so: shared.pic.o
$(LINK.cpp) -shared -o $^ $<
main.o: main.cc shared.hh
%.pic.o: %.cc
$(CXX) $(CXXFLAGS) -fPIC -c -o $# $<
#
clean:
rm -f *.o *.so main *~