I’m developing a Clang-based tool to expose internals of C++ ABI as C structs (memory layout of classes with vtable and content of vtable), so that it can be used to generate language bindings. I want to use the code at clang/lib/AST/ItaniumCXXABI.cpp and clang/lib/AST/ItaniumMangle.cpp. it should be similar to clang -cc1 -fdump-record-layouts --fdump-vtable-layout
.
Since these classes are not exposed in Clang C API (libclang), I have to link to clang-cpp library directly.
Requirements:
- dynamically link to
clang-cpp.so
to reduce binary size - out-of-tree build (it’s not going to be part of Clang, so my source tree is separated from clang’s)
I built LLVM with Clang and installed it to /home/dev/usr/llvm
.
This is my CMakeLists.txt
set(LLVM_INSTALL_PREFIX "/home/dev/usr/llvm")
# use CMAKE_MODULE_PATH
include(${LLVM_INSTALL_PREFIX}/lib/cmake/clang/ClangConfig.cmake)
include(${LLVM_INSTALL_PREFIX}/lib/cmake/llvm/LLVMConfig.cmake)
include(${LLVM_INSTALL_PREFIX}/lib/cmake/llvm/AddLLVM.cmake)
include(${LLVM_INSTALL_PREFIX}/lib/cmake/clang/AddClang.cmake)
include_directories(${LLVM_INSTALL_PREFIX}/include)
set(LLVM_LINK_COMPONENTS
Support
)
add_clang_executable(cxx-abi-export main.cpp)
target_link_libraries(cxx-abi-export
PRIVATE
clang-cpp
)
main.cpp (just a place holder):
int main(int argc, char **argv) {
if (argc > 1) {
auto ast = clang::tooling::buildASTFromCode(argv[1]);
}
}
I can build the binary successfully, but
- what’s the expected way to use
lib/cmake/clang/*
andlib/cmake/llvm/*
. Should I add them toCMAKE_MODULE_PATH
? I think these cmake files can handleinclude_directories
for me, and I can usefind(Clang)
instead of specifyingLLVM_INSTALL_PREFIX
manually.
Another issue is the system include path
.
When I run cxx-abi-export "#include <cstdio>"
, it failed with /usr/include/stdio.h:33:10: fatal error: 'stddef.h' file not found
.
According to LibTooling, the default location to look for builtin headers is in a path $(dirname /path/to/tool)/../lib/clang/3.3/include relative to the tool binary
. However, my tool should be able to start from any working directory, just like clang-format.
my tool with -v
(mind the first line):
ignoring nonexistent directory "lib/clang/17/include"
ignoring nonexistent directory "/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include"
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12
/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/x86_64-redhat-linux
/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/backward
/usr/local/include
/usr/include
End of search list.
so I have to run my tool at llvm toplevel directory.
but Clang itself can find the header files. (/home/dev/usr/llvm/bin/clang -v input.cpp
):
ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include"
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12
/usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/x86_64-redhat-linux
/usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/backward
/home/dev/usr/llvm/lib/clang/17/include
/usr/local/include
/usr/include
How can I make my tool find /home/dev/usr/llvm/lib/clang/17/include
like clang?
Currently, I add -isystem CLANG_RESOURCE_HEADERS
to fix it.
I’m new to Clang. Any idea can be helpful.