Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost Filesystem. is_directory never works

I have been searching high and low to get this question answered, and I can't seem to debug the problem out!

So, this is what I have.

I have installed boost via homebrew (Mac OSX Mavericks) version 1.55.0.

Other boost libraries work fine, but boost::filesystem doesn't seem to be able to interact with the actual filesystem.

This is how I am linking it (using QT)

macx: LIBS += -L$$PWD/../../../../../usr/local/Cellar/boost/1.55.0_1/lib/ -lboost_system-mt
macx: LIBS += -L$$PWD/../../../../../usr/local/Cellar/boost/1.55.0_1/lib/ -lboost_filesystem-mt

INCLUDEPATH += $$PWD/../../../../../usr/local/Cellar/boost/1.55.0_1/include
DEPENDPATH += $$PWD/../../../../../usr/local/Cellar/boost/1.55.0_1/include

macx: PRE_TARGETDEPS += $$PWD/../../../../../usr/local/Cellar/boost/1.55.0_1/lib/libboost_filesystem.a
macx: PRE_TARGETDEPS += $$PWD/../../../../../usr/local/Cellar/boost/1.55.0_1/lib/libboost_system.a

Please note that this was auto-generated by qt creator via the Add Library interface.

Here is the code I am running that never works. (meaning isDir is always false)

namespace fs = boost::filesystem;
boost::system::error_code c;
fs::path path("/path/to/some/dir"); // Have tried '.' '/' './' '/usr' Everything!
bool isDir = boost::filesystem::is_directory(path, c);

if(!isDir) {
    std::cout << "Error Response: " << c << std::endl;
    ui->directoryEdit->setStyleSheet("background-color: red;");
}
else {
    std::cout << "Is a directory!" << std::endl;
}

The result of the output is always system: 2 from boost::system::error_code

Addition Findings:

  • When attempting to print the path, the application crashes
  • I have re compiled boost with c++11 instead of the standard but nothing changed.

I am sure I am missing something blatantly obvious, but I admit I need help.

EDIT:

So I have isolated it into a single main.cpp file:

#include <boost/filesystem.hpp>
#include <boost/system/error_code.hpp>
#include <iostream>
#include <string>

int main(int argc, char *argv[]) {

    namespace fs = boost::filesystem;
    boost::system::error_code c;
    fs::path path("."); // Have tried '.' '/' './' '/usr' Everything!
    bool isDir = boost::filesystem::is_directory(path, c);

    if(!isDir) {
        std::cout << "Error Response: " << c << std::endl;
    }
    else {
        std::cout << "Is a directory!" << std::endl;
    }

    return 0;
 }

And I compile / run with

g++ test_boost.cpp -o main.out -lboost_system -lboost_filesystem
./main.out

And the generated response is

Error Response: system:2

Very frustrating. Going to try with an older version

EDIT 2:

Per request in comments here is /usr/local/Cellar/boost/1.55.0_1/INSTALL_RECEIPT.json

{"compiler":"clang","HEAD":"4bf4ee77fa858bb5e56406504cf86564bd5ece3d","built_as_bottle":true,"stdlib":"libcxx","tapped_from":"Homebrew/homebrew","unused_options":["--with-mpi","--c++11","--with-icu","--without-static","--with-python","--universal","--without-single"],"poured_from_bottle":true,"used_options":[],"time":1399557362}  

EDIT 3:

g++ version:

Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.2.0
Thread model: posix

c++ version:

Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.2.0
Thread model: posix
like image 506
taylorcressy Avatar asked May 30 '14 13:05

taylorcressy


People also ask

What is Boost Filesystem?

The Boost Filesystem Library provides portable facilities to query and manipulate paths, files, and directories. The motivation for the library is the need to be able to perform portable script-like operations from within C++ programs.

Is boost filesystem header only?

Unlike a large portion of the Boost ecosystem, boost::filesystem is not header-only. However, integration into a project was quite simple, and the functionality it provided was impressive.

How do you check if a file is a directory C++?

Checks if the given file status or path corresponds to a directory. 1) Equivalent to s. type() == file_type::directory. 2) Equivalent to is_directory(status(p)) or is_directory(status(p, ec)), respectively.


2 Answers

The problem is not your code, as your MCVE compiles on an online compiler and gives a successful output. One possible explanation is that Boost was compiled with a different standard library than what you're compiling your program with, as suggested by the issue crash when using boost 1.55.0 from an application that is based on libstdc++ on Mac. libc++ and libstdc++ are not binary compatible because of their implementation of string (this may not be true now, but it was definitely true in the past.) Also keep in mind that on Mac, g++ may be symlinked to clang++.

Solution:

  • Compile your program with the same std library Boost was. Try clang++ -stdlib=libc++ ... or clang++ -stdlib=libstdc++ ...

  • Recompile Boost from source using a different std library, if you prefer

like image 133
OwO Avatar answered Oct 11 '22 05:10

OwO


If /path/to/some/dir is not a regular directory (e.g. it is a symlink) then is_directory is not required to return true, even if the symlink refers to a directory

Have a look at

  • http://www.boost.org/doc/libs/1_55_0/libs/filesystem/doc/reference.html#is_symlink
  • http://www.boost.org/doc/libs/1_55_0/libs/filesystem/doc/reference.html#is_other
like image 44
sehe Avatar answered Oct 11 '22 07:10

sehe