Building library with static lib and c++ sourse code - c++

I have a static library (lwip) compiled with this makefile:
CCDEP=g++
CC=g++
#To compile for linux: make ARCH=linux
#To compile for cygwin: make ARCH=cygwin
ARCH=unix
CFLAGS=-g -Wall -D$(ARCH) -DIPv4 -DLWIP_DEBUG -fpermissive \
-Wparentheses -Wsequence-point -Wswitch-default \
-Wextra -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast \
-Wc++-compat -Wwrite-strings -Wold-style-definition \
-Wmissing-prototypes -Wredundant-decls -Wnested-externs
# not used for now but interesting:
# -Wpacked
# -Wunreachable-code
# -ansi
# -std=c89
LDFLAGS=-lpthread -lutil -lboost_thread
CONTRIBDIR=../../../..
LWIPARCH=$(CONTRIBDIR)/ports/unix
ARFLAGS=rs
#Set this to where you have the lwip core module checked out from CVS
#default assumes it's a dir named lwip at the same level as the contrib module
LWIPDIR=$(CONTRIBDIR)/../lwip/src
CFLAGS:=$(CFLAGS) \
-I. -I$(CONTRIBDIR)/apps/httpserver_raw -I$(CONTRIBDIR)/apps/shell \
-I$(CONTRIBDIR)/apps/tcpecho -I$(CONTRIBDIR)/apps/udpecho \
-I$(LWIPDIR)/include -I$(LWIPARCH)/include -I$(LWIPDIR)/include/ipv4 \
-I$(LWIPDIR) -I$(CONTRIBDIR)
# -I$(CLASSDIR)/inc
# COREFILES, CORE4FILES: The minimum set of files needed for lwIP.
COREFILES=$(LWIPDIR)/core/mem.c $(LWIPDIR)/core/memp.c $(LWIPDIR)/core/netif.c \
$(LWIPDIR)/core/pbuf.c $(LWIPDIR)/core/raw.c $(LWIPDIR)/core/stats.c \
$(LWIPDIR)/core/sys.c $(LWIPDIR)/core/tcp.c $(LWIPDIR)/core/tcp_in.c \
$(LWIPDIR)/core/tcp_out.c $(LWIPDIR)/core/udp.c $(LWIPDIR)/core/dhcp.c \
$(LWIPDIR)/core/init.c $(LWIPDIR)/core/timers.c $(LWIPDIR)/core/def.c \
CORE4FILES=$(wildcard $(LWIPDIR)/core/ipv4/*.c) $(LWIPDIR)/core/ipv4/inet.c \
$(LWIPDIR)/core/ipv4/inet_chksum.c
# SNMPFILES: Extra SNMPv1 agent
SNMPFILES=$(LWIPDIR)/core/snmp/asn1_dec.c $(LWIPDIR)/core/snmp/asn1_enc.c \
$(LWIPDIR)/core/snmp/mib2.c $(LWIPDIR)/core/snmp/mib_structs.c \
$(LWIPDIR)/core/snmp/msg_in.c $(LWIPDIR)/core/snmp/msg_out.c
# APIFILES: The files which implement the sequential and socket APIs.
APIFILES=$(LWIPDIR)/api/api_lib.c $(LWIPDIR)/api/api_msg.c $(LWIPDIR)/api/tcpip.c \
$(LWIPDIR)/api/err.c $(LWIPDIR)/api/sockets.c $(LWIPDIR)/api/netbuf.c \
$(LWIPDIR)/api/netdb.c
# NETIFFILES: Files implementing various generic network interface functions.'
NETIFFILES=$(LWIPDIR)/netif/etharp.c $(LWIPDIR)/netif/slipif.c
# NETIFFILES: Add PPP netif
NETIFFILES+=$(LWIPDIR)/netif/ppp/auth.c $(LWIPDIR)/netif/ppp/chap.c \
$(LWIPDIR)/netif/ppp/chpms.c $(LWIPDIR)/netif/ppp/fsm.c \
$(LWIPDIR)/netif/ppp/ipcp.c $(LWIPDIR)/netif/ppp/lcp.c \
$(LWIPDIR)/netif/ppp/magic.c $(LWIPDIR)/netif/ppp/md5.c \
$(LWIPDIR)/netif/ppp/pap.c $(LWIPDIR)/netif/ppp/ppp.c \
$(LWIPDIR)/netif/ppp/randm.c $(LWIPDIR)/netif/ppp/vj.c \
$(LWIPARCH)/netif/sio.c
# ARCHFILES: Architecture specific files.
ARCHFILES=$(wildcard $(LWIPARCH)/*.c $(LWIPARCH)/netif/tapif.c $(LWIPARCH)/netif/tunif.c
$(LWIPARCH)/netif/unixif.c $(LWIPARCH)/netif/list.c $(LWIPARCH)/netif/tcpdump.c)
# APPFILES: Applications.
APPFILES=$(CONTRIBDIR)/apps/httpserver_raw/fs.c
$(CONTRIBDIR)/apps/httpserver_raw/httpd.c \
$(CONTRIBDIR)/apps/udpecho/udpecho.c $(CONTRIBDIR)/apps/tcpecho/tcpecho.c \
$(CONTRIBDIR)/apps/shell/shell.c
# LWIPFILES: All the above.
LWIPFILES=$(COREFILES) $(CORE4FILES) $(SNMPFILES) $(APIFILES) $(NETIFFILES) $(ARCHFILES)
LWIPFILESW=$(wildcard $(LWIPFILES))
LWIPOBJS=$(notdir $(LWIPFILESW:.c=.o))
#LWIPOBJS+=$(notdir $(LWIPFILESW:.cpp=.o))
LWIPLIB=liblwip4.a
APPLIB=liblwipapps.a
APPOBJS=$(notdir $(APPFILES:.c=.o))
#APPOBJS+=$(notdir $(APPFILES:.cpp=.o))
%.o:
$(CC) $(CFLAGS) -c $(<:.o=.c)
all ipv4 compile: liblwip4.a
#all ipv4 compile: simhost
.PHONY: all
clean:
rm -f *.o $(LWIPLIB) $(APPLIB) simhost simnode simrouter *.s .depend* *.core core
depend dep: .depend
include .depend
$(APPLIB): $(APPOBJS)
$(AR) $(ARFLAGS) $(APPLIB) $?
$(LWIPLIB): $(LWIPOBJS)
$(AR) $(ARFLAGS) $(LWIPLIB) $?
.depend: simhost.c simnode.c simrouter.c $(LWIPFILES) $(APPFILES)
$(CCDEP) $(CFLAGS) -MM $^ > .depend || rm -f .depend
simhost: .depend $(LWIPLIB) $(APPLIB) simhost.o $(APPFILES)
$(CC) $(CFLAGS) $(LDFLAGS) -o simhost simhost.o $(APPLIB) $(LWIPLIB)
simrouter: .depend $(LWIPLIB) $(APPLIB) simrouter.o
$(CC) $(CFLAGS) $(LDFLAGS) -o simrouter simrouter.o $(APPLIB) $(LWIPLIB)
simnode: .depend $(LWIPLIB) $(APPLIB) simnode.o
$(CC) $(CFLAGS) $(LDFLAGS) -o simnode simnode.o $(APPLIB) $(LWIPLIB)
Many of these things are not needed - that was example of application in 'contrib' folder. So... I get liblwip4.a library - for now all fine.
With this Library I made some test application - a class that uses lwip lib for different connections. I used eclipse IDE (added all includes, the liblwip4.a and so on) and it works fine.
Now I want to make a my_lwiplib.a or my_lwiplib.so with this lwip lib and my class. I made directory with 3 folders - lwip(sourse files), contrib-1.4.1(platform dependent files and so on) and lwipClass(my .h and .cpp file). wrote makefile:
CC = g++
CFLAGS = -fPIC -g -fpermissive
LDFLAGS = -shared
READYLIB = ./contrib-1.4.1/ports/unix/proj/unixsim/liblwip4.a
SOURCES = $(wildcard lwipClass/src/*.cpp)
INCLUDES = -I./lwipClass/inc/ -I./lwip/src/include/ -I./lwip/src/include/lwip/
OBJECTS = $(SOURCES:.cpp=.o)
CFLAGS += $(INCLUDES)
TARGET_SO = libmy_lwip.so
TARGET_STATIC = libmy_lwip.a
clean:
rm -f $(OBJECTS) $(TARGET_SO) $(TARGET_STATIC)
shared : $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) $(READYLIB) -o $(TARGET_SO) $(LDFLAGS)
static : $(OBJECTS)
ar rcs $(TARGET_STATIC) $(OBJECTS) $(READYLIB)
When I do 'make shared' I get:
sudo make shared
g++ -fPIC -g -fpermissive -I./lwipClass/inc/ -I./lwip/src/include/ -
I./lwip/src/include/lwip/ lwipClass/src/lwipClass.o ./contrib-
1.4.1/ports/unix/proj/unixsim/liblwip4.a -o libmy_lwip.so -shared
/usr/bin/ld: lwipClass/src/lwipClass.o: relocation R_X86_64_32 against `.bss' can not be
used when making a shared object; recompile with -fPIC
lwipClass/src/lwipClass.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
make: *** [shared] Error 1
What's wrong here?
ADDED 14.08
Tryed to compile static lib. It compils ok.
Linked it to eclipse test project and made test application.
classA *myClass;
myClass->getInstance();
When i Try co compile I get
make all
Building file: ../src/test.cpp
Invoking: GCC C++ Compiler
g++ -fpermissive -I/home/user/lwip/lwipClass/inc -O0 -g3 -Wall -c -fmessage-length=0 -
MMD -MP -MF"src/test.d" -MT"src/test.d" -o "src/test.o" "../src/test.cpp"
Finished building: ../src/test.cpp
Building target: test
Invoking: GCC C++ Linker
g++ -o "test" ./src/test.o /home/user/lwip/libmy_lwip.a -lpthread -lboost_thread
/home/user/lwip/libmy_lwip.a(lwipClass.o): In function
`lwipImpl::tcpecho_thread(void*)':
lwipClass.cpp:(.text+0x85): undefined reference to `netbuf_data'
lwipClass.cpp:(.text+0xb9): undefined reference to `netbuf_next'
lwipClass.cpp:(.text+0xce): undefined reference to `netbuf_delete'
lwipClass.cpp:(.text+0xef): undefined reference to `netconn_recv'
That means there are no such functions.
I do
user:~/lwip$ objdump -t (some way /)/liblwip4.a |grep netbuf_data
00000000000003df g F .text 0000000000000103 netbuf_data
Than I do
usr:~/lwip$ objdump -t (some way/)lwip/libmy_lwip.a |grep netbuf_data
0000000000000000 *UND* 0000000000000000 netbuf_data
objdump: liblwip4.a: File format not recognized
wtf?????

In order to construct a shared library, you must first compile the source code and produce position-independent object files. That's what the -fPIC flag is for. You can't build a shared library out of "ordinary" object files, and you can't change that property of an object file later-- at least not easily.
In your example, you are trying to construct a shared library out of position-dependent object files, via a static library (). You can construct a static library from these objects, but if you want to build a shared library, as the linker is telling you, you must recompile with -fPIC.

Related

math.h not found when using llvm

I'm trying to build a python wrapper using the following Makefile:
CC=/usr/local/opt/llvm/bin/clang
OS_NAME=$(shell uname -s)
ifeq ($(OS_NAME),Linux)
LAPACKLDFLAGS=/usr/lib64/atlas/libsatlas.so # single-threaded blas
#LAPACKLDFLAGS=/usr/lib64/atlas/libtatlas.so # multi-threaded blas
#BLAS_THREADING=-D MULTITHREADED_BLAS # remove this if wrong
endif
ifeq ($(OS_NAME),Darwin) # Mac OS X
LAPACKLDFLAGS=-framework Accelerate # for OS X
endif
LAPACKCFLAGS=-Dinteger=int $(BLAS_THREADING)
STATICLAPACKLDFLAGS=-fPIC -Wall -g -fopenmp -static -static-libstdc++ /home/lear/douze/tmp/jpeg-6b/libjpeg.a /usr/lib64/libpng.a /usr/lib64/libz.a /usr/lib64/libblas.a /usr/lib/gcc/x86_64-redhat-linux/4.9.2/libgfortran.a /usr/lib/gcc/x86_64-redhat-linux/4.9.2/libquadmath.a # statically linked version
CFLAGS= -fPIC -Wall -g -std=c++11 $(LAPACKCFLAGS) -fopenmp -DUSE_OPENMP -O3
LDFLAGS=-fPIC -Wall -g -ljpeg -lpng -fopenmp
CPYTHONFLAGS=-I/usr/include/python2.7
SOURCES := $(shell find . -name '*.cpp' ! -name 'deepmatching_matlab.cpp')
OBJ := $(SOURCES:%.cpp=%.o)
HEADERS := $(shell find . -name '*.h')
all: deepmatching
.cpp.o: %.cpp %.h
$(CC) -o $# $(CFLAGS) -c $+
deepmatching: $(HEADERS) $(OBJ)
$(CC) -o $# $^ $(LDFLAGS) $(LAPACKLDFLAGS)
deepmatching-static: $(HEADERS) $(OBJ)
$(CC) -o $# $^ $(STATICLAPACKLDFLAGS)
python: $(HEADERS) $(OBJ)
# swig -python $(CPYTHONFLAGS) deepmatching.i # not necessary, only do if you have swig compiler
/usr/local/opt/llvm/bin/clang $(CFLAGS) -c deepmatching_wrap.c $(CPYTHONFLAGS)
/usr/local/opt/llvm/bin/clang -shared $(LDFLAGS) $(LAPACKLDFLAGS) deepmatching_wrap.o $(OBJ) -o _deepmatching.so $(LIBFLAGS)
clean:
rm -f $(OBJ) deepmatching *~ *.pyc .gdb_history deepmatching_wrap.o _deepmatching.so deepmatching.mex???
Previously, CC was set to g++, however, when I tried to build it like this, I'd get "ERROR: clang: error: unsupported option '-fopenmp".
Now I installed "brew install llvm" as this comes with the -fopenmp option. The unsupported error is resolved for now, but now the compiler doesn't seem to find a header file:
(base) MacBook-Pro-van-Brent:deepmatching BrentDeHauwere$ make python
/usr/local/opt/llvm/bin/clang -o hog.o -fPIC -Wall -g -std=c++11 -Dinteger=int -fopenmp -DUSE_OPENMP -O3 -I/usr/local/opt/llvm/include -c hog.cpp
In file included from hog.cpp:18:
In file included from ./std.h:20:
/usr/local/opt/llvm/bin/../include/c++/v1/math.h:300:15: fatal error: 'math.h' file not found
#include_next <math.h>
^~~~~~~~
1 error generated.
make: *** [hog.o] Error 1
I've tried setting options (I might have set them incorrectly) like -L/usr/local/opt/llvm/lib and -I/usr/local/opt/llvm/include, but no result so far. Any idea how I could point the compiler to the right direction for the header files?
Try running xcode-select —install in your terminal. This installs the xcode command line tools which should also install system headers files (as part of the macos sdk) and set your system include paths.

I get a "attempted static link of dynamic object `/usr/lib/x86_64-linux-gnu/libc++abi.a'" error when I try to statically link libc++abi.a

environment
ubuntu 18.04 (a virtual environment created by vagrant)
gcc5.5.0
I'm trying to build my own little OS.
I'm writing the kernel in C++/NASM.
I'm going to compile each of the several C++ files that make up the kernel and then link them together to create an executable file. (This is because the entry point of my own kernel is not "main", so I dare not link at the same time as compiling)
Error
The compilation of each C++ file will run without any problems and each object file will be created.
However, I get the following error in linking the object files.
But I understand that a ".a" file is a static object, not a dynamic object, so I can not understand why I'm getting this error.
I'd appreciate it if you could let me know.
ld: attempted static link of dynamic object `/usr/lib/x86_64-linux-gnu/libc++abi.a'
Here's the full text of the log
mkdir -p ./obj
g++ -O2 -g -MMD -Wall -I./include -o obj/hoge.o -c src/hoge.cpp
mkdir -p ./obj
g++ -O2 -g -MMD -Wall -I./include -o obj/huga.o -c src/huga.cpp
mkdir -p ./obj
g++ -O2 -g -MMD -Wall -I./include -o obj/piyo.o -c src/piyo.cpp
mkdir -p ./obj
nasm -f elf64 -o obj/assm.o src/assm.asm
ld --entry <ENTRY_POINT> --static -o ./ELF/kernel.elf ./obj/hoge.o ./obj/huga.o ./obj/piyo.o ./obj/assm.o -lc -lc++ -lc++abi -L/usr/lib/x86_64-linux-gnu
ld: attempted static link of dynamic object `/usr/lib/x86_64-linux-gnu/libc++abi.a'
Makefile:12: recipe for target 'ELF/kernel.elf' failed
make: *** [ELF/kernel.elf] Error 1
Makefile
COMPILER = g++
CFLAGS = -O2 -g -MMD -Wall
INCLUDE = -I./include
TARGET = ./ELF/kernel.elf
SRCDIR = ./src
SOURCES := $(shell find $(SRCDIR) -name *.cpp -or -name *.c -or -name *.asm)
OBJDIR = ./obj
OBJECTS = $(OBJDIR)/hoge.o $(OBJDIR)/huga.o $(OBJDIR)/piyo.o $(OBJDIR)/assm.o
DEPENDS = $(OBJECTS:.o=.d)
LDFLAGS = --entry <ENTRY_POINT> --static
$(TARGET): $(OBJECTS)
ld $(LDFLAGS) -o $(TARGET) $(OBJECTS) -lc -lc++ -lc++abi -L/usr/lib/x86_64-linux-gnu
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
-mkdir -p $(OBJDIR)
$(COMPILER) $(CFLAGS) $(INCLUDE) -o $# -c $<
$(OBJDIR)/%.o: $(SRCDIR)/%.asm
-mkdir -p $(OBJDIR)
nasm -f elf64 -o $# $<
all: clean $(TARGET)
clean:
rm -rf $(OBJECTS) $(DEPENDS) $(TARGET)
-include $(DEPENDS)

Building shared libraries with Makefile

I have a project that I want to build a shared library for it. The following Makefile works:
libfastpd.so: fastpd.cpp
$(CXX) -std=c++11 -fPIC -c fastpd.cpp -o fastpd.o
$(CXX) -std=c++11 -fPIC -c graph.cpp -o graph.o
$(CXX) -std=c++11 -fPIC -c LinkedBlockList.cpp -o LinkedBlockList.o
$(CXX) -std=c++11 -fPIC -c maxflow.cpp -o maxflow.o
$(CXX) -std=c++11 -shared -Wl,-soname,libfastpd.so -o libfastpd.so fastpd.o graph.o LinkedBlockList.o maxflow.o
clean:
rm *.o *.so
Then I came across this recipe in Cogswell et al.'s C++ Cookbook: https://www.oreilly.com/library/view/c-cookbook/0596007612/ch01s18.html
and decided to improve my Makefile based on that:
# Specify extensions of files to delete when cleaning
CLEANEXTS = o so
# Specify the source files, the target files,
# and the install directory
SOURCES = fastpd.cpp graph.cpp LinkedBlockList.cpp maxflow.cpp
OUTPUTFILE = libfastpd.so
INSTALLDIR = ./
.PHONY: all
all: $(OUTPUTFILE)
# Build lib*.so from all the *.o;
# subst is the search-and-replace
# function demonstrated in Recipe 1.16
$(OUTPUTFILE): $(subst .cpp,.o,$(SOURCES))
$(CXX) -shared -fPIC $(LDFLAGS) -o $# $^
.PHONY: install
install:
mkdir -p $(INSTALLDIR)
cp -p $(OUTPUTFILE) $(INSTALLDIR)
.PHONY: clean
clean:
for file in $(CLEANEXTS); do rm -f *.$$file; done
# Generate dependencies of .ccp files on .hpp files
include $(subst .cpp,.d,$(SOURCES))
%.d: %.cpp
$(CC) -M $(CPPFLAGS) $< > $#.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $# : ,g' < $#.$$$$ > $#; \
rm -f $#.$$$$
Running this file I obtained the following error:
/usr/bin/ld: fastpd.o: relocation R_X86_64_32 against `.rodata' can
not be used when making a shared object; recompile with -fPIC
fastpd.o: error adding symbols: Bad value
Checking the terminal output, I observed that the following commands were executed:
g++ -c -o fastpd.o fastpd.cpp
g++ -c -o graph.o graph.cpp
g++ -c -o LinkedBlockList.o LinkedBlockList.cpp
g++ -c -o maxflow.o maxflow.cpp
No -fPIC!
My question is: Which lines of the Makefile execute these commands and how to add -fPIC to them?
Any references to good ressources to understand the entire Makefile above would be very much appreciated as well!
Thank you very much in advance for your help!
Which lines of the Makefile execute these commands... ?
The short answer is none. The rule...
$(OUTPUTFILE): $(subst .cpp,.o,$(SOURCES))
$(CXX) -shared -fPIC $(LDFLAGS) -o $# $^
only specifies the link time dependencies and command. The -fPIC option needs to be specified when you compile the source file but you haven't provided any rule to build a .o from a .cpp so make falls back on its implicit rule which (for the purposes of this example) is essentially...
%.o: %.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $<
So the obvious solution is to add -fPIC to CXXFLAGS...
CXXFLAGS += -fPIC

Makefile leads to compilation error

I'm trying to compile a program (which isn't mine):
make -f makefile
... using the following makefile:
# Compiler for .cpp files
CPP = g++
# Use nvcc to compile .cu files
NVCC = nvcc
NVCCFLAGS = -arch sm_20 # For fermi's in keeneland
# Add CUDA Paths
ICUDA = /usr/lib/nvidia-cuda-toolkit/include
LCUDA = /usr/lib/nvidia-cuda-toolkit/lib64
# Add CUDA libraries to the link line
LFLAGS += -lcuda -lcudart -L$(LCUDA) -lgomp
# Include standard optimization flags
CPPFLAGS = -O3 -c -I $(ICUDA) -Xcompiler -fopenmp -DTHRUST_DEVICE_BACKEND=THRUST_DEVICE_BACKEND_OMP
# List of all the objects you need
OBJECTS = timer.o ar1.o kGrid.o vfInit.o parameters.o
# Rule that tells make how to make the program from the objects
main : main.o $(OBJECTS)
$(CPP) -o main main.o $(OBJECTS) $(LFLAGS)
# Rule that tells make how to turn a .cu file into a .o
%.o: %.cu
$(NVCC) ${NVCCFLAGS} $(CPPFLAGS) -c $<
# How does make know how to turn a .cpp into a .o? It's built-in!
# but if you wanted to type it out it would look like:
# %.o: %.cpp
# $(CPP) $(CPPFLAGS) -c $<
clean :
rm -f *.o
rm -f core core.*
veryclean :
rm -f *.o
rm -f core core.*
rm -f main
Which results in the following commands:
nvcc -arch sm_20 -O3 -c -I /usr/lib/nvidia-cuda-toolkit/include -Xcompiler -fopenmp -DTHRUST_DEVICE_BACKEND=THRUST_DEVICE_BACKEND_OMP -c main.cu
g++ -O3 -c -I /usr/lib/nvidia-cuda-toolkit/include -Xcompiler -fopenmp -DTHRUST_DEVICE_BACKEND=THRUST_DEVICE_BACKEND_OMP -c -o timer.o timer.cpp
g++: error: unrecognized command line option â-Xcompilerâ
make: *** [timer.o] Error 1
I don't understand the makefile: the -xCompiler flag (in the variable CPPFLAGS) should be used only by the nvcc compiler, not g++. Therefore, I understand why I am getting an error. However, I don't understand, from my basic understanding of the makefile above, why at some point the variable CPPFLAGS follows g++ (variable CPP). I don't see any such sequence in the makefile.
Your main rule requires timer.o. There is no explicit rule for timer.o so make uses a built in implicit rule (as mentioned in the comment at the end of your makefile). The implicit rule for converting .cpp files into .o files has the form
$(CPP) $(CPPFLAGS) -c $<
So it's compiling using the options in CPPFLAGS which contains -Xcompiler. You probably want the -Xcompiler flag to be in NVCCFLAGS and not CPPFLAGS.

cygwin g++ Linker doesn't find shared library

I have been creating a library. When I compile it as a static library, it works fine. Now I want to turn it into a shared library. The library is created and in the proper place, but when I try to compile the client code, the linking phase says that it can't find the library.
I already tried to rename it to al or dylib but that doesn't help either. When I put the -v flag on the linking, I can see that my library path is there. I also tried different paths. I used a relative path, but even with a full path it doesn't find it.
The Makefile from the library:
.SUFFIXES:
.SUFFIXES: .o .cpp
.SUFFIXES: .o .d
CC := g++
LNK:= g++
CXXFLAGS_RELEASE = -fPIC -shared -O2 -Wall -fmessage-length=0
CXXFLAGS_DEBUG = -fPIC -shared -g -Wall -fmessage-length=0 -D _DEBUG
CXXFLAGS = $(CXXFLAGS_DEBUG)
OBJDIR:= obj
SRCDIR:= src
HDIR:= include
INCLUDE_PATHS:= -Iinclude -Iinclude/interfaces -Iinclude/support
CPP_FILES := propertyfile/propertyfile.cpp \
propertyfile/propertyitem.cpp \
propertyfile/propertyfactory.cpp \
helper/string_helper.cpp
OBJ := $(patsubst %.cpp,$(OBJDIR)/%.o, $(CPP_FILES))
SRC := $(patsubst %.cpp,$(SRCDIR)/%.o, $(CPP_FILES))
LIBS:=
TARGET:= libsupport.so
all: $(TARGET)
$(TARGET): $(OBJ)
$(LNK) -o $(TARGET) $(OBJ) -shared
#cp $(TARGET) ../lib
#cp -r include ..
clean:
rm -f $(OBJ) $(ASM) $(TARGET)
-include $(patsubst %.cpp,$(OBJDIR)/%.d, $(CPP_FILES))
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(OBJDIR)/%.d
#mkdir -p `dirname $#`
$(CC) $(CXXFLAGS) -c $< -o $# $(INCLUDE_PATHS)
$(OBJDIR)/%.d: $(SRCDIR)/%.cpp
#mkdir -p `dirname $#`
$(CC) $(CXXFLAGS) -MM -MT $# -MF $(OBJDIR)/$*.d -c $< $(INCLUDE_PATHS)
And here is the Makefile for the application:
.SUFFIXES:
.SUFFIXES: .o .cpp
CC := g++
LD := g++
CXXFLAGS_RELEASE = -O2 -Wall -fmessage-length=0
CXXFLAGS_DEBUG = -g -Wall -fmessage-length=0 -D _DEBUG
CXXFLAGS = $(CXXFLAGS_DEBUG)
OBJDIR:= obj
SRCDIR:= src
INCLUDE_PATHS:= -Iinclude -I../include
LIBS:= -L /cygdrive/d/src/c/lib -lsupport
CPP_FILES := nohupshd.cpp \
daemon.cpp \
task.cpp
OBJ := $(patsubst %.cpp,$(OBJDIR)/%.o, $(CPP_FILES))
SRC := $(patsubst %.cpp,$(SRCDIR)/%.o, $(CPP_FILES))
TARGET:= nohupshd
all: $(TARGET)
$(TARGET): $(OBJ)
$(LD) -o $(TARGET) $(OBJ) $(LIBS)
clean:
rm -f $(OBJ) $(ASM) $(TARGET)
-include $(patsubst %.cpp,$(OBJDIR)/%.d, $(CPP_FILES))
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(OBJDIR)/%.d
#mkdir -p `dirname $#`
$(CC) $(CXXFLAGS) -c $< -o $# $(INCLUDE_PATHS)
$(OBJDIR)/%.d: $(SRCDIR)/%.cpp
#mkdir -p `dirname $#`
$(CC) $(CXXFLAGS) -MM -MT $# -MF $(OBJDIR)/$*.d -c $< $(INCLUDE_PATHS)
After some experimenting I found a solution on how to compile a shared library under cygwin.
Apparently the compiler is looking for a DLL file even though it is inside cygwin. so the first step is to add your path, where the library is going to be to the PATH variable.
export PATH=$PATH:/cygdrive/d/src/c/lib
Apparently when linking against a shared library, the linker seems to look for a DLL file by default. I don't know why, because inside cygwin I would expect it to look for a .so file just like on other UNIX systems.
However, there are two solutions to this, which both work.
First, you can create a link to your .so library with the name .dll
ln -s /cygdrive/d/src/lib/libsupport.so libsupport.dll
In this case the makefile doesn't have to be changed and -lsupport will find the library while linking. I prefer this solution.
Second, you can specify the linker option with the full name.
LIBS:= -L /cygdrive/d/src/c/lib -l:libsupport.so
then you don't have to create a link.
So the crucial thing seems to be that the shared library must be in the PATH under cygwin. Using LD_LIBRARY_PATH doesn't help in that case as you can link the executable, but when trying to run it, it will not find it.
ldd nohupshd.exe
libsupport.so => not found
UPDATE: For some reason when I checked with ldd, my library was suddenly gone from the list. I found out that cygwin uses the name to differentiate between MS Windows and Unix shared libraries. So in order to make it work, the name of the library must be cyg.so to make it work, otherwise the exectuable seems to be some Windows build. In this case you don't need to create the link named x.dll as the shared library stays inside the Unix environment.
$(LNK) -o cyg$(TARGET).so $(OBJ) -shared
When using eclipse for debugging, the path to the shared library must also be in the windows path environment variable. Otherwise the debug session immediately terminates without an error.