Boost logo

Boost :

From: Christopher Cambly (ccambly_at_[hidden])
Date: 2007-11-19 17:49:15


"Gaurav Jain-SJR" <Gaurav.Jain_at_[hidden]> wrote on 11/19/2007
06:58:42 AM:

>
> Hi,
>
> // samp.cpp Boost Library Example
> #include <iostream>
> #include <string>
> #include <cstdlib>
> #include <fstream>
> #include "boost/filesystem/operations.hpp"
> #include "boost/filesystem/path.hpp"
> #include "boost/filesystem/exception.hpp"
> #include "boost/filesystem/convenience.hpp"
> #include "boost/filesystem/fstream.hpp"
> using namespace std;
>
> int main( int argc, char* argv[] )
> {
>
> if ( argc != 2 )
> {
> std::cout << "Usage: file_size path\n";
> return 1;
> }
>
> std::cout << "sizeof(intmax_t) is " << sizeof(boost::intmax_t) <<
> '\n';
>
> boost::filesystem::path p( argv[1], boost::filesystem::native );
>
> if ( !boost::filesystem::exists( p ) )
> {
> std::cout << "not found: " << argv[1] << std::endl;
> return 1;
> }
>
> if ( boost::filesystem::is_directory( p ) )
> {
> std::cout << "not a file: " << argv[1] << std::endl;
> return 1;
> }
>
> std::cout << "size of " << argv[1] << " is " <<
> boost::filesystem::file_size( p )
> << std::endl;
> return 0;
> }
>
> I tried to build the above sample which comes with BOOST File System
> library on AIX 5.3. It got failed at link time.
> The detail of this activity is as follow:
>
> Compiler Details: XL C/C++ Enterprise Edition V9.0
>
> OS Details:- AIX 5.3
>
> Boost Version:- 1_34_0 (32 bit build)
>
> Command for building the boost libraries:-
>
> $bjam --v2 install toolset=vacpp --prefix=$HOME/1_34_1/32
> --builddir=$HOME/tmp variant=release runtime-link=static,shared
> threading=single,multi --without-python Jamfile.v2
>
> "samp.cpp":- Compilation Command
>
> $xlC_r -q32 -I/home/1_34_0/include samp.cpp -L/home/1_34_0/lib
> -lboost_filesystem-xlc-mt-1_34
>
> ld: 0711-317 ERROR: Undefined symbol:
> .boost::filesystem::detail::last_write_time_api(
> const std::basic_string<char,std::char_traits<char>,std::allocator<char>
> >&,int)
> ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more
> information.
>
>
> I tried to find a solution on google and came across with the following:
>
> http://beta.boost.org/development/tests/trunk/output/IBM_Canada_Ltd-boos
> t-bin-v2-libs-filesystem-test-operations_test_dll-test-vacpp-debug.html
>
> Even the regression test result on IBM site indicates that the certain
> test case of file system library isn't working:
>
> http://www-1.ibm.com/support/docview.wss?rs=2030&context=SSJT9L&uid=swg2
> 7010184
>
>
> I am not directly using the
> "boost::filesystem::detail::last_write_time_api" in my code, but I am
> not sure whether any other API's which I am using in my code, is using
> it indirectly.
>
> Can somebody suggest me a work around to resolve this?
>
>
> Regards,
> Gaurav Jain
>

The symbol referenced from operations_test.cpp, or in your case samp.cpp
is:

boost::filesystem::detail::last_write_time_api(const
std::basic_string<char,std::char_traits<char>,std::allocator<char> >&,int)

the symbol defined in the archive of Boost.Filesystem is:

boost::filesystem::detail::last_write_time_api(const
std::basic_string<char,std::char_traits<char>,std::allocator<char> >&,long)

The problem originates with the last parameter, std::time_t, of the
function boost::filesystem::detail::last_write_time_api(). In the
Boost.Filesystem header, boost/filesystem/operations.hpp the function
last_write_time() is declared as:

last_write_time( const Path & ph, const std::time_t new_time)

where std::time_t is typedef'ed to time_t which is defined as an int in
/usr/include/time.h. However, inside libs/filesystem/src/operations.cpp
where the definition of the function last_write_time() resides there is
some code which changes the underlying type of time_t to a long ie)

// enable the XPG-compliant version of readdir_r() on AIX
#if defined(_AIX)
# define _LINUX_SOURCE_COMPAT
#endif

This #define of _LINUX_SOURCE_COMPAT changes the time_t from an int to a
long. So the declaration of last_write_time() has std::time_t as an int
whereas the definition has std::time_t as a long, thus the link error
message.

There are two ways to fix this:

1) Compile samp.cpp with -D_LINUX_SOURCE_COMPAT but be warned this changes
more than time_t

2) The best fix is to remove the define for LINUX_SOURCE_COMPAT and add
checks around the call to readdir_r to make sure that _AIX and
__THREAD_SAFE ie) the thread safe version of the compiler on AIX is being
called so readdir_r() works correctly.

Here is a libs/filesystem/src/operations.cpp patch for Boost trunk:
(See attached file: operations.cpp.trunk.patch)

Here is a libs/filesystem/src/operations.cpp patch for Boost.1.34.1:

(See attached file: operations.cpp.1.34.patch)

Chris Cambly
IBM XL Compiler Development




Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk