Building OpenCV as a static library leads to thousands of undefined references - c++

I am working on Ubuntu 18.04 and i want to build OpenCV(4.1.0) as static lib and create a sample program. Building OpenCV works flawlessly but i get thousands of errors when i run the test application.
Building OpenCV:
configure cmake:
cmake -D CMAKE_BUILD_TYPE=Release -D
OPENCV_GENERATE_PKGCONFIG=ON -D
BUILD_SHARED_LIBS=OFF -D
OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-4.1.0/modules
-D CMAKE_INSTALL_PREFIX=/usr/local/opencv
..
build:
make -j8
install:
sudo make install
pkg-config setup:
sudo cp unix-install/opencv4.pc /usr/lib/x86_64-linux-gnu/pkgconfig/
Sample Program
#include <stdio.h>
#include <opencv2/opencv.hpp>
int main( int argc, char** argv )
{
cv::Mat testmat;
printf("Test\n");
return 0;
}
build:
g++ TestApp.cpp -o TestApp `pkg-config --cflags --libs opencv4`
I get these errors: Full Console.log
/usr/local/opencv/lib/libopencv_highgui.a(window_gtk.cpp.o): In function `cvImageWidget_class_init(void*, void*)&apos;: window_gtk.cpp:
.text._ZL24cvImageWidget_class_initPvS_+0xa): undefined reference to `gtk_widget_get_type&apos; window_gtk.cpp:
.text._ZL24cvImageWidget_class_initPvS_+0x15): undefined reference to `g_type_class_peek&apos; window_gtk.cpp:
.text._ZL24cvImageWidget_class_initPvS_+0x20): undefined reference to `g_type_check_class_cast&apos; /usr/local/opencv/lib/libopencv_highgui.a(window_gtk.cpp.o): In function `icvOnTrackbar(_GtkWidget*, void*)&apos;: window_gtk.cpp:
.text._ZL13icvOnTrackbarP10_GtkWidgetPv+0xd): undefined reference to `gtk_range_get_type&apos; window_gtk.cpp:
.text._ZL13icvOnTrackbarP10_GtkWidgetPv+0x18): undefined reference to `g_type_check_instance_cast&apos; window_gtk.cpp:
.text._ZL13icvOnTrackbarP10_GtkWidgetPv+0x20): undefined reference to `gtk_range_get_value&apos; /usr/local/opencv/lib/libopencv_highgui.a(window_gtk.cpp.o): In function `std::_Sp_counted_ptr_inplace&lt;CvWindow, std::allocator&lt;CvWindow&gt;, (__gnu_cxx::_Lock_policy)2&gt;::_M_dispose()&apos;: window_gtk.cpp:
.text._ZNSt23_Sp_counted_ptr_inplaceI8CvWindowSaIS0_ELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEv[_ZNSt23_Sp_counted_ptr_inplaceI8CvWindowSaIS0_ELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEv]+0x12): undefined reference to `gtk_widget_destroy&apos; /usr/local/opencv/lib/libopencv_highgui.a(window_gtk.cpp.o): In function `icvWindowThreadLoop(void*)&apos;: window_gtk.cpp:
.text._ZL19icvWindowThreadLoopPv+0x41): undefined reference to `gtk_main_iteration_do&apos; window_gtk.cpp:
.text._ZL19icvWindowThreadLoopPv+0x53): undefined reference to `g_usleep&apos; window_gtk.cpp:(.text._ZL19icvWindowThreadLoopPv+0x58): undefined reference to `g_thread_yield&apos; window_gtk.cpp:
.text._ZL19icvWindowThreadLoopPv+0x113): undefined reference to `gtk_main_iteration_do&apos; window_gtk.cpp:
.text._ZL19icvWindowThreadLoopPv+0x11d): undefined reference to `g_usleep&apos; window_gtk.cpp:(.text._ZL19icvWindowThreadLoopPv+0x122): undefined reference to `g_thread_yield&apos; /usr/local/opencv/lib/libopencv_highgui.a(window_gtk.cpp.o): In function `cvImageWidget_size_request(_GtkWidget*, _GtkRequisition*)&apos;: window_gtk.cpp:
(.text._ZL26cvImageWidget_size_requestP10_GtkWidgetP15_GtkRequisition+0x19): undefined reference to `gtk_widget_get_type&apos; window_gtk.cpp:
.text._ZL26cvImageWidget_size_requestP10_GtkWidgetP15_GtkRequisition+0x47): undefined reference to `g_type_register_static_simple&apos; window_gtk.cpp:
.text._ZL26cvImageWidget_size_requestP10_GtkWidgetP15_GtkRequisition+0x5b): undefined reference to `g_type_check_instance_cast&apos; /usr/local/opencv/lib/libopencv_highgui.a(window_gtk.cpp.o): In function `cvImageWidget_set_size(_GtkWidget*, int, int)&apos;: window_gtk.cpp:
.text._ZL22cvImageWidget_set_sizeP10_GtkWidgetii+0x19): undefined reference to `gtk_widget_get_type&apos; window_gtk.cpp:.text._ZL22cvImageWidget_set_sizeP10_GtkWidgetii+0x47): undefined reference to `g_type_register_static_simple&apos;
I would be thankful for any help.
Testing a fix:
The obvious answer is that OpenCV can not generate a correct .pc file in static mod. But i dont think thats the problem. To verify i built OpenCV3.2.0(the .pc file generates correctly in 3.2.0 as far as i know) and installed the perbuilt version with "sudo apt-get install libopencv-dev". The prebuilt worked but i got the same errors with the self-built version. I diffchecked both files and they were pretty much the same.
DiffCheck: diff
opencv.pc(pre-build): pre
opencv.pc(self-build): self
build-output(opencv): opencvbuild
build-output(testapp): testappbuild

