Assembler error in MIPS build of Boost.Test program
I'm writing a unit test program with Boost.Test and cross-compiling it for several embedded platforms in an OpenWrt environment. The Boost version is 1.58. All is fine when building for ARM (using gcc 5.2), however when building for MIPS (using gcc 4.8) I get the following error:
[ 66%] Building CXX object CMakeFiles/itests.dir/uci.cpp.o
{standard input}: Assembler messages:
{standard input}:715: Error: unrecognized opcode `ll $24,0($4)'
{standard input}:716: Error: invalid operands `addiu $2,$24,-1'
{standard input}:717: Error: unrecognized opcode `sc $2,0($4)'
{standard input}:720: Error: invalid operands `addiu $2,$24,-1'
CMakeFiles/itests.dir/build.make:75: recipe for target 'CMakeFiles/itests.dir/uci.cpp.o' failed
uci.cpp
contains nothing but the following skeletal code:
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_SUITE(xxx)
BOOST_AUTO_TEST_CASE(yyy)
{
}
BOOST_AUTO_TEST_SUITE_END()
The full compiler version is:
$ toolchain-mips_74kc_gcc-4.8-linaro_uClibc-1.0.14/bin/mips-openwrt-linux-uclibc-gcc --version
mips-openwrt-linux-uclibc-gcc (OpenWrt/Linaro GCC 4.8-2014.04 a083622+r49254) 4.8.3
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Due to limitations beyond my control, updating to a more recent compiler or Boost version isn't an option.
Needless to say that the rest of my OpenWrt build works, it's only the Boost.Test program that's failing. Also, building without the uci.cpp file (which is the only file using those Boost.Test macros) works fine and runs on the target device.
Does anyone have any idea what's happening, or how to fix it?
Edit: These are the build flags:
CFLAGS="-Os -pipe -mno-branch-likely -mips32r2 -mtune=74kc -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -msoft-float -mips16 -minterlink-mips16 -fPIC -fstack-protector -I/mnt/delos/qsdk/staging_dir/target-mips_74kc_uClibc-1.0.14/usr/include -I/mnt/delos/qsdk/staging_dir/target-mips_74kc_uClibc-1.0.14/include -I/mnt/delos/qsdk/staging_dir/toolchain-mips_74kc_gcc-4.8-linaro_uClibc-1.0.14/usr/include -I/mnt/delos/qsdk/staging_dir/toolchain-mips_74kc_gcc-4.8-linaro_uClibc-1.0.14/include " CXXFLAGS="-Os -pipe -mno-branch-likely -mips32r2 -mtune=74kc -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -msoft-float -mips16 -minterlink-mips16 -fPIC -fstack-protector -I/mnt/delos/qsdk/staging_dir/target-mips_74kc_uClibc-1.0.14/usr/include -I/mnt/delos/qsdk/staging_dir/target-mips_74kc_uClibc-1.0.14/include -I/mnt/delos/qsdk/staging_dir/toolchain-mips_74kc_gcc-4.8-linaro_uClibc-1.0.14/usr/include -I/mnt/delos/qsdk/staging_dir/toolchain-mips_74kc_gcc-4.8-linaro_uClibc-1.0.14/include " LDFLAGS="-L/mnt/delos/qsdk/staging_dir/target-mips_74kc_uClibc-1.0.14/usr/lib -L/mnt/delos/qsdk/staging_dir/target-mips_74kc_uClibc-1.0.14/lib -L/mnt/delos/qsdk/staging_dir/toolchain-mips_74kc_gcc-4.8-linaro_uClibc-1.0.14/usr/lib -L/mnt/delos/qsdk/staging_dir/toolchain-mips_74kc_gcc-4.8-linaro_uClibc-1.0.14/lib -specs=/mnt/delos/qsdk/include/hardened-ld-pie.specs " make -C /mnt/delos/qsdk/build_dir/target-mips_74kc_uClibc-1.0.14/itests-1/. AR="mips-openwrt-linux-uclibc-gcc-ar" AS="mips-openwrt-linux-uclibc-gcc -c -Os -pipe -mno-branch-likely -mips32r2 -mtune=74kc -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -msoft-float -fPIC -fstack-protector" LD=mips-openwrt-linux-uclibc-ld NM="mips-openwrt-linux-uclibc-gcc-nm" CC="mips-openwrt-linux-uclibc-gcc" GCC="mips-openwrt-linux-uclibc-gcc" CXX="mips-openwrt-linux-uclibc-g++" RANLIB="mips-openwrt-linux-uclibc-gcc-ranlib" STRIP=mips-openwrt-linux-uclibc-strip OBJCOPY=mips-openwrt-linux-uclibc-objcopy OBJDUMP=mips-openwrt-linux-uclibc-objdump SIZE=mips-openwrt-linux-uclibc-size CROSS="mips-openwrt-linux-uclibc-" ARCH="mips" ;
The error is caused by a bug that was fixed in Boost 1.63. A patch is here: https://github.com/boostorg/smart_ptr/commit/840e9fc96e9e1672f93c785ee78b5edc4bc4af01
Instead of patching Boost 1.58 (which isn't so easy in my context), I added the following to my code which fixes the error (by doing essentially the same as the patch, albeit in a different way):
#ifdef __mips__
#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
#include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
#endif
Thanks to Michael who provided the solution.