forked from lix-project/lix
Merge remote-tracking branch 'origin/master' into flakes
This commit is contained in:
commit
cc218b15ba
7
Makefile
7
Makefile
|
@ -19,11 +19,4 @@ GLOBAL_CXXFLAGS += -g -Wall -include config.h
|
||||||
|
|
||||||
-include Makefile.config
|
-include Makefile.config
|
||||||
|
|
||||||
OPTIMIZE = 1
|
|
||||||
|
|
||||||
ifeq ($(OPTIMIZE), 1)
|
|
||||||
GLOBAL_CFLAGS += -O3
|
|
||||||
GLOBAL_CXXFLAGS += -O3
|
|
||||||
endif
|
|
||||||
|
|
||||||
include mk/lib.mk
|
include mk/lib.mk
|
||||||
|
|
|
@ -5,10 +5,11 @@ CC = @CC@
|
||||||
CFLAGS = @CFLAGS@
|
CFLAGS = @CFLAGS@
|
||||||
CXX = @CXX@
|
CXX = @CXX@
|
||||||
CXXFLAGS = @CXXFLAGS@
|
CXXFLAGS = @CXXFLAGS@
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
ENABLE_S3 = @ENABLE_S3@
|
ENABLE_S3 = @ENABLE_S3@
|
||||||
HAVE_SODIUM = @HAVE_SODIUM@
|
HAVE_SODIUM = @HAVE_SODIUM@
|
||||||
HAVE_READLINE = @HAVE_READLINE@
|
|
||||||
HAVE_SECCOMP = @HAVE_SECCOMP@
|
HAVE_SECCOMP = @HAVE_SECCOMP@
|
||||||
|
BOOST_LDFLAGS = @BOOST_LDFLAGS@
|
||||||
LIBCURL_LIBS = @LIBCURL_LIBS@
|
LIBCURL_LIBS = @LIBCURL_LIBS@
|
||||||
OPENSSL_LIBS = @OPENSSL_LIBS@
|
OPENSSL_LIBS = @OPENSSL_LIBS@
|
||||||
PACKAGE_NAME = @PACKAGE_NAME@
|
PACKAGE_NAME = @PACKAGE_NAME@
|
||||||
|
|
52
configure.ac
52
configure.ac
|
@ -1,4 +1,5 @@
|
||||||
AC_INIT(nix, m4_esyscmd([bash -c "echo -n $(cat ./.version)$VERSION_SUFFIX"]))
|
AC_INIT(nix, m4_esyscmd([bash -c "echo -n $(cat ./.version)$VERSION_SUFFIX"]))
|
||||||
|
AC_CONFIG_MACRO_DIRS([m4])
|
||||||
AC_CONFIG_SRCDIR(README.md)
|
AC_CONFIG_SRCDIR(README.md)
|
||||||
AC_CONFIG_AUX_DIR(config)
|
AC_CONFIG_AUX_DIR(config)
|
||||||
|
|
||||||
|
@ -42,13 +43,28 @@ esac
|
||||||
|
|
||||||
AC_MSG_RESULT($system)
|
AC_MSG_RESULT($system)
|
||||||
AC_SUBST(system)
|
AC_SUBST(system)
|
||||||
AC_DEFINE_UNQUOTED(SYSTEM, ["$system"], [platform identifier (`cpu-os')])
|
AC_DEFINE_UNQUOTED(SYSTEM, ["$system"], [platform identifier ('cpu-os')])
|
||||||
|
|
||||||
|
|
||||||
# State should be stored in /nix/var, unless the user overrides it explicitly.
|
# State should be stored in /nix/var, unless the user overrides it explicitly.
|
||||||
test "$localstatedir" = '${prefix}/var' && localstatedir=/nix/var
|
test "$localstatedir" = '${prefix}/var' && localstatedir=/nix/var
|
||||||
|
|
||||||
|
|
||||||
|
# Set default flags for nix (as per AC_PROG_CC/CXX docs),
|
||||||
|
# while still allowing the user to override them from the command line.
|
||||||
|
: ${CFLAGS="-O3"}
|
||||||
|
: ${CXXFLAGS="-O3"}
|
||||||
|
AC_PROG_CC
|
||||||
|
AC_PROG_CXX
|
||||||
|
AC_PROG_CPP
|
||||||
|
AX_CXX_COMPILE_STDCXX_17([noext], [mandatory])
|
||||||
|
|
||||||
|
AC_CHECK_TOOL([AR], [ar])
|
||||||
|
|
||||||
|
# Use 64-bit file system calls so that we can support files > 2 GiB.
|
||||||
|
AC_SYS_LARGEFILE
|
||||||
|
|
||||||
|
|
||||||
# Solaris-specific stuff.
|
# Solaris-specific stuff.
|
||||||
AC_STRUCT_DIRENT_D_TYPE
|
AC_STRUCT_DIRENT_D_TYPE
|
||||||
if test "$sys_name" = sunos; then
|
if test "$sys_name" = sunos; then
|
||||||
|
@ -57,19 +73,6 @@ if test "$sys_name" = sunos; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
CFLAGS=
|
|
||||||
CXXFLAGS=
|
|
||||||
AC_PROG_CC
|
|
||||||
AC_PROG_CXX
|
|
||||||
AC_PROG_CPP
|
|
||||||
AX_CXX_COMPILE_STDCXX_17
|
|
||||||
|
|
||||||
AC_CHECK_TOOL([AR], [ar])
|
|
||||||
|
|
||||||
# Use 64-bit file system calls so that we can support files > 2 GiB.
|
|
||||||
AC_SYS_LARGEFILE
|
|
||||||
|
|
||||||
|
|
||||||
# Check for pubsetbuf.
|
# Check for pubsetbuf.
|
||||||
AC_MSG_CHECKING([for pubsetbuf])
|
AC_MSG_CHECKING([for pubsetbuf])
|
||||||
AC_LANG_PUSH(C++)
|
AC_LANG_PUSH(C++)
|
||||||
|
@ -146,6 +149,16 @@ AC_ARG_WITH(store-dir, AC_HELP_STRING([--with-store-dir=PATH],
|
||||||
AC_SUBST(storedir)
|
AC_SUBST(storedir)
|
||||||
|
|
||||||
|
|
||||||
|
# Look for boost, a required dependency.
|
||||||
|
# Note that AX_BOOST_BASE only exports *CPP* BOOST_CPPFLAGS, no CXX flags,
|
||||||
|
# and CPPFLAGS are not passed to the C++ compiler automatically.
|
||||||
|
# Thus we append the returned CPPFLAGS to the CXXFLAGS here.
|
||||||
|
AX_BOOST_BASE([1.66], [CXXFLAGS="$BOOST_CPPFLAGS $CXXFLAGS"], [AC_MSG_ERROR([Nix requires boost.])])
|
||||||
|
# For unknown reasons, setting this directly in the ACTION-IF-FOUND above
|
||||||
|
# ends up with LDFLAGS being empty, so we set it afterwards.
|
||||||
|
LDFLAGS="$BOOST_LDFLAGS $LDFLAGS"
|
||||||
|
|
||||||
|
|
||||||
# Look for OpenSSL, a required dependency.
|
# Look for OpenSSL, a required dependency.
|
||||||
PKG_CHECK_MODULES([OPENSSL], [libcrypto], [CXXFLAGS="$OPENSSL_CFLAGS $CXXFLAGS"])
|
PKG_CHECK_MODULES([OPENSSL], [libcrypto], [CXXFLAGS="$OPENSSL_CFLAGS $CXXFLAGS"])
|
||||||
|
|
||||||
|
@ -165,7 +178,16 @@ PKG_CHECK_MODULES([SQLITE3], [sqlite3 >= 3.6.19], [CXXFLAGS="$SQLITE3_CFLAGS $CX
|
||||||
PKG_CHECK_MODULES([LIBCURL], [libcurl], [CXXFLAGS="$LIBCURL_CFLAGS $CXXFLAGS"])
|
PKG_CHECK_MODULES([LIBCURL], [libcurl], [CXXFLAGS="$LIBCURL_CFLAGS $CXXFLAGS"])
|
||||||
|
|
||||||
# Look for editline, a required dependency.
|
# Look for editline, a required dependency.
|
||||||
PKG_CHECK_MODULES([EDITLINE], [libeditline], [CXXFLAGS="$EDITLINE_CFLAGS $CXXFLAGS"])
|
# The the libeditline.pc file was added only in libeditline >= 1.15.2,
|
||||||
|
# see https://github.com/troglobit/editline/commit/0a8f2ef4203c3a4a4726b9dd1336869cd0da8607,
|
||||||
|
# but e.g. Ubuntu 16.04 has an older version, so we fall back to searching for
|
||||||
|
# editline.h when the pkg-config approach fails.
|
||||||
|
PKG_CHECK_MODULES([EDITLINE], [libeditline], [CXXFLAGS="$EDITLINE_CFLAGS $CXXFLAGS"], [
|
||||||
|
AC_CHECK_HEADERS([editline.h], [true],
|
||||||
|
[AC_MSG_ERROR([Nix requires libeditline; it was found neither via pkg-config nor its normal header.])])
|
||||||
|
AC_SEARCH_LIBS([readline read_history], [editline], [],
|
||||||
|
[AC_MSG_ERROR([Nix requires libeditline; it was not found via pkg-config, but via its header, but required functions do not work. Maybe it is too old? >= 1.14 is required.])])
|
||||||
|
])
|
||||||
|
|
||||||
# Look for libsodium, an optional dependency.
|
# Look for libsodium, an optional dependency.
|
||||||
PKG_CHECK_MODULES([SODIUM], [libsodium],
|
PKG_CHECK_MODULES([SODIUM], [libsodium],
|
||||||
|
|
|
@ -864,6 +864,31 @@ requiredSystemFeatures = [ "kvm" ];
|
||||||
|
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry xml:id="conf-tarball-ttl"><term><literal>tarball-ttl</literal></term>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Default: <literal>3600</literal> seconds.</para>
|
||||||
|
|
||||||
|
<para>The number of seconds a downloaded tarball is considered
|
||||||
|
fresh. If the cached tarball is stale, Nix will check whether
|
||||||
|
it is still up to date using the ETag header. Nix will download
|
||||||
|
a new version if the ETag header is unsupported, or the
|
||||||
|
cached ETag doesn't match.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>Setting the TTL to <literal>0</literal> forces Nix to always
|
||||||
|
check if the tarball is up to date.</para>
|
||||||
|
|
||||||
|
<para>Nix caches tarballs in
|
||||||
|
<filename>$XDG_CACHE_HOME/nix/tarballs</filename>.</para>
|
||||||
|
|
||||||
|
<para>Files fetched via <envar>NIX_PATH</envar>,
|
||||||
|
<function>fetchGit</function>, <function>fetchMercurial</function>,
|
||||||
|
<function>fetchTarball</function>, and <function>fetchurl</function>
|
||||||
|
respect this TTL.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry xml:id="conf-timeout"><term><literal>timeout</literal></term>
|
<varlistentry xml:id="conf-timeout"><term><literal>timeout</literal></term>
|
||||||
|
|
||||||
|
|
|
@ -215,6 +215,48 @@ printed.)</para>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
|
<para>Special exit codes:</para>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
|
||||||
|
<varlistentry><term><literal>100</literal></term>
|
||||||
|
<listitem><para>Generic build failure, the builder process
|
||||||
|
returned with a non-zero exit code.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry><term><literal>101</literal></term>
|
||||||
|
<listitem><para>Build timeout, the build was aborted because it
|
||||||
|
did not complete within the specified <link
|
||||||
|
linkend='conf-timeout'><literal>timeout</literal></link>.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry><term><literal>102</literal></term>
|
||||||
|
<listitem><para>Hash mismatch, the build output was rejected
|
||||||
|
because it does not match the specified <link
|
||||||
|
linkend="fixed-output-drvs"><varname>outputHash</varname></link>.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry><term><literal>104</literal></term>
|
||||||
|
<listitem><para>Not deterministic, the build succeeded in check
|
||||||
|
mode but the resulting output is not binary reproducable.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
<para>With the <option>--keep-going</option> flag it's possible for
|
||||||
|
multiple failures to occur, in this case the 1xx status codes are or combined
|
||||||
|
using binary or. <screen>
|
||||||
|
1100100
|
||||||
|
^^^^
|
||||||
|
|||`- timeout
|
||||||
|
||`-- output hash mismatch
|
||||||
|
|`--- build failure
|
||||||
|
`---- not deterministic
|
||||||
|
</screen></para>
|
||||||
|
|
||||||
</refsection>
|
</refsection>
|
||||||
|
|
||||||
|
|
||||||
|
@ -883,6 +925,60 @@ $ nix-store --add ./foo.c
|
||||||
|
|
||||||
</refsection>
|
</refsection>
|
||||||
|
|
||||||
|
<!--######################################################################-->
|
||||||
|
|
||||||
|
<refsection><title>Operation <option>--add-fixed</option></title>
|
||||||
|
|
||||||
|
<refsection><title>Synopsis</title>
|
||||||
|
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>nix-store</command>
|
||||||
|
<arg><option>--recursive</option></arg>
|
||||||
|
<arg choice='plain'><option>--add-fixed</option></arg>
|
||||||
|
<arg choice='plain'><replaceable>algorithm</replaceable></arg>
|
||||||
|
<arg choice='plain' rep='repeat'><replaceable>paths</replaceable></arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
|
||||||
|
</refsection>
|
||||||
|
|
||||||
|
<refsection><title>Description</title>
|
||||||
|
|
||||||
|
<para>The operation <option>--add-fixed</option> adds the specified paths to
|
||||||
|
the Nix store. Unlike <option>--add</option> paths are registered using the
|
||||||
|
specified hashing algorithm, resulting in the same output path as a fixed output
|
||||||
|
derivation. This can be used for sources that are not available from a public
|
||||||
|
url or broke since the download expression was written.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>This operation has the following options:
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
|
||||||
|
<varlistentry><term><option>--recursive</option></term>
|
||||||
|
|
||||||
|
<listitem><para>
|
||||||
|
Use recursive instead of flat hashing mode, used when adding directories
|
||||||
|
to the store.
|
||||||
|
</para></listitem>
|
||||||
|
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</refsection>
|
||||||
|
|
||||||
|
<refsection><title>Example</title>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ nix-store --add-fixed sha256 ./hello-2.10.tar.gz
|
||||||
|
/nix/store/3x7dwzq014bblazs7kq20p9hyzz0qh8g-hello-2.10.tar.gz</screen>
|
||||||
|
|
||||||
|
</refsection>
|
||||||
|
|
||||||
|
</refsection>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--######################################################################-->
|
<!--######################################################################-->
|
||||||
|
|
|
@ -347,7 +347,7 @@ stdenv.mkDerivation { … }
|
||||||
You can change the cache timeout either on the command line with
|
You can change the cache timeout either on the command line with
|
||||||
<option>--option tarball-ttl <replaceable>number of seconds</replaceable></option> or
|
<option>--option tarball-ttl <replaceable>number of seconds</replaceable></option> or
|
||||||
in the Nix configuration file with this option:
|
in the Nix configuration file with this option:
|
||||||
<literal>tarball-ttl <replaceable>number of seconds to cache</replaceable></literal>.
|
<literal><xref linkend="conf-tarball-ttl" /> <replaceable>number of seconds to cache</replaceable></literal>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>Note that when obtaining the hash with <varname>nix-prefetch-url
|
<para>Note that when obtaining the hash with <varname>nix-prefetch-url
|
||||||
|
@ -425,6 +425,13 @@ stdenv.mkDerivation { … }
|
||||||
This is often a branch or tag name. Defaults to
|
This is often a branch or tag name. Defaults to
|
||||||
<literal>HEAD</literal>.
|
<literal>HEAD</literal>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
By default, the <varname>ref</varname> value is prefixed
|
||||||
|
with <literal>refs/heads/</literal>. As of Nix 2.3.0
|
||||||
|
Nix will not prefix <literal>refs/heads/</literal> if
|
||||||
|
<varname>ref</varname> starts with <literal>refs/</literal>.
|
||||||
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
@ -438,6 +445,14 @@ stdenv.mkDerivation { … }
|
||||||
}</programlisting>
|
}</programlisting>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
|
<example>
|
||||||
|
<title>Fetching an arbitrary ref</title>
|
||||||
|
<programlisting>builtins.fetchGit {
|
||||||
|
url = "https://gitub.com/NixOS/nix.git";
|
||||||
|
ref = "refs/heads/0.5-release";
|
||||||
|
}</programlisting>
|
||||||
|
</example>
|
||||||
|
|
||||||
<example>
|
<example>
|
||||||
<title>Fetching a repository's specific commit on an arbitrary branch</title>
|
<title>Fetching a repository's specific commit on an arbitrary branch</title>
|
||||||
<para>
|
<para>
|
||||||
|
@ -498,7 +513,7 @@ stdenv.mkDerivation { … }
|
||||||
fetch the latest version of a remote branch.
|
fetch the latest version of a remote branch.
|
||||||
</para>
|
</para>
|
||||||
<note><para>Nix will refetch the branch in accordance to
|
<note><para>Nix will refetch the branch in accordance to
|
||||||
<option>tarball-ttl</option>.</para></note>
|
<xref linkend="conf-tarball-ttl" />.</para></note>
|
||||||
<note><para>This behavior is disabled in
|
<note><para>This behavior is disabled in
|
||||||
<emphasis>Pure evaluation mode</emphasis>.</para></note>
|
<emphasis>Pure evaluation mode</emphasis>.</para></note>
|
||||||
<programlisting>builtins.fetchGit {
|
<programlisting>builtins.fetchGit {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<listitem><para>Bash Shell. The <literal>./configure</literal> script
|
<listitem><para>Bash Shell. The <literal>./configure</literal> script
|
||||||
relies on bashisms, so Bash is required.</para></listitem>
|
relies on bashisms, so Bash is required.</para></listitem>
|
||||||
|
|
||||||
<listitem><para>A version of GCC or Clang that supports C++14.</para></listitem>
|
<listitem><para>A version of GCC or Clang that supports C++17.</para></listitem>
|
||||||
|
|
||||||
<listitem><para><command>pkg-config</command> to locate
|
<listitem><para><command>pkg-config</command> to locate
|
||||||
dependencies. If your distribution does not provide it, you can get
|
dependencies. If your distribution does not provide it, you can get
|
||||||
|
@ -62,6 +62,10 @@
|
||||||
1.66.0 or higher. It can be obtained from the official web site
|
1.66.0 or higher. It can be obtained from the official web site
|
||||||
<link xlink:href="https://www.boost.org/" />.</para></listitem>
|
<link xlink:href="https://www.boost.org/" />.</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>The <literal>editline</literal> library of version
|
||||||
|
1.14.0 or higher. It can be obtained from the its repository
|
||||||
|
<link xlink:href="https://github.com/troglobit/editline" />.</para></listitem>
|
||||||
|
|
||||||
<listitem><para>The <command>xmllint</command> and
|
<listitem><para>The <command>xmllint</command> and
|
||||||
<command>xsltproc</command> programs to build this manual and the
|
<command>xsltproc</command> programs to build this manual and the
|
||||||
man-pages. These are part of the <literal>libxml2</literal> and
|
man-pages. These are part of the <literal>libxml2</literal> and
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
</partintro>
|
</partintro>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
<xi:include href="rl-2.3.xml" />
|
||||||
<xi:include href="rl-2.2.xml" />
|
<xi:include href="rl-2.2.xml" />
|
||||||
<xi:include href="rl-2.1.xml" />
|
<xi:include href="rl-2.1.xml" />
|
||||||
<xi:include href="rl-2.0.xml" />
|
<xi:include href="rl-2.0.xml" />
|
||||||
|
|
22
doc/manual/release-notes/rl-2.3.xml
Normal file
22
doc/manual/release-notes/rl-2.3.xml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="ssec-relnotes-2.3">
|
||||||
|
|
||||||
|
<title>Release 2.3 (????-??-??)</title>
|
||||||
|
|
||||||
|
<para>This release contains the following changes:</para>
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><function>builtins.fetchGit</function>'s <varname>ref</varname>
|
||||||
|
argument now allows specifying an absolute remote ref.
|
||||||
|
Nix will automatically prefix <varname>ref</varname> with
|
||||||
|
<literal>refs/heads</literal> only if <varname>ref</varname> doesn't
|
||||||
|
already begin with <literal>refs/</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</section>
|
951
m4/ax_cxx_compile_stdcxx.m4
Normal file
951
m4/ax_cxx_compile_stdcxx.m4
Normal file
|
@ -0,0 +1,951 @@
|
||||||
|
# ===========================================================================
|
||||||
|
# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
|
||||||
|
# ===========================================================================
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# Check for baseline language coverage in the compiler for the specified
|
||||||
|
# version of the C++ standard. If necessary, add switches to CXX and
|
||||||
|
# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard)
|
||||||
|
# or '14' (for the C++14 standard).
|
||||||
|
#
|
||||||
|
# The second argument, if specified, indicates whether you insist on an
|
||||||
|
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
|
||||||
|
# -std=c++11). If neither is specified, you get whatever works, with
|
||||||
|
# preference for an extended mode.
|
||||||
|
#
|
||||||
|
# The third argument, if specified 'mandatory' or if left unspecified,
|
||||||
|
# indicates that baseline support for the specified C++ standard is
|
||||||
|
# required and that the macro should error out if no mode with that
|
||||||
|
# support is found. If specified 'optional', then configuration proceeds
|
||||||
|
# regardless, after defining HAVE_CXX${VERSION} if and only if a
|
||||||
|
# supporting mode is found.
|
||||||
|
#
|
||||||
|
# LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
|
||||||
|
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
|
||||||
|
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
|
||||||
|
# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
|
||||||
|
# Copyright (c) 2015 Paul Norman <penorman@mac.com>
|
||||||
|
# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
|
||||||
|
# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
|
||||||
|
# Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com>
|
||||||
|
#
|
||||||
|
# Copying and distribution of this file, with or without modification, are
|
||||||
|
# permitted in any medium without royalty provided the copyright notice
|
||||||
|
# and this notice are preserved. This file is offered as-is, without any
|
||||||
|
# warranty.
|
||||||
|
|
||||||
|
#serial 11
|
||||||
|
|
||||||
|
dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
|
||||||
|
dnl (serial version number 13).
|
||||||
|
|
||||||
|
AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
|
||||||
|
m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
|
||||||
|
[$1], [14], [ax_cxx_compile_alternatives="14 1y"],
|
||||||
|
[$1], [17], [ax_cxx_compile_alternatives="17 1z"],
|
||||||
|
[m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
|
||||||
|
m4_if([$2], [], [],
|
||||||
|
[$2], [ext], [],
|
||||||
|
[$2], [noext], [],
|
||||||
|
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
|
||||||
|
m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
|
||||||
|
[$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
|
||||||
|
[$3], [optional], [ax_cxx_compile_cxx$1_required=false],
|
||||||
|
[m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
|
||||||
|
AC_LANG_PUSH([C++])dnl
|
||||||
|
ac_success=no
|
||||||
|
|
||||||
|
m4_if([$2], [noext], [], [dnl
|
||||||
|
if test x$ac_success = xno; then
|
||||||
|
for alternative in ${ax_cxx_compile_alternatives}; do
|
||||||
|
switch="-std=gnu++${alternative}"
|
||||||
|
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
|
||||||
|
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
|
||||||
|
$cachevar,
|
||||||
|
[ac_save_CXX="$CXX"
|
||||||
|
CXX="$CXX $switch"
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
|
||||||
|
[eval $cachevar=yes],
|
||||||
|
[eval $cachevar=no])
|
||||||
|
CXX="$ac_save_CXX"])
|
||||||
|
if eval test x\$$cachevar = xyes; then
|
||||||
|
CXX="$CXX $switch"
|
||||||
|
if test -n "$CXXCPP" ; then
|
||||||
|
CXXCPP="$CXXCPP $switch"
|
||||||
|
fi
|
||||||
|
ac_success=yes
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi])
|
||||||
|
|
||||||
|
m4_if([$2], [ext], [], [dnl
|
||||||
|
if test x$ac_success = xno; then
|
||||||
|
dnl HP's aCC needs +std=c++11 according to:
|
||||||
|
dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
|
||||||
|
dnl Cray's crayCC needs "-h std=c++11"
|
||||||
|
for alternative in ${ax_cxx_compile_alternatives}; do
|
||||||
|
for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
|
||||||
|
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
|
||||||
|
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
|
||||||
|
$cachevar,
|
||||||
|
[ac_save_CXX="$CXX"
|
||||||
|
CXX="$CXX $switch"
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
|
||||||
|
[eval $cachevar=yes],
|
||||||
|
[eval $cachevar=no])
|
||||||
|
CXX="$ac_save_CXX"])
|
||||||
|
if eval test x\$$cachevar = xyes; then
|
||||||
|
CXX="$CXX $switch"
|
||||||
|
if test -n "$CXXCPP" ; then
|
||||||
|
CXXCPP="$CXXCPP $switch"
|
||||||
|
fi
|
||||||
|
ac_success=yes
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if test x$ac_success = xyes; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi])
|
||||||
|
AC_LANG_POP([C++])
|
||||||
|
if test x$ax_cxx_compile_cxx$1_required = xtrue; then
|
||||||
|
if test x$ac_success = xno; then
|
||||||
|
AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test x$ac_success = xno; then
|
||||||
|
HAVE_CXX$1=0
|
||||||
|
AC_MSG_NOTICE([No compiler with C++$1 support was found])
|
||||||
|
else
|
||||||
|
HAVE_CXX$1=1
|
||||||
|
AC_DEFINE(HAVE_CXX$1,1,
|
||||||
|
[define if the compiler supports basic C++$1 syntax])
|
||||||
|
fi
|
||||||
|
AC_SUBST(HAVE_CXX$1)
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl Test body for checking C++11 support
|
||||||
|
|
||||||
|
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
|
||||||
|
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
dnl Test body for checking C++14 support
|
||||||
|
|
||||||
|
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
|
||||||
|
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
|
||||||
|
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
|
||||||
|
)
|
||||||
|
|
||||||
|
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
|
||||||
|
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
|
||||||
|
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
|
||||||
|
_AX_CXX_COMPILE_STDCXX_testbody_new_in_17
|
||||||
|
)
|
||||||
|
|
||||||
|
dnl Tests for new features in C++11
|
||||||
|
|
||||||
|
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
|
||||||
|
|
||||||
|
// If the compiler admits that it is not ready for C++11, why torture it?
|
||||||
|
// Hopefully, this will speed up the test.
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
|
||||||
|
#error "This is not a C++ compiler"
|
||||||
|
|
||||||
|
#elif __cplusplus < 201103L
|
||||||
|
|
||||||
|
#error "This is not a C++11 compiler"
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
namespace cxx11
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace test_static_assert
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct check
|
||||||
|
{
|
||||||
|
static_assert(sizeof(int) <= sizeof(T), "not big enough");
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_final_override
|
||||||
|
{
|
||||||
|
|
||||||
|
struct Base
|
||||||
|
{
|
||||||
|
virtual ~Base() {}
|
||||||
|
virtual void f() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Derived : public Base
|
||||||
|
{
|
||||||
|
virtual ~Derived() override {}
|
||||||
|
virtual void f() override {}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_double_right_angle_brackets
|
||||||
|
{
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
struct check {};
|
||||||
|
|
||||||
|
typedef check<void> single_type;
|
||||||
|
typedef check<check<void>> double_type;
|
||||||
|
typedef check<check<check<void>>> triple_type;
|
||||||
|
typedef check<check<check<check<void>>>> quadruple_type;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_decltype
|
||||||
|
{
|
||||||
|
|
||||||
|
int
|
||||||
|
f()
|
||||||
|
{
|
||||||
|
int a = 1;
|
||||||
|
decltype(a) b = 2;
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_type_deduction
|
||||||
|
{
|
||||||
|
|
||||||
|
template < typename T1, typename T2 >
|
||||||
|
struct is_same
|
||||||
|
{
|
||||||
|
static const bool value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
struct is_same<T, T>
|
||||||
|
{
|
||||||
|
static const bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template < typename T1, typename T2 >
|
||||||
|
auto
|
||||||
|
add(T1 a1, T2 a2) -> decltype(a1 + a2)
|
||||||
|
{
|
||||||
|
return a1 + a2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
test(const int c, volatile int v)
|
||||||
|
{
|
||||||
|
static_assert(is_same<int, decltype(0)>::value == true, "");
|
||||||
|
static_assert(is_same<int, decltype(c)>::value == false, "");
|
||||||
|
static_assert(is_same<int, decltype(v)>::value == false, "");
|
||||||
|
auto ac = c;
|
||||||
|
auto av = v;
|
||||||
|
auto sumi = ac + av + 'x';
|
||||||
|
auto sumf = ac + av + 1.0;
|
||||||
|
static_assert(is_same<int, decltype(ac)>::value == true, "");
|
||||||
|
static_assert(is_same<int, decltype(av)>::value == true, "");
|
||||||
|
static_assert(is_same<int, decltype(sumi)>::value == true, "");
|
||||||
|
static_assert(is_same<int, decltype(sumf)>::value == false, "");
|
||||||
|
static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
|
||||||
|
return (sumf > 0.0) ? sumi : add(c, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
int f() { return 0; }
|
||||||
|
int g() noexcept { return 0; }
|
||||||
|
|
||||||
|
static_assert(noexcept(f()) == false, "");
|
||||||
|
static_assert(noexcept(g()) == true, "");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_constexpr
|
||||||
|
{
|
||||||
|
|
||||||
|
template < typename CharT >
|
||||||
|
unsigned long constexpr
|
||||||
|
strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
|
||||||
|
{
|
||||||
|
return *s ? strlen_c_r(s + 1, acc + 1) : acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename CharT >
|
||||||
|
unsigned long constexpr
|
||||||
|
strlen_c(const CharT *const s) noexcept
|
||||||
|
{
|
||||||
|
return strlen_c_r(s, 0UL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert(strlen_c("") == 0UL, "");
|
||||||
|
static_assert(strlen_c("1") == 1UL, "");
|
||||||
|
static_assert(strlen_c("example") == 7UL, "");
|
||||||
|
static_assert(strlen_c("another\0example") == 7UL, "");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_rvalue_references
|
||||||
|
{
|
||||||
|
|
||||||
|
template < int N >
|
||||||
|
struct answer
|
||||||
|
{
|
||||||
|
static constexpr int value = N;
|
||||||
|
};
|
||||||
|
|
||||||
|
answer<1> f(int&) { return answer<1>(); }
|
||||||
|
answer<2> f(const int&) { return answer<2>(); }
|
||||||
|
answer<3> f(int&&) { return answer<3>(); }
|
||||||
|
|
||||||
|
void
|
||||||
|
test()
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
const int c = 0;
|
||||||
|
static_assert(decltype(f(i))::value == 1, "");
|
||||||
|
static_assert(decltype(f(c))::value == 2, "");
|
||||||
|
static_assert(decltype(f(0))::value == 3, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_uniform_initialization
|
||||||
|
{
|
||||||
|
|
||||||
|
struct test
|
||||||
|
{
|
||||||
|
static const int zero {};
|
||||||
|
static const int one {1};
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(test::zero == 0, "");
|
||||||
|
static_assert(test::one == 1, "");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_lambdas
|
||||||
|
{
|
||||||
|
|
||||||
|
void
|
||||||
|
test1()
|
||||||
|
{
|
||||||
|
auto lambda1 = [](){};
|
||||||
|
auto lambda2 = lambda1;
|
||||||
|
lambda1();
|
||||||
|
lambda2();
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
test2()
|
||||||
|
{
|
||||||
|
auto a = [](int i, int j){ return i + j; }(1, 2);
|
||||||
|
auto b = []() -> int { return '0'; }();
|
||||||
|
auto c = [=](){ return a + b; }();
|
||||||
|
auto d = [&](){ return c; }();
|
||||||
|
auto e = [a, &b](int x) mutable {
|
||||||
|
const auto identity = [](int y){ return y; };
|
||||||
|
for (auto i = 0; i < a; ++i)
|
||||||
|
a += b--;
|
||||||
|
return x + identity(a + b);
|
||||||
|
}(0);
|
||||||
|
return a + b + c + d + e;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
test3()
|
||||||
|
{
|
||||||
|
const auto nullary = [](){ return 0; };
|
||||||
|
const auto unary = [](int x){ return x; };
|
||||||
|
using nullary_t = decltype(nullary);
|
||||||
|
using unary_t = decltype(unary);
|
||||||
|
const auto higher1st = [](nullary_t f){ return f(); };
|
||||||
|
const auto higher2nd = [unary](nullary_t f1){
|
||||||
|
return [unary, f1](unary_t f2){ return f2(unary(f1())); };
|
||||||
|
};
|
||||||
|
return higher1st(nullary) + higher2nd(nullary)(unary);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_variadic_templates
|
||||||
|
{
|
||||||
|
|
||||||
|
template <int...>
|
||||||
|
struct sum;
|
||||||
|
|
||||||
|
template <int N0, int... N1toN>
|
||||||
|
struct sum<N0, N1toN...>
|
||||||
|
{
|
||||||
|
static constexpr auto value = N0 + sum<N1toN...>::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct sum<>
|
||||||
|
{
|
||||||
|
static constexpr auto value = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sum<>::value == 0, "");
|
||||||
|
static_assert(sum<1>::value == 1, "");
|
||||||
|
static_assert(sum<23>::value == 23, "");
|
||||||
|
static_assert(sum<1, 2>::value == 3, "");
|
||||||
|
static_assert(sum<5, 5, 11>::value == 21, "");
|
||||||
|
static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
|
||||||
|
// Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
|
||||||
|
// because of this.
|
||||||
|
namespace test_template_alias_sfinae
|
||||||
|
{
|
||||||
|
|
||||||
|
struct foo {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using member = typename T::member_type;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void func(...) {}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void func(member<T>*) {}
|
||||||
|
|
||||||
|
void test();
|
||||||
|
|
||||||
|
void test() { func<foo>(0); }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cxx11
|
||||||
|
|
||||||
|
#endif // __cplusplus >= 201103L
|
||||||
|
|
||||||
|
]])
|
||||||
|
|
||||||
|
|
||||||
|
dnl Tests for new features in C++14
|
||||||
|
|
||||||
|
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
|
||||||
|
|
||||||
|
// If the compiler admits that it is not ready for C++14, why torture it?
|
||||||
|
// Hopefully, this will speed up the test.
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
|
||||||
|
#error "This is not a C++ compiler"
|
||||||
|
|
||||||
|
#elif __cplusplus < 201402L
|
||||||
|
|
||||||
|
#error "This is not a C++14 compiler"
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
namespace cxx14
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace test_polymorphic_lambdas
|
||||||
|
{
|
||||||
|
|
||||||
|
int
|
||||||
|
test()
|
||||||
|
{
|
||||||
|
const auto lambda = [](auto&&... args){
|
||||||
|
const auto istiny = [](auto x){
|
||||||
|
return (sizeof(x) == 1UL) ? 1 : 0;
|
||||||
|
};
|
||||||
|
const int aretiny[] = { istiny(args)... };
|
||||||
|
return aretiny[0];
|
||||||
|
};
|
||||||
|
return lambda(1, 1L, 1.0f, '1');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_binary_literals
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr auto ivii = 0b0000000000101010;
|
||||||
|
static_assert(ivii == 42, "wrong value");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_generalized_constexpr
|
||||||
|
{
|
||||||
|
|
||||||
|
template < typename CharT >
|
||||||
|
constexpr unsigned long
|
||||||
|
strlen_c(const CharT *const s) noexcept
|
||||||
|
{
|
||||||
|
auto length = 0UL;
|
||||||
|
for (auto p = s; *p; ++p)
|
||||||
|
++length;
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert(strlen_c("") == 0UL, "");
|
||||||
|
static_assert(strlen_c("x") == 1UL, "");
|
||||||
|
static_assert(strlen_c("test") == 4UL, "");
|
||||||
|
static_assert(strlen_c("another\0test") == 7UL, "");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_lambda_init_capture
|
||||||
|
{
|
||||||
|
|
||||||
|
int
|
||||||
|
test()
|
||||||
|
{
|
||||||
|
auto x = 0;
|
||||||
|
const auto lambda1 = [a = x](int b){ return a + b; };
|
||||||
|
const auto lambda2 = [a = lambda1(x)](){ return a; };
|
||||||
|
return lambda2();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_digit_separators
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr auto ten_million = 100'000'000;
|
||||||
|
static_assert(ten_million == 100000000, "");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_return_type_deduction
|
||||||
|
{
|
||||||
|
|
||||||
|
auto f(int& x) { return x; }
|
||||||
|
decltype(auto) g(int& x) { return x; }
|
||||||
|
|
||||||
|
template < typename T1, typename T2 >
|
||||||
|
struct is_same
|
||||||
|
{
|
||||||
|
static constexpr auto value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
struct is_same<T, T>
|
||||||
|
{
|
||||||
|
static constexpr auto value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
test()
|
||||||
|
{
|
||||||
|
auto x = 0;
|
||||||
|
static_assert(is_same<int, decltype(f(x))>::value, "");
|
||||||
|
static_assert(is_same<int&, decltype(g(x))>::value, "");
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cxx14
|
||||||
|
|
||||||
|
#endif // __cplusplus >= 201402L
|
||||||
|
|
||||||
|
]])
|
||||||
|
|
||||||
|
|
||||||
|
dnl Tests for new features in C++17
|
||||||
|
|
||||||
|
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
|
||||||
|
|
||||||
|
// If the compiler admits that it is not ready for C++17, why torture it?
|
||||||
|
// Hopefully, this will speed up the test.
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
|
||||||
|
#error "This is not a C++ compiler"
|
||||||
|
|
||||||
|
#elif __cplusplus < 201703L
|
||||||
|
|
||||||
|
#error "This is not a C++17 compiler"
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <initializer_list>
|
||||||
|
#include <utility>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace cxx17
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace test_constexpr_lambdas
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr int foo = [](){return 42;}();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test::nested_namespace::definitions
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_fold_expression
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
int multiply(Args... args)
|
||||||
|
{
|
||||||
|
return (args * ... * 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
bool all(Args... args)
|
||||||
|
{
|
||||||
|
return (args && ...);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_extended_static_assert
|
||||||
|
{
|
||||||
|
|
||||||
|
static_assert (true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_auto_brace_init_list
|
||||||
|
{
|
||||||
|
|
||||||
|
auto foo = {5};
|
||||||
|
auto bar {5};
|
||||||
|
|
||||||
|
static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
|
||||||
|
static_assert(std::is_same<int, decltype(bar)>::value);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_typename_in_template_template_parameter
|
||||||
|
{
|
||||||
|
|
||||||
|
template<template<typename> typename X> struct D;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_fallthrough_nodiscard_maybe_unused_attributes
|
||||||
|
{
|
||||||
|
|
||||||
|
int f1()
|
||||||
|
{
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] int f2()
|
||||||
|
{
|
||||||
|
[[maybe_unused]] auto unused = f1();
|
||||||
|
|
||||||
|
switch (f1())
|
||||||
|
{
|
||||||
|
case 17:
|
||||||
|
f1();
|
||||||
|
[[fallthrough]];
|
||||||
|
case 42:
|
||||||
|
f1();
|
||||||
|
}
|
||||||
|
return f1();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_extended_aggregate_initialization
|
||||||
|
{
|
||||||
|
|
||||||
|
struct base1
|
||||||
|
{
|
||||||
|
int b1, b2 = 42;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct base2
|
||||||
|
{
|
||||||
|
base2() {
|
||||||
|
b3 = 42;
|
||||||
|
}
|
||||||
|
int b3;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct derived : base1, base2
|
||||||
|
{
|
||||||
|
int d;
|
||||||
|
};
|
||||||
|
|
||||||
|
derived d1 {{1, 2}, {}, 4}; // full initialization
|
||||||
|
derived d2 {{}, {}, 4}; // value-initialized bases
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_general_range_based_for_loop
|
||||||
|
{
|
||||||
|
|
||||||
|
struct iter
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
int& operator* ()
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int& operator* () const
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
iter& operator++()
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sentinel
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator== (const iter& i, const sentinel& s)
|
||||||
|
{
|
||||||
|
return i.i == s.i;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!= (const iter& i, const sentinel& s)
|
||||||
|
{
|
||||||
|
return !(i == s);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct range
|
||||||
|
{
|
||||||
|
iter begin() const
|
||||||
|
{
|
||||||
|
return {0};
|
||||||
|
}
|
||||||
|
|
||||||
|
sentinel end() const
|
||||||
|
{
|
||||||
|
return {5};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void f()
|
||||||
|
{
|
||||||
|
range r {};
|
||||||
|
|
||||||
|
for (auto i : r)
|
||||||
|
{
|
||||||
|
[[maybe_unused]] auto v = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_lambda_capture_asterisk_this_by_value
|
||||||
|
{
|
||||||
|
|
||||||
|
struct t
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int foo()
|
||||||
|
{
|
||||||
|
return [*this]()
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_enum_class_construction
|
||||||
|
{
|
||||||
|
|
||||||
|
enum class byte : unsigned char
|
||||||
|
{};
|
||||||
|
|
||||||
|
byte foo {42};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_constexpr_if
|
||||||
|
{
|
||||||
|
|
||||||
|
template <bool cond>
|
||||||
|
int f ()
|
||||||
|
{
|
||||||
|
if constexpr(cond)
|
||||||
|
{
|
||||||
|
return 13;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_selection_statement_with_initializer
|
||||||
|
{
|
||||||
|
|
||||||
|
int f()
|
||||||
|
{
|
||||||
|
return 13;
|
||||||
|
}
|
||||||
|
|
||||||
|
int f2()
|
||||||
|
{
|
||||||
|
if (auto i = f(); i > 0)
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (auto i = f(); i + 4)
|
||||||
|
{
|
||||||
|
case 17:
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_template_argument_deduction_for_class_templates
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename T1, typename T2>
|
||||||
|
struct pair
|
||||||
|
{
|
||||||
|
pair (T1 p1, T2 p2)
|
||||||
|
: m1 {p1},
|
||||||
|
m2 {p2}
|
||||||
|
{}
|
||||||
|
|
||||||
|
T1 m1;
|
||||||
|
T2 m2;
|
||||||
|
};
|
||||||
|
|
||||||
|
void f()
|
||||||
|
{
|
||||||
|
[[maybe_unused]] auto p = pair{13, 42u};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_non_type_auto_template_parameters
|
||||||
|
{
|
||||||
|
|
||||||
|
template <auto n>
|
||||||
|
struct B
|
||||||
|
{};
|
||||||
|
|
||||||
|
B<5> b1;
|
||||||
|
B<'a'> b2;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_structured_bindings
|
||||||
|
{
|
||||||
|
|
||||||
|
int arr[2] = { 1, 2 };
|
||||||
|
std::pair<int, int> pr = { 1, 2 };
|
||||||
|
|
||||||
|
auto f1() -> int(&)[2]
|
||||||
|
{
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto f2() -> std::pair<int, int>&
|
||||||
|
{
|
||||||
|
return pr;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
int x1 : 2;
|
||||||
|
volatile double y1;
|
||||||
|
};
|
||||||
|
|
||||||
|
S f3()
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto [ x1, y1 ] = f1();
|
||||||
|
auto& [ xr1, yr1 ] = f1();
|
||||||
|
auto [ x2, y2 ] = f2();
|
||||||
|
auto& [ xr2, yr2 ] = f2();
|
||||||
|
const auto [ x3, y3 ] = f3();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_exception_spec_type_system
|
||||||
|
{
|
||||||
|
|
||||||
|
struct Good {};
|
||||||
|
struct Bad {};
|
||||||
|
|
||||||
|
void g1() noexcept;
|
||||||
|
void g2();
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Bad
|
||||||
|
f(T*, T*);
|
||||||
|
|
||||||
|
template<typename T1, typename T2>
|
||||||
|
Good
|
||||||
|
f(T1*, T2*);
|
||||||
|
|
||||||
|
static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_inline_variables
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class T> void f(T)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<class T> inline T g(T)
|
||||||
|
{
|
||||||
|
return T{};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> inline void f<>(int)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<> int g<>(int)
|
||||||
|
{
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cxx17
|
||||||
|
|
||||||
|
#endif // __cplusplus < 201703L
|
||||||
|
|
||||||
|
]])
|
35
m4/ax_cxx_compile_stdcxx_17.m4
Normal file
35
m4/ax_cxx_compile_stdcxx_17.m4
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
# =============================================================================
|
||||||
|
# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_17.html
|
||||||
|
# =============================================================================
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# AX_CXX_COMPILE_STDCXX_17([ext|noext], [mandatory|optional])
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# Check for baseline language coverage in the compiler for the C++17
|
||||||
|
# standard; if necessary, add switches to CXX and CXXCPP to enable
|
||||||
|
# support.
|
||||||
|
#
|
||||||
|
# This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX
|
||||||
|
# macro with the version set to C++17. The two optional arguments are
|
||||||
|
# forwarded literally as the second and third argument respectively.
|
||||||
|
# Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for
|
||||||
|
# more information. If you want to use this macro, you also need to
|
||||||
|
# download the ax_cxx_compile_stdcxx.m4 file.
|
||||||
|
#
|
||||||
|
# LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
|
||||||
|
# Copyright (c) 2016 Krzesimir Nowak <qdlacz@gmail.com>
|
||||||
|
#
|
||||||
|
# Copying and distribution of this file, with or without modification, are
|
||||||
|
# permitted in any medium without royalty provided the copyright notice
|
||||||
|
# and this notice are preserved. This file is offered as-is, without any
|
||||||
|
# warranty.
|
||||||
|
|
||||||
|
#serial 2
|
||||||
|
|
||||||
|
AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX])
|
||||||
|
AC_DEFUN([AX_CXX_COMPILE_STDCXX_17], [AX_CXX_COMPILE_STDCXX([17], [$1], [$2])])
|
|
@ -91,7 +91,7 @@ define build-library
|
||||||
$(1)_PATH := $$(_d)/$$($(1)_NAME).$(SO_EXT)
|
$(1)_PATH := $$(_d)/$$($(1)_NAME).$(SO_EXT)
|
||||||
|
|
||||||
$$($(1)_PATH): $$($(1)_OBJS) $$(_libs) | $$(_d)/
|
$$($(1)_PATH): $$($(1)_OBJS) $$(_libs) | $$(_d)/
|
||||||
$$(trace-ld) $(CXX) -o $$(abspath $$@) -shared $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$($(1)_LDFLAGS_PROPAGATED) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE)) $$($(1)_LDFLAGS_UNINSTALLED)
|
$$(trace-ld) $(CXX) -o $$(abspath $$@) -shared $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$($(1)_LDFLAGS_PROPAGATED) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE)) $$($(1)_LDFLAGS_UNINSTALLED)
|
||||||
|
|
||||||
ifneq ($(OS), Darwin)
|
ifneq ($(OS), Darwin)
|
||||||
$(1)_LDFLAGS_USE += -Wl,-rpath,$$(abspath $$(_d))
|
$(1)_LDFLAGS_USE += -Wl,-rpath,$$(abspath $$(_d))
|
||||||
|
@ -105,7 +105,7 @@ define build-library
|
||||||
$$(eval $$(call create-dir, $$($(1)_INSTALL_DIR)))
|
$$(eval $$(call create-dir, $$($(1)_INSTALL_DIR)))
|
||||||
|
|
||||||
$$($(1)_INSTALL_PATH): $$($(1)_OBJS) $$(_libs_final) | $(DESTDIR)$$($(1)_INSTALL_DIR)/
|
$$($(1)_INSTALL_PATH): $$($(1)_OBJS) $$(_libs_final) | $(DESTDIR)$$($(1)_INSTALL_DIR)/
|
||||||
$$(trace-ld) $(CXX) -o $$@ -shared $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$($(1)_LDFLAGS_PROPAGATED) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE_INSTALLED))
|
$$(trace-ld) $(CXX) -o $$@ -shared $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$($(1)_LDFLAGS_PROPAGATED) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE_INSTALLED))
|
||||||
|
|
||||||
$(1)_LDFLAGS_USE_INSTALLED += -L$$(DESTDIR)$$($(1)_INSTALL_DIR) -l$$(patsubst lib%,%,$$(strip $$($(1)_NAME)))
|
$(1)_LDFLAGS_USE_INSTALLED += -L$$(DESTDIR)$$($(1)_INSTALL_DIR) -l$$(patsubst lib%,%,$$(strip $$($(1)_NAME)))
|
||||||
ifneq ($(OS), Darwin)
|
ifneq ($(OS), Darwin)
|
||||||
|
|
|
@ -32,7 +32,7 @@ define build-program
|
||||||
$$(eval $$(call create-dir, $$(_d)))
|
$$(eval $$(call create-dir, $$(_d)))
|
||||||
|
|
||||||
$$($(1)_PATH): $$($(1)_OBJS) $$(_libs) | $$(_d)/
|
$$($(1)_PATH): $$($(1)_OBJS) $$(_libs) | $$(_d)/
|
||||||
$$(trace-ld) $(CXX) -o $$@ $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE))
|
$$(trace-ld) $(CXX) -o $$@ $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE))
|
||||||
|
|
||||||
$(1)_INSTALL_DIR ?= $$(bindir)
|
$(1)_INSTALL_DIR ?= $$(bindir)
|
||||||
$(1)_INSTALL_PATH := $$($(1)_INSTALL_DIR)/$(1)
|
$(1)_INSTALL_PATH := $$($(1)_INSTALL_DIR)/$(1)
|
||||||
|
@ -46,7 +46,7 @@ define build-program
|
||||||
_libs_final := $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_INSTALL_PATH))
|
_libs_final := $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_INSTALL_PATH))
|
||||||
|
|
||||||
$(DESTDIR)$$($(1)_INSTALL_PATH): $$($(1)_OBJS) $$(_libs_final) | $(DESTDIR)$$($(1)_INSTALL_DIR)/
|
$(DESTDIR)$$($(1)_INSTALL_PATH): $$($(1)_OBJS) $$(_libs_final) | $(DESTDIR)$$($(1)_INSTALL_DIR)/
|
||||||
$$(trace-ld) $(CXX) -o $$@ $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE_INSTALLED))
|
$$(trace-ld) $(CXX) -o $$@ $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE_INSTALLED))
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,4 @@ GLOBAL_CXXFLAGS += -g -Wall
|
||||||
|
|
||||||
-include Makefile.config
|
-include Makefile.config
|
||||||
|
|
||||||
OPTIMIZE = 1
|
|
||||||
|
|
||||||
ifeq ($(OPTIMIZE), 1)
|
|
||||||
GLOBAL_CFLAGS += -O3
|
|
||||||
GLOBAL_CXXFLAGS += -O3
|
|
||||||
endif
|
|
||||||
|
|
||||||
include mk/lib.mk
|
include mk/lib.mk
|
||||||
|
|
|
@ -2,8 +2,10 @@ AC_INIT(nix-perl, m4_esyscmd([bash -c "echo -n $(cat ../.version)$VERSION_SUFFIX
|
||||||
AC_CONFIG_SRCDIR(MANIFEST)
|
AC_CONFIG_SRCDIR(MANIFEST)
|
||||||
AC_CONFIG_AUX_DIR(../config)
|
AC_CONFIG_AUX_DIR(../config)
|
||||||
|
|
||||||
CFLAGS=
|
# Set default flags for nix (as per AC_PROG_CC/CXX docs),
|
||||||
CXXFLAGS=
|
# while still allowing the user to override them from the command line.
|
||||||
|
: ${CFLAGS="-O3"}
|
||||||
|
: ${CXXFLAGS="-O3"}
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
AC_PROG_CXX
|
AC_PROG_CXX
|
||||||
AX_CXX_COMPILE_STDCXX_11
|
AX_CXX_COMPILE_STDCXX_11
|
||||||
|
|
|
@ -112,7 +112,10 @@ GitInfo exportGit(ref<Store> store, std::string uri,
|
||||||
runProgram("git", true, { "init", "--bare", repoDir });
|
runProgram("git", true, { "init", "--bare", repoDir });
|
||||||
}
|
}
|
||||||
|
|
||||||
Path localRefFile = repoDir + "/refs/heads/" + *ref;
|
Path localRefFile =
|
||||||
|
ref->compare(0, 5, "refs/") == 0
|
||||||
|
? cacheDir + "/" + *ref
|
||||||
|
: cacheDir + "/refs/heads/" + *ref;
|
||||||
|
|
||||||
bool doFetch;
|
bool doFetch;
|
||||||
time_t now = time(0);
|
time_t now = time(0);
|
||||||
|
|
|
@ -266,6 +266,12 @@ public:
|
||||||
/* Set if at least one derivation had a timeout. */
|
/* Set if at least one derivation had a timeout. */
|
||||||
bool timedOut;
|
bool timedOut;
|
||||||
|
|
||||||
|
/* Set if at least one derivation fails with a hash mismatch. */
|
||||||
|
bool hashMismatch;
|
||||||
|
|
||||||
|
/* Set if at least one derivation is not deterministic in check mode. */
|
||||||
|
bool checkMismatch;
|
||||||
|
|
||||||
LocalStore & store;
|
LocalStore & store;
|
||||||
|
|
||||||
std::unique_ptr<HookInstance> hook;
|
std::unique_ptr<HookInstance> hook;
|
||||||
|
@ -3213,6 +3219,7 @@ void DerivationGoal::registerOutputs()
|
||||||
|
|
||||||
/* Throw an error after registering the path as
|
/* Throw an error after registering the path as
|
||||||
valid. */
|
valid. */
|
||||||
|
worker.hashMismatch = true;
|
||||||
delayedException = std::make_exception_ptr(
|
delayedException = std::make_exception_ptr(
|
||||||
BuildError("hash mismatch in fixed-output derivation '%s':\n wanted: %s\n got: %s",
|
BuildError("hash mismatch in fixed-output derivation '%s':\n wanted: %s\n got: %s",
|
||||||
dest, h.to_string(SRI), h2.to_string(SRI)));
|
dest, h.to_string(SRI), h2.to_string(SRI)));
|
||||||
|
@ -3255,6 +3262,7 @@ void DerivationGoal::registerOutputs()
|
||||||
if (!worker.store.isValidPath(path)) continue;
|
if (!worker.store.isValidPath(path)) continue;
|
||||||
auto info = *worker.store.queryPathInfo(path);
|
auto info = *worker.store.queryPathInfo(path);
|
||||||
if (hash.first != info.narHash) {
|
if (hash.first != info.narHash) {
|
||||||
|
worker.checkMismatch = true;
|
||||||
if (settings.runDiffHook || settings.keepFailed) {
|
if (settings.runDiffHook || settings.keepFailed) {
|
||||||
Path dst = worker.store.toRealPath(path + checkSuffix);
|
Path dst = worker.store.toRealPath(path + checkSuffix);
|
||||||
deletePath(dst);
|
deletePath(dst);
|
||||||
|
@ -3266,10 +3274,10 @@ void DerivationGoal::registerOutputs()
|
||||||
buildUser ? buildUser->getGID() : getgid(),
|
buildUser ? buildUser->getGID() : getgid(),
|
||||||
path, dst, drvPath, tmpDir);
|
path, dst, drvPath, tmpDir);
|
||||||
|
|
||||||
throw Error(format("derivation '%1%' may not be deterministic: output '%2%' differs from '%3%'")
|
throw NotDeterministic(format("derivation '%1%' may not be deterministic: output '%2%' differs from '%3%'")
|
||||||
% drvPath % path % dst);
|
% drvPath % path % dst);
|
||||||
} else
|
} else
|
||||||
throw Error(format("derivation '%1%' may not be deterministic: output '%2%' differs")
|
throw NotDeterministic(format("derivation '%1%' may not be deterministic: output '%2%' differs")
|
||||||
% drvPath % path);
|
% drvPath % path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4101,6 +4109,8 @@ Worker::Worker(LocalStore & store)
|
||||||
lastWokenUp = steady_time_point::min();
|
lastWokenUp = steady_time_point::min();
|
||||||
permanentFailure = false;
|
permanentFailure = false;
|
||||||
timedOut = false;
|
timedOut = false;
|
||||||
|
hashMismatch = false;
|
||||||
|
checkMismatch = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4461,7 +4471,29 @@ void Worker::waitForInput()
|
||||||
|
|
||||||
unsigned int Worker::exitStatus()
|
unsigned int Worker::exitStatus()
|
||||||
{
|
{
|
||||||
return timedOut ? 101 : (permanentFailure ? 100 : 1);
|
/*
|
||||||
|
* 1100100
|
||||||
|
* ^^^^
|
||||||
|
* |||`- timeout
|
||||||
|
* ||`-- output hash mismatch
|
||||||
|
* |`--- build failure
|
||||||
|
* `---- not deterministic
|
||||||
|
*/
|
||||||
|
unsigned int mask = 0;
|
||||||
|
bool buildFailure = permanentFailure || timedOut || hashMismatch;
|
||||||
|
if (buildFailure)
|
||||||
|
mask |= 0x04; // 100
|
||||||
|
if (timedOut)
|
||||||
|
mask |= 0x01; // 101
|
||||||
|
if (hashMismatch)
|
||||||
|
mask |= 0x02; // 102
|
||||||
|
if (checkMismatch) {
|
||||||
|
mask |= 0x08; // 104
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask)
|
||||||
|
mask |= 0x60;
|
||||||
|
return mask ? mask : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -244,6 +244,8 @@ struct CurlDownloader : public Downloader
|
||||||
#if LIBCURL_VERSION_NUM >= 0x072f00
|
#if LIBCURL_VERSION_NUM >= 0x072f00
|
||||||
if (downloadSettings.enableHttp2)
|
if (downloadSettings.enableHttp2)
|
||||||
curl_easy_setopt(req, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS);
|
curl_easy_setopt(req, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS);
|
||||||
|
else
|
||||||
|
curl_easy_setopt(req, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
|
||||||
#endif
|
#endif
|
||||||
curl_easy_setopt(req, CURLOPT_WRITEFUNCTION, DownloadItem::writeCallbackWrapper);
|
curl_easy_setopt(req, CURLOPT_WRITEFUNCTION, DownloadItem::writeCallbackWrapper);
|
||||||
curl_easy_setopt(req, CURLOPT_WRITEDATA, this);
|
curl_easy_setopt(req, CURLOPT_WRITEDATA, this);
|
||||||
|
@ -864,10 +866,11 @@ CachedDownloadResult Downloader::downloadCached(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expectedStorePath != "" && storePath != expectedStorePath) {
|
if (expectedStorePath != "" && storePath != expectedStorePath) {
|
||||||
|
unsigned int statusCode = 102;
|
||||||
Hash gotHash = request.unpack
|
Hash gotHash = request.unpack
|
||||||
? hashPath(request.expectedHash.type, store->toRealPath(storePath)).first
|
? hashPath(request.expectedHash.type, store->toRealPath(storePath)).first
|
||||||
: hashFile(request.expectedHash.type, store->toRealPath(storePath));
|
: hashFile(request.expectedHash.type, store->toRealPath(storePath));
|
||||||
throw nix::Error("hash mismatch in file downloaded from '%s':\n wanted: %s\n got: %s",
|
throw nix::Error(statusCode, "hash mismatch in file downloaded from '%s':\n wanted: %s\n got: %s",
|
||||||
url, request.expectedHash.to_string(), gotHash.to_string());
|
url, request.expectedHash.to_string(), gotHash.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,18 +86,25 @@ string storePathToHash(const Path & path)
|
||||||
void checkStoreName(const string & name)
|
void checkStoreName(const string & name)
|
||||||
{
|
{
|
||||||
string validChars = "+-._?=";
|
string validChars = "+-._?=";
|
||||||
|
|
||||||
|
auto baseError = format("The path name '%2%' is invalid: %3%. "
|
||||||
|
"Path names are alphanumeric and can include the symbols %1% "
|
||||||
|
"and must not begin with a period. "
|
||||||
|
"Note: If '%2%' is a source file and you cannot rename it on "
|
||||||
|
"disk, builtins.path { name = ... } can be used to give it an "
|
||||||
|
"alternative name.") % validChars % name;
|
||||||
|
|
||||||
/* Disallow names starting with a dot for possible security
|
/* Disallow names starting with a dot for possible security
|
||||||
reasons (e.g., "." and ".."). */
|
reasons (e.g., "." and ".."). */
|
||||||
if (string(name, 0, 1) == ".")
|
if (string(name, 0, 1) == ".")
|
||||||
throw Error(format("illegal name: '%1%'") % name);
|
throw Error(baseError % "it is illegal to start the name with a period");
|
||||||
for (auto & i : name)
|
for (auto & i : name)
|
||||||
if (!((i >= 'A' && i <= 'Z') ||
|
if (!((i >= 'A' && i <= 'Z') ||
|
||||||
(i >= 'a' && i <= 'z') ||
|
(i >= 'a' && i <= 'z') ||
|
||||||
(i >= '0' && i <= '9') ||
|
(i >= '0' && i <= '9') ||
|
||||||
validChars.find(i) != string::npos))
|
validChars.find(i) != string::npos))
|
||||||
{
|
{
|
||||||
throw Error(format("invalid character '%1%' in name '%2%'")
|
throw Error(baseError % (format("the '%1%' character is invalid") % i));
|
||||||
% i % name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,4 +6,4 @@ libutil_DIR := $(d)
|
||||||
|
|
||||||
libutil_SOURCES := $(wildcard $(d)/*.cc)
|
libutil_SOURCES := $(wildcard $(d)/*.cc)
|
||||||
|
|
||||||
libutil_LDFLAGS = $(LIBLZMA_LIBS) -lbz2 -pthread $(OPENSSL_LIBS) $(LIBBROTLI_LIBS) -lboost_context
|
libutil_LDFLAGS = $(LIBLZMA_LIBS) -lbz2 -pthread $(OPENSSL_LIBS) $(LIBBROTLI_LIBS) $(BOOST_LDFLAGS) -lboost_context
|
||||||
|
|
|
@ -17,7 +17,7 @@ nix_SOURCES := \
|
||||||
|
|
||||||
nix_LIBS = libexpr libmain libstore libutil
|
nix_LIBS = libexpr libmain libstore libutil
|
||||||
|
|
||||||
nix_LDFLAGS = -pthread $(SODIUM_LIBS) $(EDITLINE_LIBS)
|
nix_LDFLAGS = -pthread $(SODIUM_LIBS) $(EDITLINE_LIBS) $(BOOST_LDFLAGS) -lboost_context -lboost_thread -lboost_system
|
||||||
|
|
||||||
$(foreach name, \
|
$(foreach name, \
|
||||||
nix-build nix-channel nix-collect-garbage nix-copy-closure nix-daemon nix-env nix-hash nix-instantiate nix-prefetch-url nix-shell nix-store, \
|
nix-build nix-channel nix-collect-garbage nix-copy-closure nix-daemon nix-env nix-hash nix-instantiate nix-prefetch-url nix-shell nix-store, \
|
||||||
|
|
|
@ -39,8 +39,8 @@ static bool haveInternet()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (i->ifa_addr->sa_family == AF_INET6) {
|
} else if (i->ifa_addr->sa_family == AF_INET6) {
|
||||||
if (!IN6_IS_ADDR_LOOPBACK(((sockaddr_in6 *) i->ifa_addr)->sin6_addr.s6_addr) &&
|
if (!IN6_IS_ADDR_LOOPBACK(&((sockaddr_in6 *) i->ifa_addr)->sin6_addr) &&
|
||||||
!IN6_IS_ADDR_LINKLOCAL(((sockaddr_in6 *) i->ifa_addr)->sin6_addr.s6_addr))
|
!IN6_IS_ADDR_LINKLOCAL(&((sockaddr_in6 *) i->ifa_addr)->sin6_addr))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,14 @@
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
#include <readline/readline.h>
|
#include <readline/readline.h>
|
||||||
#else
|
#else
|
||||||
|
// editline < 1.15.2 don't wrap their API for C++ usage
|
||||||
|
// (added in https://github.com/troglobit/editline/commit/91398ceb3427b730995357e9d120539fb9bb7461).
|
||||||
|
// This results in linker errors due to to name-mangling of editline C symbols.
|
||||||
|
// For compatibility with these versions, we wrap the API here
|
||||||
|
// (wrapping multiple times on newer versions is no problem).
|
||||||
|
extern "C" {
|
||||||
#include <editline.h>
|
#include <editline.h>
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "shared.hh"
|
#include "shared.hh"
|
||||||
|
|
|
@ -10,6 +10,11 @@ with import ./config.nix;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
hashmismatch = import <nix/fetchurl.nix> {
|
||||||
|
url = "file://" + toString ./dummy;
|
||||||
|
sha256 = "0mdqa9w1p6cmli6976v4wi0sw9r4p5prkj7lzfd1877wk11c9c73";
|
||||||
|
};
|
||||||
|
|
||||||
fetchurl = import <nix/fetchurl.nix> {
|
fetchurl = import <nix/fetchurl.nix> {
|
||||||
url = "file://" + toString ./lang/eval-okay-xml.exp.xml;
|
url = "file://" + toString ./lang/eval-okay-xml.exp.xml;
|
||||||
sha256 = "0kg4sla7ihm8ijr8cb3117fhl99zrc2bwy1jrngsfmkh8bav4m0v";
|
sha256 = "0kg4sla7ihm8ijr8cb3117fhl99zrc2bwy1jrngsfmkh8bav4m0v";
|
||||||
|
|
|
@ -6,14 +6,16 @@ nix-build dependencies.nix --no-out-link
|
||||||
nix-build dependencies.nix --no-out-link --check
|
nix-build dependencies.nix --no-out-link --check
|
||||||
|
|
||||||
nix-build check.nix -A nondeterministic --no-out-link
|
nix-build check.nix -A nondeterministic --no-out-link
|
||||||
(! nix-build check.nix -A nondeterministic --no-out-link --check 2> $TEST_ROOT/log)
|
nix-build check.nix -A nondeterministic --no-out-link --check 2> $TEST_ROOT/log || status=$?
|
||||||
grep 'may not be deterministic' $TEST_ROOT/log
|
grep 'may not be deterministic' $TEST_ROOT/log
|
||||||
|
[ "$status" = "104" ]
|
||||||
|
|
||||||
clearStore
|
clearStore
|
||||||
|
|
||||||
nix-build dependencies.nix --no-out-link --repeat 3
|
nix-build dependencies.nix --no-out-link --repeat 3
|
||||||
|
|
||||||
(! nix-build check.nix -A nondeterministic --no-out-link --repeat 1 2> $TEST_ROOT/log)
|
nix-build check.nix -A nondeterministic --no-out-link --repeat 1 2> $TEST_ROOT/log || status=$?
|
||||||
|
[ "$status" = "1" ]
|
||||||
grep 'differs from previous round' $TEST_ROOT/log
|
grep 'differs from previous round' $TEST_ROOT/log
|
||||||
|
|
||||||
path=$(nix-build check.nix -A fetchurl --no-out-link --hashed-mirrors '')
|
path=$(nix-build check.nix -A fetchurl --no-out-link --hashed-mirrors '')
|
||||||
|
@ -23,10 +25,23 @@ echo foo > $path
|
||||||
chmod -w $path
|
chmod -w $path
|
||||||
|
|
||||||
nix-build check.nix -A fetchurl --no-out-link --check --hashed-mirrors ''
|
nix-build check.nix -A fetchurl --no-out-link --check --hashed-mirrors ''
|
||||||
|
|
||||||
# Note: "check" doesn't repair anything, it just compares to the hash stored in the database.
|
# Note: "check" doesn't repair anything, it just compares to the hash stored in the database.
|
||||||
[[ $(cat $path) = foo ]]
|
[[ $(cat $path) = foo ]]
|
||||||
|
|
||||||
nix-build check.nix -A fetchurl --no-out-link --repair --hashed-mirrors ''
|
nix-build check.nix -A fetchurl --no-out-link --repair --hashed-mirrors ''
|
||||||
|
|
||||||
[[ $(cat $path) != foo ]]
|
[[ $(cat $path) != foo ]]
|
||||||
|
|
||||||
|
nix-build check.nix -A hashmismatch --no-out-link --hashed-mirrors '' || status=$?
|
||||||
|
[ "$status" = "102" ]
|
||||||
|
|
||||||
|
echo -n > ./dummy
|
||||||
|
nix-build check.nix -A hashmismatch --no-out-link --hashed-mirrors ''
|
||||||
|
echo 'Hello World' > ./dummy
|
||||||
|
|
||||||
|
nix-build check.nix -A hashmismatch --no-out-link --check --hashed-mirrors '' || status=$?
|
||||||
|
[ "$status" = "102" ]
|
||||||
|
|
||||||
|
# Multiple failures with --keep-going
|
||||||
|
nix-build check.nix -A nondeterministic --no-out-link
|
||||||
|
nix-build check.nix -A nondeterministic -A hashmismatch --no-out-link --check --keep-going --hashed-mirrors '' || status=$?
|
||||||
|
[ "$status" = "110" ]
|
||||||
|
|
|
@ -2,10 +2,14 @@
|
||||||
|
|
||||||
source common.sh
|
source common.sh
|
||||||
|
|
||||||
failed=0
|
|
||||||
messages="`nix-build -Q timeout.nix -A infiniteLoop --timeout 2 2>&1 || failed=1`"
|
set +e
|
||||||
if [ $failed -ne 0 ]; then
|
messages=$(nix-build -Q timeout.nix -A infiniteLoop --timeout 2 2>&1)
|
||||||
echo "error: 'nix-store' succeeded; should have timed out"
|
status=$?
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ $status -ne 101 ]; then
|
||||||
|
echo "error: 'nix-store' exited with '$status'; should have exited 101"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue