Building and using a pure llvm toolchain for c++ on linux - c++

Assuming this is possible, could someone tell me, how I have to configure the cmake build to create a "pure" llvm toolchain on ubuntu-16.04 consisting of
clang
lld
libc++
libc++abi
libunwind (llvm)
compiler-rt
any other pieces that might be relevant and are "production ready"
The resulting compiler should
be as fast as possible (optimizations turned on, no unnecessary asserts or other checks in the compiler binary itself)
be installed in a separate, local directory (lets call it <llvm_install>)
not have dependencies to the llvm tolchain provided by packet manager
use libc++, libc++abi etc by default.
support the sanitizers (ubsan, address, memory, thread) (which probably means that I have to compile libc++ a second time)
So far I have cloned
llvm from http://llvm.org/git/llvm.git into <llvm_root>
clang from http://llvm.org/git/clang.git into <llvm_root>/tools/clang
lld from http://llvm.org/git/lld.git into <llvm_root>/tools/lld
compiler-rt, libcxx, libcxxabi, libunwind from http://llvm.org/git/<project_name> into <llvm_root>/projects/<project_name>
Then run ccmake in a separate directory - I have tried various settings, but as soon as I try anything more fancy beyond turning optimizations on, I almost always get some sort of build error. Unfortunately, I have yet to find a way to export my changes from ccmake otherwise I'd give you an example with the settings and according error, but I'm more interested in a best practice than a fix to my test configs anyway.
Bonus points: By default, this should build with the default g++ toolchain, but I'd also be interested in a two stage build if that improves the performance of the final toolchain (e.g. by using LTO).
Btw.: The whole Idea came from watching chandler's talk
Pacific++ 2017: Chandler Carruth "LLVM: A Modern, Open C++ Toolchain"

My usual procedure is to build a small enough LLVM/Clang so that I have something working with libc++ and libc++abi. I guess you can use the system-provided LLVM, but I haven't tried it. For this step, what you have checked-out is probably enough. A sample script for this:
cmake
-G Ninja \
-DCMAKE_EXPORT_COMPILE_COMMANDS=On \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DBUILD_SHARED_LIBS=On \
-DLLVM_ENABLE_ASSERTIONS=Off \
-DLLVM_TARGETS_TO_BUILD="X86" \
-DLLVM_ENABLE_SPHINX=Off \
-DLLVM_ENABLE_THREADS=On \
-DLIBCXX_ENABLE_EXCEPTIONS=On \
-DLIBCXX_ENABLE_RTTI=On \
-DCMAKE_INSTALL_PREFIX=[path-to-install-dir] \
[path-to-source-dir]
Having the aforementioned clang in your PATH environment variable,
you can use the below build script again and adjust based on your needs (sanitizers, etc). Apart from the main documentation page on the subject, poking around the CMakeLists.txt of each respective tool is also illuminating and helps adjust the build process from version to version.
LLVM_TOOLCHAIN_LIB_DIR=$(llvm-config --libdir)
LD_FLAGS=""
LD_FLAGS="${LD_FLAGS} -Wl,-L ${LLVM_TOOLCHAIN_LIB_DIR}"
LD_FLAGS="${LD_FLAGS} -Wl,-rpath-link ${LLVM_TOOLCHAIN_LIB_DIR}"
LD_FLAGS="${LD_FLAGS} -lc++ -lc++abi"
CXX_FLAGS=""
CXX_FLAGS="${CXX_FLAGS} -stdlib=libc++ -pthread"
CC=clang CXX=clang++ \
cmake -G Ninja \
-DCMAKE_EXPORT_COMPILE_COMMANDS=On \
-DBUILD_SHARED_LIBS=On \
-DLLVM_ENABLE_LIBCXX=On \
-DLLVM_ENABLE_LIBCXXABI=On \
-DLLVM_ENABLE_ASSERTIONS=On \
-DLLVM_TARGETS_TO_BUILD="X86" \
-DLLVM_ENABLE_SPHINX=Off \
-DLLVM_ENABLE_THREADS=On \
-DLLVM_INSTALL_UTILS=On \
-DLIBCXX_ENABLE_EXCEPTIONS=On \
-DLIBCXX_ENABLE_RTTI=On \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="${CXX_FLAGS}" \
-DCMAKE_SHARED_LINKER_FLAGS="${LD_FLAGS}" \
-DCMAKE_MODULE_LINKER_FLAGS="${LD_FLAGS}" \
-DCMAKE_EXE_LINKER_FLAGS="${LD_FLAGS}" \
-DCMAKE_POLICY_DEFAULT_CMP0056=NEW \
-DCMAKE_POLICY_DEFAULT_CMP0058=NEW \
-DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \
[path-to-source-dir]
A note on performance: I haven't watched that talk yet, but my motivation behind this 2 step build was to have a toolchain that I can easily relocate between systems since the minimal system dependence that matters is libc.
Lastly, relevant to the above procedure is this older question of mine, which still bugs me. If you have any insight on this, please don't hesitate.
PS: Scripts have been tested with LLVM 3.7 through 3.9 and current trunk 6.0.0.
Update: I've also applied these suggestions, and there is marked improvement when using the gold linker instead of ld. LTO is also a boost.

