From 5a31589001ff39cdc917eb6a179c5bc6f67e0bc5 Mon Sep 17 00:00:00 2001 From: Uilian Ries Date: Sat, 13 Jan 2018 12:27:31 -0200 Subject: [PATCH] Build Conan package on Travis CI (#4590) - Added multi package support on Linux, running on Travis CI - Only upload when branch is a tag and named "vX.Y.Z" - Replace Conan injection by Conan wrapper - Removed os_build os_arch -- Conan 1.0.1 hotfix Signed-off-by: Uilian Ries --- .travis.yml | 14 ++++++++- conan/CMakeLists.txt | 8 +++++ conan/build.py | 47 +++++++++++++++++++++++++++++ conan/test_package/CMakeLists.txt | 8 +++++ conan/test_package/conanfile.py | 25 +++++++++++++++ conan/test_package/test_package.cpp | 35 +++++++++++++++++++++ conan/travis/build.py | 36 ++++++++++++++++++++++ conanfile.py | 17 +++++------ 8 files changed, 179 insertions(+), 11 deletions(-) create mode 100644 conan/CMakeLists.txt create mode 100644 conan/build.py create mode 100644 conan/test_package/CMakeLists.txt create mode 100644 conan/test_package/conanfile.py create mode 100644 conan/test_package/test_package.cpp create mode 100755 conan/travis/build.py diff --git a/.travis.yml b/.travis.yml index 6cc6b033cc53..61524f51a553 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,6 @@ matrix: script: - if [ "$BIICODE" == "false" ]; then cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE . && make && make test; fi - if [ "$BIICODE" == "true" ] && [ "$TRAVIS_OS_NAME" == "linux" ]; then ./biicode/support/bii-travis.sh $BUILD_TYPE; fi - - if [ "$CONAN" == "true" ] && [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo pip install conan && conan create . flatbuffers/testing -s build_type=$BUILD_TYPE; fi - language: android sudo: true @@ -81,3 +80,16 @@ matrix: - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which gcc-$GCC_VERSION) /usr/bin/gcc; fi script: - failed=0; for build_gradle in $(git ls-files | grep build.gradle); do ( cd "$(dirname "${build_gradle}")" && ./gradlew build ) || failed=1; done; exit $((failed)) + + - language: python + os: linux + sudo: required + python: "3.6" + services: + - docker + install: + - pip install conan conan-package-tools + script: + - python conan/travis/build.py + on: + tags: true diff --git a/conan/CMakeLists.txt b/conan/CMakeLists.txt new file mode 100644 index 000000000000..e320d0a4f1b3 --- /dev/null +++ b/conan/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 2.8) + +message("Conan FlatBuffers Wrapper") + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup() + +include(${CMAKE_SOURCE_DIR}/CMakeListsOriginal.txt) diff --git a/conan/build.py b/conan/build.py new file mode 100644 index 000000000000..7a3551e995b0 --- /dev/null +++ b/conan/build.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from conan.packager import ConanMultiPackager +import os, re + + +def get_value_from_recipe(search_string): + with open("conanfile.py", "r") as conanfile: + contents = conanfile.read() + result = re.search(search_string, contents) + return result + + +def get_name_from_recipe(): + return get_value_from_recipe(r'''name\s*=\s*["'](\S*)["']''').groups()[0] + + +def get_version_from_recipe(): + return get_value_from_recipe(r'''version\s*=\s*["'](\S*)["']''').groups()[0] + + +def get_env_vars(): + username = os.getenv("CONAN_USERNAME", "flatbuffers") + channel = os.getenv("CONAN_CHANNEL", "testing") + name = get_name_from_recipe() + version = get_version_from_recipe() + return name, version, username, channel + + +if __name__ == "__main__": + name, version, username, channel = get_env_vars() + reference = "{0}/{1}".format(name, version) + upload = "https://api.bintray.com/conan/{0}/conan".format(username) + + builder = ConanMultiPackager( + args="-tf %s" % os.path.join("conan", "test_package"), + username=username, + channel=channel, + reference=reference, + upload=upload, + remotes=upload, + upload_only_when_stable=True, + stable_branch_pattern=r"v\d+\.\d+\.\d+") + + builder.add_common_builds(shared_option_name="%s:shared" % name, pure_c=False) + builder.run() diff --git a/conan/test_package/CMakeLists.txt b/conan/test_package/CMakeLists.txt new file mode 100644 index 000000000000..ac820e0a13e2 --- /dev/null +++ b/conan/test_package/CMakeLists.txt @@ -0,0 +1,8 @@ +project(test_package) +cmake_minimum_required(VERSION 2.8.11) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup() + +add_executable(${PROJECT_NAME} test_package.cpp) +target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS}) diff --git a/conan/test_package/conanfile.py b/conan/test_package/conanfile.py new file mode 100644 index 000000000000..5a65c25cfccf --- /dev/null +++ b/conan/test_package/conanfile.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from conans import ConanFile, CMake, tools, RunEnvironment +import os + + +class TestPackageConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + generators = "cmake" + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def test(self): + with tools.environment_append(RunEnvironment(self).vars): + bin_path = os.path.join("bin", "test_package") + if self.settings.os == "Windows": + self.run(bin_path) + elif self.settings.os == "Macos": + self.run("DYLD_LIBRARY_PATH=%s %s" % (os.environ.get('DYLD_LIBRARY_PATH', ''), bin_path)) + else: + self.run("LD_LIBRARY_PATH=%s %s" % (os.environ.get('LD_LIBRARY_PATH', ''), bin_path)) diff --git a/conan/test_package/test_package.cpp b/conan/test_package/test_package.cpp new file mode 100644 index 000000000000..df7d577ae640 --- /dev/null +++ b/conan/test_package/test_package.cpp @@ -0,0 +1,35 @@ +/* + * Copyright 2018 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "flatbuffers/util.h" + +// Test to validate Conan package generated + +int main(int /*argc*/, const char * /*argv*/ []) { + + const std::string filename("conanbuildinfo.cmake"); + + if (flatbuffers::FileExists(filename.c_str())) { + std::cout << "File " << filename << " exists.\n"; + } else { + std::cout << "File " << filename << " does not exist.\n"; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/conan/travis/build.py b/conan/travis/build.py new file mode 100755 index 000000000000..71268b9b3f24 --- /dev/null +++ b/conan/travis/build.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import pip +import os +import subprocess +import sys +import platform + + +def build_packages_on_linux(): + build_linux_gcc() + build_linux_clang() + + +def build_linux_gcc(): + gcc_versions = ["4.9", "5", "6", "7"] + for version in gcc_versions: + os.environ["CONAN_GCC_VERSIONS"] = version + os.environ["CONAN_DOCKER_IMAGE"] = "lasote/conangcc%s" % version.replace(".", "") + + subprocess.call(["python", os.path.join("conan", "build.py")]) + + +def build_linux_clang(): + clang_versions = ["3.9", "4.0"] + for version in clang_versions: + os.environ["CONAN_CLANG_VERSIONS"] = version + os.environ["CONAN_DOCKER_IMAGE"] = "lasote/conanclang%s" % version.replace(".", "") + + subprocess.call(["python", os.path.join("conan", "build.py")]) + + +if __name__ == "__main__": + if platform.system() == "Linux": + build_packages_on_linux() diff --git a/conanfile.py b/conanfile.py index aac7606d0a5c..f07a05177bb2 100644 --- a/conanfile.py +++ b/conanfile.py @@ -4,6 +4,7 @@ """Conan recipe package for Google FlatBuffers """ import os +import shutil from conans import ConanFile, CMake, tools @@ -13,26 +14,22 @@ class FlatbuffersConan(ConanFile): license = "https://github.com/google/flatbuffers/blob/master/LICENSE.txt" url = "https://github.com/google/flatbuffers" description = "Memory Efficient Serialization Library" - settings = "os", "compiler", "build_type", "arch", "os_build", "arch_build" + settings = "os", "compiler", "build_type", "arch" options = {"shared": [True, False]} default_options = "shared=False" generators = "cmake" exports = "LICENSE.txt" - exports_sources = ["CMake/*", "include/*", "src/*", "grpc/*", "CMakeLists.txt"] + exports_sources = ["CMake/*", "include/*", "src/*", "grpc/*", "CMakeLists.txt", "conan/CMakeLists.txt"] - def _inject_magic_lines(self): - """Inject Conan setup in cmake file to solve exteral dependencies. + def source(self): + """Wrap the original CMake file to call conan_basic_setup """ - conan_magic_lines = '''project(FlatBuffers) - include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) - conan_basic_setup() - ''' - tools.replace_in_file("CMakeLists.txt", "project(FlatBuffers)", conan_magic_lines) + shutil.move("CMakeLists.txt", "CMakeListsOriginal.txt") + shutil.move(os.path.join("conan", "CMakeLists.txt"), "CMakeLists.txt") def build(self): """Configure, build and install FlatBuffers using CMake. """ - self._inject_magic_lines() cmake = CMake(self) cmake.definitions["FLATBUFFERS_BUILD_TESTS"] = False cmake.definitions["FLATBUFFERS_BUILD_SHAREDLIB"] = self.options.shared