Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set up Clang to use MinGW libstdc++

Tags:

c++

clang

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);
like image 407
Puppy Avatar asked Dec 24 '12 16:12

Puppy


1 Answers

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.

like image 52
Puppy Avatar answered Sep 20 '22 23:09

Puppy