From 5ad50c1ffa4b8c4541b3771f5fc8abe3a3fa5b68 Mon Sep 17 00:00:00 2001 From: ttroy50 Date: Sun, 14 Feb 2016 11:24:59 +0000 Subject: [PATCH] example for using clang and ninja --- .gitignore | 3 +- .../I-compiling-with-clang/CMakeLists.txt | 10 ++ 01-basic/I-compiling-with-clang/README.adoc | 126 ++++++++++++++ 01-basic/I-compiling-with-clang/main.cpp | 7 + 01-basic/I-compiling-with-clang/run_test.sh | 17 ++ 01-basic/J-building-with-ninja/CMakeLists.txt | 10 ++ 01-basic/J-building-with-ninja/README.adoc | 160 ++++++++++++++++++ 01-basic/J-building-with-ninja/main.cpp | 7 + 01-basic/J-building-with-ninja/run_test.sh | 2 + test.sh | 19 ++- 10 files changed, 356 insertions(+), 5 deletions(-) create mode 100644 01-basic/I-compiling-with-clang/CMakeLists.txt create mode 100644 01-basic/I-compiling-with-clang/README.adoc create mode 100644 01-basic/I-compiling-with-clang/main.cpp create mode 100755 01-basic/I-compiling-with-clang/run_test.sh create mode 100644 01-basic/J-building-with-ninja/CMakeLists.txt create mode 100644 01-basic/J-building-with-ninja/README.adoc create mode 100644 01-basic/J-building-with-ninja/main.cpp create mode 100755 01-basic/J-building-with-ninja/run_test.sh diff --git a/.gitignore b/.gitignore index bd5fafc..be7ebf6 100644 --- a/.gitignore +++ b/.gitignore @@ -57,4 +57,5 @@ install_manifest.txt *.out *.app -/**/build \ No newline at end of file +/**/build +/**/build.* diff --git a/01-basic/I-compiling-with-clang/CMakeLists.txt b/01-basic/I-compiling-with-clang/CMakeLists.txt new file mode 100644 index 0000000..ec649c0 --- /dev/null +++ b/01-basic/I-compiling-with-clang/CMakeLists.txt @@ -0,0 +1,10 @@ +# Set the minimum version of CMake that can be used +# To find the cmake version run +# $ cmake --version +cmake_minimum_required(VERSION 2.6) + +# Set the project name +project (hello_cmake) + +# Add an executable +add_executable(hello_cmake main.cpp) \ No newline at end of file diff --git a/01-basic/I-compiling-with-clang/README.adoc b/01-basic/I-compiling-with-clang/README.adoc new file mode 100644 index 0000000..daca8f9 --- /dev/null +++ b/01-basic/I-compiling-with-clang/README.adoc @@ -0,0 +1,126 @@ += Compiling with clang +:toc: +:toc-placement!: + +toc::[] + +# Introduction + +When building with CMake, it is possible to set the C and C++ compiler. This example +is the same as the link:../A-hello-cmake[hello-cmake] example exccept shows the most basic +method of changing the compiler from the default gcc to clang. + +The files in this tutorial are below: + +``` +A-hello-cmake$ tree +. +├── CMakeLists.txt +├── main.cpp +``` + + * CMakeLists.txt - Contains the CMake commands you wish to run + * main.cpp - A simple "Hello World" cpp file. + +# Concepts + +### Compiler Option + +CMake exposes options to control the programs used to compile and link your code. These +programs include: + + * CMAKE_C_COMPILER - The program used to compile c code. + * CMAKE_CXX_COMPILER - The program used to compile c++ code. + * CMAKE_LINKER - The program used to link your binary. + +[NOTE] +==== +In this example clang-3.6 is installed via the command `sudo apt-get install clang-3.6` +==== + +[NOTE] +==== +This is the most basic and easiest way to invoke clang. Future examples will show better +ways to invoke the compiler. +==== + + +### Setting Flags + +As described in the link:../F-build-type[Build Type] example, you can set CMake options +using either a cmake gui or by passing from the command line. + +Below is an example of passing the compiler via the command line. + +[source,cmake] +---- +cmake .. -DCMAKE_C_COMPILER=clang-3.6 -DCMAKE_CXX_COMPILER=clang++-3.6 +---- + +After setting these options when your run `make` clang will be used to compile your binary. This +can be seen from the following lines in the make output. + +[source,bash] +---- +/usr/bin/clang++-3.6 -o CMakeFiles/hello_cmake.dir/main.cpp.o -c /home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/main.cpp +Linking CXX executable hello_cmake +/usr/bin/cmake -E cmake_link_script CMakeFiles/hello_cmake.dir/link.txt --verbose=1 +/usr/bin/clang++-3.6 CMakeFiles/hello_cmake.dir/main.cpp.o -o hello_cmake -rdynamic +---- + + + +# Building the Examples + +Below is sample output from building this example. + +[source,bash] +---- +$ mkdir build.clang + +$ cd build.clang/ + +$ cmake .. -DCMAKE_C_COMPILER=clang-3.6 -DCMAKE_CXX_COMPILER=clang++-3.6 +-- The C compiler identification is Clang 3.6.0 +-- The CXX compiler identification is Clang 3.6.0 +-- Check for working C compiler: /usr/bin/clang-3.6 +-- Check for working C compiler: /usr/bin/clang-3.6 -- works +-- Detecting C compiler ABI info +-- Detecting C compiler ABI info - done +-- Check for working CXX compiler: /usr/bin/clang++-3.6 +-- Check for working CXX compiler: /usr/bin/clang++-3.6 -- works +-- Detecting CXX compiler ABI info +-- Detecting CXX compiler ABI info - done +-- Configuring done +-- Generating done +-- Build files have been written to: /home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang + +$ make VERBOSE=1 +/usr/bin/cmake -H/home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang -B/home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang --check-build-system CMakeFiles/Makefile.cmake 0 +/usr/bin/cmake -E cmake_progress_start /home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang/CMakeFiles /home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang/CMakeFiles/progress.marks +make -f CMakeFiles/Makefile2 all +make[1]: Entering directory `/home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang' +make -f CMakeFiles/hello_cmake.dir/build.make CMakeFiles/hello_cmake.dir/depend +make[2]: Entering directory `/home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang' +cd /home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang /home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang /home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang /home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang /home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang/CMakeFiles/hello_cmake.dir/DependInfo.cmake --color= +Dependee "/home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang/CMakeFiles/hello_cmake.dir/DependInfo.cmake" is newer than depender "/home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang/CMakeFiles/hello_cmake.dir/depend.internal". +Dependee "/home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang/CMakeFiles/hello_cmake.dir/depend.internal". +Scanning dependencies of target hello_cmake +make[2]: Leaving directory `/home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang' +make -f CMakeFiles/hello_cmake.dir/build.make CMakeFiles/hello_cmake.dir/build +make[2]: Entering directory `/home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang' +/usr/bin/cmake -E cmake_progress_report /home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang/CMakeFiles 1 +[100%] Building CXX object CMakeFiles/hello_cmake.dir/main.cpp.o +/usr/bin/clang++-3.6 -o CMakeFiles/hello_cmake.dir/main.cpp.o -c /home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/main.cpp +Linking CXX executable hello_cmake +/usr/bin/cmake -E cmake_link_script CMakeFiles/hello_cmake.dir/link.txt --verbose=1 +/usr/bin/clang++-3.6 CMakeFiles/hello_cmake.dir/main.cpp.o -o hello_cmake -rdynamic +make[2]: Leaving directory `/home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang' +/usr/bin/cmake -E cmake_progress_report /home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang/CMakeFiles 1 +[100%] Built target hello_cmake +make[1]: Leaving directory `/home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang' +/usr/bin/cmake -E cmake_progress_start /home/matrim/workspace/cmake-examples/01-basic/I-compiling-with-clang/build.clang/CMakeFiles 0 + +$ ./hello_cmake +Hello CMake! +---- diff --git a/01-basic/I-compiling-with-clang/main.cpp b/01-basic/I-compiling-with-clang/main.cpp new file mode 100644 index 0000000..750dcac --- /dev/null +++ b/01-basic/I-compiling-with-clang/main.cpp @@ -0,0 +1,7 @@ +#include + +int main(int argc, char *argv[]) +{ + std::cout << "Hello CMake!" << std::endl; + return 0; +} \ No newline at end of file diff --git a/01-basic/I-compiling-with-clang/run_test.sh b/01-basic/I-compiling-with-clang/run_test.sh new file mode 100755 index 0000000..56c8965 --- /dev/null +++ b/01-basic/I-compiling-with-clang/run_test.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# Ubuntu supports multiple versions of clang to be installed at the same time. +# The tests need to determin the clang binary before calling cmake +clang_bin=`which clang` +clang_xx_bin="clang++" + +if [ -z $clang_bin ]; then + clang_ver=`dpkg --get-selections | grep clang | grep -v -m1 libclang | cut -f1 | cut -d '-' -f2` + clang_bin="clang-$clang_ver" + clang_xx_bin="clang++-$clang_ver" +fi + +echo "Will use clang [$clang_bin] and clang++ [$clang_xx_bin]" + + +mkdir -p build.clang && cd build.clang && \ + cmake .. -DCMAKE_C_COMPILER=$clang_bin -DCMAKE_CXX_COMPILER=$clang_xx_bin && make diff --git a/01-basic/J-building-with-ninja/CMakeLists.txt b/01-basic/J-building-with-ninja/CMakeLists.txt new file mode 100644 index 0000000..ec649c0 --- /dev/null +++ b/01-basic/J-building-with-ninja/CMakeLists.txt @@ -0,0 +1,10 @@ +# Set the minimum version of CMake that can be used +# To find the cmake version run +# $ cmake --version +cmake_minimum_required(VERSION 2.6) + +# Set the project name +project (hello_cmake) + +# Add an executable +add_executable(hello_cmake main.cpp) \ No newline at end of file diff --git a/01-basic/J-building-with-ninja/README.adoc b/01-basic/J-building-with-ninja/README.adoc new file mode 100644 index 0000000..e5a7081 --- /dev/null +++ b/01-basic/J-building-with-ninja/README.adoc @@ -0,0 +1,160 @@ += Building with ninja +:toc: +:toc-placement!: + +toc::[] + +# Introduction + +As mentioned in the introduction, CMake is a meta-build system that can be used to + create the build files for many other build tools. This example shows how + to have CMake use the https://ninja-build.org/[ninja build] tool. + +The files in this tutorial are below: + +``` +A-hello-cmake$ tree +. +├── CMakeLists.txt +├── main.cpp +``` + + * CMakeLists.txt - Contains the CMake commands you wish to run + * main.cpp - A simple "Hello World" cpp file. + +# Concepts + +### Generators + +CMake https://cmake.org/cmake/help/v3.0/manual/cmake-generators.7.html[generators] are +responsible for writing the input files (e.g. Makefiles) for the underlying build system. Running `cmake --help` +will show the generators available. For cmake v2.8.12.2 the generators supported +on my system include: + +[source,bash] +---- +Generators + +The following generators are available on this platform: + Unix Makefiles = Generates standard UNIX makefiles. + Ninja = Generates build.ninja files (experimental). + CodeBlocks - Ninja = Generates CodeBlocks project files. + CodeBlocks - Unix Makefiles = Generates CodeBlocks project files. + Eclipse CDT4 - Ninja = Generates Eclipse CDT 4.0 project files. + Eclipse CDT4 - Unix Makefiles + = Generates Eclipse CDT 4.0 project files. + KDevelop3 = Generates KDevelop 3 project files. + KDevelop3 - Unix Makefiles = Generates KDevelop 3 project files. + Sublime Text 2 - Ninja = Generates Sublime Text 2 project files. + Sublime Text 2 - Unix Makefiles + = Generates Sublime Text 2 project files.Generators +---- + +As specified in this https://stackoverflow.com/questions/25941536/what-is-a-cmake-generator[post], +CMake includes different types of generators such as Command-Line, IDE, and Extra generators. + +#### Command-Line Build Tool Generators + +These generators are for command-line build tools, like Make and Ninja. The chosen tool chain must be configured prior to generating the build system with CMake. + +The supported generators include: + + * Borland Makefiles + * MSYS Makefiles + * MinGW Makefiles + * NMake Makefiles + * NMake Makefiles JOM + * Ninja + * Unix Makefiles + * Watcom WMake + +#### IDE Build Tool Generators + +These generators are for Integrated Development Environments that include their own compiler. Examples are Visual Studio and Xcode which include a compiler natively. + +The supported generators include: + + * Visual Studio 6 + * Visual Studio 7 + * Visual Studio 7 .NET 2003 + * Visual Studio 8 2005 + * Visual Studio 9 2008 + * Visual Studio 10 2010 + * Visual Studio 11 2012 + * Visual Studio 12 2013 + * Xcode + +#### Extra Generators + +These are generators create a configuration to work with an alternative IDE tool and must be included with either an IDE or Command-Line generator. + +The supported generators include: + + * CodeBlocks + * CodeLite + * Eclipse CDT4 + * KDevelop3 + * Kate + * Sublime Text 2 + + +[NOTE] +==== +In this example ninja is installed via the command `sudo apt-get install ninja-build` +==== + +### Calling a Generator + +To call a CMake generator you can use the `-G` command line switch, for example: + +[source,cmake] +---- +cmake .. -G Ninja +---- + +After doing the above CMake will generate the required Ninja build files, which can be run +from using the `ninja` command. + +[source,bash] +---- +$ cmake .. -G Ninja + +$ ls +build.ninja CMakeCache.txt CMakeFiles cmake_install.cmake rules.ninja +---- + +# Building the Examples + +Below is sample output from building this example. + +[source,bash] +---- +$ mkdir build.ninja + +$ cd build.ninja/ + +$ cmake .. -G Ninja +-- The C compiler identification is GNU 4.8.4 +-- The CXX compiler identification is GNU 4.8.4 +-- Check for working C compiler using: Ninja +-- Check for working C compiler using: Ninja -- works +-- Detecting C compiler ABI info +-- Detecting C compiler ABI info - done +-- Check for working CXX compiler using: Ninja +-- Check for working CXX compiler using: Ninja -- works +-- Detecting CXX compiler ABI info +-- Detecting CXX compiler ABI info - done +-- Configuring done +-- Generating done +-- Build files have been written to: /home/matrim/workspace/cmake-examples/01-basic/J-building-with-ninja/build.ninja + +$ ninja -v +[1/2] /usr/bin/c++ -MMD -MT CMakeFiles/hello_cmake.dir/main.cpp.o -MF "CMakeFiles/hello_cmake.dir/main.cpp.o.d" -o CMakeFiles/hello_cmake.dir/main.cpp.o -c ../main.cpp +[2/2] : && /usr/bin/c++ CMakeFiles/hello_cmake.dir/main.cpp.o -o hello_cmake -rdynamic && : + +$ ls +build.ninja CMakeCache.txt CMakeFiles cmake_install.cmake hello_cmake rules.ninja + +$ ./hello_cmake +Hello CMake! +---- diff --git a/01-basic/J-building-with-ninja/main.cpp b/01-basic/J-building-with-ninja/main.cpp new file mode 100644 index 0000000..750dcac --- /dev/null +++ b/01-basic/J-building-with-ninja/main.cpp @@ -0,0 +1,7 @@ +#include + +int main(int argc, char *argv[]) +{ + std::cout << "Hello CMake!" << std::endl; + return 0; +} \ No newline at end of file diff --git a/01-basic/J-building-with-ninja/run_test.sh b/01-basic/J-building-with-ninja/run_test.sh new file mode 100755 index 0000000..4156cc3 --- /dev/null +++ b/01-basic/J-building-with-ninja/run_test.sh @@ -0,0 +1,2 @@ +mkdir -p build.ninja && cd build.ninja && \ + cmake .. -G Ninja && ninja diff --git a/test.sh b/test.sh index bf3bc4b..bcd689c 100755 --- a/test.sh +++ b/test.sh @@ -8,6 +8,8 @@ dirs=( ./01-basic/A-hello-cmake \ ./01-basic/F-build-type \ ./01-basic/G-compile-flags \ ./01-basic/H-third-party-library \ +./01-basic/I-compiling-with-clang \ +./01-basic/J-building-with-ninja \ ./02-sub-projects/A-basic \ ./03-code-generation/protobuf \ ./03-code-generation/configure-files \ @@ -38,10 +40,19 @@ do fi fi - cd $dir && mkdir -p build && cd build && cmake .. && make - if [ $? -ne 0 ]; then - echo "Error running example $dir" - exit 1 + if [ -f "$dir/run_test.sh" ]; then + echo "running run_test" + $ROOT_DIR/$dir/run_test.sh + if [ $? -ne 0 ]; then + echo "Error running run_test for $dir" + exit 1 + fi + else + cd $dir && mkdir -p build && cd build && cmake .. && make + if [ $? -ne 0 ]; then + echo "Error running example $dir" + exit 1 + fi fi if [ -f "$ROOT_DIR/$dir/post_test.sh" ]; then