0

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)?

4

1 回答 1

0

根据手册页:

-pie
    Produce a position independent executable.

因为,您正在构建共享对象,您需要删除它,否则它会抱怨“main”。它适用于 Mac OS X,因为如果在构建非可执行文件时使用它,它会简单地忽略 -pie 开关。

于 2013-07-30T12:26:29.970 回答