I'm using Boost 1.49, OpenCV 2.3.1, CMake 2.8 in a C++ project.
I'm building two executables with the same header file, one for production and the other for testing. The contest.hpp
file specifies:
namespace boost
{
namespace serialization
{
template<class Archive>
void serialize(Archive& ar, cv::Point& p, const unsigned int version);
template<class Archive>
void serialize(Archive& ar, cv::Rect_<int>& r, const unsigned int version);
template<class Archive>
void serialize(Archive& ar, cv::Size_<int>& s, const unsigned int version);
}
}
and these are implemented in contest.cpp
file like
namespace boost
{
namespace serialization
{
template<class Archive>
void serialize(Archive& ar, cv::Point& p, const unsigned int version)
{
ar & p.x;
ar & p.y;
}
template<class Archive>
void serialize(Archive& ar, cv::Rect_<int>& r, const unsigned int version)
{
ar & r.x;
ar & r.y;
ar & r.height;
ar & r.width;
}
template<class Archive>
void serialize(Archive& ar, cv::Size_<int>& s, const unsigned int version)
{
ar & s.width;
ar & s.height;
}
}
}
And test-contest.cpp
mundanely tests these like
BOOST_AUTO_TEST_CASE(Serialization1)
{
Point point_write(3, 5);
{
ofstream point_file("Point.txt");
ar::text_oarchive point_archive(point_file);
sr::serialize(point_archive, point_write, 0);
}
Point point_read(0, 0);
{
ifstream point_file("Point.txt");
ar::text_iarchive point_archive(point_file);
sr::serialize(point_archive, point_read, 0);
}
BOOST_CHECK(point_read == point_write);
Rect rect_write(3, 5, 1, 7);
{
ofstream rect_file("Rect.txt");
ar::text_oarchive rect_archive(rect_file);
sr::serialize(rect_archive, rect_write, 0);
}
Rect rect_read(0, 0, 0, 0);
{
ifstream rect_file("Rect.txt");
ar::text_iarchive rect_archive(rect_file);
sr::serialize(rect_archive, rect_read, 0);
}
BOOST_CHECK((rect_read.x) == (rect_write.y) && (rect_read.y) == (rect_write.y));
Size size_write(3, 5);
{
ofstream size_file("Size.txt");
ar::text_oarchive size_archive(size_file);
sr::serialize(size_archive, size_write, 0);
}
Size size_read(0, 0);
{
ifstream size_file("Size.txt");
ar::text_iarchive size_archive(size_file);
sr::serialize(size_archive, size_read, 0);
}
BOOST_CHECK(size_read == size_write);
}
where sr
and ar
are defined in common.hpp
like
namespace ar = ::boost::archive;
namespace sr = ::boost::serialization;
The makefiles are produced from CMake configuration like:
link_directories(${DEPENDENCY_DIR}/libboost/lib)
link_directories(${DEPENDENCY_DIR}/libopencv/lib)
add_executable(test-contest test-contest.cpp contest.cpp)
add_executable(contest main.cpp contest.cpp)
target_link_libraries(test-contest boost_serialization opencv_core opencv_highgui opencv_imgproc boost_program_options boost_unit_test_framework boost_filesystem)
target_link_libraries(contest boost_serialization opencv_core opencv_highgui opencv_imgproc boost_program_options boost_filesystem)
so, the moral of the story is, both contest
and test-contest
are compiled and linked against the same header and libraries. Note that other Boost libraries are linked and tested successfully.
When it comes to make
after cmake 'Unix Makefiles' ..
, for contest
it says
[ 40%] Building CXX object CMakeFiles/contest.dir/main.cpp.o
[ 60%] Building CXX object CMakeFiles/contest.dir/contest.cpp.o
Linking CXX executable contest
[ 60%] Built target contest
but for test-contest
[ 80%] Building CXX object CMakeFiles/test-contest.dir/test-contest.cpp.o
[100%] Building CXX object CMakeFiles/test-contest.dir/contest.cpp.o
Linking CXX executable test-contest
CMakeFiles/test-contest.dir/test-contest.cpp.o: In function `otap::TPageImage::Serialization1::test_method()':
/home/iesahin/Repository/otapexplorer/cli/contest-2012/test-contest.cpp:119: undefined reference to `void boost::serialization::serialize<boost::archive::text_oarchive>(boost::archive::text_oarchive&, cv::Rect_<int>&, unsigned int)'
/home/iesahin/Repository/otapexplorer/cli/contest-2012/test-contest.cpp:125: undefined reference to `void boost::serialization::serialize<boost::archive::text_iarchive>(boost::archive::text_iarchive&, cv::Rect_<int>&, unsigned int)'
/home/iesahin/Repository/otapexplorer/cli/contest-2012/test-contest.cpp:133: undefined reference to `void boost::serialization::serialize<boost::archive::text_oarchive>(boost::archive::text_oarchive&, cv::Size_<int>&, unsigned int)'
/home/iesahin/Repository/otapexplorer/cli/contest-2012/test-contest.cpp:139: undefined reference to `void boost::serialization::serialize<boost::archive::text_iarchive>(boost::archive::text_iarchive&, cv::Size_<int>&, unsigned int)'
collect2: ld returned 1 exit status
make[2]: *** [test-contest] Error 1
And IMHO the weirdest part is, there are no errors for serialize(Archive, cv::Point, int)
which is from the same header/library in OpenCV with serialize(Archive, cv::Rect_<int>, int)
or cv::Size_<int>
. Their serialization/test functions are almost identically defined.
I'm linking these serialize
functions from contest.cpp
file successfully. I tried replacing Rect
with Rect_<int>
in the definitions, to no change. I tried changing the order of libraries in CMakeLists.txt
and took boost_serialization
from the end to its current place, to no avail.
Where am I doing it wrong?