16

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
taylorcressy
  • 966
  • 8
  • 23
  • 1
    The fact that the program crashes when you try to print the path is suspicious. Maybe you have memory corruption occurring elsewhere in the program? Try making an absolutely minimal example program (e.g. just the code you have posted, trimmed down, and put in a `main` function - no Qt) and see what happens there. – nobody May 30 '14 at 14:39
  • 1
    I have already done exactly that. upon a debug `current_path` gives me an empty string as well by the way – taylorcressy May 30 '14 at 15:29
  • Can you show us the contents of `Homebrew/Cellar/boost/1.55.0_1/INSTALL_RECEIPT.json`? I'm not able to recreate your failure on OS X Mavericks with a homebrew compiled boost. – Bill Lynch May 30 '14 at 15:58
  • @sharth I have added it to the original post. – taylorcressy May 30 '14 at 16:03
  • @taylorcressy: That looks correct to me. What does `g++ --version` and `c++ --version` say? – Bill Lynch May 30 '14 at 16:13
  • @taylorcressy: Thanks! And with that last piece of information, I have no clue why it's not working for you. I believe I have the exact same setup (except I install Homebrew to ~/Homebrew), and I'm getting the correct result with your reduced testcase. – Bill Lynch May 30 '14 at 16:23
  • @sharth Thanks anyway, I am going to try to install directly from source (without Homebrew) to see if it has something to do with their pre-built binaries. I don't reckon installing Homebrew in the home directory would have anything to do with it, especially since mine is the default way. Plus, I highly doubt it's a permissions problem... – taylorcressy May 30 '14 at 16:29
  • 1
    The "system:2" error message indicates an ENOENT (No such file or directory). Can this problem still be reproduced? I don't have a Mac to test it on currently, and the code works for me on a current Linux machine. – whydoubt Dec 27 '17 at 17:03
  • If it crashes when printing a path that indicates a serious problem. I would bet it is a mismatch between old and new style string types. I believe Apple used the GCC default of reference-counted strings but I don't know if they updated to C++11 mandatory copy strings with SSO or kept the reference counted strings for backward compatibility. – Zan Lynx Jan 01 '18 at 01:31

2 Answers2

5

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

OwO
  • 361
  • 3
  • 7
  • Thanks for the response after all this time. Unfortunately, this project is long gone and so is the machine I ran it on. So I can't actually verify this is the correct answer. – taylorcressy Jan 10 '18 at 17:17
4

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

sehe
  • 374,641
  • 47
  • 450
  • 633
  • 1
    But if you look at my comments I have tried many different directories. For example "/" or "." Should definitely work, but it doesn't! – taylorcressy May 30 '14 at 13:51
  • If the file or directory exists, but is not of the type being tested for, the error returned should be 0. Error 2 (ENOENT) indicates the file or directory does not exist. (It may also occur if it is a symlink and the symlink *target* does not exist) – whydoubt Dec 27 '17 at 17:08