I'm trying to make simple working tool with SyntaxOnlyAction and custom CompilationDatabase subclass which returns single file and command: clang++ -c -v -o target/test-object.cpp.o test-object.cpp
.
But unless I add -I/usr/lib/clang/14.0.6/include
to that command line, it does not find stddef.h
, then stdarg.h
, etc.
-v
option reports weird thing: ... "-resource-dir" "/home/me/work/tmp/lib/clang/14.0.6" ... "-internal-isystem" "/home/me/work/tmp/lib/clang/14.0.6/include" ...
Looks like it prepends clang's include paths with my working directory /home/me/work/tmp
. Other paths look weird too (some start with /../
), but clang accepts them.
What am I doing wrong & how can I fix it without manually adding clang's includes?
Thanks.
My system is ArtixLinux / x86-64.
tool.cpp
#include <clang/Basic/Version.inc>
#include <clang/Frontend/FrontendActions.h>
#include <clang/Tooling/CompilationDatabase.h>
#include <clang/Tooling/Tooling.h>
class MyCompilationDatabase : public clang::tooling::CompilationDatabase {
std::vector<std::string> cpps;
public:
// This example is cut from larger source where move() is inappropriate.
MyCompilationDatabase(const std::vector<std::string>& cpps) : cpps(cpps) {}
std::vector<std::string> getAllFiles() const override { return cpps; }
std::vector<clang::tooling::CompileCommand> getCompileCommands(llvm::StringRef filePath) const override {
// This is a bug: filePath is absolute; but fixing it doesn't change anything:
// clang invocation does not contain -o option.
std::string o = "target/" + filePath.str() + ".o";
std::vector<std::string> cmd = {"clang++", "-c", "-v", /*"-I/usr/lib/clang/" CLANG_VERSION_STRING "/include",*/ "-o", o, filePath.str()};
return {clang::tooling::CompileCommand(".", filePath, std::move(cmd), o)};
}
};
int main() {
MyCompilationDatabase db({"test-object.cpp"});
clang::tooling::ClangTool tool(db, db.getAllFiles());
return tool.run(clang::tooling::newFrontendActionFactory<clang::SyntaxOnlyAction>().get());
}
test-object.cpp
#include <stdio.h>
int main() {
puts("Hello world!");
}
makefile (yes I'm using gcc as main compiler -- for historical reasons, cross-compilation to Windows, ensuring that gcc & clang work together this way in a "hostile environment", etc.)
.PHONY: all
all: target/tool
$<; echo "Tool exit status: $$?"
target/%: %.cpp
mkdir -p target
g++ -std=c++20 -fno-rtti -Wall -Wextra -Wpedantic -Werror=format -Werror=return-type -O2 -flto -o $@ $< -lclang-cpp -lclang -lLLVM-14
full output
$ make
mkdir -p target
g++ -std=c++20 -fno-rtti -Wall -Wextra -Wpedantic -Werror=format -Werror=return-type -O2 -flto -o target/tool tool.cpp -lclang-cpp -lclang -lLLVM-14
target/tool; echo "Tool exit status: $?"
clang version 14.0.6
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir:
Found candidate GCC installation: /../lib/gcc/x86_64-pc-linux-gnu/12.2.0
Found candidate GCC installation: /../lib64/gcc/x86_64-pc-linux-gnu/12.2.0
Selected GCC installation: /../lib64/gcc/x86_64-pc-linux-gnu/12.2.0
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Selected multilib: .;@m64
clang Invocation:
"clang++" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-fsyntax-only" "-disable-free" "-clear-ast-before-backend" "-disable-llvm-verifier" "-discard-value-names" "-main-file-name" "test-object.cpp" "-mrelocation-model" "pic" "-pic-level" "2" "-pic-is-pie" "-mframe-pointer=all" "-fmath-errno" "-ffp-contract=on" "-fno-rounding-math" "-mconstructor-aliases" "-funwind-tables=2" "-target-cpu" "x86-64" "-tune-cpu" "generic" "-mllvm" "-treat-scalable-fixed-error-as-warning" "-debugger-tuning=gdb" "-v" "-fcoverage-compilation-dir=/home/me/work/tmp" "-resource-dir" "/home/me/work/tmp/lib/clang/14.0.6" "-c-isystem" "/home/me/include" "-c-isystem" "." "-cxx-isystem" "/home/me/include" "-cxx-isystem" "." "-internal-isystem" "/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0" "-internal-isystem" "/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/x86_64-pc-linux-gnu" "-internal-isystem" "/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/backward" "-internal-isystem" "/home/me/work/tmp/lib/clang/14.0.6/include" "-internal-isystem" "/usr/local/include" "-internal-isystem" "/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../x86_64-pc-linux-gnu/include" "-internal-externc-isystem" "/include" "-internal-externc-isystem" "/usr/include" "-fdeprecated-macro" "-fdebug-compilation-dir=/home/me/work/tmp" "-ferror-limit" "19" "-stack-protector" "2" "-fgnuc-version=4.2.1" "-fcxx-exceptions" "-fexceptions" "-fcolor-diagnostics" "-faddrsig" "-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-x" "c++" "/home/me/work/tmp/test-object.cpp"
clang -cc1 version 14.0.6 based upon LLVM 14.0.6 default target x86_64-pc-linux-gnu
ignoring nonexistent directory "/home/me/work/tmp/lib/clang/14.0.6/include"
ignoring nonexistent directory "/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../x86_64-pc-linux-gnu/include"
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
/home/me/include
.
/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0
/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/x86_64-pc-linux-gnu
/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/backward
/usr/local/include
/usr/include
End of search list.
In file included from /home/me/work/tmp/test-object.cpp:1:
/usr/include/stdio.h:33:10: fatal error: 'stddef.h' file not found
#include <stddef.h>
^~~~~~~~~~
1 error generated.
Error while processing /home/me/work/tmp/test-object.cpp.
Tool exit status: 1