diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/predef | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/predef')
38 files changed, 2724 insertions, 0 deletions
diff --git a/src/boost/libs/predef/CMakeLists.txt b/src/boost/libs/predef/CMakeLists.txt new file mode 100644 index 00000000..dc69fe5d --- /dev/null +++ b/src/boost/libs/predef/CMakeLists.txt @@ -0,0 +1,38 @@ +# Copyright Mike Dev 2018 +# Copyright Rene Rivera 2018 +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt + +# NOTE: +# CMake support for Boost.Predef is currently experimental at best and the +# interface is likely to change in the future +# +# This file provides minimal cmake support (no unit-tests, +# no installation) for integration into a "host" cmake project +# via the "add_subdirectory( <path-to-boost-predef> )" command. +# +# Other cmake targets can then use the public target name +# "Boost::predef" in order to express their dependency +# on this library. I.e: +# +# target_link_libraries( <my-exe/lib> PUBLIC Boost::predef ) + +# Only need the basic minimum of project, add_library, and +# target_include_directories commands. +cmake_minimum_required( VERSION 3.0 ) + +# Don't set VERSION, as that's a pita to keep up to date with the version +# header. And don't set LANGUAGES as we are multi-language and header +# only, so it's irrelevant. +project( BoostPredef ) + +# Simple INTERFACE, and header only, library target. +add_library( boost_predef INTERFACE ) + +# The only usage requirement is include dir for consumers. +target_include_directories( boost_predef INTERFACE include ) + +# Add an alias to be compatible with consumers that may have used the +# FindBoost script. +add_library( Boost::predef ALIAS boost_predef ) diff --git a/src/boost/libs/predef/build.jam b/src/boost/libs/predef/build.jam new file mode 100644 index 00000000..56938e19 --- /dev/null +++ b/src/boost/libs/predef/build.jam @@ -0,0 +1,43 @@ +# Copyright Rene Rivera 2014-2019 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +#| +This B2 project provides support for using the Predef library externally as +a standalone project or by embedding in your B2 project tree. To use +externally you would need a `use-project` declaration and to use the +project as a dependency where needed: + +---- +use-project /hash-predef : /path/to/hash-predef/root ; + +exe my_thing : main.cpp : <dependency>/hash-predef ; +---- + +To use in your project tree you would only need to place the Predef tree +in a subdirectory and reference the project location as a dependency where +needed. + +---- +exe my_thin : main.cpp : <dependency>libs/hash-predef ; +---- +|# + +import project ; + +path-constant BOOST_PREDEF_ROOT : . ; +path-constant BOOST_PREDEF_INCLUDE : include ; +constant PREDEF_DIST : boost ; + +project /boost/predef + : usage-requirements + <include>$(BOOST_PREDEF_INCLUDE) ; + +if [ project.is-jamroot-module $(__name__) ] +{ + local attributes = [ project.attributes $(__name__) ] ; + $(attributes).set "build-dir" : bin ; +} + +alias libs ; diff --git a/src/boost/libs/predef/check/predef.jam b/src/boost/libs/predef/check/predef.jam new file mode 100644 index 00000000..7042dc1d --- /dev/null +++ b/src/boost/libs/predef/check/predef.jam @@ -0,0 +1,17 @@ +# Copyright Rene Rivera 2016 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# Hack, to reload check/predef.jam at its new location. +import modules ; +local _loaded_ ; +for local _module_ in [ modules.peek modules : .loaded ] +{ + if $(_module_) != "predef" + { + _loaded_ += $(_module_) ; + } +} +modules.poke modules : .loaded : $(_loaded_) ; +import ../tools/check/predef ; diff --git a/src/boost/libs/predef/index.html b/src/boost/libs/predef/index.html new file mode 100644 index 00000000..f99afa58 --- /dev/null +++ b/src/boost/libs/predef/index.html @@ -0,0 +1,14 @@ +<html> +<head> +<meta http-equiv="refresh" content="0; URL=../../doc/html/predef.html"> +</head> +<body> +Automatic redirection failed, please go to +<a href="../../doc/html/predef.html">../../doc/html/predef.html</a> +<p>Copyright Rene Rivera 2013-2014</p> +<p>Distributed under the Boost Software License, Version 1.0. (See accompanying file +<a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at +<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>). +</p> +</body> +</html> diff --git a/src/boost/libs/predef/meta/libraries.json b/src/boost/libs/predef/meta/libraries.json new file mode 100644 index 00000000..d7e326cd --- /dev/null +++ b/src/boost/libs/predef/meta/libraries.json @@ -0,0 +1,14 @@ +{ + "key": "predef", + "name": "Predef", + "authors": [ + "Rene Rivera" + ], + "description": "This library defines a set of compiler, architecture, operating system, library, and other version numbers from the information it can gather of C, C++, Objective C, and Objective C++ predefined macros or those defined in generally available headers.", + "category": [ + "Miscellaneous" + ], + "maintainers": [ + "Rene Rivera <grafikrobot -at- gmail.com>" + ] +} diff --git a/src/boost/libs/predef/test/build.jam b/src/boost/libs/predef/test/build.jam new file mode 100644 index 00000000..e894a31e --- /dev/null +++ b/src/boost/libs/predef/test/build.jam @@ -0,0 +1,57 @@ +# Copyright Rene Rivera 2011-2019 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import ../tools/check/predef : require check : predef-require predef-check ; +import path ; + +# This deals with the unfortunate aspect of a Boost monolithic release +# not having the modular include dirs. This is a kludge that just removes +# the direct depdndency to the header if it can't find it. +local PREDEF_H = $(BOOST_PREDEF_INCLUDE)/boost/predef.h ; +if ! [ path.exists $(PREDEF_H) ] +{ + PREDEF_H = ; +} + +project + : requirements + <include>$(BOOST_PREDEF_INCLUDE) + # Add explicit dependency since we don't have header scanner for + # .m and .mm files. + <dependency>$(PREDEF_H) + ; + +using testing ; + +test-suite predef : + [ run info_as_cpp.cpp : : : <test-info>always_show_run_output ] + [ run info_as_c.c : : : <test-info>always_show_run_output ] + [ run info_as_objcpp.mm : : : <test-info>always_show_run_output ] + [ run info_as_objc.m : : : <test-info>always_show_run_output ] + [ run version.cpp ] + [ run make.cpp ] + [ compile macos_endian.c : [ predef-require "BOOST_OS_MACOS" : cpp ] ] + [ compile macos_vs_bsd.c : [ predef-require "BOOST_OS_MACOS" : cpp ] ] + [ run check_value.cpp : : : <test-info>always_show_run_output + [ predef-check "BOOST_COMP_CLANG > 0.0.0" "BOOST_OS_LINUX == 0" : : <cxxflags>-DCHECK_VALUE=true ] ] + [ run workaround.cpp ] + [ compile workaround_strict_config.cpp ] + [ run tested_at.cpp ] + [ compile-fail tested_at_outdated.cpp : <test-info>always_show_run_output ] + [ compile platform_windows.cpp ] + ; + +# Minimal testing done for predef for CI. Since +# we don't have many we can just do all of them. +alias minimal : predef ; + +# Full testing target for regular regression tests. +alias full : predef ; + +# Extra's target. Nothing for Predef. +alias extra ; + +explicit minimal ; +explicit extra ; diff --git a/src/boost/libs/predef/test/check_value.cpp b/src/boost/libs/predef/test/check_value.cpp new file mode 100644 index 00000000..30ae806f --- /dev/null +++ b/src/boost/libs/predef/test/check_value.cpp @@ -0,0 +1,26 @@ +/* +Copyright Rene Rivera 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +/* + * Simple program that just prints out the externally + * defined CHECK_VALUE def. It's used to test the check + * program and the related BB support. + */ + +#include <boost/predef.h> +#include <iostream> +#include <string> + +#ifndef CHECK_VALUE +#define CHECK_VALUE "undefined" +#endif + +int main() +{ + std::cout << "CHECK_VALUE == " << CHECK_VALUE << "\n" ; + return 0; +} diff --git a/src/boost/libs/predef/test/info_as_c.c b/src/boost/libs/predef/test/info_as_c.c new file mode 100644 index 00000000..44f7e8dc --- /dev/null +++ b/src/boost/libs/predef/test/info_as_c.c @@ -0,0 +1,7 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include "predef_info.h" diff --git a/src/boost/libs/predef/test/info_as_cpp.cpp b/src/boost/libs/predef/test/info_as_cpp.cpp new file mode 100644 index 00000000..44f7e8dc --- /dev/null +++ b/src/boost/libs/predef/test/info_as_cpp.cpp @@ -0,0 +1,7 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include "predef_info.h" diff --git a/src/boost/libs/predef/test/info_as_objc.m b/src/boost/libs/predef/test/info_as_objc.m new file mode 100644 index 00000000..44f7e8dc --- /dev/null +++ b/src/boost/libs/predef/test/info_as_objc.m @@ -0,0 +1,7 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include "predef_info.h" diff --git a/src/boost/libs/predef/test/info_as_objcpp.mm b/src/boost/libs/predef/test/info_as_objcpp.mm new file mode 100644 index 00000000..44f7e8dc --- /dev/null +++ b/src/boost/libs/predef/test/info_as_objcpp.mm @@ -0,0 +1,7 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include "predef_info.h" diff --git a/src/boost/libs/predef/test/macos_endian.c b/src/boost/libs/predef/test/macos_endian.c new file mode 100644 index 00000000..7f29f900 --- /dev/null +++ b/src/boost/libs/predef/test/macos_endian.c @@ -0,0 +1,21 @@ +/* +Copyright Rene Rivera 2013 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +/* + * OSX can define the BSD symbols if sys/param.h is included + * before detection. This causes the endian detection to misfire + * as both MACOS and BSD are "detected" (currently). This just + * tests that the sys/param.h include can be included before + * endian detection and still have it work correctly. + */ + +#if defined(__APPLE__) +# include <sys/param.h> +# include <boost/predef/os/bsd.h> +# include <boost/predef/os/macos.h> +# include <boost/predef/other/endian.h> +#endif diff --git a/src/boost/libs/predef/test/macos_vs_bsd.c b/src/boost/libs/predef/test/macos_vs_bsd.c new file mode 100644 index 00000000..173b5a42 --- /dev/null +++ b/src/boost/libs/predef/test/macos_vs_bsd.c @@ -0,0 +1,19 @@ +/* +Copyright Rene Rivera 2013 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +/* + * OSX can masquerade as BSD when sys/param.h is previously included. + * So we test that we only detect OSX in this combination. + */ +#if defined(__APPLE__) +# include <sys/param.h> +# include <boost/predef/os/bsd.h> +# include <boost/predef/os/macos.h> +# if !BOOST_OS_MACOS || BOOST_OS_BSD +# error "BOOST_OS_MACOS not detected and/or BOOST_OS_BSD mis-detected." +# endif +#endif diff --git a/src/boost/libs/predef/test/make.cpp b/src/boost/libs/predef/test/make.cpp new file mode 100644 index 00000000..6b846246 --- /dev/null +++ b/src/boost/libs/predef/test/make.cpp @@ -0,0 +1,94 @@ +/* +Copyright Rene Rivera 2011-2013 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/predef/version_number.h> +#include <boost/predef/make.h> +#include <exception> +#include <vector> +#include <string> +#include <iostream> + +namespace +{ + struct test_info + { + std::string value; + bool passed; + + test_info(std::string const & v, bool p) : value(v), passed(p) {} + test_info(test_info const & o) : value(o.value), passed(o.passed) {} + }; + + std::vector<test_info> test_results; +} + +#define PREDEF_CHECK(X) test_results.push_back(test_info(#X,(X))) + +void test_BOOST_VERSION_NUMBER() +{ + PREDEF_CHECK(BOOST_PREDEF_MAKE_0X_VRP(0xFFF) == BOOST_VERSION_NUMBER(0xF,0xF,0xF)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_0X_VVRP(0xFFFF) == BOOST_VERSION_NUMBER(0xFF,0xF,0xF)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_0X_VRPP(0xFFFF) == BOOST_VERSION_NUMBER(0xF,0xF,0xFF)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_0X_VVRR(0xFFFF) == BOOST_VERSION_NUMBER(0xFF,0xFF,0x0)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_0X_VRRPPPP(0xFFFFFFF) == BOOST_VERSION_NUMBER(0xF,0xFF,0xFFFF)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_0X_VVRRP(0xFFFFF) == BOOST_VERSION_NUMBER(0xFF,0xFF,0xF)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_0X_VRRPP000(0xFFFFF000) == BOOST_VERSION_NUMBER(0xF,0xFF,0xFF)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_0X_VVRRPP(0xFFFFFF) == BOOST_VERSION_NUMBER(0xFF,0xFF,0xFF)); + + PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VR0(980) == BOOST_VERSION_NUMBER(9,8,0)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VRP(999) == BOOST_VERSION_NUMBER(9,9,9)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VPPP(9999) == BOOST_VERSION_NUMBER(9,0,999)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VVRRPP(999999) == BOOST_VERSION_NUMBER(99,99,99)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VVRR(9999) == BOOST_VERSION_NUMBER(99,99,0)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VVRRP(98765) == BOOST_VERSION_NUMBER(98,76,5)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VRPP(9999) == BOOST_VERSION_NUMBER(9,9,99)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VRRPP(99999) == BOOST_VERSION_NUMBER(9,99,99)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VRPPPP(460002) == BOOST_VERSION_NUMBER(4,6,2)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VRPPPP(491000) == BOOST_VERSION_NUMBER(4,9,1000)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VRP000(999000) == BOOST_VERSION_NUMBER(9,9,9)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VRR000(999000) == BOOST_VERSION_NUMBER(9,99,0)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VVRR00PP00(2199009900u) == BOOST_VERSION_NUMBER(21,99,99)); + /* PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VVRR00PP00(9999009900ull) == BOOST_VERSION_NUMBER(99,99,99)); */ + PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VVRR0PP00(999909900) == BOOST_VERSION_NUMBER(99,99,99)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VV00(9900) == BOOST_VERSION_NUMBER(99,00,00)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VVRR0PPPP(999909999) == BOOST_VERSION_NUMBER(99,99,9999)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VRR(999) == BOOST_VERSION_NUMBER(9,99,00)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VVRRPPP(903122) == BOOST_VERSION_NUMBER(9,3,122)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_10_VVRRPPP(1101002) == BOOST_VERSION_NUMBER(11,1,2)); + + PREDEF_CHECK(BOOST_PREDEF_MAKE_DATE(1971,1,1) == BOOST_VERSION_NUMBER(1,1,1)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_YYYYMMDD(19700101) == BOOST_VERSION_NUMBER(0,1,1)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_YYYYMMDD(19710101) == BOOST_VERSION_NUMBER(1,1,1)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_YYYYMMDD(20691231) == BOOST_VERSION_NUMBER(99,12,31)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_YYYYMM(197001) == BOOST_VERSION_NUMBER(0,1,1)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_YYYYMM(197101) == BOOST_VERSION_NUMBER(1,1,1)); + PREDEF_CHECK(BOOST_PREDEF_MAKE_YYYYMM(206912) == BOOST_VERSION_NUMBER(99,12,1)); +} + +int main() +{ + test_BOOST_VERSION_NUMBER(); + + unsigned fail_count = 0; + std::vector<test_info>::iterator i = test_results.begin(); + std::vector<test_info>::iterator e = test_results.end(); + for (; i != e; ++i) + { + std::cout + << (i->passed ? "[passed]" : "[failed]") + << " " << i->value + << std::endl; + fail_count += i->passed ? 0 : 1; + } + std::cout + << std::endl + << "TOTAL: " + << "passed " << (test_results.size()-fail_count) << ", " + << "failed " << (fail_count) << ", " + << "of " << (test_results.size()) + << std::endl; + return fail_count; +} diff --git a/src/boost/libs/predef/test/platform_windows.cpp b/src/boost/libs/predef/test/platform_windows.cpp new file mode 100644 index 00000000..53f3ecc5 --- /dev/null +++ b/src/boost/libs/predef/test/platform_windows.cpp @@ -0,0 +1,177 @@ +/* +Copyright James E. King, III - 2017 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#include <boost/predef/platform.h> + +// +// This file is used to verify the BOOST_PLAT_WINDOWS_* logic. +// +// To exercise all of the combinations the CI build needs many +// jobs where it defines all the different possible WINAPI_FAMILY +// values on all supported platforms. +// + +// +// UWP is available on Windows SDK 8.0 or later, or on MinGW-w64 major release 3 or later +// +#if (defined(__MINGW64__) && (__MINGW64_VERSION_MAJOR >= 3)) || (BOOST_PLAT_WINDOWS_SDK_VERSION >= 9200) +#if !BOOST_PLAT_WINDOWS_UWP +#error "BOOST_PLAT_WINDOWS_UWP should be available" +#endif +#else +#if BOOST_PLAT_WINDOWS_UWP +#error "BOOST_PLAT_WINDOWS_UWP should not be available" +#endif +#endif + +#if !BOOST_PLAT_WINDOWS_UWP + +// +// If BOOST_PLAT_WINDOWS_UWP is not available, none of the other BOOST_PLAT_WINDOWS_* are either +// except for BOOST_PLAT_WINDOWS_DESKTOP which is available for backwards compatibility. +// + +#if BOOST_OS_WINDOWS && !BOOST_PLAT_WINDOWS_DESKTOP +#error "BOOST_PLAT_WINDOWS_DESKTOP should be available" +#endif +#if BOOST_PLAT_WINDOWS_PHONE +#error "BOOST_PLAT_WINDOWS_PHONE should not be available" +#endif +#if BOOST_PLAT_WINDOWS_RUNTIME /* deprecated */ +#error "BOOST_PLAT_WINDOWS_RUNTIME should not be available" +#endif +#if BOOST_PLAT_WINDOWS_SERVER +#error "BOOST_PLAT_WINDOWS_SERVER should not be available" +#endif +#if BOOST_PLAT_WINDOWS_STORE +#error "BOOST_PLAT_WINDOWS_STORE should not be available" +#endif +#if BOOST_PLAT_WINDOWS_SYSTEM +#error "BOOST_PLAT_WINDOWS_SYSTEM should not be available" +#endif + +#else // !BOOST_PLAT_WINDOWS_UWP + +// +// If BOOST_PLAT_WINDOWS_UWP is available, and the SDK supports a particular family, +// and if WINAPI_FAMILY is set to it, then it and only it should be available. +// + +#if !defined(WINAPI_FAMILY) +#error "windows_uwp.h should have included <winapifamily.h> which should have defined supported families" +#endif + +#if WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP +#if !BOOST_PLAT_WINDOWS_DESKTOP +#error "BOOST_PLAT_WINDOWS_DESKTOP should be available" +#endif +#if BOOST_PLAT_WINDOWS_PHONE +#error "BOOST_PLAT_WINDOWS_PHONE should not be available" +#endif +#if BOOST_PLAT_WINDOWS_RUNTIME /* deprecated */ +#error "BOOST_PLAT_WINDOWS_RUNTIME should not be available" +#endif +#if BOOST_PLAT_WINDOWS_SERVER +#error "BOOST_PLAT_WINDOWS_SERVER should not be available" +#endif +#if BOOST_PLAT_WINDOWS_STORE +#error "BOOST_PLAT_WINDOWS_STORE should not be available" +#endif +#if BOOST_PLAT_WINDOWS_SYSTEM +#error "BOOST_PLAT_WINDOWS_SYSTEM should not be available" +#endif +#endif + +#if defined(WINAPI_FAMILY_PHONE_APP) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#if BOOST_PLAT_WINDOWS_DESKTOP +#error "BOOST_PLAT_WINDOWS_DESKTOP should not be available" +#endif +#if !BOOST_PLAT_WINDOWS_PHONE +#error "BOOST_PLAT_WINDOWS_PHONE should be available" +#endif +#if !BOOST_PLAT_WINDOWS_RUNTIME /* deprecated */ +#error "BOOST_PLAT_WINDOWS_RUNTIME should be available" +#endif +#if BOOST_PLAT_WINDOWS_SERVER +#error "BOOST_PLAT_WINDOWS_SERVER should not be available" +#endif +#if BOOST_PLAT_WINDOWS_STORE +#error "BOOST_PLAT_WINDOWS_STORE should not be available" +#endif +#if BOOST_PLAT_WINDOWS_SYSTEM +#error "BOOST_PLAT_WINDOWS_SYSTEM should not be available" +#endif +#endif + +#if defined(WINAPI_FAMILY_SERVER_APP) && WINAPI_FAMILY == WINAPI_FAMILY_SERVER_APP +#if BOOST_PLAT_WINDOWS_DESKTOP +#error "BOOST_PLAT_WINDOWS_DESKTOP should not be available" +#endif +#if BOOST_PLAT_WINDOWS_PHONE +#error "BOOST_PLAT_WINDOWS_PHONE should not be available" +#endif +#if BOOST_PLAT_WINDOWS_RUNTIME /* deprecated */ +#error "BOOST_PLAT_WINDOWS_RUNTIME should not be available" +#endif +#if !BOOST_PLAT_WINDOWS_SERVER +#error "BOOST_PLAT_WINDOWS_SERVER should be available" +#endif +#if BOOST_PLAT_WINDOWS_STORE +#error "BOOST_PLAT_WINDOWS_STORE should not be available" +#endif +#if BOOST_PLAT_WINDOWS_SYSTEM +#error "BOOST_PLAT_WINDOWS_SYSTEM should not be available" +#endif +#endif + +// Store is WINAPI_FAMILY_APP in MinGW-w64 and in Windows SDK 8.0 +// then in Windows SDK 8.1 it was deprecated in favor of WINAPI_FAMILY_PC_APP + +#if ((defined(WINAPI_FAMILY_PC_APP) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) || \ + (defined(WINAPI_FAMILY_APP) && WINAPI_FAMILY == WINAPI_FAMILY_APP)) +#if BOOST_PLAT_WINDOWS_DESKTOP +#error "BOOST_PLAT_WINDOWS_DESKTOP should not be available" +#endif +#if BOOST_PLAT_WINDOWS_PHONE +#error "BOOST_PLAT_WINDOWS_PHONE should not be available" +#endif +#if !BOOST_PLAT_WINDOWS_RUNTIME /* deprecated */ +#error "BOOST_PLAT_WINDOWS_RUNTIME should be available" +#endif +#if BOOST_PLAT_WINDOWS_SERVER +#error "BOOST_PLAT_WINDOWS_SERVER should not be available" +#endif +#if !BOOST_PLAT_WINDOWS_STORE +#error "BOOST_PLAT_WINDOWS_STORE should be available" +#endif +#if BOOST_PLAT_WINDOWS_SYSTEM +#error "BOOST_PLAT_WINDOWS_SYSTEM should not be available" +#endif +#endif + +#if defined(WINAPI_FAMILY_SYSTEM_APP) && WINAPI_FAMILY == WINAPI_FAMILY_SYSTEM_APP +#if BOOST_PLAT_WINDOWS_DESKTOP +#error "BOOST_PLAT_WINDOWS_DESKTOP should not be available" +#endif +#if BOOST_PLAT_WINDOWS_PHONE +#error "BOOST_PLAT_WINDOWS_PHONE should not be available" +#endif +#if BOOST_PLAT_WINDOWS_RUNTIME /* deprecated */ +#error "BOOST_PLAT_WINDOWS_RUNTIME should not be available" +#endif +#if BOOST_PLAT_WINDOWS_SERVER +#error "BOOST_PLAT_WINDOWS_SERVER should not be available" +#endif +#if BOOST_PLAT_WINDOWS_STORE +#error "BOOST_PLAT_WINDOWS_STORE should not be available" +#endif +#if !BOOST_PLAT_WINDOWS_SYSTEM +#error "BOOST_PLAT_WINDOWS_SYSTEM should be available" +#endif +#endif + +#endif // !BOOST_PLAT_WINDOWS_UWP diff --git a/src/boost/libs/predef/test/predef_info.h b/src/boost/libs/predef/test/predef_info.h new file mode 100644 index 00000000..213d94b4 --- /dev/null +++ b/src/boost/libs/predef/test/predef_info.h @@ -0,0 +1,46 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/predef/detail/test_def.h> + +int main() +{ + unsigned x = 0; + create_predef_entries(); + qsort(generated_predef_info,generated_predef_info_count, + sizeof(predef_info),predef_info_compare); + /* + for (x = 0; x < generated_predef_info_count; ++x) + { + printf("%s: %d\n", generated_predef_info[x].name, generated_predef_info[x].value); + } + */ + puts("** Detected **"); + for (x = 0; x < generated_predef_info_count; ++x) + { + if (generated_predef_info[x].value > 0) + printf("%s = %u (%u,%u,%u) | %s\n", + generated_predef_info[x].name, + generated_predef_info[x].value, + (generated_predef_info[x].value/10000000)%100, + (generated_predef_info[x].value/100000)%100, + (generated_predef_info[x].value)%100000, + generated_predef_info[x].description); + } + puts("** Not Detected **"); + for (x = 0; x < generated_predef_info_count; ++x) + { + if (generated_predef_info[x].value == 0) + printf("%s = %u | %s\n", + generated_predef_info[x].name, + generated_predef_info[x].value, + generated_predef_info[x].description); + } + if (generated_predef_info_count > 0) + return 0; + else + return 1; +} diff --git a/src/boost/libs/predef/test/test_cmake/CMakeLists.txt b/src/boost/libs/predef/test/test_cmake/CMakeLists.txt new file mode 100644 index 00000000..9bdbd62d --- /dev/null +++ b/src/boost/libs/predef/test/test_cmake/CMakeLists.txt @@ -0,0 +1,29 @@ +# Copyright Mike Dev 2018 +# Copyright Rene Rivera 2018 +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt + +# NOTE: +# This does NOT run the unit tests for Boost.Predef. +# It only tests, if the CMakeLists.txt file in predef's +# root directory works as expected (i.e. it provides the +# target Boost::predef which in turn provides the +# correct include directory ) + +# We have very simple cmake requirements we we still require the new style +# declarative targets. +cmake_minimum_required( VERSION 3.0 ) + +project( PredefCMakeSelfTest ) + +# Process cmake file at root of library and use +# ${CMAKE_CURRENT_BINARY_DIR}/libs/predef as workspace +add_subdirectory( ../.. ${CMAKE_CURRENT_BINARY_DIR}/libs/predef ) + +# The executable just includes a predef header to verify that it's used. +add_executable( predef_cmake_test_prj main.cpp ) + +# The executable needs to "use" the Predef "library" to get the usage +# requirements added to the executable build. +target_link_libraries( predef_cmake_test_prj Boost::predef ) diff --git a/src/boost/libs/predef/test/test_cmake/main.cpp b/src/boost/libs/predef/test/test_cmake/main.cpp new file mode 100644 index 00000000..c8005bc4 --- /dev/null +++ b/src/boost/libs/predef/test/test_cmake/main.cpp @@ -0,0 +1,19 @@ +/* +Copyright Mike Dev 2018 +Copyright 2018 Rene Rivera +Distributed under the Boost Software License, Version 1.0. +See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt +*/ + +/* +Dummy executable, just to make sure that we can find the Boost Predef header +files. +*/ + +#include <boost/predef.h> + +int main() +{ + return 0; +} diff --git a/src/boost/libs/predef/test/tested_at.cpp b/src/boost/libs/predef/test/tested_at.cpp new file mode 100644 index 00000000..2c4816eb --- /dev/null +++ b/src/boost/libs/predef/test/tested_at.cpp @@ -0,0 +1,62 @@ +/* +Copyright Rene Rivera 2011-2017 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/predef/version_number.h> +#include <boost/predef/other/workaround.h> +#include <exception> +#include <vector> +#include <string> +#include <iostream> + +namespace +{ + struct test_info + { + std::string value; + bool passed; + + test_info(std::string const & v, bool p) : value(v), passed(p) {} + test_info(test_info const & o) : value(o.value), passed(o.passed) {} + }; + + std::vector<test_info> test_results; +} + +#define PREDEF_CHECK(X) test_results.push_back(test_info(#X,(X))) + +void test_BOOST_PREDEF_TESTED_AT() +{ + PREDEF_CHECK(BOOST_PREDEF_TESTED_AT(BOOST_VERSION_NUMBER(15,15,15),0xF,0xF,0xF)); + PREDEF_CHECK(BOOST_PREDEF_TESTED_AT(BOOST_VERSION_NUMBER(1,0,0),1,0,0)); + PREDEF_CHECK(BOOST_PREDEF_TESTED_AT(BOOST_VERSION_NUMBER(0,9,0),1,0,0)); + PREDEF_CHECK(BOOST_PREDEF_TESTED_AT(BOOST_VERSION_NUMBER(2,0,0),1,0,0)); + PREDEF_CHECK(!BOOST_PREDEF_TESTED_AT(BOOST_VERSION_NUMBER_NOT_AVAILABLE,1,0,0)); +} + +int main() +{ + test_BOOST_PREDEF_TESTED_AT(); + + unsigned fail_count = 0; + std::vector<test_info>::iterator i = test_results.begin(); + std::vector<test_info>::iterator e = test_results.end(); + for (; i != e; ++i) + { + std::cout + << (i->passed ? "[passed]" : "[failed]") + << " " << i->value + << std::endl; + fail_count += i->passed ? 0 : 1; + } + std::cout + << std::endl + << "TOTAL: " + << "passed " << (test_results.size()-fail_count) << ", " + << "failed " << (fail_count) << ", " + << "of " << (test_results.size()) + << std::endl; + return fail_count; +} diff --git a/src/boost/libs/predef/test/tested_at_outdated.cpp b/src/boost/libs/predef/test/tested_at_outdated.cpp new file mode 100644 index 00000000..534ebafe --- /dev/null +++ b/src/boost/libs/predef/test/tested_at_outdated.cpp @@ -0,0 +1,18 @@ +/* +Copyright Rene Rivera 2011-2017 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/predef/version_number.h> +#define BOOST_DETECT_OUTDATED_WORKAROUNDS +#include <boost/predef/other/workaround.h> + +int main() +{ +#if BOOST_PREDEF_TESTED_AT(BOOST_VERSION_NUMBER(2,0,0),1,0,0) + return 1; +#else + return 0; +#endif +} diff --git a/src/boost/libs/predef/test/version.cpp b/src/boost/libs/predef/test/version.cpp new file mode 100644 index 00000000..68e724fb --- /dev/null +++ b/src/boost/libs/predef/test/version.cpp @@ -0,0 +1,83 @@ +/* +Copyright Rene Rivera 2011-2012 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/predef/version_number.h> +#include <exception> +#include <vector> +#include <string> +#include <iostream> + +namespace +{ + struct test_info + { + std::string value; + bool passed; + + test_info(std::string const & v, bool p) : value(v), passed(p) {} + test_info(test_info const & o) : value(o.value), passed(o.passed) {} + }; + + std::vector<test_info> test_results; +} + +#define PREDEF_CHECK(X) test_results.push_back(test_info(#X,(X))) + +void test_BOOST_VERSION_NUMBER() +{ + PREDEF_CHECK(BOOST_VERSION_NUMBER(0,0,1) == 1L); + PREDEF_CHECK(BOOST_VERSION_NUMBER(99,99,99999) == 999999999L); + PREDEF_CHECK(BOOST_VERSION_NUMBER(299UL,99UL,99999UL) != 2999999999UL); + PREDEF_CHECK(BOOST_VERSION_NUMBER(100,99,99999) != 1009999999L); + PREDEF_CHECK(BOOST_VERSION_NUMBER(100,99,99999) == 9999999L); + PREDEF_CHECK(BOOST_VERSION_NUMBER(100,100,100000) == 0L); + + PREDEF_CHECK( + BOOST_VERSION_NUMBER_MAJOR(BOOST_VERSION_NUMBER(0,0,0)) == 0); + PREDEF_CHECK( + BOOST_VERSION_NUMBER_MAJOR(BOOST_VERSION_NUMBER(3,3,3)) == 3); + PREDEF_CHECK( + BOOST_VERSION_NUMBER_MAJOR(BOOST_VERSION_NUMBER(99,99,99999)) == 99); + + PREDEF_CHECK( + BOOST_VERSION_NUMBER_MINOR(BOOST_VERSION_NUMBER(0,0,0)) == 0); + PREDEF_CHECK( + BOOST_VERSION_NUMBER_MINOR(BOOST_VERSION_NUMBER(3,3,3)) == 3); + PREDEF_CHECK( + BOOST_VERSION_NUMBER_MINOR(BOOST_VERSION_NUMBER(99,99,99999)) == 99); + + PREDEF_CHECK( + BOOST_VERSION_NUMBER_PATCH(BOOST_VERSION_NUMBER(0,0,0)) == 0); + PREDEF_CHECK( + BOOST_VERSION_NUMBER_PATCH(BOOST_VERSION_NUMBER(3,3,3)) == 3); + PREDEF_CHECK( + BOOST_VERSION_NUMBER_PATCH(BOOST_VERSION_NUMBER(99,99,99999)) == 99999); +} + +int main() +{ + test_BOOST_VERSION_NUMBER(); + + unsigned fail_count = 0; + std::vector<test_info>::iterator i = test_results.begin(); + std::vector<test_info>::iterator e = test_results.end(); + for (; i != e; ++i) + { + std::cout + << (i->passed ? "[passed]" : "[failed]") + << " " << i->value + << std::endl; + fail_count += i->passed ? 0 : 1; + } + std::cout + << std::endl + << "TOTAL: " + << "passed " << (test_results.size()-fail_count) << ", " + << "failed " << (fail_count) << ", " + << "of " << (test_results.size()) + << std::endl; + return fail_count; +} diff --git a/src/boost/libs/predef/test/workaround.cpp b/src/boost/libs/predef/test/workaround.cpp new file mode 100644 index 00000000..368daea3 --- /dev/null +++ b/src/boost/libs/predef/test/workaround.cpp @@ -0,0 +1,62 @@ +/* +Copyright Rene Rivera 2011-2017 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/predef/version_number.h> +#include <boost/predef/other/workaround.h> +#include <exception> +#include <vector> +#include <string> +#include <iostream> + +namespace +{ + struct test_info + { + std::string value; + bool passed; + + test_info(std::string const & v, bool p) : value(v), passed(p) {} + test_info(test_info const & o) : value(o.value), passed(o.passed) {} + }; + + std::vector<test_info> test_results; +} + +#define PREDEF_CHECK(X) test_results.push_back(test_info(#X,(X))) + +void test_BOOST_PREDEF_WORKAROUND() +{ + PREDEF_CHECK(BOOST_PREDEF_WORKAROUND(BOOST_VERSION_NUMBER(15,15,15),==,0xF,0xF,0xF)); + PREDEF_CHECK(BOOST_PREDEF_WORKAROUND(BOOST_VERSION_NUMBER(0,9,0),<,1,0,0)); + PREDEF_CHECK(BOOST_PREDEF_WORKAROUND(BOOST_VERSION_NUMBER(0,9,0),!=,1,0,0)); + PREDEF_CHECK(BOOST_PREDEF_WORKAROUND(BOOST_VERSION_NUMBER_MIN,<,1,0,0)); + PREDEF_CHECK(BOOST_PREDEF_WORKAROUND(BOOST_VERSION_NUMBER_MIN,>,0,0,0)); +} + +int main() +{ + test_BOOST_PREDEF_WORKAROUND(); + + unsigned fail_count = 0; + std::vector<test_info>::iterator i = test_results.begin(); + std::vector<test_info>::iterator e = test_results.end(); + for (; i != e; ++i) + { + std::cout + << (i->passed ? "[passed]" : "[failed]") + << " " << i->value + << std::endl; + fail_count += i->passed ? 0 : 1; + } + std::cout + << std::endl + << "TOTAL: " + << "passed " << (test_results.size()-fail_count) << ", " + << "failed " << (fail_count) << ", " + << "of " << (test_results.size()) + << std::endl; + return fail_count; +} diff --git a/src/boost/libs/predef/test/workaround_strict_config.cpp b/src/boost/libs/predef/test/workaround_strict_config.cpp new file mode 100644 index 00000000..df7b1764 --- /dev/null +++ b/src/boost/libs/predef/test/workaround_strict_config.cpp @@ -0,0 +1,17 @@ +/* +Copyright Rene Rivera 2011-2017 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/predef/version_number.h> +#define BOOST_STRICT_CONFIG +#include <boost/predef/other/workaround.h> + +int main() +{ +#if BOOST_PREDEF_WORKAROUND(BOOST_VERSION_NUMBER_AVAILABLE,==,0,0,1) + fail(); +#endif + return 0; +} diff --git a/src/boost/libs/predef/tools/check/build.jam b/src/boost/libs/predef/tools/check/build.jam new file mode 100644 index 00000000..1ce4f11e --- /dev/null +++ b/src/boost/libs/predef/tools/check/build.jam @@ -0,0 +1,9 @@ +# Copyright Rene Rivera 2015 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +exe predef_check_as_c : predef_check_as_c.c : <include>../include ; +exe predef_check_as_cpp : predef_check_as_cpp.cpp : <include>../include ; +exe predef_check_as_objc : predef_check_as_objc.m : <include>../include ; +exe predef_check_as_objcpp : predef_check_as_objcpp.mm : <include>../include ; diff --git a/src/boost/libs/predef/tools/check/predef.jam b/src/boost/libs/predef/tools/check/predef.jam new file mode 100644 index 00000000..dd18bfb0 --- /dev/null +++ b/src/boost/libs/predef/tools/check/predef.jam @@ -0,0 +1,202 @@ +# Copyright Rene Rivera 2015 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# Defines rules that provide requirements based on checking +# conditions using Boost Predef definitions and version numbers. + +import modules ; +import project ; +import feature ; +import string ; +import toolset ; +import modules ; +import path ; +import "class" : new ; +import regex ; + +# Create a project for our targets. +project.extension predef check ; + +# Feature to pass check expressions to check programs. +feature.feature predef-expression : : free ; + +# Checks the expressions and when used evaluates to the true-properties +# if the expressions are all true. Otherwise evaluates to the +# false-properties. +rule check ( expressions + : language ? : true-properties * : false-properties * ) +{ + # Default to C++ on the check context. + language ?= cpp ; + + local project_target = [ project.target $(__name__) ] ; + project.push-current $(project_target) ; + local terms ; + local result ; + for expression in $(expressions) + { + if $(expression:L) in "and" "or" + { + terms += $(expression:L) ; + } + else + { + # Create the check run if we don't have one yet. + local key = [ MD5 "$(language)::$(expression)" ] ; + if ! ( $(key) in $(_checks_) ) + { + _checks_ += $(key) ; + _message_(/check/predef//predef_check_cc_$(key)) = $(expression) ; + check_target $(language) $(key) : [ change_term_to_def $(expression) ] ; + } + + terms += /check/predef//predef_check_cc_$(key) ; + } + } + local instance = [ new check-expression-evaluator + $(terms) : $(true-properties) : $(false-properties) ] ; + result = <conditional>@$(instance).check ; + project.pop-current ; + return $(result) ; +} + +# Checks the expressions and when used evaluates to <build>no +# if the expressions are all false. Otherwise evaluates to the +# nothing. +rule require ( expressions + : language ? ) +{ + return [ check $(expressions) : $(language) : : <build>no ] ; +} + +############################################################################# + +.c.ext = c ; +.cpp.ext = cpp ; +.objc.ext = m ; +.objcpp.ext = mm ; + +# Check targets. Each needs to be compiled for different languages +# even though they are all the same source code. +local rule check_target ( language key : requirements * ) +{ + # Need to use absolute paths because we don't know the + # context of the invocation which affects where the paths + # originate from. + local predef_jam + = [ modules.binding $(__name__) ] ; + local source_path + = $(predef_jam:D)/predef_check_cc_as_$(language).$(.$(language).ext) ; + local include_path + = $(predef_jam:D)/../../include $(BOOST_ROOT) ; + obj predef_check_cc_$(key) + : $(source_path) + : <include>$(include_path) $(requirements) ; + explicit predef_check_cc_$(key) ; + return predef_check_cc_$(key) ; +} + +local rule change_term_to_def ( term ) +{ + local parts = [ regex.split $(term) " " ] ; + if $(parts[3]) + { + local version_number = [ regex.split $(parts[3]) "[.]" ] ; + if ! $(version_number[2]) { version_number += "0" ; } + if ! $(version_number[3]) { version_number += "0" ; } + parts = $(parts[1-2]) BOOST_VERSION_NUMBER($(version_number:J=",")) ; + } + return <define>CHECK=\"$(parts:J=" ")\" ; +} + +class check-expression-evaluator +{ + import configure ; + + rule __init__ ( expression + : true-properties * : false-properties * ) + { + self.expression = $(expression) ; + self.true-properties = $(true-properties) ; + self.false-properties = $(false-properties) ; + } + + rule check ( properties * ) + { + local to-eval ; + local tokens = "and" "or" ; + # Go through the expression and: eval the target values, + # and normalize to a full expression. + for local term in $(self.expression) + { + if ! ( $(term:L) in $(tokens) ) + { + # A value is a target reference that will evan to "true" + # or "false". + if $(to-eval[-1]:L) && ! ( $(to-eval[-1]:L) in $(tokens) ) + { + # Default to "and" operation. + to-eval += "and" ; + } + local message = [ modules.peek predef : _message_($(term)) ] ; + if [ configure.builds $(term) : $(properties) : $(message) ] + { + to-eval += "true" ; + } + else + { + to-eval += "false" ; + } + } + else + { + to-eval += $(term) ; + } + } + # Eval full the expression. + local eval-result = [ eval $(to-eval) ] ; + # And resolve true/false properties. + if $(eval-result) = "true" + { + return $(self.true-properties) ; + } + else + { + return $(self.false-properties) ; + } + } + + rule eval ( e * ) + { + local r ; + if $(e[1]) && $(e[2]) && $(e[3]) + { + if $(e[2]) = "and" + { + if $(e[1]) = "true" && $(e[3]) = "true" + { + r = [ eval "true" $(e[4-]) ] ; + } + else + { + r = [ eval "false" $(e[4-]) ] ; + } + } + else if $(e[2]) = "or" + { + if $(e[1]) = "true" || $(e[3]) = "true" + { + r = [ eval "true" $(e[4-]) ] ; + } + else + { + r = [ eval "false" $(e[4-]) ] ; + } + } + } + else + { + r = $(e[1]) ; + } + return $(r) ; + } +} diff --git a/src/boost/libs/predef/tools/check/predef_check.h b/src/boost/libs/predef/tools/check/predef_check.h new file mode 100644 index 00000000..a6917c17 --- /dev/null +++ b/src/boost/libs/predef/tools/check/predef_check.h @@ -0,0 +1,98 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/predef/detail/test_def.h> + +const char * str_token(const char ** str, const char * space) +{ + unsigned span; + char * token; + for (; **str != 0; *str += 1) + { + if (0 == strchr(space, **str)) + { + break; + } + } + span = strcspn(*str, space); + token = (char *)malloc(span+1); + strncpy(token, *str, span); + token[span] = 0; + for (*str += span; **str != 0; *str += 1) + { + if (0 == strchr(space, **str)) + { + break; + } + } + return token; +} + +const char * whitespace = " "; +const char * dot = "."; + +int main(int argc, const char ** argv) +{ + unsigned x = 0; + int argi = 1; + create_predef_entries(); +#if 0 + qsort(generated_predef_info,generated_predef_info_count, + sizeof(predef_info),predef_info_compare); + for (x = 0; x < generated_predef_info_count; ++x) + { + printf("%s: %d\n", generated_predef_info[x].name, generated_predef_info[x].value); + } +#endif + int result = -1; + for (argi = 1; argi < argc; ++argi) + { + const char * exp = argv[argi]; + const char * exp_name = str_token(&exp, whitespace); + const char * exp_op = str_token(&exp, whitespace); + const char * exp_val = str_token(&exp, whitespace); + unsigned exp_version = 0; + if (*exp_val != 0) + { + exp = exp_val; + const char * exp_val_a = str_token(&exp, dot); + const char * exp_val_b = str_token(&exp, dot); + const char * exp_val_c = str_token(&exp, dot); + exp_version = BOOST_VERSION_NUMBER(atoi(exp_val_a), atoi(exp_val_b),atoi(exp_val_c)); + } + for (x = 0; x < generated_predef_info_count; ++x) + { + if (*exp_op == 0 && + generated_predef_info[x].value > 0 && + strcmp(exp_name, generated_predef_info[x].name) == 0) + { + /* Expression of the form "BOOST_x_yy" is true. */ + result = 0; + break; + } + else if (*exp_op == 0 && + generated_predef_info[x].value == 0 && + strcmp(exp_name, generated_predef_info[x].name) == 0) + { + /* Expression of the form "BOOST_x_yy" is false. */ + return argi; + } + else if (*exp_op != 0 && *exp_val != 0 && + strcmp(exp_name, generated_predef_info[x].name) == 0) + { + /* Expression of the form "BOOST_x_yy op val". */ + result = 0; + if (0 == strcmp(">",exp_op) && !(generated_predef_info[x].value > exp_version)) return argi; + if (0 == strcmp("<",exp_op) && !(generated_predef_info[x].value < exp_version)) return argi; + if (0 == strcmp(">=",exp_op) && !(generated_predef_info[x].value >= exp_version)) return argi; + if (0 == strcmp("<=",exp_op) && !(generated_predef_info[x].value <= exp_version)) return argi; + if (0 == strcmp("==",exp_op) && !(generated_predef_info[x].value == exp_version)) return argi; + if (0 == strcmp("!=",exp_op) && !(generated_predef_info[x].value != exp_version)) return argi; + } + } + } + return result; +} diff --git a/src/boost/libs/predef/tools/check/predef_check_as_c.c b/src/boost/libs/predef/tools/check/predef_check_as_c.c new file mode 100644 index 00000000..352c18ba --- /dev/null +++ b/src/boost/libs/predef/tools/check/predef_check_as_c.c @@ -0,0 +1,7 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include "predef_check.h" diff --git a/src/boost/libs/predef/tools/check/predef_check_as_cpp.cpp b/src/boost/libs/predef/tools/check/predef_check_as_cpp.cpp new file mode 100644 index 00000000..352c18ba --- /dev/null +++ b/src/boost/libs/predef/tools/check/predef_check_as_cpp.cpp @@ -0,0 +1,7 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include "predef_check.h" diff --git a/src/boost/libs/predef/tools/check/predef_check_as_objc.m b/src/boost/libs/predef/tools/check/predef_check_as_objc.m new file mode 100644 index 00000000..352c18ba --- /dev/null +++ b/src/boost/libs/predef/tools/check/predef_check_as_objc.m @@ -0,0 +1,7 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include "predef_check.h" diff --git a/src/boost/libs/predef/tools/check/predef_check_as_objcpp.mm b/src/boost/libs/predef/tools/check/predef_check_as_objcpp.mm new file mode 100644 index 00000000..352c18ba --- /dev/null +++ b/src/boost/libs/predef/tools/check/predef_check_as_objcpp.mm @@ -0,0 +1,7 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include "predef_check.h" diff --git a/src/boost/libs/predef/tools/check/predef_check_cc.h b/src/boost/libs/predef/tools/check/predef_check_cc.h new file mode 100644 index 00000000..da7609ec --- /dev/null +++ b/src/boost/libs/predef/tools/check/predef_check_cc.h @@ -0,0 +1,19 @@ +/* +Copyright Rene Rivera 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/predef.h> + +#ifdef CHECK +# if ((CHECK) == 0) +# error "FAILED" +# endif +#endif + +int dummy() +{ + static int d = 0; + return d++; +} diff --git a/src/boost/libs/predef/tools/check/predef_check_cc_as_c.c b/src/boost/libs/predef/tools/check/predef_check_cc_as_c.c new file mode 100644 index 00000000..24fab13e --- /dev/null +++ b/src/boost/libs/predef/tools/check/predef_check_cc_as_c.c @@ -0,0 +1,7 @@ +/* +Copyright Rene Rivera 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include "predef_check_cc.h" diff --git a/src/boost/libs/predef/tools/check/predef_check_cc_as_cpp.cpp b/src/boost/libs/predef/tools/check/predef_check_cc_as_cpp.cpp new file mode 100644 index 00000000..24fab13e --- /dev/null +++ b/src/boost/libs/predef/tools/check/predef_check_cc_as_cpp.cpp @@ -0,0 +1,7 @@ +/* +Copyright Rene Rivera 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include "predef_check_cc.h" diff --git a/src/boost/libs/predef/tools/check/predef_check_cc_as_objc.m b/src/boost/libs/predef/tools/check/predef_check_cc_as_objc.m new file mode 100644 index 00000000..24fab13e --- /dev/null +++ b/src/boost/libs/predef/tools/check/predef_check_cc_as_objc.m @@ -0,0 +1,7 @@ +/* +Copyright Rene Rivera 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include "predef_check_cc.h" diff --git a/src/boost/libs/predef/tools/check/predef_check_cc_as_objcpp.mm b/src/boost/libs/predef/tools/check/predef_check_cc_as_objcpp.mm new file mode 100644 index 00000000..24fab13e --- /dev/null +++ b/src/boost/libs/predef/tools/check/predef_check_cc_as_objcpp.mm @@ -0,0 +1,7 @@ +/* +Copyright Rene Rivera 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include "predef_check_cc.h" diff --git a/src/boost/libs/predef/tools/ci/build_log.py b/src/boost/libs/predef/tools/ci/build_log.py new file mode 100644 index 00000000..6ae156b7 --- /dev/null +++ b/src/boost/libs/predef/tools/ci/build_log.py @@ -0,0 +1,428 @@ +#!/usr/bin/env python + +# Copyright 2008 Rene Rivera +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +import re +import optparse +import time +import xml.dom.minidom +import xml.dom.pulldom +from xml.sax.saxutils import unescape, escape +import os.path +from pprint import pprint +from __builtin__ import exit + +class BuildOutputXMLParsing(object): + ''' + XML parsing utilities for dealing with the Boost Build output + XML format. + ''' + + def get_child_data( self, root, tag = None, id = None, name = None, strip = False, default = None ): + return self.get_data(self.get_child(root,tag=tag,id=id,name=name),strip=strip,default=default) + + def get_data( self, node, strip = False, default = None ): + data = None + if node: + data_node = None + if not data_node: + data_node = self.get_child(node,tag='#text') + if not data_node: + data_node = self.get_child(node,tag='#cdata-section') + data = "" + while data_node: + data += data_node.data + data_node = data_node.nextSibling + if data_node: + if data_node.nodeName != '#text' \ + and data_node.nodeName != '#cdata-section': + data_node = None + if not data: + data = default + else: + if strip: + data = data.strip() + return data + + def get_child( self, root, tag = None, id = None, name = None, type = None ): + return self.get_sibling(root.firstChild,tag=tag,id=id,name=name,type=type) + + def get_sibling( self, sibling, tag = None, id = None, name = None, type = None ): + n = sibling + while n: + found = True + if type and found: + found = found and type == n.nodeType + if tag and found: + found = found and tag == n.nodeName + if (id or name) and found: + found = found and n.nodeType == xml.dom.Node.ELEMENT_NODE + if id and found: + if n.hasAttribute('id'): + found = found and n.getAttribute('id') == id + else: + found = found and n.hasAttribute('id') and n.getAttribute('id') == id + if name and found: + found = found and n.hasAttribute('name') and n.getAttribute('name') == name + if found: + return n + n = n.nextSibling + return None + +class BuildOutputProcessor(BuildOutputXMLParsing): + + def __init__(self, inputs): + self.test = {} + self.target_to_test = {} + self.target = {} + self.parent = {} + self.timestamps = [] + for input in inputs: + self.add_input(input) + + def add_input(self, input): + ''' + Add a single build XML output file to our data. + ''' + events = xml.dom.pulldom.parse(input) + context = [] + for (event,node) in events: + if event == xml.dom.pulldom.START_ELEMENT: + context.append(node) + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + x_f = self.x_name_(*context) + if x_f: + events.expandNode(node) + # expanding eats the end element, hence walking us out one level + context.pop() + # call handler + (x_f[1])(node) + elif event == xml.dom.pulldom.END_ELEMENT: + context.pop() + + def x_name_(self, *context, **kwargs): + node = None + names = [ ] + for c in context: + if c: + if not isinstance(c,xml.dom.Node): + suffix = '_'+c.replace('-','_').replace('#','_') + else: + suffix = '_'+c.nodeName.replace('-','_').replace('#','_') + node = c + names.append('x') + names = map(lambda x: x+suffix,names) + if node: + for name in names: + if hasattr(self,name): + return (name,getattr(self,name)) + return None + + def x_build_test(self, node): + ''' + Records the initial test information that will eventually + get expanded as we process the rest of the results. + ''' + test_node = node + test_name = test_node.getAttribute('name') + test_target = self.get_child_data(test_node,tag='target',strip=True) + ## print ">>> %s %s" %(test_name,test_target) + self.test[test_name] = { + 'library' : "/".join(test_name.split('/')[0:-1]), + 'test-name' : test_name.split('/')[-1], + 'test-type' : test_node.getAttribute('type').lower(), + 'test-program' : self.get_child_data(test_node,tag='source',strip=True), + 'target' : test_target, + 'info' : self.get_child_data(test_node,tag='info',strip=True), + 'dependencies' : [], + 'actions' : [], + } + # Add a lookup for the test given the test target. + self.target_to_test[self.test[test_name]['target']] = test_name + return None + + def x_build_targets_target( self, node ): + ''' + Process the target dependency DAG into an ancestry tree so we can look up + which top-level library and test targets specific build actions correspond to. + ''' + target_node = node + name = self.get_child_data(target_node,tag='name',strip=True) + path = self.get_child_data(target_node,tag='path',strip=True) + jam_target = self.get_child_data(target_node,tag='jam-target',strip=True) + #~ Map for jam targets to virtual targets. + self.target[jam_target] = { + 'name' : name, + 'path' : path + } + #~ Create the ancestry. + dep_node = self.get_child(self.get_child(target_node,tag='dependencies'),tag='dependency') + while dep_node: + child = self.get_data(dep_node,strip=True) + child_jam_target = '<p%s>%s' % (path,child.split('//',1)[1]) + self.parent[child_jam_target] = jam_target + dep_node = self.get_sibling(dep_node.nextSibling,tag='dependency') + return None + + def x_build_action( self, node ): + ''' + Given a build action log, process into the corresponding test log and + specific test log sub-part. + ''' + action_node = node + name = self.get_child(action_node,tag='name') + if name: + name = self.get_data(name) + #~ Based on the action, we decide what sub-section the log + #~ should go into. + action_type = None + if re.match('[^%]+%[^.]+[.](compile)',name): + action_type = 'compile' + elif re.match('[^%]+%[^.]+[.](link|archive)',name): + action_type = 'link' + elif re.match('[^%]+%testing[.](capture-output)',name): + action_type = 'run' + elif re.match('[^%]+%testing[.](expect-failure|expect-success)',name): + action_type = 'result' + else: + # TODO: Enable to see what other actions can be included in the test results. + # action_type = None + action_type = 'other' + #~ print "+ [%s] %s %s :: %s" %(action_type,name,'','') + if action_type: + #~ Get the corresponding test. + (target,test) = self.get_test(action_node,type=action_type) + #~ Skip action that have no corresponding test as they are + #~ regular build actions and don't need to show up in the + #~ regression results. + if not test: + ##print "??? [%s] %s %s :: %s" %(action_type,name,target,test) + return None + ##print "+++ [%s] %s %s :: %s" %(action_type,name,target,test) + #~ Collect some basic info about the action. + action = { + 'command' : self.get_action_command(action_node,action_type), + 'output' : self.get_action_output(action_node,action_type), + 'info' : self.get_action_info(action_node,action_type) + } + #~ For the test result status we find the appropriate node + #~ based on the type of test. Then adjust the result status + #~ accordingly. This makes the result status reflect the + #~ expectation as the result pages post processing does not + #~ account for this inversion. + action['type'] = action_type + if action_type == 'result': + if re.match(r'^compile',test['test-type']): + action['type'] = 'compile' + elif re.match(r'^link',test['test-type']): + action['type'] = 'link' + elif re.match(r'^run',test['test-type']): + action['type'] = 'run' + #~ The result sub-part we will add this result to. + if action_node.getAttribute('status') == '0': + action['result'] = 'succeed' + else: + action['result'] = 'fail' + # Add the action to the test. + test['actions'].append(action) + # Set the test result if this is the result action for the test. + if action_type == 'result': + test['result'] = action['result'] + return None + + def x_build_timestamp( self, node ): + ''' + The time-stamp goes to the corresponding attribute in the result. + ''' + self.timestamps.append(self.get_data(node).strip()) + return None + + def get_test( self, node, type = None ): + ''' + Find the test corresponding to an action. For testing targets these + are the ones pre-declared in the --dump-test option. For libraries + we create a dummy test as needed. + ''' + jam_target = self.get_child_data(node,tag='jam-target') + base = self.target[jam_target]['name'] + target = jam_target + while target in self.parent: + target = self.parent[target] + #~ print "--- TEST: %s ==> %s" %(jam_target,target) + #~ main-target-type is a precise indicator of what the build target is + #~ originally meant to be. + #main_type = self.get_child_data(self.get_child(node,tag='properties'), + # name='main-target-type',strip=True) + main_type = None + if main_type == 'LIB' and type: + lib = self.target[target]['name'] + if not lib in self.test: + self.test[lib] = { + 'library' : re.search(r'libs/([^/]+)',lib).group(1), + 'test-name' : os.path.basename(lib), + 'test-type' : 'lib', + 'test-program' : os.path.basename(lib), + 'target' : lib + } + test = self.test[lib] + else: + target_name_ = self.target[target]['name'] + if self.target_to_test.has_key(target_name_): + test = self.test[self.target_to_test[target_name_]] + else: + test = None + return (base,test) + + #~ The command executed for the action. For run actions we omit the command + #~ as it's just noise. + def get_action_command( self, action_node, action_type ): + if action_type != 'run': + return self.get_child_data(action_node,tag='command') + else: + return '' + + #~ The command output. + def get_action_output( self, action_node, action_type ): + return self.get_child_data(action_node,tag='output',default='') + + #~ Some basic info about the action. + def get_action_info( self, action_node, action_type ): + info = {} + #~ The jam action and target. + info['name'] = self.get_child_data(action_node,tag='name') + info['path'] = self.get_child_data(action_node,tag='path') + #~ The timing of the action. + info['time-start'] = action_node.getAttribute('start') + info['time-end'] = action_node.getAttribute('end') + info['time-user'] = action_node.getAttribute('user') + info['time-system'] = action_node.getAttribute('system') + #~ Testing properties. + test_info_prop = self.get_child_data(self.get_child(action_node,tag='properties'),name='test-info') + info['always_show_run_output'] = test_info_prop == 'always_show_run_output' + #~ And for compiles some context that may be hidden if using response files. + if action_type == 'compile': + info['define'] = [] + define = self.get_child(self.get_child(action_node,tag='properties'),name='define') + while define: + info['define'].append(self.get_data(define,strip=True)) + define = self.get_sibling(define.nextSibling,name='define') + return info + +class BuildConsoleSummaryReport(object): + + HEADER = '\033[35m\033[1m' + INFO = '\033[34m' + OK = '\033[32m' + WARNING = '\033[33m' + FAIL = '\033[31m' + ENDC = '\033[0m' + + def __init__(self, bop, opt): + self.bop = bop + + def generate(self): + self.summary_info = { + 'total' : 0, + 'success' : 0, + 'failed' : [], + } + self.header_print("======================================================================") + self.print_test_log() + self.print_summary() + self.header_print("======================================================================") + + @property + def failed(self): + return len(self.summary_info['failed']) > 0 + + def print_test_log(self): + self.header_print("Tests run..") + self.header_print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") + for k in sorted(self.bop.test.keys()): + test = self.bop.test[k] + if len(test['actions']) > 0: + self.summary_info['total'] += 1 + ##print ">>>> {0}".format(test['test-name']) + if 'result' in test: + succeed = test['result'] == 'succeed' + else: + succeed = test['actions'][-1]['result'] == 'succeed' + if succeed: + self.summary_info['success'] += 1 + else: + self.summary_info['failed'].append(test) + if succeed: + self.ok_print("[PASS] {0}",k) + else: + self.fail_print("[FAIL] {0}",k) + for action in test['actions']: + self.print_action(succeed, action) + + def print_action(self, test_succeed, action): + ''' + Print the detailed info of failed or always print tests. + ''' + #self.info_print(">>> {0}",action.keys()) + if not test_succeed or action['info']['always_show_run_output']: + output = action['output'].strip() + if output != "": + p = self.fail_print if action['result'] == 'fail' else self.p_print + self.info_print("") + self.info_print("({0}) {1}",action['info']['name'],action['info']['path']) + p("") + p("{0}",action['command'].strip()) + p("") + for line in output.splitlines(): + p("{0}",line.encode('utf-8')) + + def print_summary(self): + self.header_print("") + self.header_print("Testing summary..") + self.header_print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") + self.p_print("Total: {0}",self.summary_info['total']) + self.p_print("Success: {0}",self.summary_info['success']) + if self.failed: + self.fail_print("Failed: {0}",len(self.summary_info['failed'])) + for test in self.summary_info['failed']: + self.fail_print(" {0}/{1}",test['library'],test['test-name']) + + def p_print(self, format, *args, **kargs): + print format.format(*args,**kargs) + + def info_print(self, format, *args, **kargs): + print self.INFO+format.format(*args,**kargs)+self.ENDC + + def header_print(self, format, *args, **kargs): + print self.HEADER+format.format(*args,**kargs)+self.ENDC + + def ok_print(self, format, *args, **kargs): + print self.OK+format.format(*args,**kargs)+self.ENDC + + def warn_print(self, format, *args, **kargs): + print self.WARNING+format.format(*args,**kargs)+self.ENDC + + def fail_print(self, format, *args, **kargs): + print self.FAIL+format.format(*args,**kargs)+self.ENDC + +class Main(object): + + def __init__(self,args=None): + op = optparse.OptionParser( + usage="%prog [options] input+") + op.add_option( '--output', + help="type of output to generate" ) + ( opt, inputs ) = op.parse_args(args) + bop = BuildOutputProcessor(inputs) + output = None + if opt.output == 'console': + output = BuildConsoleSummaryReport(bop, opt) + if output: + output.generate() + self.failed = output.failed + +if __name__ == '__main__': + m = Main() + if m.failed: + exit(-1) diff --git a/src/boost/libs/predef/tools/ci/common.py b/src/boost/libs/predef/tools/ci/common.py new file mode 100644 index 00000000..7536276f --- /dev/null +++ b/src/boost/libs/predef/tools/ci/common.py @@ -0,0 +1,887 @@ +#!/usr/bin/env python + +# Copyright Rene Rivera 2016 +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import sys +import inspect +import optparse +import os.path +import string +import time +import subprocess +import codecs +import shutil +import threading + +toolset_info = { + 'clang-3.4' : { + 'ppa' : ["ppa:h-rayflood/llvm"], + 'package' : 'clang-3.4', + 'command' : 'clang++-3.4', + 'toolset' : 'clang', + 'version' : '' + }, + 'clang-3.5' : { + 'ppa' : ["ppa:h-rayflood/llvm"], + 'package' : 'clang-3.5', + 'command' : 'clang++-3.5', + 'toolset' : 'clang', + 'version' : '' + }, + 'clang-3.6' : { + 'ppa' : ["ppa:h-rayflood/llvm"], + 'package' : 'clang-3.6', + 'command' : 'clang++-3.6', + 'toolset' : 'clang', + 'version' : '' + }, + 'clang-3.7' : { + 'deb' : ["http://apt.llvm.org/trusty/","llvm-toolchain-trusty-3.7","main"], + 'apt-key' : ['http://apt.llvm.org/llvm-snapshot.gpg.key'], + 'package' : 'clang-3.7', + 'command' : 'clang++-3.7', + 'toolset' : 'clang', + 'version' : '' + }, + 'clang-3.8' : { + 'deb' : ["http://apt.llvm.org/trusty/","llvm-toolchain-trusty-3.8","main"], + 'apt-key' : ['http://apt.llvm.org/llvm-snapshot.gpg.key'], + 'package' : 'clang-3.8', + 'command' : 'clang++-3.8', + 'toolset' : 'clang', + 'version' : '' + }, + 'clang-3.9' : { + 'deb' : ["http://apt.llvm.org/trusty/","llvm-toolchain-trusty-3.9","main"], + 'apt-key' : ['http://apt.llvm.org/llvm-snapshot.gpg.key'], + 'package' : 'clang-3.9', + 'command' : 'clang++-3.9', + 'toolset' : 'clang', + 'version' : '' + }, + 'clang-4.0' : { + 'deb' : ["http://apt.llvm.org/trusty/","llvm-toolchain-trusty-4.0","main"], + 'apt-key' : ['http://apt.llvm.org/llvm-snapshot.gpg.key'], + 'package' : 'clang-4.0', + 'command' : 'clang++-4.0', + 'toolset' : 'clang', + 'version' : '' + }, + 'clang-5.0' : { + 'deb' : ["http://apt.llvm.org/trusty/","llvm-toolchain-trusty-5.0","main"], + 'apt-key' : ['http://apt.llvm.org/llvm-snapshot.gpg.key'], + 'package' : 'clang-5.0', + 'command' : 'clang++-5.0', + 'toolset' : 'clang', + 'version' : '' + }, + 'clang-6.0' : { + 'deb' : ["http://apt.llvm.org/trusty/","llvm-toolchain-trusty-6.0","main"], + 'apt-key' : ['http://apt.llvm.org/llvm-snapshot.gpg.key'], + 'package' : 'clang-6.0', + 'command' : 'clang++-6.0', + 'toolset' : 'clang', + 'version' : '' + }, + 'gcc-4.7' : { + 'ppa' : ["ppa:ubuntu-toolchain-r/test"], + 'package' : 'g++-4.7', + 'command' : 'g++-4.7', + 'toolset' : 'gcc', + 'version' : '' + }, + 'gcc-4.8' : { + 'bin' : 'gcc-4.8', + 'ppa' : ["ppa:ubuntu-toolchain-r/test"], + 'package' : 'g++-4.8', + 'command' : 'g++-4.8', + 'toolset' : 'gcc', + 'version' : '' + }, + 'gcc-4.9' : { + 'ppa' : ["ppa:ubuntu-toolchain-r/test"], + 'package' : 'g++-4.9', + 'command' : 'g++-4.9', + 'toolset' : 'gcc', + 'version' : '' + }, + 'gcc-5.1' : { + 'ppa' : ["ppa:ubuntu-toolchain-r/test"], + 'package' : 'g++-5', + 'command' : 'g++-5', + 'toolset' : 'gcc', + 'version' : '' + }, + 'gcc-5' : { + 'ppa' : ["ppa:ubuntu-toolchain-r/test"], + 'package' : 'g++-5', + 'command' : 'g++-5', + 'toolset' : 'gcc', + 'version' : '' + }, + 'gcc-6' : { + 'ppa' : ["ppa:ubuntu-toolchain-r/test"], + 'package' : 'g++-6', + 'command' : 'g++-6', + 'toolset' : 'gcc', + 'version' : '' + }, + 'gcc-7' : { + 'ppa' : ["ppa:ubuntu-toolchain-r/test"], + 'package' : 'g++-7', + 'command' : 'g++-7', + 'toolset' : 'gcc', + 'version' : '' + }, + 'gcc-8' : { + 'ppa' : ["ppa:ubuntu-toolchain-r/test"], + 'package' : 'g++-8', + 'command' : 'g++-8', + 'toolset' : 'gcc', + 'version' : '' + }, + 'mingw-5' : { + 'toolset' : 'gcc', + 'command' : 'C:\\\\MinGW\\\\bin\\\\g++.exe', + 'version' : '' + }, + 'mingw64-6' : { + 'toolset' : 'gcc', + 'command' : 'C:\\\\mingw-w64\\\\x86_64-6.3.0-posix-seh-rt_v5-rev1\\\\mingw64\\\\bin\\\\g++.exe', + 'version' : '' + }, + 'vs-2008' : { + 'toolset' : 'msvc', + 'command' : '', + 'version' : '9.0' + }, + 'vs-2010' : { + 'toolset' : 'msvc', + 'command' : '', + 'version' : '10.0' + }, + 'vs-2012' : { + 'toolset' : 'msvc', + 'command' : '', + 'version' : '11.0' + }, + 'vs-2013' : { + 'toolset' : 'msvc', + 'command' : '', + 'version' : '12.0' + }, + 'vs-2015' : { + 'toolset' : 'msvc', + 'command' : '', + 'version' : '14.0' + }, + 'vs-2017' : { + 'toolset' : 'msvc', + 'command' : '', + 'version' : '14.1' + }, + 'xcode-6.1' : { + 'command' : 'clang++', + 'toolset' : 'clang', + 'version' : '' + }, + 'xcode-6.2' : { + 'command' : 'clang++', + 'toolset' : 'clang', + 'version' : '' + }, + 'xcode-6.3' : { + 'command' : 'clang++', + 'toolset' : 'clang', + 'version' : '' + }, + 'xcode-6.4' : { + 'command' : 'clang++', + 'toolset' : 'clang', + 'version' : '' + }, + 'xcode-7.0' : { + 'command' : 'clang++', + 'toolset' : 'clang', + 'version' : '' + }, + 'xcode-7.1' : { + 'command' : 'clang++', + 'toolset' : 'clang', + 'version' : '' + }, + 'xcode-7.2' : { + 'command' : 'clang++', + 'toolset' : 'clang', + 'version' : '' + }, + 'xcode-7.3' : { + 'command' : 'clang++', + 'toolset' : 'clang', + 'version' : '' + }, + 'xcode-8.0' : { + 'command' : 'clang++', + 'toolset' : 'clang', + 'version' : '' + }, + 'xcode-8.1' : { + 'command' : 'clang++', + 'toolset' : 'clang', + 'version' : '' + }, + 'xcode-8.2' : { + 'command' : 'clang++', + 'toolset' : 'clang', + 'version' : '' + }, + 'xcode-8.3' : { + 'command' : 'clang++', + 'toolset' : 'clang', + 'version' : '' + }, + 'xcode-9.0' : { + 'command' : 'clang++', + 'toolset' : 'clang', + 'version' : '' + }, + 'xcode-9.1' : { + 'command' : 'clang++', + 'toolset' : 'clang', + 'version' : '' + }, + 'xcode-9.2' : { + 'command' : 'clang++', + 'toolset' : 'clang', + 'version' : '' + }, + 'xcode-9.3' : { + 'command' : 'clang++', + 'toolset' : 'clang', + 'version' : '' + }, + 'xcode-9.4' : { + 'command' : 'clang++', + 'toolset' : 'clang', + 'version' : '' + }, + 'xcode-10.0' : { + 'command' : 'clang++', + 'toolset' : 'clang', + 'version' : '' + }, + } + +class SystemCallError(Exception): + def __init__(self, command, result): + self.command = command + self.result = result + def __str__(self, *args, **kwargs): + return "'%s' ==> %s"%("' '".join(self.command), self.result) + +class utils: + + call_stats = [] + + @staticmethod + def call(*command, **kargs): + utils.log( "%s> '%s'"%(os.getcwd(), "' '".join(command)) ) + t = time.time() + result = subprocess.call(command, **kargs) + t = time.time()-t + if result != 0: + print "Failed: '%s' ERROR = %s"%("' '".join(command), result) + utils.call_stats.append((t,os.getcwd(),command,result)) + utils.log( "%s> '%s' execution time %s seconds"%(os.getcwd(), "' '".join(command), t) ) + return result + + @staticmethod + def print_call_stats(): + utils.log("================================================================================") + for j in sorted(utils.call_stats, reverse=True): + utils.log("{:>12.4f}\t{}> {} ==> {}".format(*j)) + utils.log("================================================================================") + + @staticmethod + def check_call(*command, **kargs): + cwd = os.getcwd() + result = utils.call(*command, **kargs) + if result != 0: + raise(SystemCallError([cwd].extend(command), result)) + + @staticmethod + def makedirs( path ): + if not os.path.exists( path ): + os.makedirs( path ) + + @staticmethod + def log_level(): + frames = inspect.stack() + level = 0 + for i in frames[ 3: ]: + if i[0].f_locals.has_key( '__log__' ): + level = level + i[0].f_locals[ '__log__' ] + return level + + @staticmethod + def log( message ): + sys.stdout.flush() + sys.stderr.flush() + sys.stderr.write( '# ' + ' ' * utils.log_level() + message + '\n' ) + sys.stderr.flush() + + @staticmethod + def rmtree(path): + if os.path.exists( path ): + #~ shutil.rmtree( unicode( path ) ) + if sys.platform == 'win32': + os.system( 'del /f /s /q "%s" >nul 2>&1' % path ) + shutil.rmtree( unicode( path ) ) + else: + os.system( 'rm -f -r "%s"' % path ) + + @staticmethod + def retry( f, max_attempts=5, sleep_secs=10 ): + for attempts in range( max_attempts, -1, -1 ): + try: + return f() + except Exception, msg: + utils.log( '%s failed with message "%s"' % ( f.__name__, msg ) ) + if attempts == 0: + utils.log( 'Giving up.' ) + raise + + utils.log( 'Retrying (%d more attempts).' % attempts ) + time.sleep( sleep_secs ) + + @staticmethod + def web_get( source_url, destination_file, proxy = None ): + import urllib + + proxies = None + if proxy is not None: + proxies = { + 'https' : proxy, + 'http' : proxy + } + + src = urllib.urlopen( source_url, proxies = proxies ) + + f = open( destination_file, 'wb' ) + while True: + data = src.read( 16*1024 ) + if len( data ) == 0: break + f.write( data ) + + f.close() + src.close() + + @staticmethod + def unpack_archive( archive_path ): + utils.log( 'Unpacking archive ("%s")...' % archive_path ) + + archive_name = os.path.basename( archive_path ) + extension = archive_name[ archive_name.find( '.' ) : ] + + if extension in ( ".tar.gz", ".tar.bz2" ): + import tarfile + import stat + + mode = os.path.splitext( extension )[1][1:] + tar = tarfile.open( archive_path, 'r:%s' % mode ) + for tarinfo in tar: + tar.extract( tarinfo ) + if sys.platform == 'win32' and not tarinfo.isdir(): + # workaround what appears to be a Win32-specific bug in 'tarfile' + # (modification times for extracted files are not set properly) + f = os.path.join( os.curdir, tarinfo.name ) + os.chmod( f, stat.S_IWRITE ) + os.utime( f, ( tarinfo.mtime, tarinfo.mtime ) ) + tar.close() + elif extension in ( ".zip" ): + import zipfile + + z = zipfile.ZipFile( archive_path, 'r', zipfile.ZIP_DEFLATED ) + for f in z.infolist(): + destination_file_path = os.path.join( os.curdir, f.filename ) + if destination_file_path[-1] == "/": # directory + if not os.path.exists( destination_file_path ): + os.makedirs( destination_file_path ) + else: # file + result = open( destination_file_path, 'wb' ) + result.write( z.read( f.filename ) ) + result.close() + z.close() + else: + raise 'Do not know how to unpack archives with extension \"%s\"' % extension + + @staticmethod + def make_file(filename, *text): + text = string.join( text, '\n' ) + with codecs.open( filename, 'w', 'utf-8' ) as f: + f.write( text ) + + @staticmethod + def append_file(filename, *text): + with codecs.open( filename, 'a', 'utf-8' ) as f: + f.write( string.join( text, '\n' ) ) + + @staticmethod + def mem_info(): + if sys.platform == "darwin": + utils.call("top","-l","1","-s","0","-n","0") + elif sys.platform.startswith("linux"): + utils.call("free","-m","-l") + + @staticmethod + def query_boost_version(boost_root): + ''' + Read in the Boost version from a given boost_root. + ''' + boost_version = None + if os.path.exists(os.path.join(boost_root,'Jamroot')): + with codecs.open(os.path.join(boost_root,'Jamroot'), 'r', 'utf-8') as f: + for line in f.readlines(): + parts = line.split() + if len(parts) >= 5 and parts[1] == 'BOOST_VERSION': + boost_version = parts[3] + break + if not boost_version: + boost_version = 'default' + return boost_version + + @staticmethod + def git_clone(owner, repo, branch, commit = None, repo_dir = None, submodules = False, url_format = "https://github.com/%(owner)s/%(repo)s.git"): + ''' + This clone mimicks the way Travis-CI clones a project's repo. So far + Travis-CI is the most limiting in the sense of only fetching partial + history of the repo. + ''' + if not repo_dir: + repo_dir = os.path.join(os.getcwd(), owner+','+repo) + utils.makedirs(os.path.dirname(repo_dir)) + if not os.path.exists(os.path.join(repo_dir,'.git')): + utils.check_call("git","clone", + "--depth=1", + "--branch=%s"%(branch), + url_format%{'owner':owner,'repo':repo}, + repo_dir) + os.chdir(repo_dir) + else: + os.chdir(repo_dir) + utils.check_call("git","pull", + # "--depth=1", # Can't do depth as we get merge errors. + "--quiet","--no-recurse-submodules") + if commit: + utils.check_call("git","checkout","-qf",commit) + if os.path.exists(os.path.join('.git','modules')): + if sys.platform == 'win32': + utils.check_call('dir',os.path.join('.git','modules')) + else: + utils.check_call('ls','-la',os.path.join('.git','modules')) + if submodules: + utils.check_call("git","submodule","--quiet","update", + "--quiet","--init","--recursive", + ) + utils.check_call("git","submodule","--quiet","foreach","git","fetch") + return repo_dir + +class parallel_call(threading.Thread): + ''' + Runs a synchronous command in a thread waiting for it to complete. + ''' + + def __init__(self, *command, **kargs): + super(parallel_call,self).__init__() + self.command = command + self.command_kargs = kargs + self.start() + + def run(self): + self.result = utils.call(*self.command, **self.command_kargs) + + def join(self): + super(parallel_call,self).join() + if self.result != 0: + raise(SystemCallError(self.command, self.result)) + +def set_arg(args, k, v = None): + if not args.get(k): + args[k] = v + return args[k] + +class script_common(object): + ''' + Main script to run continuous integration. + ''' + + def __init__(self, ci_klass, **kargs): + self.ci = ci_klass(self) + + opt = optparse.OptionParser( + usage="%prog [options] [commands]") + + #~ Debug Options: + opt.add_option( '--debug-level', + help="debugging level; controls the amount of debugging output printed", + type='int' ) + opt.add_option( '-j', + help="maximum number of parallel jobs to use for building with b2", + type='int', dest='jobs') + opt.add_option('--branch') + opt.add_option('--commit') + kargs = self.init(opt,kargs) + kargs = self.ci.init(opt, kargs) + set_arg(kargs,'debug_level',0) + set_arg(kargs,'jobs',2) + set_arg(kargs,'branch',None) + set_arg(kargs,'commit',None) + set_arg(kargs,'repo',None) + set_arg(kargs,'repo_dir',None) + set_arg(kargs,'actions',None) + set_arg(kargs,'pull_request', None) + + #~ Defaults + for (k,v) in kargs.iteritems(): + setattr(self,k,v) + ( _opt_, self.actions ) = opt.parse_args(None,self) + if not self.actions or self.actions == []: + self.actions = kargs.get('actions',None) + if not self.actions or self.actions == []: + self.actions = [ 'info' ] + if not self.repo_dir: + self.repo_dir = os.getcwd() + self.build_dir = os.path.join(os.path.dirname(self.repo_dir), "build") + + # API keys. + self.bintray_key = os.getenv('BINTRAY_KEY') + + try: + self.start() + self.command_info() + self.main() + utils.print_call_stats() + except: + utils.print_call_stats() + raise + + def init(self, opt, kargs): + return kargs + + def start(self): + pass + + def main(self): + for action in self.actions: + action_m = "command_"+action.replace('-','_') + ci_command = getattr(self.ci, action_m, None) + ci_script = getattr(self, action_m, None) + if ci_command or ci_script: + utils.log( "### %s.."%(action) ) + if os.path.exists(self.repo_dir): + os.chdir(self.repo_dir) + if ci_command: + ci_command() + elif ci_script: + ci_script() + + def b2( self, *args, **kargs ): + cmd = ['b2','--debug-configuration', '-j%s'%(self.jobs)] + cmd.extend(args) + + if 'toolset' in kargs: + cmd.append('toolset=' + kargs['toolset']) + + if 'parallel' in kargs: + return parallel_call(*cmd) + else: + return utils.check_call(*cmd) + + # Common test commands in the order they should be executed.. + + def command_info(self): + pass + + def command_install(self): + utils.makedirs(self.build_dir) + os.chdir(self.build_dir) + + def command_install_toolset(self, toolset): + if self.ci and hasattr(self.ci,'install_toolset'): + self.ci.install_toolset(toolset) + + def command_before_build(self): + pass + + def command_build(self): + pass + + def command_before_cache(self): + pass + + def command_after_success(self): + pass + +class ci_cli(object): + ''' + This version of the script provides a way to do manual building. It sets up + additional environment and adds fetching of the git repos that would + normally be done by the CI system. + + The common way to use this variant is to invoke something like: + + mkdir ci + cd ci + python path-to/library_test.py --branch=develop [--repo=mylib] ... + + Status: In working order. + ''' + + def __init__(self,script): + if sys.platform == 'darwin': + # Requirements for running on OSX: + # https://www.stack.nl/~dimitri/doxygen/download.html#srcbin + # https://tug.org/mactex/morepackages.html + doxygen_path = "/Applications/Doxygen.app/Contents/Resources" + if os.path.isdir(doxygen_path): + os.environ["PATH"] = doxygen_path+':'+os.environ['PATH'] + self.script = script + self.repo_dir = os.getcwd() + self.exit_result = 0 + + def init(self, opt, kargs): + kargs['actions'] = [ + # 'clone', + 'install', + 'before_build', + 'build', + 'before_cache', + 'finish' + ] + return kargs + + def finish(self, result): + self.exit_result = result + + def command_finish(self): + exit(self.exit_result) + +class ci_travis(object): + ''' + This variant build releases in the context of the Travis-CI service. + ''' + + def __init__(self,script): + self.script = script + + def init(self, opt, kargs): + set_arg(kargs,'repo_dir', os.getenv("TRAVIS_BUILD_DIR")) + set_arg(kargs,'branch', os.getenv("TRAVIS_BRANCH")) + set_arg(kargs,'commit', os.getenv("TRAVIS_COMMIT")) + set_arg(kargs,'repo', os.getenv("TRAVIS_REPO_SLUG").split("/")[1]) + set_arg(kargs,'pull_request', + os.getenv('TRAVIS_PULL_REQUEST') \ + if os.getenv('TRAVIS_PULL_REQUEST') != 'false' else None) + return kargs + + def finish(self, result): + exit(result) + + def install_toolset(self, toolset): + ''' + Installs specific toolset on CI system. + ''' + info = toolset_info[toolset] + if sys.platform.startswith('linux'): + os.chdir(self.script.build_dir) + if 'ppa' in info: + for ppa in info['ppa']: + utils.check_call( + 'sudo','add-apt-repository','--yes',ppa) + if 'deb' in info: + utils.make_file('sources.list', + "deb %s"%(' '.join(info['deb'])), + "deb-src %s"%(' '.join(info['deb']))) + utils.check_call('sudo','bash','-c','cat sources.list >> /etc/apt/sources.list') + if 'apt-key' in info: + for key in info['apt-key']: + utils.check_call('wget',key,'-O','apt.key') + utils.check_call('sudo','apt-key','add','apt.key') + utils.check_call( + 'sudo','apt-get','update','-qq') + utils.check_call( + 'sudo','apt-get','install','-qq',info['package']) + if 'debugpackage' in info and info['debugpackage']: + utils.check_call( + 'sudo','apt-get','install','-qq',info['debugpackage']) + + # Travis-CI commands in the order they are executed. We need + # these to forward to our common commands, if they are different. + + def command_before_install(self): + pass + + def command_install(self): + self.script.command_install() + + def command_before_script(self): + self.script.command_before_build() + + def command_script(self): + self.script.command_build() + + def command_before_cache(self): + self.script.command_before_cache() + + def command_after_success(self): + self.script.command_after_success() + + def command_after_failure(self): + pass + + def command_before_deploy(self): + pass + + def command_after_deploy(self): + pass + + def command_after_script(self): + pass + +class ci_circleci(object): + ''' + This variant build releases in the context of the CircleCI service. + ''' + + def __init__(self,script): + self.script = script + + def init(self, opt, kargs): + set_arg(kargs,'repo_dir', os.path.join(os.getenv("HOME"),os.getenv("CIRCLE_PROJECT_REPONAME"))) + set_arg(kargs,'branch', os.getenv("CIRCLE_BRANCH")) + set_arg(kargs,'commit', os.getenv("CIRCLE_SHA1")) + set_arg(kargs,'repo', os.getenv("CIRCLE_PROJECT_REPONAME").split("/")[1]) + set_arg(kargs,'pull_request', os.getenv('CIRCLE_PR_NUMBER')) + return kargs + + def finish(self, result): + exit(result) + + def command_machine_post(self): + # Apt update for the pckages installs we'll do later. + utils.check_call('sudo','apt-get','-qq','update') + # Need PyYAML to read Travis yaml in a later step. + utils.check_call("pip","install","--user","PyYAML") + + def command_checkout_post(self): + os.chdir(self.script.repo_dir) + utils.check_call("git","submodule","update","--quiet","--init","--recursive") + + def command_dependencies_pre(self): + # Read in .travis.yml for list of packages to install + # as CircleCI doesn't have a convenient apt install method. + import yaml + utils.check_call('sudo','-E','apt-get','-yqq','update') + utils.check_call('sudo','apt-get','-yqq','purge','texlive*') + with open(os.path.join(self.script.repo_dir,'.travis.yml')) as yml: + travis_yml = yaml.load(yml) + utils.check_call('sudo','apt-get','-yqq', + '--no-install-suggests','--no-install-recommends','--force-yes','install', + *travis_yml['addons']['apt']['packages']) + + def command_dependencies_override(self): + self.script.command_install() + + def command_dependencies_post(self): + pass + + def command_database_pre(self): + pass + + def command_database_override(self): + pass + + def command_database_post(self): + pass + + def command_test_pre(self): + self.script.command_install() + self.script.command_before_build() + + def command_test_override(self): + # CircleCI runs all the test subsets. So in order to avoid + # running the after_success we do it here as the build step + # will halt accordingly. + self.script.command_build() + self.script.command_before_cache() + self.script.command_after_success() + + def command_test_post(self): + pass + +class ci_appveyor(object): + + def __init__(self,script): + self.script = script + + def init(self, opt, kargs): + set_arg(kargs,'repo_dir',os.getenv("APPVEYOR_BUILD_FOLDER")) + set_arg(kargs,'branch',os.getenv("APPVEYOR_REPO_BRANCH")) + set_arg(kargs,'commit',os.getenv("APPVEYOR_REPO_COMMIT")) + set_arg(kargs,'repo',os.getenv("APPVEYOR_REPO_NAME").split("/")[1]) + set_arg(kargs,'address_model',os.getenv("PLATFORM",None)) + set_arg(kargs,'variant',os.getenv("CONFIGURATION","debug")) + set_arg(kargs,'pull_request', os.getenv('APPVEYOR_PULL_REQUEST_NUMBER')) + return kargs + + def finish(self, result): + exit(result) + + # Appveyor commands in the order they are executed. We need + # these to forward to our common commands, if they are different. + + def command_install(self): + self.script.command_install() + + def command_before_build(self): + os.chdir(self.script.repo_dir) + utils.check_call("git","submodule","update","--quiet","--init","--recursive") + self.script.command_before_build() + + def command_build_script(self): + self.script.command_build() + + def command_after_build(self): + self.script.command_before_cache() + + def command_before_test(self): + pass + + def command_test_script(self): + pass + + def command_after_test(self): + pass + + def command_on_success(self): + self.script.command_after_success() + + def command_on_failure(self): + pass + + def command_on_finish(self): + pass + +def main(script_klass): + if os.getenv('TRAVIS', False): + script_klass(ci_travis) + elif os.getenv('CIRCLECI', False): + script_klass(ci_circleci) + elif os.getenv('APPVEYOR', False): + script_klass(ci_appveyor) + else: + script_klass(ci_cli) diff --git a/src/boost/libs/predef/tools/ci/library_test.py b/src/boost/libs/predef/tools/ci/library_test.py new file mode 100644 index 00000000..3cde056d --- /dev/null +++ b/src/boost/libs/predef/tools/ci/library_test.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python + +# Copyright Rene Rivera 2016 +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import os.path +import shutil +import sys +from common import toolset_info, main, utils, script_common, ci_cli, set_arg + +__dirname__ = os.path.dirname(os.path.realpath(__file__)) + +class script(script_common): + ''' + Main script to test a Boost C++ Library. + ''' + + def __init__(self, ci_klass, **kargs): + script_common.__init__(self, ci_klass, **kargs) + + def init(self, opt, kargs): + opt.add_option( '--toolset', + help="single toolset to test with" ) + opt.add_option( '--target', + help="test target to build for testing, defaults to TARGET or 'minimal'") + opt.add_option( '--address-model', + help="address model to test, ie 64 or 32" ) + opt.add_option( '--variant', + help="variant to test, ie debug, release" ) + set_arg(kargs, 'toolset', os.getenv("TOOLSET")) + set_arg(kargs, 'target', os.getenv('TARGET', 'minimal')) + set_arg(kargs, 'address_model', os.getenv("ADDRESS_MODEL",None)) + set_arg(kargs, 'variant', os.getenv("VARIANT","debug")) + set_arg(kargs, 'cxxflags', os.getenv("CXXFLAGS",None)) + return kargs + + def start(self): + script_common.start(self) + # Some setup we need to redo for each invocation. + self.b2_dir = os.path.join(self.build_dir, 'b2') + + def command_install(self): + script_common.command_install(self) + # Fetch & install toolset.. + utils.log( "Install toolset: %s"%(self.toolset) ) + if self.toolset: + self.command_install_toolset(self.toolset) + + def command_before_build(self): + script_common.command_before_build(self) + + # Fetch dependencies. + utils.git_clone('boostorg','build','develop',repo_dir=self.b2_dir) + + # Create config file for b2 toolset. + if not isinstance(self.ci, ci_cli): + cxxflags = None + if self.cxxflags: + cxxflags = self.cxxflags.split() + cxxflags = " <cxxflags>".join(cxxflags) + utils.make_file(os.path.join(self.repo_dir, 'project-config.jam'), + """ +using %(toolset)s : %(version)s : %(command)s : %(cxxflags)s ; +using python : %(pyversion)s : "%(python)s" ; +"""%{ + 'toolset':toolset_info[self.toolset]['toolset'], + 'version':toolset_info[self.toolset]['version'], + 'command':toolset_info[self.toolset]['command'], + 'cxxflags':"<cxxflags>"+cxxflags if cxxflags else "", + 'pyversion':"%s.%s"%(sys.version_info[0],sys.version_info[1]), + 'python':sys.executable.replace("\\","\\\\") + }) + + # "Convert" boostorg-predef into standalone b2 project. + if os.path.exists(os.path.join(self.repo_dir,'build.jam')) and not os.path.exists(os.path.join(self.repo_dir,'project-root.jam')): + os.rename(os.path.join(self.repo_dir,'build.jam'), os.path.join(self.repo_dir,'project-root.jam')) + + def command_build(self): + script_common.command_build(self) + + # Set up tools. + if not isinstance(self.ci, ci_cli) and toolset_info[self.toolset]['command']: + os.environ['PATH'] = os.pathsep.join([ + os.path.dirname(toolset_info[self.toolset]['command']), + os.environ['PATH']]) + + # Bootstrap Boost Build engine. + os.chdir(self.b2_dir) + if sys.platform == 'win32': + utils.check_call(".\\bootstrap.bat") + else: + utils.check_call("./bootstrap.sh") + os.environ['PATH'] = os.pathsep.join([self.b2_dir, os.environ['PATH']]) + os.environ['BOOST_BUILD_PATH'] = self.b2_dir + + # Run the limited tests. + print("--- Testing %s ---"%(self.repo_dir)) + os.chdir(os.path.join(self.repo_dir,'test')) + toolset_to_test = "" + if self.toolset: + if not isinstance(self.ci, ci_cli): + toolset_to_test = toolset_info[self.toolset]['toolset'] + else: + toolset_to_test = self.toolset + self.b2( + '-d1', + '-p0', + 'preserve-test-targets=off', + '--dump-tests', + '--verbose-test', + '--build-dir=%s'%(self.build_dir), + '--out-xml=%s'%(os.path.join(self.build_dir,'regression.xml')), + '' if not toolset_to_test else 'toolset=%s'%(toolset_to_test), + '' if not self.address_model else 'address-model=%s'%(self.address_model), + 'variant=%s'%(self.variant), + self.target + ) + + # Generate a readable test report. + import build_log + log_main = build_log.Main([ + '--output=console', + os.path.join(self.build_dir,'regression.xml')]) + # And exit with an error if the report contains failures. + # This lets the CI notice the error and report a failed build. + # And hence trigger the failure machinery, like sending emails. + if log_main.failed: + self.ci.finish(-1) + + def command_before_cache(self): + script_common.command_before_cache(self) + os.chdir(self.b2_dir) + utils.check_call("git","clean","-dfqx") + utils.check_call("git","status","-bs") + # utils.check_call("git","submodule","--quiet","foreach","git","clean","-dfqx") + # utils.check_call("git","submodule","foreach","git","status","-bs") + +main(script) |