I fixed it
My build command was missing the --static flag.
g++ TestApp.cpp -o TestApp `pkg-config --cflags --static --libs opencv4`
Now it can build my test application with OpenCV3.2.0 with no problems but I get this error when i use OpenCV4.1.0.
/usr/bin/ld: cannot find -lgflags_shared
I dont think I need this lib so i fixed this by removing -lgflags_shared from the opencv.pc file. Doing it manually works but using the command line is more convenient.
sed -i 's/-lgflags_shared //g' unix-install/opencv4.pc

Related

Undefined Reference to `SDL2_Init` with LD when G++ is not giving an error

(FYI Yes I do know that a similar question exists, But I have already tried all the answers.)
I'm trying to setup SDL2 with MinGW and I have everything set up beside one thing. Whenever I try to compile G++ gives no errors but then LD gives me a: undefined reference to SDL_Init Error.
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: C:\Users\user\AppData\Local\Temp\cc28dE2R.o: in function `SDL_main':
C:\Users\user\Documents\SDL2/src/main.cpp:11: undefined reference to `SDL_Init'
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: C:\Users\user\Documents\SDL2/src/main.cpp:14: undefined reference to `SDL_GetError'
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: C:\Users\user\Documents\SDL2/src/main.cpp:18: undefined reference to `IMG_Init'
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: C:\Users\user\Documents\SDL2/src/main.cpp:20: undefined reference to `SDL_GetError'
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../libmingw32.a(main.o):(.text.startup+0xc0): undefined reference to `WinMain#16'
collect2.exe: error: ld returned 1 exit status
The terminal process "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Command C:\MinGW\bin\g++.exe -g src\*.cpp -o build\game.exe -ID:C:\MinGW\include -LD:C:\MinGW\lib -mwindows -lmingw32 -lSDL2main -lSDL2_image -lSDL2" terminated with exit code: 1.
I have tried to move the args around. doing -mwindows, adding -lmingw32. I still keep getting the same errors.. I was able to fix the WinMain Error.. But everything else I couldn't fix.
The command I'm Running to compile:
C:\MinGW\bin\g++.exe -g src\*.cpp -o build\game.exe -ID:C:\MinGW\include -LD:C:\MinGW\lib -mwindows -lSDL2main -lSDL2_image -lSDL2
If i could get any help that would be amazing
The common cause of mysterious undefined reference errors on MinGW is using libraries compiled for x64 with an x32 compiler, or vice versa. SDL ships both x32 and x64 ones, try the other ones.
I was able to fix the WinMain Error
Be aware that the intended way of fixing undefined reference to WinMain#16 is not adding #define SDL_MAIN_HANDLED and not doing #undef main. Once you get the right libraries (see the first paragraph), the error should disappear by itself.
Make sure you use int main(int, char**) (and not int main() nor void main()), otherwise it won't work.
-ID:C:\MinGW\include -LD:C:\MinGW\lib
You shouldn't need those flags. Those directories will be searched automatically.
Since you didn't specify any other directories, I assume you placed the SDL files directly into the compiler directories, which isn't a good practice, IMO.
I assume D:C: a typo?
-mwindows
The only purpose of this flag (that I know of) is to prevent your app from automatically opening a terminal window for itself, for release builds.

quantlib multithreading/enable-sessions build error on Linux

