I can't get my g++ to compile and link a minimal boost co-routine program (and I guess other components as well) on my machine.
// example.cpp
#include <boost/coroutine/all.hpp>
#include <iostream>
using namespace boost::coroutines;
void mycorofunc(coroutine<void>::push_type &sink){
std::cout << "1";
sink();
std::cout << " 3";
}
int main() {
coroutine<void>::pull_type source{mycorofunc};
std::cout << " 2";
source();
std::cout << " 4!" << std::endl;
}
I used apt-get to install boost (libboost-all-dev), but neither
g++ example.cpp -lboost_coroutine -lboost_system
nor
g++ example.cpp -I/usr/include -L/usr/lib/x86_64-linux-gnu -lboost_coroutine -lboost_system
works. g++'s output is as follows:
In file included from /usr/include/boost/coroutine/v1/coroutine.hpp:19:0,
from /usr/include/boost/coroutine/coroutine.hpp:13,
from /usr/include/boost/coroutine/all.hpp:11,
from example.cpp:3:
/usr/include/boost/type_traits/function_traits.hpp: In instantiation of ‘struct boost::function_traits<void>’:
example.cpp:7:31: required from here
/usr/include/boost/type_traits/function_traits.hpp:168:8: error: invalid use of incomplete type ‘struct boost::detail::function_traits_helper<void*>’
struct function_traits :
^
/usr/include/boost/type_traits/function_traits.hpp:21:36: error: declaration of ‘struct boost::detail::function_traits_helper<void*>’
template<typename Function> struct function_traits_helper;
^
example.cpp:7:31: error: ‘arity’ is not a member of ‘boost::function_traits<void>’
void mycorofunc(coroutine<void>::push_type &sink){
^
example.cpp:7:31: error: template argument 2 is invalid
example.cpp:7:44: error: expected ‘,’ or ‘...’ before ‘&’ token
void mycorofunc(coroutine<void>::push_type &sink){
^
example.cpp: In function ‘void mycorofunc(int)’:
example.cpp:9:8: error: ‘sink’ was not declared in this scope
sink();
^
example.cpp: In function ‘int main()’:
example.cpp:14:17: error: ‘arity’ is not a member of ‘boost::function_traits<void>’
coroutine<void>::pull_type source{mycorofunc};
^
example.cpp:14:17: error: template argument 2 is invalid
example.cpp:14:30: error: expected initializer before ‘source’
coroutine<void>::pull_type source{mycorofunc};
^
example.cpp:16:10: error: ‘source’ was not declared in this scope
source();
Some more information about my environment:
$$ locate coroutine/all.hpp
/usr/include/boost/coroutine/all.hpp
/usr/local/boost_1_58_0/boost/coroutine/all.hpp
$$ locate boost_system
/usr/lib/x86_64-linux-gnu/libboost_system.a
/usr/lib/x86_64-linux-gnu/libboost_system.so
/usr/lib/x86_64-linux-gnu/libboost_system.so.1.54.0
$$ locate boost_coroutine
/usr/lib/x86_64-linux-gnu/libboost_coroutine.a
$$ g++ -E -x c++ - -v < /dev/null # printing g++ include path
Using built-in specs.
COLLECT_GCC=g++
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.2-19ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)
COLLECT_GCC_OPTIONS='-E' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
/usr/lib/gcc/x86_64-linux-gnu/4.8/cc1plus -E -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE - -mtune=generic -march=x86-64 -fstack-protector -Wformat -Wformat-security
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/4.8"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/include/c++/4.8
/usr/include/x86_64-linux-gnu/c++/4.8
/usr/include/c++/4.8/backward
/usr/lib/gcc/x86_64-linux-gnu/4.8/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
# 1 "<stdin>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "<stdin>"
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.8/:/usr/lib/gcc/x86_64-linux-gnu/4.8/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.8/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.8/:/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-E' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
Compiler: have tried both g++ (v. 4.8.2) and g++-5
Distro: Ubuntu 14.04.1 LTS
After days of debugging, this is the solution I found. It is possible that even a subset of the following instructions is equally enough to go about the problem.
Quick instructions without much detail
Perform the following instructions:
g++-6(any version newer than5.2which supportsc++14will most likely work as well, though I have not tested them).1.58or newer (support for coroutine2). As of the date of this post, the latest version available in Ubuntu PPA is1.54. Therefore, you need to manually install boost. If you do not know how, follow this link.-std=c++14flag. Also, if you are working with coroutines like me, make sure to link againstlibboost_context. I have noticed that for coroutines 2,libboost_systemis not needed, perhaps because it is automally pulled in bylibboost_context, though I'm not sure about the reason.To put these points together, here's the command I used to compile and link my code (let's say I install boost in
/usr/local/):g++-6 -std=c++14 example.cpp -I/usr/local/include -L/usr/local/lib -lboost_coroutine -lboost_context -lboost_systemMore details
Apparently,
boost.coroutinelibrary in boost1.54is implemented with the deprecated C-like fcontext-API from boost.context [source]. I have noticed that my machine had problem compiling those parts. Unfortunately, Ubuntu PPA does not offer any newer version than1.54at this moment.Boost.coroutine2is the recommended library to use, which can be found in version1.59or newer. Therefore, you need to manually download a suitable version of boost from its website and install it.After doing so, my code successfully compilied, but not linked:
Surprisingly, adding
-lboost_contextflag to the compile command did not remove this link error, suggesting thatlibboost_contextis not properly linked against.I then came across a question in boost forum wherein the original poster had somewhat similar problem to what I had. In short, there are a number of C macros that prevent execution_context to be properly included, and thus the problem with
libboost_context. The code to know if your compiler has some of these macros enabled is as follows (I'm not sure if all of these macros are relevant):The solution is easy: installing
g++-6(or I guess5.2or newer), and compiling the code withstd=-c++14.