I've been trying to set up Clang on Windows. So far I survived building with Visual Studio and CMake, and a few other surprises. But it turns out that Clang does not come with its own C++ stdlib implementation, so I decided to use GCC 4.7.0's libstdc++ built for MinGW.
To begin with, I added the search path to my HeaderSearchOptions.
headeropts->AddPath(path, clang::frontend::IncludeDirGroup::CXXSystem, true, false, false);
The path is exactly where the headers reside- I literally copied and pasted it from Windows Explorer (and then doubled the backslashes for escapes). But Clang still insists that it cannot find <iostream>
, even though a file named iostream
exists exactly at path
.
Why can't Clang find my header, and what else do I need to do to use libstdc++?
Here's my code
llvm::LLVMContext c;
llvm::Module m("", c);
clang::CompilerInstance ci;
clang::FileSystemOptions fso;
clang::FileManager fm(fso);
std::string errors;
llvm::raw_string_ostream error_stream(errors);
clang::DiagnosticOptions diagopts;
clang::TextDiagnosticPrinter printer(error_stream, &diagopts);
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagids(new clang::DiagnosticIDs);
clang::DiagnosticsEngine engine(diagids, &diagopts, &printer, false);
clang::SourceManager sm(engine, fm);
clang::LangOptions langopts;
langopts.CPlusPlus = true;
langopts.CPlusPlus0x = true;
clang::TargetOptions target;
target.Triple = llvm::sys::getDefaultTargetTriple();
auto targetinfo = clang::TargetInfo::CreateTargetInfo(engine, &target);
auto headeropts = llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions>(new clang::HeaderSearchOptions());
headeropts->AddPath("D:\\Backups\\unsorted\\x86_64-w64-mingw32-gcc-4.7.0-release-win64_rubenvb\\mingw64\\include\\c++\\4.7.0",clang::frontend::IncludeDirGroup::CXXSystem, true, false, false);
headeropts->UseStandardCXXIncludes = true;
headeropts->UseStandardSystemIncludes = true;
clang::HeaderSearch hs(headeropts, fm, engine, langopts, targetinfo);
auto x = llvm::IntrusiveRefCntPtr<clang::PreprocessorOptions>(new clang::PreprocessorOptions());
clang::Preprocessor p(x, engine, langopts, targetinfo, sm, hs, ci);
clang::ASTContext astcon(langopts, sm, targetinfo, p.getIdentifierTable(), p.getSelectorTable(), p.getBuiltinInfo(), 1000);
CodeGenConsumer consumer;
clang::CodeGen::CodeGenModule codegen(astcon, clang::CodeGenOptions(), m, llvm::DataLayout(&m), engine);
consumer.mod = &codegen;
clang::Sema sema(p, astcon, consumer, clang::TranslationUnitKind::TU_Complete);
sm.createMainFileID(fm.getFile("main.cpp"));
engine.getClient()->BeginSourceFile(langopts, &p);
clang::ParseAST(sema);
It is necessary to manually call clang::InitializePreprocessor
and clang::BuiltinContext::InitializeBuiltins
when not using the Frontend.
In addition, the triple must name "MinGW32" as vendor. If you name, say, "MinGW", then Clang will silently fail to realize that you wished for said compatibility and produce useless object files.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With