How to include libclang as a dependency using meson? - c++

I am trying to use libclang for some source parsing on linux. I have libclang-dev installed and it appears under the list of packages for apt on my system.
However when i try to add it as a dependency through any of:
dependency('clang')
dependency('libclang')
dependency('libclang-dev')
dependency('libclang-cpp-dev')
In all cases I get
Run-time dependency clang found: NO (tried pkgconfig and cmake)
Despite it no being able to find it in my system I thought I could just compile it from source. To that effect I tried this:
opt_var = cmake.subproject_options()
opt_var.append_link_args('-fPIC')
sub_proj = cmake.subproject('clang', options : opt_var)
clang = sub_proj.dependency('clang')
Which gives :
../subprojects/clang/meson.build:0:0: ERROR: Can't link non-PIC static library 'clangBasic' into shared library 'clang_cpp'. Use the 'pic' option to static_library to build with PIC.
I tested compilation of clang outside of meson (i.e. i made a build directory and did cmake .. && make) and it works so this is a problem with how meson is calling cmake, not with the library.
Any ideas?

I found a temporary solution but I hate it because it's too system specific, you can add the following:
cpp = meson.get_compiler('cpp')
includes = include_directories(['/usr/lib/llvm-13/include/'])
libclang_lib = cpp.find_library('clang', dirs:'/usr/lib/llvm-13/lib', header_include_directories: includes)
libclang = declare_dependency(dependencies:libclang_lib, include_directories:includes)
To your meson script. Then use libclang as a dependency.
I am still interested in an answer that is more general/less OS specific.

Related

Build protoc for C++ with CMake

I'm currently working on a C++ project that reference gRPC as a git submodule and I'm using CMake to compile the dependencies and my sources. For that I basically have this in my CMakeLists.txt:
ADD_SUBDIRECTORY(lib/grpc)
Then I run:
make grpc_cpp_plugin
make my_project
Even though I specify cpp_plugin here, when it's time to compile protoc I'm actually compiling for all the languages supported, eg (Java, Csharp, ...) :
/src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc.o
/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc.o
/src/google/protobuf/compiler/java/java_context.cc.o
/src/google/protobuf/compiler/java/java_doc_comment.cc.o
After looking around for some info on how to build protoc only for C++, I found that someone opened an issue on the github protobuf directory (link). However, it doesn't seem to give a clear answer.
Is there a 'clean' way to only compile the c++ dependency here ?
After doing tons of grep in gRPC's CMake files I finally compiled only the c++ version of protoc, protobuf and gRPC. And I did it in 3 steps:
go to grpc/third_party/protobuf/cmake/libprotoc.cmake and remove the lines including csharp, java, ruby, ... (Be careful to keep cpp and the langage agnostic ones)
go to grpc/CMakeLists.txt and you should be able to find this:
add_library(grpc_plugin_support
src/compiler/cpp_generator.cc
src/compiler/csharp_generator.cc
src/compiler/node_generator.cc
src/compiler/objective_c_generator.cc
src/compiler/php_generator.cc
src/compiler/python_generator.cc
src/compiler/ruby_generator.cc
)
so remove what's not needed.
and finally, grpc/third_party/protobuf/src/google/protobuf/compiler/main.cc and remove all the references to the other langage.

Why does CMake Fail to Link Libbitcoin C++?

I have recently installed CMake in order to write code to make use of Libbitcoin in C++ but I am having a hard time, I was trying to build the example code on GitHub here. And it haters been going terribly. I can't manage to link the library right in CMake, here is my code. I read and people were saying that I should try Autoconf but I have no idea how to even start that as I know nothing about Autoconf. I have CMake 3.16, and installed Libbitcoin with brew but alias were made in /usr/local/include for the library, I am on Mac OS X 10.15. The CMake runs fine but when running "make", it responds with:
Scanning dependencies of target CreateAddr
main.cxx:1:10: fatal error: bitcoin/bitcoin.hpp: No such file or directory
1 | #include <bitcoin/bitcoin.hpp>
| ^~~~~~~~~~~~~~~~~~~~~
Here is my CMake text:
Please all help is appreciated I am beyond lost.
It is hard to be sure without knowing the specifics of your installation, but it appears that your include directory paths may be overlapping with what is specified for the header in main.cxx. The include_directories() call tells the compiler to include headers from this directory:
/usr/local/include/bitcoin
Then, in main.cxx, you're including the file with bitcoin/bitcoin.hpp. Combining these suggests the file is located here:
/usr/local/include/bitcoin/bitcoin/bitcoin.hpp
The error states the header could not be found, so perhaps you meant to locate it here:
/usr/local/include/bitcoin/bitcoin.hpp
In that case, just remove the relative directory path from the main.cxx file, like this:
#include <bitcoin.hpp>
Also, you want to link to your libbitcoin library correctly. Using link_directories() is not recommended. Instead, you can specify the full path to your libbitcoin library directly in the call to target_link_libraries(). The library may not be located in /usr/local/include/bitcoin. With these changes, the last few lines in your CMake would look something more like this:
include_directories(/usr/local/include/bitcoin)
add_executable(CreateAddr main.cxx)
target_link_libraries(CreateAddr PUBLIC /your/path/to/libs/libbitcoin.so)