Related

Issue with C++ macros on Red Hat Enterprise Linux (RHEL) using CPPCHECK

At my employment we are working on a large C++ project on Red Hat Enterprise Linux (RHEL) 6, soon to be RHEL 8. with Bash shell. We sometimes use Netbeans for editing source code, but I prefer to use vim. We are doing DevOps and Agile with two week sprints, and using Jenkins build engine with AccuRev for source control. Every time a code change is promoted in AccuRev, Jenkins automatically starts a new build of the code base. As part of that build, CPPCHECK is used to do static code analysis on the C++ source code.
In part of our system, we are using C++ macros to define unit test scripts. the macros are not fully defined, since we are allowing the unit test script developer to customize them for doing unit tests. This system works fine with no error at compile time with g++ compiler, and also there is no error at run time either.
However, when Jenkins does a build, and it uses CPPCHECK to analyze the code, it is generating
error-id: unknownMacro
text: There is an unknown macro here somewhere. Configuration is required. If SCRIPT is a macro then please configure it.
Here is an example of the C++ code we are using to complete partially defined C++ macro:
SCRIPT(SampleScript)
BODY()
{
cout << "SampleScript running." << endl;
}
END_SCRIPT()
SCRIPT, BODY, and END_SCRIPT are C++ macros listed in an include file, but are not completely defined. On the Github site for CPPCHECK there is a supposed solution to this issue by using -I option, but I tried that and the missing macro CPPCHECK errors are still occurring.
This is the CPPCHECK command listed with its arguments, including the -I option, but so far this command is still generating "unknownMacro" error.
cppcheck \
-I ./* \
-j 4 \
--xml-version=2 \
Ok, I have many years experience with Unix and Linux, but was not aware of the following fix. The fix is to use the -I option with CPPCHECK, which I was doing, but I was doing the following in the Makefile with an asterisk:
cppcheck \
-I ./* \
-j 4 \
--xml-version=2 \
I just found out from another person that asterisk * is not recognized in Unix and Linux Makefiles, but IS recognized from the command line with Bash and other shells like I have known for a long time. So I removed the asterisk from the CPPCHECK call and now there are no more CPPCHECK errors with the C++ code in the Jenkins build.
cppcheck \
-I ./ \
-j 4 \
--xml-version=2 \

how to compile node-v4.2.4 with armv7 without fpu?

I have a device whose cpu is armv7 but without fpu.
I can compile node with option --with-arm-float-abi=soft, but when I run "node", "Illegal instruction (core dumped)" happened.
root#router:/tmp/target/bin# ./node -v
v4.2.4
root#router:/tmp/target/bin# ./node --v8-options | head -2
target arm v7 vfp3 soft
ARMv7=1 VFP3=1 VFP32DREGS=0 NEON=0 SUDIV=0 UNALIGNED_ACCESSES=1
MOVW_MOVT_IMMEDIATE_LOADS=0 COHERENT_CACHE=0 USE_EABI_HARDFLOAT=0
The tool objdump showed me that there are instructions (such as vpush, vpop...) in use which are not supported by my cpu (arm v7 without fpu).
For the further, I found openssl and v8 in the source of node use fpu's instructions.
the configure line as below
./configure \
--prefix=target \
--dest-cpu=arm \
--dest-os=linux \
--without-snapshot \
--with-arm-float-abi=soft \
--fully-static
Can somebody tell me how to compile node-v4.2.4 without fpu supported?
source code: nodejs-v4.2.2
arm version: Cortex-A9 Floating-Point Unit (FPU)(Optional)
After many tries, I used node-v0.10.14 instead, which works well without fpu supported. ;-)
So I still do not known how to compile nodejs-v4.2.2 without fpu supported.
It's impossible.
V8 does not support no fpu mode since 3.18 (https://github.com/nodejs/node/issues/4447#issuecomment-168549889), the assumption is that the kernel can emulate the FPU for you. And NodeJS is based on V8.
Relavant comment in the source code:
https://github.com/v8/v8/blob/master/src/arm/assembler-arm.cc#L174
It's clarified in v8-users mailing list too.

Compiling and running in OCaml

I'm new to OCaml and I would like to know how can I write an ocaml code into a file and then compile it to run it whenever I want.
Now I'm using OCaml by typing ocaml in the mac or linux terminal and writing the code, but when I'm done and I close the software I lose all the work.
There're plenty of options, but the easiest one (to my opinion) is to use ocamlbuild. If you have your code in file program.ml, then
ocamlbuild program.native
will compile your program into a native binary, so that you can run it as simple as:
./program.native
There is also a shortcut that allows you to compile and run a program as one action:
ocamlbuild program.native --
You can pass arguments to your program after the -- sign.
If your program consists of more than one file, that's not a problem, as ocamlbuild will scan it, and automatically build all dependencies in a correct order.
If your program requires external libraries, then you can specify them with a -pkg or -pkgs option. Like this:
ocamlbuild -pkg lwt program.native
I'm thinking this tutorial - Compiling OCaml projects might help. It describes the basics of compiling OCaml. It discusses ocamlc and ocamlopt compilers in depth and other compiler tools.
If you are using Jane Street's Core, you should consider using the command corebuild to compile, which includes a bunch of defaults after ocamlbuild:
ocamlbuild \
-use-ocamlfind \
-pkg core \
-tag "ppx(ppx-jane -as-ppx)" \
-tag thread \
-tag debug \
-tag bin_annot \
-tag short_paths \
-cflags "-w A-4-33-40-41-42-43-34-44" \
-cflags -strict-sequence \
"$#"
I got this here.

How to build clang/examples/PrintFunctionNames?

I need some simple example to start using clang.
I downloaded llvm and clang and built:
mkdir llvm-build
cd llvm-build
../llvm/configure
make
I tried to build PrintFunctionNames from clang examples but got an error message:
../../../../Makefile.common:61: ../../../../Makefile.config: No such file or directory
../../../../Makefile.common:69: /Makefile.rules: No such file or directory
make: * No rule to make target `/Makefile.rules'. Stop.
Readme file says that only make is needed.
So how to build this plugin?
Go into llvm-build/tools/clang, and run "make BUILD_EXAMPLES=1".
Most assuredly you will have your LLVM trunk checkout and under the tools path you have checked out Clang trunk as well [explained under building Clang via http://clang.llvm.org/get_started.html.
Makefile Build Guide: http://llvm.org/docs/MakefileGuide.html
On OS X the build set up is a bit different, but on Debian Linux I'm building it daily as follows:
../trunk/configure --enable-target=x86_64,arm,cpp,cbe --with-built-clang --enable-pic --enable-polly --enable-shared --with-cxx-include-arch=x86_64 --enable-optimized --with-optimize-option=-Os --enable-assertions --disable-bootstrap --disable-multilib --enable-jit --enable-threads --no-create --no-recursion
then applying the make -j (n+1 number of cores) on the command for my Pentium D 945 system:
make [building against autotools make -j (n+1) doesn't always building llvm cleanly as it does against cmake. So if you want to run all cores, expect the possibility of running make -j(n+1) more than once to result in a clean build.
Standard form without accessing multiple cores:
make BUILD_EXAMPLES='1' //Read the note below
always results in a clean build, and if it doesn't report a bug to LLVM.
Note: If you're at the top level you can svn update the llvm trunk, project-test trunk and clang trunk as follows:
make trunk
Then go and run make again now that BUILD_EXAMPLES=1 is configured ahead of time.
make BUILD_EXAMPLES='1'
NOTE: Autotools will allow one to configure the BUILD_EXAMPLES='1' but will ignore the flag when you go to run make if you don't explicitly include BUILD_EXAMPLES='1' after make on the command line.
At the top of the LLVM tree you build against running make BUILD_EXAMPLES='1' will build the LLVM specific examples, then going inside your build/tools/clang path you then must run make BUILD_EXAMPLES='1' again to build the Clang examples.
Hence:
LLVM Top:
make BUILD_EXAMPLES='1' // for LLVM examples
cd tools/clang
make BUILD_EXAMPLES='1' // for Clang specific examples
Verify the examples installing under /usr/local/bin for LLVM and /usr/local/lib/ for Clang.
If you use CMAKE the default location for the binary examples is under /usr/local/examples
I followed the instructions at http://clang.llvm.org/get_started.html with two exceptions:
My build dir is inside the source dir (i.e. cd llvm ; mkdir build), but I don't think it's relevant.
I issued cmake as so :
cd build
cmake -DLLVM_BUILD_EXAMPLES=1 -DCLANG_BUILD_EXAMPLES=1 ..
After that (and compiling of course (make -j8)) I could find the examples in the build dir :
find -iname '*printfunctionname*'
./lib/PrintFunctionNames.so
...
I tried to do something similar yesterday: get a list of methods in a class using clang and succeeded. Maybe my post helps here also. My best help was this AST Matchers tutorial.

How can I build imagemagick without any asserts

Right now I'm using the following:
export CFLAGS="-O2-isysroot/Developer/SDKs/MacOSX10.5.sdk -arch i386 -I/sw/include/"
export LDFLAGS="-Wl,-syslibroot,/Developer/SDKs/MacOSX10.5.sdk,-L/sw/lib/"
sudo ./configure --prefix=/sw --with-quantum-depth=16 --disable-dependency-tracking --with-x=no --without-perl --enable-static --disable-shared --with-jpeg --with-tiff --disable-assert make
The code above still generates an 'identify' tool with asserts. I'm testing this by identifying a corrupted png image. Identify just crashes/exits with an assert. I'm running this on a Mac.
Any suggestions to build release mode without any asserts?
(I'm anticipating a really simple solution :) )
When running configure do this:
./configure DEFS=-DNDEBUG
The idea is to have NDEBUG defined.