Domanda

I am creating a jni library that uses GraphicsMagick for some of it's functionality. I have the following files in a directory

phash.h
phash.cc
thumbnail.h
thumbnail.cc
image_jni.h  // This is generated by the javah tool
image_jni.cc

To compile a .so file I am using a make file. I first generate the .o files for each of the sources like this:

HEADERS = image_jni.h phash.h thumbnail.h

CPPFLAGS = $(PLATFORM_CPPFLAGS) -I/opt/X11/include `GraphicsMagick++-config --cppflags`

CXXFLAGS = $(PLATFORM_CXXFLAGS) -fPIC -std=gnu++11 -Os `GraphicsMagick++-config --cxxflags`

LDFLAGS = $(PLATFORM_LDFLAGS) -fPIC -lc -std=gnu++11 -L/opt/X11/lib -lX11 `GraphicsMagick++-config --ldflags --libs`

PROJECT_ROOT = ../../..

LIBPATH = $(PROJECT_ROOT)/lib/libMyfoo.$(LIB_EXT)

%.o: %.cc $(HEADERS)
    $(CXX) -o $@ $(CPPFLAGS) $(CXXFLAGS) -c $< 

$(LIBPATH): phash.o thumbnail.o image_jni.o
    $(CXX) -o $@ -shared $^ $(LDFLAGS)

The platform specific flags for linux are set as follows:

PLATFORM_CPPFLAGS = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux
LIB_EXT = so

This works fine on Mac OS X and I can use the shared library in my Java code. However this does not work on Linux with Gcc 4.7.3. It works fine when creating the .o files but when creating the .so it complains with the following cryptic error message:

g++ -o ../../../lib/libMyfoo.so -shared phash.o thumbnail.o image_jni.o  -fPIC -lc -std=gnu++11 -L/opt/X11/lib -lX11 `GraphicsMagick++-config --ldflags --libs`
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [../../../lib/libMyfoo.so] Error 1

The translation from the make file seems to be legitimate. My guess is that g++ is not aware that it needs to create a shared library. It could also be a weird interaction between GraphicsMagick++-config --ldflags --libs and my own linker options. The Graphics Magick command expands to:

-L/usr/lib -fPIE -pie -Wl,-z,relro -Wl,-z,now -L/usr/lib/X11 -L/usr/lib -L/usr/lib
-lGraphicsMagick++ -lGraphicsMagick -llcms -ltiff -lfreetype -ljasper -ljpeg -lpng -lwmflite -lXext -lSM -lICE -lX11 -lbz2 -lxml2 -lz -lm -lgomp -lpthread -lltdl

Maybe the -fPIE -pie options don't go well with the rest of my options (fPIC)?

È stato utile?

Soluzione

As per man page:

-pie
    Produce a position independent executable.

As, you are building shared object, you need to remove that, otherwise it will complain for "main". It works on Mac OS X, because it simply ignores -pie switch if used while building non-executables.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top