Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) cannot find -lboost_filesystem (from i686-pc-mingw32-qmake)

 

Link error (BEI 6) I encountered while busy solving How to cross-compile a Qt Creator project from Ubuntu to a windows executable: example 3: console application with a Boost library.

 

 

 

 

 

 

 

System specifics

 

Operating system: Ubuntu 10.04 LTS Lucid Lynx

IDE: Qt Creator 2.0.0

Project type: console application

Compiler: G++ 4.4.1

Libraries used:

 

 

 

 

 

Source code: main.cpp

 

#include <iostream>
#include <string>
#include <vector>
//---------------------------------------------------------------------------
#include <boost/filesystem.hpp>
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/CppGetFilesInFolder.htm
const std::vector<std::string> GetFilesInFolder(const std::string& folder)
{
  std::vector<std::string> v;

  const boost::filesystem::path my_folder
    = boost::filesystem::system_complete(
        boost::filesystem::path(folder));

  if (!boost::filesystem::is_directory(my_folder)) return v;

  const boost::filesystem::directory_iterator j;
  for ( boost::filesystem::directory_iterator i(my_folder);
        i != j;
        ++i)
  {
    if ( boost::filesystem::is_regular_file( i->status() ) )
    {
      const std::string filename = i->path().filename();
      //const std::string full_filename = folder + "/" + filename;
      v.push_back(filename);
    }
  }
  return v;
}
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/CppGetPath.htm
const std::string GetPath(const std::string& filename)
{
  return boost::filesystem::path(filename).parent_path().string();
}
//---------------------------------------------------------------------------
int main(int, char* argv[])
{
  const std::vector<std::string> v = GetFilesInFolder(GetPath(argv[0]));
  std::copy(v.begin(),v.end(),std::ostream_iterator<std::string>(std::cout,"\n"));
  std::cout << "Number of files: " << v.size() << '\n';
}
//---------------------------------------------------------------------------

 

 

 

 

 

Process

 

Just follow the approach by [1]:

 

wget http://download.savannah.nongnu.org/releases/mingw-cross-env/mingw-cross-env-2.15.tar.gz
tar -xzvf mingw-cross-env-2.15.tar.gz
make

 

[build]    binutils
[done]     binutils
[download] gcc-gmp
[done]     gcc-gmp
[download] gcc-mpc
[done]     gcc-mpc
[download] gcc-mpfr
[done]     gcc-mpfr
[download] gcc
[build]    gcc
[done]     gcc
[download] libiconv
[build]    libiconv
[done]     libiconv
[download] gettext
[build]    gettext
[done]     gettext
[download] pcre
[build]    pcre
[done]     pcre
[download] zlib
[build]    zlib
[done]     zlib
[download] glib
[build]    glib

Failed to build package glib!
------------------------------------------------------------
(cd '/home/richel/mingw-cross-env-2.15/tmp-glib/glib-2.25.7' && patch -p1 -u) < ./src/glib-5-fix-stray-commas.patch
patching file gio/gioenums.h
cd '/home/richel/mingw-cross-env-2.15/tmp-glib/glib-2.25.7' && aclocal
bash: aclocal: command not found
make[1]: *** [build-only-glib] Error 127
make[1]: Leaving directory `/home/richel/mingw-cross-env-2.15'
real 0m2.364s
user 0m2.108s
sys 0m0.212s
------------------------------------------------------------
[log]      /home/richel/mingw-cross-env-2.15/log/glib

make: *** [/home/richel/mingw-cross-env-2.15/usr/installed/glib] Error 1

 

Tried to obtain 'aclocal' from an Ubuntu terminal:

 

sudo apt-get install aclocal

 

Screen output:

 

[sudo] password for richel:
Reading package lists... Done
Building dependency tree      
Reading state information... Done
E: Couldn't find package aclocal

 

This approach fails due to the absence of aclocal.

 

But I would be happy if I could use Boost and the STL, so I try to make Qt:

 

make qt

 

Screen output:

 

[download] libodbc++
[build]    libodbc++

Failed to build package libodbc++!
------------------------------------------------------------
patching file src/datastream.h
patching file include/odbc++/resultset.h
cd '/home/richel/mingw-cross-env-2.15/tmp-libodbc++/libodbc++-0.2.5' && autoconf
bash: autoconf: command not found
make[1]: *** [build-only-libodbc++] Error 127
make[1]: Leaving directory `/home/richel/mingw-cross-env-2.15'
real 0m0.289s
user 0m0.236s
sys 0m0.044s
------------------------------------------------------------
[log]      /home/richel/mingw-cross-env-2.15/log/libodbc++

make: *** [/home/richel/mingw-cross-env-2.15/usr/installed/libodbc++] Error 1

 

Installing autoconf:

 

sudo apt-get install autoconf

 

Well, just install all programs as stated in the prerequisites:

 

sudo aptitude install -R autoconf automake bash bison bzip2 cmake flex g++ make sed libtool openssl libssl-dev patch perl pkg-config scons unzip wget

 

Try to make qt again:

 

make qt

 

Screen output:

 

[build]    libodbc++
[done]     libodbc++
[download] libgpg_error
[build]    libgpg_error
[done]     libgpg_error
[download] libgcrypt
[build]    libgcrypt
[done]     libgcrypt
[download] openssl
[build]    openssl
[done]     openssl
[download] postgresql
[build]    postgresql
[done]     postgresql
[download] freetds
[build]    freetds
[done]     freetds
[download] libpng
[build]    libpng
[done]     libpng
[download] jpeg
[build]    jpeg
[done]     jpeg
[download] libmng
[build]    libmng
[done]     libmng
[download] tiff
[build]    tiff
[done]     tiff
[download] giflib
[build]    giflib
[done]     giflib
[download] sqlite
[build]    sqlite
[done]     sqlite
[download] qt
[build]    qt
[done]     qt

 

I also want to use Boost:

 

make boost

 

Screen output:

 

[download] bzip2
[build]    bzip2
[done]     bzip2
[download] expat
[build]    expat
[done]     expat
[download] boost
[build]    boost
[done]     boost

 

According to [1], I had to 'Edit your .bashrc script in order to change $PATH', so I typed:

 

sudo gedit /etc/bash.bashrc

 

I added this at the second line of '/etc/bash.bashrc':

 

export PATH=/home/richel/mingw-cross-env-2.15/usr/bin:$PATH

 

After navigating to the folder ('cd /home/richel/qtsdk-2010.04/bin/Projects/Website/CppQtCrosscompileToWindowsExample15') I tried it out:

 

i686-pc-mingw32-qmake CppQtCrosscompileToWindowsExample15.pro

 

No screen output...

 

Now running make:

 

make

 

Screen output:

 

make -f Makefile.Release
make[1]: Entering directory `/home/richel/qtsdk-2010.04/bin/Projects/Website/CppQtCrosscompileToWindowsExample15'
i686-pc-mingw32-g++ -c -pipe -O2 -frtti -fexceptions -mthreads -Wall -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_NO_DEBUG -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I'/home/richel/mingw-cross-env-2.15/usr/i686-pc-mingw32/include/QtCore' -I'/home/richel/mingw-cross-env-2.15/usr/i686-pc-mingw32/include' -I'/home/richel/mingw-cross-env-2.15/usr/i686-pc-mingw32/include/ActiveQt' -I'release' -I'/home/richel/mingw-cross-env-2.15/usr/i686-pc-mingw32/mkspecs/unsupported/win32-g++-cross' -o release/main.o main.cpp
i686-pc-mingw32-g++ -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -Wl,-s -Wl,-subsystem,console -mthreads -Wl -o release/CppQtCrosscompileToWindowsExample15.exe release/main.o  -L'/home/richel/mingw-cross-env-2.15/usr/i686-pc-mingw32/lib' -L/usr/local/lib -lboost_filesystem -lQtCore -lkernel32 -luser32 -lshell32 -luuid -lole32 -ladvapi32 -lws2_32 -lz
/home/richel/mingw-cross-env-2.15/usr/lib/gcc/i686-pc-mingw32/4.5.0/../../../../i686-pc-mingw32/bin/ld: cannot find -lboost_filesystem
collect2: ld returned 1 exit status
make[1]: *** [release/CppQtCrosscompileToWindowsExample15.exe] Error 1
make[1]: Leaving directory `/home/richel/qtsdk-2010.04/bin/Projects/Website/CppQtCrosscompileToWindowsExample15'
make: *** [release] Error 2

 

