I have some existing code that I am trying to compile using clang 3.3 and libc++ from llvm.org. A simple step to retrieve the result of another command. It appears that std::filebuf doesn't offer a FILE* constructor any more and all the ideas that I have tried to replace the code have all failed to open the command, that is fb.is_open() always returns false.
From what I can find I would have to use something like fb.open(cppcommand.c_str(), std::ios::in);
instead of popen.
The essential parts of the code are :-
std::string cppcommand = "/usr/bin/cpp -xc -nostdinc test.c";
FILE *cpppipe = popen (cppcommand.c_str(), "r");
std::filebuf fb (cpppipe);
if (! cpppipe || ! fb.is_open()) {
std::cerr << "Could not run '" << cppcommand.c_str() << "'\n";
return false;
} else {
std::istream in (&fb);
std::ostringstream ss;
ss << in.rdbuf();
result = ss.str();
}
How can I get this running with libc++?
The code is from OpenShadingLanguage and I am trying to get it to compile under FreeBSD 10.0 Beta1 which contains clang 3.3 and libc++ after removing gcc and libstdc++ from the base install.
The cppcommand string being used runs without error if manually pasted into the terminal.
Actually
std::filebuf
has never offered a constructor taking aFILE*
. You've fallen victim to a gcc extension.The C++ I/O system is very extensible, though in a fairly antique fashion. It is not that difficult to create a custom
streambuf
which could be constructed from aFILE*
, in perfectly portable C++. Normally I'd just plop the code down here. However it is a little long for an answer. And normally I don't shamelessly plug a product instead of offering an answer.In this case I'm making an exception.
Josuttis' "The C++ Standard Library" shows how to do this for a POSIX file descriptor in section 15.13.3. It would be trivial to adopt this code to use a
FILE*
instead of a POSIX file descriptor.If this was the only thing you could get out of Nicolai's book, I probably wouldn't recommend it. However that is far from the case. I recommend this book.