I'm having hard time trying to create a shared library that has ffmpeg libraries "baked in" as static ones.
Consider the following directory schema:
include/
my own .h files
ext/
ffmpeg .h files
lib/
libav*.a archive files (softlinks to the actual .a files)
libValkka.so (my shared library)
test/
mytest.cpp
bin/
(binaries appear here)
I've come a long way (see Including objects to a shared library from a C++ archive (.a) ) and the library compiles ok with this: ([STUFF] has been omitted for brevity)
/usr/bin/c++ -fPIC -std=c++14 -pthread -Iinclude/ext -I/usr/include/libdrm -g -shared -Wl,-soname,libValkka.so -o lib/libValkka.so CMakeFiles/Valkka.dir/src/avthread.cpp.o CMakeFiles/Valkka.dir/src/opengl.cpp.o CMakeFiles/Valkka.dir/src/openglthread.cpp.o [STUFF] CMakeFiles/Valkka.dir/src/filters.cpp.o -lX11 -lGLEW -lGLU -lGL -Wl,--allow-multiple-definition -Wl,-Bsymbolic -Wl,--whole-archive -Wreorder lib/libavdevice.a lib/libavfilter.a lib/libavformat.a lib/libavcodec.a lib/libavutil.a lib/libswscale.a lib/libswresample.a -Wl,--no-whole-archive
However, when creating executables - their source code does not use any ffmpeg api (just my own api) - with:
c++ -std=c++14 -pthread -Iinclude -Iinclude/ext -Llib test/mytest.cpp -lValkka -g -o bin/mytest
I get a hoard of errors about missing ffmpeg dependencies. Not everything is missing, just some weird stuff:
lib/libValkka.so: undefined reference to `pa_stream_get_index'
lib/libValkka.so: undefined reference to `deflateInit_'
lib/libValkka.so: undefined reference to `pa_stream_get_state'
lib/libValkka.so: undefined reference to `lzma_stream_decoder'
lib/libValkka.so: undefined reference to `BZ2_bzDecompress'
lib/libValkka.so: undefined reference to `vaInitialize'
lib/libValkka.so: undefined reference to `pa_stream_unref'
lib/libValkka.so: undefined reference to `deflateInit2_'
lib/libValkka.so: undefined reference to `snd_pcm_close'
...
lib/libValkka.so: undefined reference to `vaGetDisplayDRM'
lib/libValkka.so: undefined reference to `vaMaxNumEntrypoints'
lib/libValkka.so: undefined reference to `uncompress'
lib/libValkka.so: undefined reference to `pa_stream_drop'
lib/libValkka.so: undefined reference to `pa_context_connect'
lib/libValkka.so: undefined reference to `FT_Get_Kerning'
lib/libValkka.so: undefined reference to `ass_free_track'
lib/libValkka.so: undefined reference to `pa_operation_unref'
lib/libValkka.so: undefined reference to `FT_Stroker_Done'
lib/libValkka.so: undefined reference to `vaTerminate'
lib/libValkka.so: undefined reference to `ass_new_track'
lib/libValkka.so: undefined reference to `jack_client_close'
...
lib/libValkka.so: undefined reference to `xcb_xfixes_query_version'
lib/libValkka.so: undefined reference to `xcb_shape_rectangles'
lib/libValkka.so: undefined reference to `pa_mainloop_free'
lib/libValkka.so: undefined reference to `snd_device_name_hint'
lib/libValkka.so: undefined reference to `vaCreateImage'
lib/libValkka.so: undefined reference to `vaBeginPicture'
lib/libValkka.so: undefined reference to `DtsSetColorSpace'
lib/libValkka.so: undefined reference to `vaDestroyConfig'
lib/libValkka.so: undefined reference to `pa_stream_writable_size'
lib/libValkka.so: undefined reference to `snd_pcm_hw_params_get_buffer_size_max'
lib/libValkka.so: undefined reference to `ass_read_file'
This is pretty frustrating, especially when I can see that those names are included in the shared library..!
nm lib/libValkka.so | grep "vaBeginPicture"
gives
U vaBeginPicture
etc. I thought it might be a problem regarding the dependency order the archive .a files, and also tried with:
..... -Wl,--allow-multiple-definition -Wl,-Bsymbolic -Wl,--start-group -Wl,--whole-archive -Wreorder lib/libavdevice.a lib/libavfilter.a lib/libavformat.a lib/libavcodec.a lib/libavutil.a lib/libswscale.a lib/libswresample.a -Wl,--no-whole-archive -Wl,--end-group
But the problem persists.
I have succesfully created a shared library that does not "bake in" those .a archives, i.e. that just depends dynamically on ffmpeg libraries, and there are no such problems.
I am baffled.. Have I misunderstood something fundamental, forgot some annoying linked option, or both? Help appreciated!
You need to link your shared library with 3rd party/system libraries required by ffmpeg: libbz2, libva, libxcb, libass, freetype2 etc. Actual list should be somewhere in ffmpeg distribution/build artifacts (automake's .pc files)
ignore-all is not a good idea; your application might run OK but these unresolved items are still there; it will crash as soon as it hits any of them. My guess is that most of them won't be hit, ever, since they are for libavdevice which you might not be even using, but still a bad idea. Also, check if you actually need that libavdevice library - you might trim a list of required libraries quite a bit if you get rid of that one.
Telling linker to ignore unresolved symbols when creating the executable does the trick:
c++ -std=c++14 -pthread -Iinclude -Iinclude/ext -Llib test/mytest.cpp -lValkka -g -o bin/mytest -Wl,--unresolved-symbols=ignore-all
The resulting executable also runs OK.
However.. using such a linker flag rubs me the wrong way. Maybe there is a better option? And why those symbols are not found in the first place?
EDIT
Following Andrey's suggestion, I stripped all external libraries from ffmpeg, with the aid of ffmpeg's configure script. That was a bit awkward process, so I created a nice python script that does it automagically. It might be a bit of an overkill, but here it goes:
#!/usr/bin/python3
"""
* Creates script "run_configure.bash" that launches ffmpeg's "configure" script with correct parameters (enabling/disabling stuff)
* Run in the same directory where you have ffmpeg's configure script
"""
import subprocess
import os
import re
def features(switch, adstring="", remove=[]):
p=subprocess.Popen(["./configure",switch],stdout=subprocess.PIPE)
st=p.stdout.read()
fst=""
for s in st.split():
ss=s.decode("utf-8")
ok=True
for rem in remove:
if (ss.find(rem)!=-1):
ok=False
if ok: fst+=adstring+ss+" "
return fst
def disable_external():
p=subprocess.Popen(["./configure","-h"],stdout=subprocess.PIPE)
st=p.stdout.read().decode("utf-8")
# find some text tags from the configure output:
# i1=st.find("External library support:")
i1=st.find("themselves, not all their features will necessarily be usable by FFmpeg.")
i2=st.find("Toolchain options:")
st=st[i1:i2]
""" # debugging ..
print(st)
stop
"""
p=re.compile('--(enable|disable)-(\S*)')
switches=[]
for sw in p.findall(st):
if (sw[1] not in switches):
# print(sw[1]) # debugging
switches.append(sw[1])
fst=""
for sw in switches:
fst+="--disable-"+sw+" "
return fst
st ="./configure "
st+="--disable-everything --disable-doc --disable-gpl --disable-pthreads --enable-static --enable-shared "
st+= disable_external()
st+= features("--list-decoders",adstring="--enable-decoder=", remove=["vdpau","crystalhd","zlib"])
st+= features("--list-muxers", adstring="--enable-muxer=")
st+= features("--list-demuxers",adstring="--enable-demuxer=")
st+= features("--list-parsers", adstring="--enable-parser=")
f=open("run_configure.bash","w")
f.write("#!/bin/bash\n")
f.write(st+"\n")
f.close()
os.system("chmod a+x run_configure.bash")
print("\nNext run ./run_configure.bash\n")
"""
For cleaning up .a and .so files, use
find -name *.a -exec ls {} \;
find -name *.so* -exec ls {} \;
"""
Hopefully someone finds it useful. Run with python3.
Related
Overview
I am attempting to convert a C++ project from a Visual Studio solution to a makefile project (using g++), as a first step to supporting multiple platforms with ease. This project requires the Simple DirectMedia Layer 2 (SDL2) and SDL_image libraries. The project previously compiled without errors, and I have since corrected any errors halting the g++ compiler. I am still using Windows x64 and MinGW x64 at this point.
Problem
When linking, g++ throws errors as though there is something wrong with the SDL2 library, claiming that all functions of SDL2 can't be found. However, I know it is finding the libraries, because when I provide an incorrect name or path, I get an explicit error.
Here is my new makefile, apologies if it isn't up to standard:
# Source files
SRC_ENTITIES = Entity_Block.cpp Entity_Controller.cpp Entity_Cursor.cpp Entity_GreenEye.cpp Entity_Harry.cpp
SRC_ENGINE = Game.cpp Sound.cpp SoundManager.cpp Sprite.cpp Texture.cpp TextureManager.cpp Entity.cpp EntityManager.cpp
SRC_ENTRY = main.cpp
# Source and destination
SOURCE = $(SRC_ENTITIES) $(SRC_ENGINE) $(SRC_ENTRY)
DEST = crystal_engine.bin
# Compiler options
OUTPUT = -o $(DEST)
INCLUDES = -I . -I.\include\windows\SDL2-devel-2.0.4-mingw\SDL2-2.0.4\x86_64-w64-mingw32\include\SDL2 -I.\include\windows\SDL2_image-devel-2.0.1-mingw\SDL2_image-2.0.1\x86_64-w64-mingw32\include\SDL2
LIBPATHS = -L.\include\windows\SDL2-devel-2.0.4-mingw\SDL2-2.0.4\x86_64-w64-mingw32\lib -L.\include\windows\SDL2_image-devel-2.0.1-mingw\SDL2_image-2.0.1\x86_64-w64-mingw32\lib
LIBRARIES = -lSDL2 -lSDL2main -lSDL2_image
STANDARD = -std=c++0x
FLAGS = -Wall
default:
echo No task selected
compile:
g++ $(STANDARD) $(INCLUDES) $(FLAGS) $(SOURCE) $(OUTPUT) $(LIBPATHS) $(LIBRARIES)
run:
./$(DEST)
run_win:
$(DEST)
Therefor the command line currently looks like this:
g++ -std=c++0x -I . -I.\include\windows\SDL2-devel-2.0.4-mingw\SDL2-2.0.4\x86_64-w64-mingw32\include\SDL2 -I.\include\windows\SDL2_image-devel-2.0.1-mingw\SDL2_image-2.0.1\x86_64-w64-mingw32\include\SDL2 -Wall Entity_Block.cpp Entity_Controller.cpp Entity_Cursor.cpp Entity_GreenEye.cpp Entity_Harry.cpp Game.cpp Sound.cpp SoundManager.cpp Sprite.cpp Texture.cpp TextureManager.cpp Entity.cpp EntityManager.cpp main.cpp -o crystal_engine.bin -L.\include\windows\SDL2-devel-2.0.4-mingw\SDL2-2.0.4\x86_64-w64-mingw32\lib -L.\include\windows\SDL2_image-devel-2.0.1-mingw\SDL2_image-2.0.1\x86_64-w64-mingw32\lib -lSDL2 -lSDL2main -lSDL2_image
Disregarding warnings (removing -Wall), the output of the compile looks like this:
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x169): undefined reference to `SDL_GetTicks'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x2b4): undefined reference to `SDL_GetMouseState'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x2c2): undefined reference to `SDL_PollEvent'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x2d0): undefined reference to `SDL_GetTicks'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x363): undefined reference to `SDL_GetTicks'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x3ef): undefined reference to `SDL_GetTicks'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x46c): undefined reference to `SDL_GetTicks'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x4e3): undefined reference to `SDL_RenderClear'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x4fd): undefined reference to `SDL_RenderPresent'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x597): undefined reference to `SDL_ShowCursor'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x5b1): undefined reference to `SDL_Init'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x633): undefined reference to `SDL_CreateRenderer'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x663): undefined reference to `SDL_CreateWindowAndRenderer'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x678): undefined reference to `SDL_SetWindowTitle'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x836): undefined reference to `SDL_SetRenderDrawColor'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x844): undefined reference to `SDL_RenderClear'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x852): undefined reference to `SDL_RenderPresent'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x865): undefined reference to `SDL_SetHint'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x881): undefined reference to `SDL_RenderSetLogicalSize'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x895): undefined reference to `SDL_GL_SetAttribute'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x8a3): undefined reference to `SDL_GetError'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x8d8): undefined reference to `SDL_GL_SetAttribute'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0x8e6): undefined reference to `SDL_GetError'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0xa3d): undefined reference to `SDL_Quit'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0xaba): undefined reference to `SDL_DestroyWindow'
C:\Users\[...]\ccSkHjgE.o:Game.cpp:(.text+0xad1): undefined reference to `SDL_DestroyRenderer'
f:/mingw/mingw-4.8.1/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: C:\Users\[...]\ccSkHjgE.o: bad reloc address 0x1b in section `.text$printf[_printf]'
collect2.exe: error: ld returned 1 exit status
make: *** [compile] Error 1
Troubleshooting
I have tried a number of things from supplying exact paths to libraries to updating SDL from 2.0.3 to 2.0.4. The behavior is the same. There are two include/lib folders in the MinGW devel folder for each architecture, and changing which one I include does not make a difference.
There seems to be a lot of commotion about the order of which arguments are supplied to g++, given the three posts below:
SDL2 Undefined references to functions
Try to change the sequence of the input params:
I've stumbled over this before (on Linux)
https://askubuntu.com/questions/68922/cant-compile-program-that-uses-sdl-after-upgrade-to-11-10-undefined-reference
Ok, solved. Apparently, for some mysterious reason, the order of the gcc options now matters.
http://smf.cataclysmdda.com/index.php?topic=11028.0
It looks like the SDL2_image library is included, but the main SDL2 library is not (the references could be out of order).
Unfortunately, regardless of how I have reordered the arguments, I can't seem to change this result. Unlike with most issues, I haven't even been able to make it any worse! Any and all help is greatly appreciated.
I don't believe this has anything to do with my code, considering a compile without linking -c completes fine, but if it assists with the solution I would be more than happy to post some of it (it is a LOT of code).
Edits
Per request, here is a dump of the full compile with the -v and -Wall options. It is too large for this question so I threw it in a pastebin.
http://pastebin.com/ydET621i
When using the -DDECLSPEC=__declspec(dllimport) option, the output becomes:
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x169): undefined reference to `_imp__SDL_GetTicks'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x2b6): undefined reference to `_imp__SDL_GetMouseState'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x2c6): undefined reference to `_imp__SDL_PollEvent'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x2d6): undefined reference to `_imp__SDL_GetTicks'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x36b): undefined reference to `_imp__SDL_GetTicks'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x3f9): undefined reference to `_imp__SDL_GetTicks'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x478): undefined reference to `_imp__SDL_GetTicks'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x4f1): undefined reference to `_imp__SDL_RenderClear'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x50d): undefined reference to `_imp__SDL_RenderPresent'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x5a9): undefined reference to `_imp__SDL_ShowCursor'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x5c5): undefined reference to `_imp__SDL_Init'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x649): undefined reference to `_imp__SDL_CreateRenderer'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x67b): undefined reference to `_imp__SDL_CreateWindowAndRenderer'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x692): undefined reference to `_imp__SDL_SetWindowTitle'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x852): undefined reference to `_imp__SDL_SetRenderDrawColor'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x862): undefined reference to `_imp__SDL_RenderClear'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x872): undefined reference to `_imp__SDL_RenderPresent'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x887): undefined reference to `_imp__SDL_SetHint'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x8a5): undefined reference to `_imp__SDL_RenderSetLogicalSize'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x8bb): undefined reference to `_imp__SDL_GL_SetAttribute'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x8cb): undefined reference to `_imp__SDL_GetError'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x902): undefined reference to `_imp__SDL_GL_SetAttribute'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0x912): undefined reference to `_imp__SDL_GetError'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0xa6b): undefined reference to `_imp__SDL_Quit'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0xaea): undefined reference to `_imp__SDL_DestroyWindow'
C:\Users\[...]\ccZ61vi9.o:Game.cpp:(.text+0xb03): undefined reference to `_imp__SDL_DestroyRenderer'
f:/mingw/mingw-4.8.1/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: C:\Users\[...]\ccZ61vi9.o: bad reloc address 0x1b in section `.text$printf[_printf]'
collect2.exe: error: ld returned 1 exit status
make: *** [compile] Error 1
Running ar -t libSDL2.a produces the following:
SDL.o
SDL_assert.o
SDL_error.o
SDL_hints.o
SDL_log.o
SDL_atomic.o
SDL_spinlock.o
SDL_audio.o
SDL_audiocvt.o
SDL_audiodev.o
SDL_audiotypecvt.o
SDL_mixer.o
SDL_wave.o
SDL_cpuinfo.o
SDL_dynapi.o
SDL_clipboardevents.o
SDL_dropevents.o
SDL_events.o
SDL_gesture.o
SDL_keyboard.o
SDL_mouse.o
SDL_quit.o
SDL_touch.o
SDL_windowevents.o
SDL_rwops.o
SDL_haptic.o
SDL_gamecontroller.o
SDL_joystick.o
e_atan2.o
e_log.o
e_pow.o
e_rem_pio2.o
e_sqrt.o
k_cos.o
k_rem_pio2.o
k_sin.o
k_tan.o
s_atan.o
s_copysign.o
s_cos.o
s_fabs.o
s_floor.o
s_scalbn.o
s_sin.o
s_tan.o
SDL_power.o
SDL_d3dmath.o
SDL_render.o
SDL_yuv_mmx.o
SDL_yuv_sw.o
SDL_render_d3d.o
SDL_render_d3d11.o
SDL_render_gl.o
SDL_shaders_gl.o
SDL_render_gles.o
SDL_render_gles2.o
SDL_shaders_gles2.o
SDL_render_psp.o
SDL_blendfillrect.o
SDL_blendline.o
SDL_blendpoint.o
SDL_drawline.o
SDL_drawpoint.o
SDL_render_sw.o
SDL_rotate.o
SDL_getenv.o
SDL_iconv.o
SDL_malloc.o
SDL_qsort.o
SDL_stdlib.o
SDL_string.o
SDL_thread.o
SDL_timer.o
SDL_RLEaccel.o
SDL_blit.o
SDL_blit_0.o
SDL_blit_1.o
SDL_blit_A.o
SDL_blit_N.o
SDL_blit_auto.o
SDL_blit_copy.o
SDL_blit_slow.o
SDL_bmp.o
SDL_clipboard.o
SDL_egl.o
SDL_fillrect.o
SDL_pixels.o
SDL_rect.o
SDL_shape.o
SDL_stretch.o
SDL_surface.o
SDL_video.o
SDL_nullevents.o
SDL_nullframebuffer.o
SDL_nullvideo.o
SDL_diskaudio.o
SDL_dummyaudio.o
SDL_windows.o
SDL_xinput.o
SDL_windowsclipboard.o
SDL_windowsevents.o
SDL_windowsframebuffer.o
SDL_windowskeyboard.o
SDL_windowsmessagebox.o
SDL_windowsmodes.o
SDL_windowsmouse.o
SDL_windowsopengl.o
SDL_windowsopengles.o
SDL_windowsshape.o
SDL_windowsvideo.o
SDL_windowswindow.o
SDL_winmm.o
SDL_directsound.o
SDL_xaudio2.o
SDL_dinputjoystick.o
SDL_mmjoystick.o
SDL_windowsjoystick.o
SDL_xinputjoystick.o
SDL_dinputhaptic.o
SDL_windowshaptic.o
SDL_xinputhaptic.o
SDL_syspower.o
SDL_sysfilesystem.o
SDL_sysmutex.o
SDL_syssem.o
SDL_systhread.o
SDL_systls.o
SDL_syscond.o
SDL_systimer.o
SDL_sysloadso.o
Thanks to suggestions from #J.JHakala and #user657267 I have reached the conclusion that my installation of MinGW is actually 32 bit! Given that I was using the 64 bit libraries, they would read in like any other library, but the functions within them were not recognized.
For anyone else having this problem, you can download the 64 bit version of MinGW or alternatively just switch which libraries you are importing.
x86: i686-w64-mingw32
x64: x86_64-w64-mingw32
I'm creating a shared library/DLL using cygwin which makes use of Xerces. When I call the xercesc functions from the main application everything is fine, but when I try to put some code into the library, then I get undefined symbols for all the static stuff that xerxesc defines.
For example:
std::string fromXMLString(XMLCh *oXMLString)
{
std::string result;
xercesc::DOMImplementation *impl = xercesc::DOMImplementationRegistry::getDOMImplementation(X("Core"));
char *temp = xercesc::XMLString::transcode(oXMLString);
result = temp;
xercesc::XMLString::release(&temp);
return result;
}
Linking:
g++ -shared -Wl,-soname,cygsupport.so -L /usr/local/lib -l xerces-c -o cygsupport.so obj/helper/xml_helper.o
When linking the library, I get:
/usr/local/include/xercesc/internal/XSerializable.hpp:37: undefined reference to `xercesc_3_1::DOMImplementationRegistry::getDOMImplementation(wchar_t const*)'
/usr/local/include/xercesc/internal/XSerializable.hpp:37: undefined reference to `xercesc_3_1::XMLPlatformUtils::fgMemoryManager'
/usr/local/include/xercesc/internal/XSerializable.hpp:37: undefined reference to `xercesc_3_1::XMLString::transcode(wchar_t const*, xercesc_3_1::MemoryManager*)'
/usr/local/include/xercesc/internal/XSerializable.hpp:37: undefined reference to `xercesc_3_1::XMLPlatformUtils::fgMemoryManager'
/usr/local/include/xercesc/internal/XSerializable.hpp:37: undefined reference to `xercesc_3_1::XMLString::release(char**, xercesc_3_1::MemoryManager*)'
/usr/local/include/xercesc/internal/XSerializable.hpp:37: undefined reference to `xercesc_3_1::XMLPlatformUtils::fgMemoryManager'
/usr/local/include/xercesc/internal/XSerializable.hpp:37: undefined reference to `xercesc_3_1::XMLString::release(wchar_t**, xercesc_3_1::MemoryManager*)'
/usr/local/include/xercesc/internal/XSerializable.hpp:37: undefined reference to `xercesc_3_1::XMLPlatformUtils::fgMemoryManager'
...
Finally after several days on looking into this issue I found the solution. It is as simple as stupid.
My original linker commandline looked like this:
g++ -shared -o mylib.so -L/usr/local/lib -lxerces-c objects...
Googling on this problem didn't yield anything usefull, so finally I decided to create a fresh new sample project with eclipse and suddenly it worked. The only difference was in the commandline to the linker. When I applied the same order to my main project it suddenly compiled.
g++ -L/usr/local/lib -shared -o mylib.so objects... -lxerces-c
Note that in the above line, the objects come before the library, and apperently this makes the difference. I thought that the ordering of the libs only applies to the libraries, but apparently also the objects must be ordered appropriately.
I'm having trouble compiling some examples in a odbc sdk. After some time mingling with the library order, I somehow managed to get the number of undefined references to just a handful of them.
Sadly, I can't figure out how to get rid of the remaining ones. Here's the command that's failing:
g++ -Wall -z defs -m64 -DSIMBA -D_REENTRANT -fPIC -O0 -g -shared Common/TabbedUnicodeFileReader_Linux_x8664_debug.cpp.o Core/QSConnection_Linux_x8664_debug.cpp.o Core/QSDriver_Linux_x8664_debug.cpp.o Core/QSEnvironment_Linux_x8664_debug.cpp.o Core/QSStatement_Linux_x8664_debug.cpp.o DataEngine/QSDataEngine_Linux_x8664_debug.cpp.o DataEngine/QSMetadataHelper_Linux_x8664_debug.cpp.o DataEngine/QSTable_Linux_x8664_debug.cpp.o DataEngine/QSTableUtilities_Linux_x8664_debug.cpp.o DataEngine/QSTypeInfoMetadataSource_Linux_x8664_debug.cpp.o Common/QSTableMetadataFile_Unix_Linux_x8664_debug.cpp.o Common/QSUtilities_Unix_Linux_x8664_debug.cpp.o Main_Unix_Linux_x8664_debug.cpp.o -Wl,--no-undefined -Wl,--no-allow-shlib-undefined -Wl,--whole-archive,/home/hector/Downloads/SimbaEngineSDK/9.0/DataAccessComponents//Lib/Linux_x8664/libSimbaDSI_debug.a,/home/hector/Downloads/SimbaEngineSDK/9.0/DataAccessComponents//Lib/Linux_x8664/libSimbaSupport_debug.a,/home/hector/Downloads/SimbaEngineSDK/9.0/DataAccessComponents//Lib/Linux_x8664/libAEProcessor_debug.a,/home/hector/Downloads/SimbaEngineSDK/9.0/DataAccessComponents//Lib/Linux_x8664/libCore_debug.a,/home/hector/Downloads/SimbaEngineSDK/9.0/DataAccessComponents//Lib/Linux_x8664/libDSIExt_debug.a,/home/hector/Downloads/SimbaEngineSDK/9.0/DataAccessComponents//Lib/Linux_x8664/libExecutor_debug.a,/home/hector/Downloads/SimbaEngineSDK/9.0/DataAccessComponents//Lib/Linux_x8664/libParser_debug.a,/home/hector/Downloads/SimbaEngineSDK/9.0/DataAccessComponents//Lib/Linux_x8664/libSimbaODBC_debug.a -Wl,--no-whole-archive -Wl,--soname=../Bin/Linux_x8664/libQuickstart_debug.so -L/home/hector/Downloads/SimbaEngineSDK/9.0/DataAccessComponents//ThirdParty/icu/Linux_x8664/lib -licuuc_simba64 -licudata_simba64 -licui18n_simba64 -lpthread -lm -lc -ldl -Wl,--version-script=exports_Linux.map -o ../Bin/Linux_x8664/libQuickstart_debug.so
Edit: Missing symbols
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libdl.so: undefined reference to `_dl_rtld_di_serinfo#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libpthread.so.0: undefined reference to `_dl_allocate_tls_init#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libpthread.so.0: undefined reference to `__libc_stack_end#GLIBC_2.2.5'
/lib/x86_64-linux-gnu/libpthread.so.0: undefined reference to `_dl_get_tls_static_info#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libpthread.so.0: undefined reference to `__tls_get_addr#GLIBC_2.3'
/lib/x86_64-linux-gnu/libpthread.so.0: undefined reference to `_dl_deallocate_tls#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libpthread.so.0: undefined reference to `_rtld_global#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libc.so.6: undefined reference to `_dl_argv#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libc.so.6: undefined reference to `__libc_enable_secure#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libpthread.so.0: undefined reference to `_dl_allocate_tls#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libpthread.so.0: undefined reference to `_rtld_global_ro#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libpthread.so.0: undefined reference to `_dl_make_stack_executable#GLIBC_PRIVATE'
Fixed:
Removing -Wl,--no-allow-shlib-undefined seemed to do the trick. The built shared library seems to work perfectly.
I had a similar issue with a completely separate application. The following compile time flag worked for me:
-B/usr/lib/gold-ld/
which i found at:
https://bugs.launchpad.net/ubuntu/+source/binutils/+bug/885927
I'm using gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1 I was trying to compile with lto.
You do a very common newbie mistake. you place the libraries to link with in the middle or the beginning of the command line. The linker GCC uses needs dependencies in reverse order. That means if you have an source/object file S using a function in library L, the file A has to be before the library L on the command line.
In short, put the libraries (-lm -lc -ldl) last on the command line instead.
If linker fails to resolve all referenced symbols then this can be a result of wrong order of provided libraries. If you are not sure what is the correct order then put archives in "--start-group archives --end-group" which according to ld manual will force linker to search the specified archives repeatedly until no new undefined references are created. But pay attention to a performance cost.
The OP mentioned "Removing -Wl,--no-allow-shlib-undefined" helped.
In my case I had to add the opposite:
-Wl,--allow-shlib-undefined
(Everything was working fine with an older version of GCC)
I'm trying to link an open source project that uses GSL and I get undefined references in libgsl. I'm using eclipse and I've added -lgslcblas -lgsl to the libraries setting. What am I missing?
g++ -L/home/erwin/ochack/bin/opencog/spatial -L/home/erwin/ochack/bin/opencog/persist/sql -L/home/erwin/ochack/bin/opencog/guile -L/home/erwin/ochack/bin/opencog/util -L/home/erwin/ochack/bin/opencog/persist/xml -o "ocserver" ./opencog/server/Agent.o ./opencog/server/BaseServer.o ./opencog/server/BuiltinRequestsModule.o ./opencog/server/CogServer.o ./opencog/server/CogServerMain.o ./opencog/server/ConsoleSocket.o ./opencog/server/DataRequest.o ./opencog/server/ExitRequest.o ./opencog/server/HelpRequest.o ./opencog/server/ListRequest.o ./opencog/server/LoadModuleRequest.o ./opencog/server/LoadRequest.o ./opencog/server/NetworkServer.o ./opencog/server/Request.o ./opencog/server/SaveRequest.o ./opencog/server/ServerSocket.o ./opencog/server/ShutdownRequest.o ./opencog/server/SleepRequest.o ./opencog/server/SystemActivityTable.o ./opencog/server/UnloadModuleRequest.o ./opencog/atomspace/Atom.o ./opencog/atomspace/AtomSpace.o ./opencog/atomspace/AtomSpaceAsync.o ./opencog/atomspace/AtomSpaceImpl.o ./opencog/atomspace/AtomSpaceInit.o ./opencog/atomspace/AtomTable.o ./opencog/atomspace/AttentionBank.o ./opencog/atomspace/AttentionValue.o ./opencog/atomspace/ClassServer.o ./opencog/atomspace/CompositeTruthValue.o ./opencog/atomspace/CountTruthValue.o ./opencog/atomspace/FixedIntegerIndex.o ./opencog/atomspace/Handle.o ./opencog/atomspace/HandleEntry.o ./opencog/atomspace/HandleIterator.o ./opencog/atomspace/HandleSeqIndex.o ./opencog/atomspace/HandleSet.o ./opencog/atomspace/HandleTemporalPair.o ./opencog/atomspace/HandleTemporalPairEntry.o ./opencog/atomspace/HandleToTemporalEntryMap.o ./opencog/atomspace/ImportanceIndex.o ./opencog/atomspace/IndefiniteTruthValue.o ./opencog/atomspace/Link.o ./opencog/atomspace/LinkIndex.o ./opencog/atomspace/NameIndex.o ./opencog/atomspace/Node.o ./opencog/atomspace/NodeIndex.o ./opencog/atomspace/NullTruthValue.o ./opencog/atomspace/PredicateIndex.o ./opencog/atomspace/SimpleTruthValue.o ./opencog/atomspace/SpaceServer.o ./opencog/atomspace/StatisticsMonitor.o ./opencog/atomspace/StringIndex.o ./opencog/atomspace/TLB.o ./opencog/atomspace/TargetTypeIndex.o ./opencog/atomspace/Temporal.o ./opencog/atomspace/TemporalEntry.o ./opencog/atomspace/TemporalMap.o ./opencog/atomspace/TemporalTable.o ./opencog/atomspace/TemporalToHandleSetMap.o ./opencog/atomspace/TimeServer.o ./opencog/atomspace/Trail.o ./opencog/atomspace/TruthValue.o ./opencog/atomspace/TypeIndex.o ./opencog/atomspace/VersionHandle.o ./opencog/atomspace/ZMQMessages.pb.o -lboost_filesystem -lpersist -lsmob -lgslcblas -lgsl -lboost_signals -lboost_thread -lxml -lutil -lSpaceMap -lzmq -lboost_system -lprotobuf
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libgsl.so: undefined reference to `cblas_zher2k'
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libgsl.so: undefined reference to `cblas_strsv'
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libgsl.so: undefined reference to `cblas_zdotc_sub'
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libgsl.so: undefined reference to `cblas_dtrsm'
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libgsl.so: undefined reference to `cblas_zhemm'
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libgsl.so: undefined reference to `cblas_sgemv'
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libgsl.so: undefined reference to `cblas_strmm'
etc...
I found the solution: apparently the order of the libraries is important: -lgsl -lgslcblas works.
Potentially, there are lots of things that could be wrong here.
Have you made sure that you've added the libraries properly in Eclipse? For instance, you shouldn't specify -lgsl in Paths and Symbols -> Libraries. Eclipse adds the preceding -l itself so all you specify is gsl.
Have you added the library paths in the build variant that you're actually trying to run? You may, for instance, have specified library paths only for the Debug variant when you're trying to get a Release variant build going.
Alternatively, (and this is really just a guess), it's reasonably common for scientific libraries to allow you to use an external version of BLAS. Sometimes their configuration settings even insist on external BLAS as a default. Does passing -lcblas as a link option help out with these errors?
I'm working on a really old source code (compiled in Red Hat). Before it had lua-4.0.1 so I just compiled the latest lua (lua-5.1.4) and installed it in the same directory as the old one. The implementation isn't very big so there wasn't much to change except a few function names and I had to include "lauxlib.h" to get it to compile. It compiles without any problems but it gives these linking errors.
/usr/local/lib/liblua.a(loadlib.o): In function `ll_load':
loadlib.o(.text+0x19): undefined reference to `dlopen'
loadlib.o(.text+0x2a): undefined reference to `dlerror'
/usr/local/lib/liblua.a(loadlib.o): In function `ll_sym':
loadlib.o(.text+0x52): undefined reference to `dlsym'
loadlib.o(.text+0x63): undefined reference to `dlerror'
/usr/local/lib/liblua.a(loadlib.o): In function `ll_unloadlib':
loadlib.o(.text+0x8): undefined reference to `dlclose'
Basically all the paths are correct but I use the same flags for the compiler as the old one, I havent changed the makefile at all.
-static -lpthread -lnsl -lutil -ldl -lmysqlclient -llua -llualib -lz -lcppunit
The ldl flag is already there.
I just want to know things to try. Everything is appreciated. This is driving me insane.
Place -ldl at the end of the liner command. The order is important.
The linker searches for libraries fulfilling an unreferenced symbol only in libs which are standing more right on the command line. Your new liblua.a now uses dlopen and friends, while the older didn't. Since -ldl is left of -llua, the linker does not use libdl to link the lua references.