I changed the Qt Creator project file (called CppQtCrosscompileToWindowsExample15.pro):

 

#-------------------------------------------------
#
# Project created by QtCreator 2010-09-25T09:43:28
#
#-------------------------------------------------
QT       += core
QT       -= gui
LIBS += -L/usr/lib -lboost_filesystem
TARGET = CppQtCrosscompileToWindowsExample15
CONFIG   += console
CONFIG   -= app_bundle
TEMPLATE = app
SOURCES += main.cpp

 

Screen output:

 

make -f Makefile.Release
make[1]: Entering directory `/home/richel/qtsdk-2010.04/bin/Projects/Website/CppQtCrosscompileToWindowsExample15'
i686-pc-mingw32-g++ -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -Wl,-s -Wl,-subsystem,console -mthreads -Wl -o release/CppQtCrosscompileToWindowsExample15.exe release/main.o  -L'/home/richel/mingw-cross-env-2.15/usr/i686-pc-mingw32/lib' -L/usr/lib -lboost_filesystem -lQtCore -lkernel32 -luser32 -lshell32 -luuid -lole32 -ladvapi32 -lws2_32 -lz
release/main.o:main.cpp:(.text+0x84f): undefined reference to 'boost::system::get_system_category()''
release/main.o:main.cpp:(.text+0x859): undefined reference to `boost::system::get_generic_category()'
release/main.o:main.cpp:(.text+0x863): undefined reference to `boost::system::get_generic_category()'
release/main.o:main.cpp:(.text+0x86d): undefined reference to `boost::system::get_generic_category()'
release/main.o:main.cpp:(.text+0x877): undefined reference to `boost::system::get_system_category()'
release/main.o:main.cpp:(.text$_ZN5boost6detail17sp_counted_impl_pINS_10filesystem6detail11dir_itr_impINS2_10basic_pathISsNS2_11path_traitsEEEEEE7disposeEv[boost::detail::sp_counted_impl_p<boost::filesystem::detail::dir_itr_imp<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> > >::dispose()]+0x4a): undefined reference to `boost::filesystem::detail::dir_itr_close(void*&)'
release/main.o:main.cpp:(.text$_ZN5boost14checked_deleteINS_10filesystem6detail11dir_itr_impINS1_10basic_pathISsNS1_11path_traitsEEEEEEEvPT_[void boost::checked_delete<boost::filesystem::detail::dir_itr_imp<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> > >(boost::filesystem::detail::dir_itr_imp<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >*)]+0x47): undefined reference to `boost::filesystem::detail::dir_itr_close(void*&)'
release/main.o:main.cpp:(.text$_ZN5boost10filesystem12is_directoryINS0_10basic_pathISsNS0_11path_traitsEEEEENS_9enable_ifINS0_13is_basic_pathIT_EEbE4typeERKS7_[boost::enable_if<boost::filesystem::is_basic_path<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >, bool>::type boost::filesystem::is_directory<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >(boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> const&)]+0x5b): undefined reference to `boost::system::get_system_category()'
release/main.o:main.cpp:(.text$_ZN5boost10filesystem12is_directoryINS0_10basic_pathISsNS0_11path_traitsEEEEENS_9enable_ifINS0_13is_basic_pathIT_EEbE4typeERKS7_[boost::enable_if<boost::filesystem::is_basic_path<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >, bool>::type boost::filesystem::is_directory<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >(boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> const&)]+0xb9): undefined reference to `boost::filesystem::detail::status_api(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, boost::system::error_code&)'
release/main.o:main.cpp:(.text$_ZN5boost10filesystem6statusINS0_10basic_pathISsNS0_11path_traitsEEEEENS_9enable_ifINS0_13is_basic_pathIT_EENS0_11file_statusEE4typeERKS7_[boost::enable_if<boost::filesystem::is_basic_path<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >, boost::filesystem::file_status>::type boost::filesystem::status<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >(boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> const&)]+0x5b): undefined reference to `boost::system::get_system_category()'
release/main.o:main.cpp:(.text$_ZN5boost10filesystem6statusINS0_10basic_pathISsNS0_11path_traitsEEEEENS_9enable_ifINS0_13is_basic_pathIT_EENS0_11file_statusEE4typeERKS7_[boost::enable_if<boost::filesystem::is_basic_path<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >, boost::filesystem::file_status>::type boost::filesystem::status<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >(boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> const&)]+0xb9): undefined reference to `boost::filesystem::detail::status_api(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, boost::system::error_code&)'
release/main.o:main.cpp:(.text$_ZN5boost10filesystem15system_completeINS0_10basic_pathISsNS0_11path_traitsEEEEENS_9enable_ifINS0_13is_basic_pathIT_EES7_E4typeERKS7_[boost::enable_if<boost::filesystem::is_basic_path<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >, boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >::type boost::filesystem::system_complete<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >(boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> const&)]+0xc1): undefined reference to `boost::filesystem::detail::get_full_path_name_api(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)'
release/main.o:main.cpp:(.text$_ZN5boost10filesystem24basic_directory_iteratorINS0_10basic_pathISsNS0_11path_traitsEEEE9incrementEv[boost::filesystem::basic_directory_iterator<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >::increment()]+0x7e): undefined reference to `boost::system::get_system_category()'
release/main.o:main.cpp:(.text$_ZN5boost10filesystem24basic_directory_iteratorINS0_10basic_pathISsNS0_11path_traitsEEEE9incrementEv[boost::filesystem::basic_directory_iterator<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >::increment()]+0xb5): undefined reference to `boost::filesystem::detail::dir_itr_increment(void*&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, boost::filesystem::file_status&, boost::filesystem::file_status&)'
release/main.o:main.cpp:(.text$_ZN5boost10filesystem24basic_directory_iteratorINS0_10basic_pathISsNS0_11path_traitsEEEE6m_initERKS4_[boost::filesystem::basic_directory_iterator<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >::m_init(boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> const&)]+0xd4): undefined reference to `boost::filesystem::detail::dir_itr_first(void*&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, boost::filesystem::file_status&, boost::filesystem::file_status&)'
release/main.o:main.cpp:(.text$_ZN5boost10filesystem24basic_directory_iteratorINS0_10basic_pathISsNS0_11path_traitsEEEE6m_initERKS4_[boost::filesystem::basic_directory_iterator<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >::m_init(boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> const&)]+0x24e): undefined reference to `boost::system::get_system_category()'
release/main.o:main.cpp:(.text$_ZN5boost10filesystem24basic_directory_iteratorINS0_10basic_pathISsNS0_11path_traitsEEEE6m_initERKS4_[boost::filesystem::basic_directory_iterator<boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> >::m_init(boost::filesystem::basic_path<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::filesystem::path_traits> const&)]+0x311): undefined reference to `boost::filesystem::detail::not_found_error()'
collect2: ld returned 1 exit status
make[1]: *** [release/CppQtCrosscompileToWindowsExample15.exe] Error 1
make[1]: Leaving directory `/home/richel/qtsdk-2010.04/bin/Projects/Website/CppQtCrosscompileToWindowsExample15'
make: *** [release] Error 2

 