Hand built clang cannot find implicitly linked static library in Xcode default toolchain

As part of a research project I'm trying to use clang 6.0.1 with Xcode 9.4.1. I've built and installed clang in a custom location (/opt/llvm-6_0_1/clang). I wrote a simple xcplugin compiler specification to integrate my clang version with Xcode.
Now I can open projects in Xcode, select my proxy compiler and use it to build instead of Apple's default clang.
There were some minor additions that I had to make to the xcplugin's xcspec file to get this to work that probably won't be interesting to most people, so I won't provide the details here unless asked.
This all works with most of the projects I've played with, but I'm running into an odd problem where an implicitly linked static library cannot be found by my copy of clang. Specifically I get this error:
ld: file not found: /opt/llvm-6_0_1/clang/Toolchains/LLVM6.0.1.xctoolchain/usr/lib/arc/libarclite_macosx.a
clang-6.0: error: linker command failed with exit code 1 (use -v to see invocation)
Note that the libarclite_macosx.a file is not explicitly included by the Xcode project. I figured it must be implicitly included, perhaps because this project enables ARC?
After pouring over the Xcode generated link command line (it's complex) I decided to look at the MyProject__dependency_info.dat file, which is passed in via the -dependency_info option. Apparently this data file (the path is defined as env var LD_DEPENDENCY_INFO_FILE) is created during the linking process, not as an input to the linker. Perhaps it exists because of a hack workaround using symlinks that I used to get a link to work (described at the end).
In any case the format appears to be binary, but I was able to see a text reference to libarclite_macosx.a in the file:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_macosx.a
After enabling the -Xlinker -v option I could see that my built clang was not searching the default toolchain lib or arc paths so I added them:
-L/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib
-L/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc
Now I can see the search paths in the verbose output, but clang still cannot find the library:
Library search paths:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc
I've tried adding the paths to the frameworks search paths. I also tried defining the various link path env vars. Nothing has worked.
To try to get a sense of what clang is actually doing, I used fs_usage while getting the link error:
sudo fs_usage -e -w -f filesys | grep "lib/arc"
14:11:00.461965 stat64 [ 2] /opt/llvm-6_0_1/clang/Toolchains/LLVM6.0.1.xctoolchain/usr/lib/arc>>>>>>>>>>>>>>>>>>>>>> 0.000006 ld.1421614
14:11:00.461968 stat64 [ 2] /opt/llvm-6_0_1/clang/Toolchains/LLVM6.0.1.xctoolchain/usr/lib/arc>>>>>>>>>>>>>>>>>>>>>> 0.000002 ld.1421614
Clearly clang really wants to look for this file in the installed location, not the location indicated in the -dependency_info, nor in the search paths that I'm providing.
At this stage the only way I can get a build to work is to add a symlink to Xcode's "arc" directory to my installed clang lib directory. That "works", but is fragile and nasty.
Any thoughts as to how how I can get clang find the static library where it actually lives?

Compiling Tensorflow with a custom Clang + Libc++ (instead of stdlibc++)

I am trying to compile tensorflow with a custom clang/llvm toolchain and using clang's native libc++ (instead of borrowing Gcc's stdlibc++).
It looks like bazel plain assumes that every clang will use Gcc's libraries because I get these errors:
$ bazel build --cxxopt=-std=c++11 --cxxopt=-stdlib=libc++ tensorflow:libtensorflow.so
INFO: Found 1 target...
INFO: From Compiling
external/protobuf/src/google/protobuf/compiler/js/embed.cc [for host]:
external/protobuf/src/google/protobuf/compiler/js/embed.cc:37:12:
warning: unused variable 'output_file' [-Wunused-const-variable]
const char output_file[] = "well_known_types_embed.cc";
^
1 warning generated.
ERROR: /home/hbucher/.cache/bazel/_bazel_hbucher/ad427c7fddd5b68de5e1cfaa7cd8c8cc/external/com_googlesource_code_re2/BUILD:11:1: undeclared inclusion(s) in rule '#com_googlesource_code_re2//:re2':
this rule is missing dependency declarations for the following files included by 'external/com_googlesource_code_re2/re2/bitstate.cc':
'/home/hbucher/install/include/c++/v1/stddef.h'
'/home/hbucher/install/include/c++/v1/__config'
I tried to hack into tools/cpp/CROSSTOOL inside bazel as some posts suggested to add the line
cxx_builtin_include_directory: "/home/hbucher/install/include/c++/v1"
but to no avail, it does not seem to make any difference.
Then I tried to follow a bazel tutorial to create a custom toolchain. The text does not help much because they are actually writing a cross tool while what I am trying to do is to tweak the existing host rules and somehow bazel seems to undo every attempt I try to tweak its parameters.
I have got to the point that is currently in my github repository https://github.com/HFTrader/BazelCustomToolchain
However it does not compile and I cannot even figure out how to start debugging this message.
$ bazel build --crosstool_top=#hbclang//:toolchain tensorflow:libtensorflow.so
.....................
ERROR: The crosstool_top you specified was resolved to
'#hbclang//:toolchain', which does not contain a CROSSTOOL file. You can
use a crosstool from the depot by specifying its label.
INFO: Elapsed time: 2.216s
I have appended these lines to my tensorflow/WORKSPACE
new_local_repository(
name="hbclang",
path="/home/hbucher/BazelCustomToolchain",
build_file = "/home/hbucher/BazelCustomToolchain/BUILD",
)
I have asked this question on bazel's google groups but they redirected me to stackoverflow. At this point I am about to give up.
Have someone attempted to do this or I'm breaking ground here?
Thank you.
Solved. Not in the intended way but it works for me.
export INSTALL_DIR="$HOME/install"
export CC=$INSTALL_DIR/bin/clang
export CXX=$INSTALL_DIR/bin/clang++
export CXXFLAGS="-stdlib=libc++ -L$INSTALL_DIR/lib"
export LDFLAGS="-L$INSTALL_DIR/lib -lm -lrt"
export LD_LIBRARY_PATH="/usr/lib:/lib/x86_64-linux-gnu/:$INSTALL_DIR/lib"
git clone https://github.com/tensorflow/tensorflow.git tensorflow-github
cd tensorflow-github
mkdir build-tmp && cd build-tmp
cmake ../tensorflow/contrib/cmake/
make -j4
Easy as 1-2-3 with cmake
[2020-05-24: Edit to make the answer up to date.]
TLDR: To build a project with Bazel with a specific Clang binary, and with libc++, this works for me (where INSTALL_DIR is where I've installed llvm):
CC="$INSTALL_DIR/bin/clang" \
BAZEL_CXXOPTS="-stdlib=libc++:-isystem$INSTALL_DIR/include" \
BAZEL_LINKOPTS="-stdlib=libc++" \
BAZEL_LINKLIBS="-L$INSTALL_DIR/lib:-Wl,-rpath,$INSTALL_DIR/lib:-lc++:-lm" \
bazel test //...
Background:
You can use --repo_env option, e.g. --repo_env=CC=clang, to put these defaults into your project- or system-wide .bazelrc.
This approach uses Bazel's C++ toolchain autoconfiguration which doesn't attempt to declare all the toolchain inputs in BUILD files. This is to simplify the configuration for the user. Therefore whenever you modify the C++ toolchain in a way that Bazel cannot know about (rebuild llvm etc.), you have to run bazel clean --expunge to flush the cache and rerun the autoconfiguration the next time.
The robust solution to specifying C++ toolchain in Bazel is to use the CcToolchainConfigInfo. See the documentation at https://docs.bazel.build/versions/master/tutorial/cc-toolchain-config.html and https://docs.bazel.build/versions/master/cc-toolchain-config-reference.html.

Compile proftpd and include a library copy inside the installation directory

I do already ask a quiet similar question but in fact I now change my mind.
Id like like to compile proftpd and add a copy of the library it uses to the choosen installation directory.
Let's say I define a prefix in my compilation like:
/usr/local/proftpd
Under this directory I would like to find and use those directories only :
./lib
./usr/lib
./usr/bin
./usr/.....
./etc
./var/log/proftpd
./bin
./sbin
./and others I will not put the whole list
So the idea is after I have all libraries and config file in my main directory I could tar it and send it on another server with the same OS and without installing all the dependencies of protfpd I could use it.
I know it does sound like a windows installer not using shared library but that's in fact exactly what I'm trying to accomplish.
So far I have manage to compile it on AIX using this command line:
./configure --with-modules=mod_tls:mod_sql:mod_sql_mysql:mod_sql_passwd:mod_sftp:mod_sftp_sql --without-getopt --enable-openssl --with-includes=/opt/freeware/include:/opt/freeware/include/mysql/mysql/:/home/poney2/src_proftpd/libmath_header/ --with-libraries=/opt/freeware/lib:/opt/freeware/lib/mysql/mysql/:/home/poney2/src_proftpd/libmath_lib --prefix=/home/poney/proftpd_bin --exec-prefix=/home/poney/proftpd_bin/proftpd
Before trying to ask me why I'm doing so, it's because I have to compile proftpd on IBM AIX with almost all modules and this is not available on the IBM rpm binary repositories.
The use of this LDFLAG
LDFLAGS="-Wl,-blibpath:/a/new/lib/path"
where /a/new/lib/path contains all your library does work with Xlc and Gcc compiler.