Getting below errors after compiling quantlib 1.9.2 with boost 1.5.4 on Fedora 20 with enable-sessions flag, and running one of the examples, any ideas?
cd QuantLib-1.9.2/
nohup ./configure --enable-sessions --enable-thread-safe-observer-pattern &
tail -f nohup.out
nohup make &
tail -f nohup.out
cp ql/.libs/libQuantLib.so.0.0.0 /lib64/libQuantLib.so
cp ql/.libs/libQuantLib.so.0.0.0 /lib64/libQuantLib.so.0
cd Examples/BermudanSwaption
g++ BermudanSwaption.cpp -o BermudanSwaption -lQuantLib
/usr/lib/gcc/x86_64-redhat-linux/4.8.3/../../../../lib64/libQuantLib.so:
undefined reference to `pthread_mutexattr_destroy'
undefined reference to `QuantLib::sessionId()'
undefined reference to `pthread_mutexattr_init'
undefined reference to `boost::system::system_category()'
undefined reference to `pthread_mutexattr_settype'
undefined reference to `boost::system::generic_category()'
collect2: error: ld returned 1 exit status
Note: Im trying to enable sessions since getting segfault when quantlib is used in multi-threaded client application
answering my own question
1) the pthread and boost_system error disappeared after adding -lboost_system flag to compiler command line:
g++ BermudanSwaption.cpp -o BermudanSwaption -lQuantLib -lboost_system
this helped: undefined reference to boost::system::system_category() when compiling
2) to solve sessionId error I added sessionId function in BermudanSwaption.cpp as suggested here under QL_ENABLE_SESSIONS: https://github.com/lballabio/QuantLib/blob/master/ql/userconfig.hpp
"You will have to provide and link with the library a sessionId()
function in namespace QuantLib, returning a different session id
for each session"
after I commented out #if defined(QL_ENABLE_SESSIONS) in BermudanSwaption.cpp it compiled without errors:
//#if defined(QL_ENABLE_SESSIONS)
namespace QuantLib {
Integer sessionId() { return 0; }
}
//#endif

Creating a shared library that statically includes ffmpeg

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.

g++ Windows Linker "Undefined reference to..." with SDL2

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

Compiling Box2D HelloWorld on Ubuntu 12.04

I am planning to use Box2D in my C++ project. I have downloaded the latest version (v2.3.0.7 when asking this question) of Box2D and built it successfully. I can run the Testbed without any errors.
Now, I am trying to build the HelloWorld.cpp example, which resides in HelloWorld folder in Box2D source files but I can't compile this example.
Below is my command for compiling:
g++ -g -Wall -L/home/viki/Desktop/collision_test/Box2D_v2.3.0/Box2D/Build/Box2D -lBox2D -I/home/viki/Desktop/collision_test/Box2D_v2.3.0/Box2D HelloWorld.cpp -o Hello
And this is the output I get:
/tmp/cc2U314E.o: In function `main':
/home/viki/Desktop/collision_test/test/HelloWorld.cpp:37: undefined reference to `b2World::b2World(b2Vec2 const&)'
/home/viki/Desktop/collision_test/test/HelloWorld.cpp:46: undefined reference to `b2World::CreateBody(b2BodyDef const*)'
/home/viki/Desktop/collision_test/test/HelloWorld.cpp:52: undefined reference to `b2PolygonShape::SetAsBox(float, float)'
/home/viki/Desktop/collision_test/test/HelloWorld.cpp:55: undefined reference to `b2Body::CreateFixture(b2Shape const*, float)'
/home/viki/Desktop/collision_test/test/HelloWorld.cpp:61: undefined reference to `b2World::CreateBody(b2BodyDef const*)'
/home/viki/Desktop/collision_test/test/HelloWorld.cpp:65: undefined reference to `b2PolygonShape::SetAsBox(float, float)'
/home/viki/Desktop/collision_test/test/HelloWorld.cpp:78: undefined reference to `b2Body::CreateFixture(b2FixtureDef const*)'
/home/viki/Desktop/collision_test/test/HelloWorld.cpp:92: undefined reference to `b2World::Step(float, int, int)'
/home/viki/Desktop/collision_test/test/HelloWorld.cpp:104: undefined reference to `b2World::~b2World()'
/home/viki/Desktop/collision_test/test/HelloWorld.cpp:104: undefined reference to `b2World::~b2World()'
/tmp/cc2U314E.o: In function `b2PolygonShape':
/home/viki/Desktop/collision_test/Box2D_v2.3.0/Box2D/Box2D/Collision/Shapes/b2PolygonShape.h:87: undefined reference to `vtable for b2PolygonShape'
/tmp/cc2U314E.o: In function `~b2PolygonShape':
/home/viki/Desktop/collision_test/Box2D_v2.3.0/Box2D/Box2D/Collision/Shapes/b2PolygonShape.h:28: undefined reference to `vtable for b2PolygonShape'
collect2: ld returned 1 exit status
I'm using
-L flag for searching for libBox2D.a
-l flag for linking Box2D
-I flag for pointing to the Box2D headers directory
What am I missing? Is there any specific library or command argument I am supposed to add?
Put the -lBox2D behind the HelloWorld.cpp
If you have built your project properly the HelloWorld example will be automatically built for you. There's a CMakeLists.txt file in the example folder just run cmake CMakeLists.txt in the folder and then run make. Prior to this you must have built and installed Box2D library. Here is what I did:
I entered the Build directory within the Box2D and typed the following command:
cmake -DBOX2D_INSTALL=ON -DBOX2D_BUILD_SHARED=ON -DCMAKE_INSTALL_PREFIX=/opt/Box2D ..
Then I went one level up to Box2D directory and ran make then sudo make install.
Then I entered the HelloWorld directory and it was automatically built. I didn't have to build it manually. Also this is the output from make that showed the example was built:
Linking CXX static library libBox2D.a
[ 42%] Built target Box2D
[ 43%] Building CXX object HelloWorld/CMakeFiles/HelloWorld.dir/HelloWorld.cpp.o