The error is familiar: undefined reference to 'boost::system::get_system_category()'.

 

 

 

 

References

 

 

 

 

 

[1] http://mingw-cross-env.nongnu.org/#tutorial

 

Tutorial
Step 1: Download and Unpack

First, you should ensure that your system meets mingw-cross-env's requirements. You probably need to install some stuff.

When everything is fine, download the latest release:

wget http://download.savannah.nongnu.org/releases/mingw-cross-env/mingw-cross-env-2.15.tar.gz

and unpack the tarball:

tar -xzvf mingw-cross-env-2.15.tar.gz

If you don't mind installing it in your home directory, just skip the following step and go straight to step 3.
Step 2: System-wide Installation (optional)

Now you should save any previous installation of the mingw-cross-env. Assuming you've installed it under /opt/mingw (any other directory will do as well), you should execute the following commands:

su
mv /opt/mingw /opt/mingw.old
exit

Then you need to transfer the entire directory to its definitive location. We will assume again you use /opt/mingw, but feel free to use any other directory if you like.

su
mv mingw-cross-env-2.15 /opt/mingw
exit

We're almost done. Just change to your newly created directory and get going:

cd /opt/mingw

Step 3: Build mingw-cross-env

Enter the directory where you've unpacked the mingw-cross-env. Now it depends on what you actually want ? or need.

