From 787fe64ab8bbbe504fdf1550137a7e5a0f8a80df Mon Sep 17 00:00:00 2001 From: Thom Troy Date: Sat, 6 Apr 2019 21:54:32 +0100 Subject: [PATCH] add basic conan example with tests --- 07-package-management/D-conan/README.adoc | 134 ++++++++++- .../D-conan/basic/CMakeLists.txt | 17 ++ .../D-conan/basic/README.adoc | 213 ++++++++++++++++++ .../D-conan/basic/conanfile.txt | 5 + 07-package-management/D-conan/basic/main.cpp | 8 + .../D-conan/basic/run_test.sh | 19 ++ README.adoc | 6 + dockerfiles/ubuntu16.04-cmake-3.10.3 | 3 + dockerfiles/ubuntu16.04-default-cmake-3.5.1 | 3 + test.sh | 1 + 10 files changed, 406 insertions(+), 3 deletions(-) create mode 100644 07-package-management/D-conan/basic/CMakeLists.txt create mode 100644 07-package-management/D-conan/basic/README.adoc create mode 100644 07-package-management/D-conan/basic/conanfile.txt create mode 100644 07-package-management/D-conan/basic/main.cpp create mode 100755 07-package-management/D-conan/basic/run_test.sh diff --git a/07-package-management/D-conan/README.adoc b/07-package-management/D-conan/README.adoc index 3f53402..3c5b23e 100644 --- a/07-package-management/D-conan/README.adoc +++ b/07-package-management/D-conan/README.adoc @@ -12,13 +12,141 @@ Conan servers can be installed privately or you can use public servers and packa Full documentation for conan can be found from link:https://docs.conan.io/en/latest/[here] -# Installing +# Installing Conan Conan is a python application and can be installed using pip. [source,bash] ---- -$ pip install conan +$ sudo apt-get install python3 python3-pip +$ pip3 install conan +$ conan help +Consumer commands + install Installs the requirements specified in a recipe (conanfile.py or conanfile.txt). +... ---- -Alternatively, native packages are available for most operating systems. Full details are available link:https://docs.conan.io/en/latest/installation.html[here]. \ No newline at end of file +Alternatively, native packages are available for most operating systems. Full details are available link:https://docs.conan.io/en/latest/installation.html[here]. + +# Conan Profile + +In conan link:https://docs.conan.io/en/latest/reference/profiles.html#profiles[profiles] control information such as the compiler and environments that are available on your system. + +To create a new default profile run + +[source,bash] +---- +$ conan profile new default --detect +Found gcc 5.4 +gcc>=5, using the major as version +Profile created with detected settings: /home/devuser/.conan/profiles/default +---- + +The generated profile will look something like: + +[source,bash] +---- +[settings] +os=Linux +os_build=Linux +arch=x86_64 +arch_build=x86_64 +compiler=gcc +compiler.version=5 +compiler.libcxx=libstdc++ +build_type=Release +[options] +[build_requires] +[env] +---- + + +[NOTE] +==== +If you are using GCC compiler >= 5.1, Conan will set the compiler.libcxx to the old ABI for backwards compatibility. You can change this with the following commands: + +[source,bash] +---- +$ conan profile update settings.compiler.libcxx=libstdc++11 default # Sets libcxx to C++11 ABI +---- + +[source,bash] +---- +[settings] +os=Linux +os_build=Linux +arch=x86_64 +arch_build=x86_64 +compiler=gcc +compiler.version=5 +compiler.libcxx=libstdc++11 +build_type=Release +[options] +[build_requires] +[env] +---- + +You can find more information about this link:https://docs.conan.io/en/latest/howtos/manage_gcc_abi.html#manage-gcc-abi[here]. +==== + +All examples provided will assume that the ABI being used for libstdc++ is the C++11 ABI. + +# Finding Packages + +Remote repositories can be searched for conan packages. By default the `conan-center` remote is configured. This is located in link:https://bintray.com/conan/conan-center[bintray]. + +## Searching for Packages + +You can search for packages using the `conan search` command. For example, to search for a package such as link:https://github.com/fmtlib/fmt[fmtlib] you can run: + +[source,bash] +---- +$ conan search fmt* --remote=conan-center +Existing package recipes: + +fmt/4.0.0@bincrafters/stable +fmt/4.1.0@bincrafters/stable +fmt/5.0.0@bincrafters/stable +fmt/5.1.0@bincrafters/stable +fmt/5.2.0@bincrafters/stable +fmt/5.2.1@bincrafters/stable +fmt/5.3.0@bincrafters/stable + +---- + +## Inspecting Packages + +You can then inspect a package using the `conan inspect` command. To inspect one one of the fmt packages from the search command above you can run: + +[source,bash] +---- +$ conan inspect fmt/5.3.0@bincrafters/stable --remote=conan-center +name: fmt +version: 5.3.0 +url: https://github.com/bincrafters/conan-fmt +homepage: https://github.com/fmtlib/fmt +license: MIT +author: Bincrafters +description: A safe and fast alternative to printf and IOStreams. +topics: None +generators: cmake +exports: ['LICENSE.md'] +exports_sources: ['CMakeLists.txt'] +short_paths: False +apply_env: True +build_policy: None +revision_mode: hash +settings: ('os', 'compiler', 'build_type', 'arch') +options: + fPIC: [True, False] + header_only: [True, False] + shared: [True, False] + with_fmt_alias: [True, False] +default_options: + fPIC: True + header_only: False + shared: False + with_fmt_alias: False +---- + +This shows details about the package including what link:https://docs.conan.io/en/latest/using_packages/conanfile_txt.html#options[options] can be set when including the package. In the case of fmtlib there are 4 options which allow you to specify the type of installion you want. \ No newline at end of file diff --git a/07-package-management/D-conan/basic/CMakeLists.txt b/07-package-management/D-conan/basic/CMakeLists.txt new file mode 100644 index 0000000..5edd7ff --- /dev/null +++ b/07-package-management/D-conan/basic/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.5) +project (conan_third_party_include) + +set(CMAKE_CXX_STANDARD 11) + +# Included the conan build information +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup() + +# Add an executable +add_executable(third_party_include main.cpp) + +# link against the fmt target supplied by conan +target_link_libraries(third_party_include + PRIVATE + ${CONAN_LIBS} +) \ No newline at end of file diff --git a/07-package-management/D-conan/basic/README.adoc b/07-package-management/D-conan/basic/README.adoc new file mode 100644 index 0000000..2632a83 --- /dev/null +++ b/07-package-management/D-conan/basic/README.adoc @@ -0,0 +1,213 @@ += Conan Basic Example +:toc: +:toc-placement!: + +toc::[] + +# Introduction + +link:http://conan.io[Conan] supports downloading libraries and making them available to an application developers. Packages are defined in the +link:https://docs.conan.io/en/latest/using_packages/conanfile_txt.htm[conanfile.txt]+ file, which defines packages, options, and the link:https://docs.conan.io/en/latest/reference/generators.html#generators-reference[generators] for your project. + +The files in this tutorial are below: + +``` +. +├── CMakeLists.txt +├── conanfile.txt +├── main.cpp +└── README.adoc +``` + + * link:CMakeLists.txt[] - Contains the CMake commands to run + * link:conanfile.txt[] - Contains the conan dependencies and options + * link:main.cpp[] - Source file of the application. + +# Concepts + +## conanfile.txt + +### requires + +The conanfile.txt defines the required packages you wish to install + +[source,ini] +---- +[requires] +fmt/5.3.0@bincrafters/stable +---- + + +Where: + + * `fmt` is the name of the package / library. + * `5.3.0` is the version of the package. + * `bincrafters` is the owner / builder of the package. + * `stable` is channel of the package. Channels provide a to have different variants of packages. + +### generators + +Generators define the build systems that you are using and allows Conan to create files with all the information needed to find your libraries and link your program. + +[source,ini] +---- +[generators] +cmake +---- + +The CMake generator will create the file `conanbuildinfo.cmake` which should be included in your +CMakeLists.txt+ file. This will be a per-user file and should not be committed to your source control system. + +## Installing Packages + +To install packages you should run the following: + +[source,bash] +---- +$ mkdir build +$ cd build +$ conan install .. +---- + +This will tell conan to read the +conanfile.txt+ from your root folder and install any required package configurations. If the package is not availabe in your package cache it will be downloaded. + +As per our requires section, `conan install` will download a static library version of fmtlib along with all required headers. On my system with default configuration, this cached library is as follows: + +[source,bash] +---- +$ ls ~/.conan/data/fmt/5.3.0/bincrafters/stable/package/4d887c1c2779c63d2cdd81580698d2e22cb35b29/ +conaninfo.txt conanmanifest.txt include lib licenses share +$ ls ~/.conan/data/fmt/5.3.0/bincrafters/stable/package/4d887c1c2779c63d2cdd81580698d2e22cb35b29/lib +cmake libfmt.a +---- + +The install command will also create any temporary files such as the +conanbuildinfo.cmake+ file. + +## conanbuildinfo.cmake + +As mentioned the +conanbuildinfo.cmake+ file contains any CMake commands that are required to link against your installed libraries. You must include this file in your CMakeLists.txt as follows + +[source,cmake] +---- +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup() +---- + +The +CMAKE_BINARY_DIR+ here is the same build directory that your ran `conan install` in and will eventually run your `cmake` command in. + +Once included the variable +CONAN_LIBS+ is made available which contains the information you need to link against the libraries. + +[source,cmake] +---- +# link against the fmt target supplied by conan +target_link_libraries(third_party_include + PRIVATE + ${CONAN_LIBS} +) +---- + +# Building the Example + +[source,bash] +---- +$ mkdir build + +$ cd build/ + +$ conan install .. +Configuration: +[settings] +arch=x86_64 +arch_build=x86_64 +build_type=Release +compiler=gcc +compiler.libcxx=libstdc++11 +compiler.version=5 +os=Linux +os_build=Linux +[options] +[build_requires] +[env] + +fmt/5.3.0@bincrafters/stable: Not found in local cache, looking in remotes... +fmt/5.3.0@bincrafters/stable: Trying with 'conan-center'... +Downloading conanmanifest.txt +[==================================================] 166B/166B +Downloading conanfile.py +[==================================================] 2.9KB/2.9KB +Downloading conan_export.tgz +[==================================================] 758B/758B +Decompressing conan_export.tgz: 1.98kB [00:00, 504kB/s] +fmt/5.3.0@bincrafters/stable: Downloaded recipe revision 0 +conanfile.txt: Installing package +Requirements + fmt/5.3.0@bincrafters/stable from 'conan-center' - Downloaded +Packages + fmt/5.3.0@bincrafters/stable:4d887c1c2779c63d2cdd81580698d2e22cb35b29 - Download + +fmt/5.3.0@bincrafters/stable: Retrieving package 4d887c1c2779c63d2cdd81580698d2e22cb35b29 from remote 'conan-center' +Downloading conanmanifest.txt +[==================================================] 1.1KB/1.1KB +Downloading conaninfo.txt +[==================================================] 550B/550B +Downloading conan_package.tgz +[==================================================] 156.2KB/156.2KB +Decompressing conan_package.tgz: 161kB [00:00, 13.8MB/s] +fmt/5.3.0@bincrafters/stable: Package installed 4d887c1c2779c63d2cdd81580698d2e22cb35b29 +fmt/5.3.0@bincrafters/stable: Downloaded package revision 0 +conanfile.txt: Generator cmake created conanbuildinfo.cmake +conanfile.txt: Generator txt created conanbuildinfo.txt +conanfile.txt: Generated conaninfo.txt +conanfile.txt: Generated graphinfo + +$ cmake .. +-- The C compiler identification is GNU 5.4.0 +-- The CXX compiler identification is GNU 5.4.0 +-- Check for working C compiler: /usr/bin/cc +-- Check for working C compiler: /usr/bin/cc -- works +-- Detecting C compiler ABI info +-- Detecting C compiler ABI info - done +-- Detecting C compile features +-- Detecting C compile features - done +-- Check for working CXX compiler: /usr/bin/c++ +-- Check for working CXX compiler: /usr/bin/c++ -- works +-- Detecting CXX compiler ABI info +-- Detecting CXX compiler ABI info - done +-- Detecting CXX compile features +-- Detecting CXX compile features - done +-- Conan: Adjusting output directories +-- Conan: Using cmake global configuration +-- Conan: Adjusting default RPATHs Conan policies +-- Conan: Adjusting language standard +-- Current conanbuildinfo.cmake directory: /home/devuser/ws/build +-- Conan: Compiler GCC>=5, checking major version 5 +-- Conan: Checking correct version: 5 +-- Configuring done +-- Generating done +-- Build files have been written to: /home/devuser/ws/build + +$ make VERBOSE=1 +/usr/bin/cmake -H/home/devuser/ws -B/home/devuser/ws/build --check-build-system CMakeFiles/Makefile.cmake 0 +/usr/bin/cmake -E cmake_progress_start /home/devuser/ws/build/CMakeFiles /home/devuser/ws/build/CMakeFiles/progress.marks +make -f CMakeFiles/Makefile2 all +make[1]: Entering directory '/home/devuser/ws/build' +make -f CMakeFiles/third_party_include.dir/build.make CMakeFiles/third_party_include.dir/depend +make[2]: Entering directory '/home/devuser/ws/build' +cd /home/devuser/ws/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/devuser/ws /home/devuser/ws /home/devuser/ws/build /home/devuser/ws/build /home/devuser/ws/build/CMakeFiles/third_party_include.dir/DependInfo.cmake --color= +Dependee "/home/devuser/ws/build/CMakeFiles/third_party_include.dir/DependInfo.cmake" is newer than depender "/home/devuser/ws/build/CMakeFiles/third_party_include.dir/depend.internal". +Dependee "/home/devuser/ws/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/home/devuser/ws/build/CMakeFiles/third_party_include.dir/depend.internal". +Scanning dependencies of target third_party_include +make[2]: Leaving directory '/home/devuser/ws/build' +make -f CMakeFiles/third_party_include.dir/build.make CMakeFiles/third_party_include.dir/build +make[2]: Entering directory '/home/devuser/ws/build' +[ 50%] Building CXX object CMakeFiles/third_party_include.dir/main.cpp.o +/usr/bin/c++ -I/home/devuser/.conan/data/fmt/5.3.0/bincrafters/stable/package/4d887c1c2779c63d2cdd81580698d2e22cb35b29/include -std=gnu++11 -o CMakeFiles/third_party_include.dir/main.cpp.o -c /home/devuser/ws/main.cpp +[100%] Linking CXX executable bin/third_party_include +/usr/bin/cmake -E cmake_link_script CMakeFiles/third_party_include.dir/link.txt --verbose=1 +/usr/bin/c++ CMakeFiles/third_party_include.dir/main.cpp.o -o bin/third_party_include -L/home/devuser/.conan/data/fmt/5.3.0/bincrafters/stable/package/4d887c1c2779c63d2cdd81580698d2e22cb35b29/lib -lfmt -Wl,-rpath,/home/devuser/.conan/data/fmt/5.3.0/bincrafters/stable/package/4d887c1c2779c63d2cdd81580698d2e22cb35b29/lib +make[2]: Leaving directory '/home/devuser/ws/build' +[100%] Built target third_party_include +make[1]: Leaving directory '/home/devuser/ws/build' +/usr/bin/cmake -E cmake_progress_start /home/devuser/ws/build/CMakeFiles 0 + +$ ./bin/third_party_include +Hello, conan. This is fmtlib! +---- \ No newline at end of file diff --git a/07-package-management/D-conan/basic/conanfile.txt b/07-package-management/D-conan/basic/conanfile.txt new file mode 100644 index 0000000..1ff62aa --- /dev/null +++ b/07-package-management/D-conan/basic/conanfile.txt @@ -0,0 +1,5 @@ +[requires] +fmt/5.3.0@bincrafters/stable + +[generators] +cmake diff --git a/07-package-management/D-conan/basic/main.cpp b/07-package-management/D-conan/basic/main.cpp new file mode 100644 index 0000000..385a81a --- /dev/null +++ b/07-package-management/D-conan/basic/main.cpp @@ -0,0 +1,8 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + fmt::print("Hello, {}. This is {}!\n", "conan", "fmtlib"); + return 0; +} diff --git a/07-package-management/D-conan/basic/run_test.sh b/07-package-management/D-conan/basic/run_test.sh new file mode 100755 index 0000000..777acb2 --- /dev/null +++ b/07-package-management/D-conan/basic/run_test.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +conan_bin=`which conan` + +if [ -z $conan_bin ]; then + exit 0 +fi + +conan profile show default || { + conan profile new default --detect +} +conan profile update settings.compiler.libcxx=libstdc++11 default + +echo "correct version of cmake" +mkdir -p build && cd build && conan install .. && cmake .. && make +if [ $? -ne 0 ]; then + echo "Error running example" + exit 1 +fi diff --git a/README.adoc b/README.adoc index 8ce0426..fab3fc6 100644 --- a/README.adoc +++ b/README.adoc @@ -66,6 +66,11 @@ Some specific examples may require other tools including: $ sudo apt-get install ninja-build +* link:https://conan.io[conan] + + $ sudo apt-get install python3 python3-pip + $ sudo pip3 install conan + ## Docker Docker containers with all requirements and various versions of CMake are generated to help make testing the examples easier. These are available from the docker hub repository link:https://hub.docker.com/r/matrim/cmake-examples/[matrim/cmake-examples]. @@ -100,3 +105,4 @@ to some of these which I have found helpful in my CMake journey. * https://www.openfoundry.org/svn/cms/trunk/cmake/CppcheckTargets.cmake[CppCheck Targets] * https://samthursfield.wordpress.com/2015/10/20/some-cmake-tips/[CMake Tips] * https://www.johnlamp.net/cmake-tutorial.html[John Lamp - CMake Tutorial] + * link:https://docs.conan.io[Conan Documentation] diff --git a/dockerfiles/ubuntu16.04-cmake-3.10.3 b/dockerfiles/ubuntu16.04-cmake-3.10.3 index f094b95..074a896 100644 --- a/dockerfiles/ubuntu16.04-cmake-3.10.3 +++ b/dockerfiles/ubuntu16.04-cmake-3.10.3 @@ -13,6 +13,9 @@ RUN apt-get update && apt-get install -y build-essential \ ninja-build \ wget \ git \ + python3 \ + python3-pip \ + && pip3 install conan \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* diff --git a/dockerfiles/ubuntu16.04-default-cmake-3.5.1 b/dockerfiles/ubuntu16.04-default-cmake-3.5.1 index 3500cba..9398ec8 100644 --- a/dockerfiles/ubuntu16.04-default-cmake-3.5.1 +++ b/dockerfiles/ubuntu16.04-default-cmake-3.5.1 @@ -13,6 +13,9 @@ RUN apt-get update && apt-get install -y build-essential \ ninja-build \ wget \ git \ + python3 \ + python3-pip \ + && pip3 install conan \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* diff --git a/test.sh b/test.sh index 369b350..fd6aa5d 100755 --- a/test.sh +++ b/test.sh @@ -36,6 +36,7 @@ dirs=(./01-basic/A-hello-cmake \ ./05-unit-testing/google-test-download \ ./05-unit-testing/catch2-vendored \ ./06-installer/deb \ +./07-package-management/D-conan/basic \ ) ROOT_DIR=`pwd`