If you choose to enter:

make

you're in for a long wait, because it compiles a lot of packages. On the other hand it doesn't require any intervention, so you're free to do whatever you like ? like watch a movie or go for a night on the town. When it's done you'll find that you've installed a very capable Win32 cross compiler onto your system.

If you only need the most basic tools you can also use:

make gcc

and add any additional packages you need later on. You can also supply a host of packages on the command line, e.g.:

make gtk lua libidn

You'll always end up with a consistent cross compiling environment.

After you're done it just needs a little post-installation.
Step 4: Environment Variables

Edit your .bashrc script in order to change $PATH:

export PATH=/where mingw-cross-env is installed/usr/bin:$PATH

Note that any compiler related environment variables (like $CC, $LDFLAGS, etc.) may spoil your compiling pleasure, so be sure to delete or disable those.

Congratulations! You're ready to cross compile anything you like.
Step 5a: Cross compile your Project (Autotools)

If you use the Autotools, all you have to do is:

./configure --host=i686-pc-mingw32
make

Don't worry about a warning like this:

configure: WARNING: If you wanted to set the --build type, don't use --host.
If a cross compiler is detected then cross compile mode will be used.

Everything will be just fine.
Step 5b: Cross compile your Project (Qt)

If you have a Qt application, all you have to do is:

i686-pc-mingw32-qmake
make

If you are using Qt plugins such as database drivers or graphics plugins, you should also have a look at the Qt documentation about static plugins.
Step 5c: Cross compile your Project (Makefile)

If you have a handwritten Makefile, you probably will have to make a few adjustments to it:

CC=$(CROSS)gcc
LD=$(CROSS)ld
AR=$(CROSS)ar

You may have to add a few others, depending on your project.

Then, all you have to do is:

make CROSS=i686-pc-mingw32-

That's it!
Step 5d: Cross compile your Project (OSG)

Using static OpenSceneGraph libraries requires a few changes to your source. The graphics subsystem and all plugins required by your application must be referenced explicitly. Use a code block like the following:

#ifdef OSG_LIBRARY_STATIC
USE_GRAPHICSWINDOW()
USE_OSGPLUGIN(<plugin1>)
USE_OSGPLUGIN(<plugin2>)
...
#endif

Look at examples/osgstaticviewer/osgstaticviewer.cpp in the OpenSceneGraph source distribution for an example. This example can be compiled with the following command:

i686-pc-mingw32-g++ \
    -o osgstaticviewer.exe examples/osgstaticviewer/osgstaticviewer.cpp \
    `i686-pc-mingw32-pkg-config --cflags openscenegraph-osgViewer openscenegraph-osgPlugins` \
    `i686-pc-mingw32-pkg-config --libs openscenegraph-osgViewer openscenegraph-osgPlugins`

The i686-pc-mingw32-pkg-config command from mingw-cross-env will automatically add -DOSG_LIBRARY_STATIC to your compiler flags.

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict