diff --git a/.azure-pipelines/azure-pipelines-osx.yml b/.azure-pipelines/azure-pipelines-osx.yml index 84d4f42..8032e96 100755 --- a/.azure-pipelines/azure-pipelines-osx.yml +++ b/.azure-pipelines/azure-pipelines-osx.yml @@ -5,7 +5,7 @@ jobs: - job: osx pool: - vmImage: macOS-10.15 + vmImage: macOS-11 strategy: matrix: osx_64_: diff --git a/.azure-pipelines/azure-pipelines-win.yml b/.azure-pipelines/azure-pipelines-win.yml index 88fd9c1..a192c0b 100755 --- a/.azure-pipelines/azure-pipelines-win.yml +++ b/.azure-pipelines/azure-pipelines-win.yml @@ -14,47 +14,30 @@ jobs: timeoutInMinutes: 360 variables: CONDA_BLD_PATH: D:\\bld\\ + UPLOAD_TEMP: D:\\tmp steps: - - script: | - choco install vcpython27 -fdv -y --debug - condition: contains(variables['CONFIG'], 'vs2008') - displayName: Install vcpython27.msi (if needed) - - # Cygwin's git breaks conda-build. (See https://github.com/conda-forge/conda-smithy-feedstock/pull/2.) - # - script: rmdir C:\cygwin /s /q - # continueOnError: true - - - powershell: | - Set-PSDebug -Trace 1 - - $batchcontent = @" - ECHO ON - SET vcpython=C:\Program Files (x86)\Common Files\Microsoft\Visual C++ for Python\9.0 - - DIR "%vcpython%" - - CALL "%vcpython%\vcvarsall.bat" %* - "@ - - $batchDir = "C:\Program Files (x86)\Common Files\Microsoft\Visual C++ for Python\9.0\VC" - $batchPath = "$batchDir" + "\vcvarsall.bat" - New-Item -Path $batchPath -ItemType "file" -Force - - Set-Content -Value $batchcontent -Path $batchPath + - task: PythonScript@0 + displayName: 'Download Miniforge' + inputs: + scriptSource: inline + script: | + import urllib.request + url = 'https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Windows-x86_64.exe' + path = r"$(Build.ArtifactStagingDirectory)/Miniforge.exe" + urllib.request.urlretrieve(url, path) - Get-ChildItem -Path $batchDir + - script: | + start /wait "" %BUILD_ARTIFACTSTAGINGDIRECTORY%\Miniforge.exe /InstallationType=JustMe /RegisterPython=0 /S /D=C:\Miniforge + displayName: Install Miniforge - Get-ChildItem -Path ($batchDir + '\..') + - powershell: Write-Host "##vso[task.prependpath]C:\Miniforge\Scripts" + displayName: Add conda to PATH - condition: contains(variables['CONFIG'], 'vs2008') - displayName: Patch vs2008 (if needed) - - task: CondaEnvironment@1 - inputs: - packageSpecs: 'python=3.9 conda-build conda pip boa conda-forge-ci-setup=3' # Optional - installOptions: "-c conda-forge" - updateConda: true - displayName: Install conda-build and activate environment + - script: | + call activate base + mamba.exe install "python=3.9" conda-build conda pip boa conda-forge-ci-setup=3 "py-lief<0.12" -c conda-forge --strict-channel-priority --yes + displayName: Install conda-build - script: set PYTHONUNBUFFERED=1 displayName: Set PYTHONUNBUFFERED @@ -71,25 +54,16 @@ jobs: call activate base run_conda_forge_build_setup displayName: conda-forge build setup - - - # Special cased version setting some more things! - - script: | - call activate base - conda.exe build "recipe" -m .ci_support\%CONFIG%.yaml - displayName: Build recipe (vs2008) - env: - VS90COMNTOOLS: "C:\\Program Files (x86)\\Common Files\\Microsoft\\Visual C++ for Python\\9.0\\VC\\bin" - PYTHONUNBUFFERED: 1 - condition: contains(variables['CONFIG'], 'vs2008') - script: | call activate base + if EXIST LICENSE.txt ( + copy LICENSE.txt "recipe\\recipe-scripts-license.txt" + ) conda.exe mambabuild "recipe" -m .ci_support\%CONFIG%.yaml --suppress-variables displayName: Build recipe env: PYTHONUNBUFFERED: 1 - condition: not(contains(variables['CONFIG'], 'vs2008')) - script: | set "FEEDSTOCK_NAME=%BUILD_REPOSITORY_NAME:*/=%" call activate base @@ -99,6 +73,9 @@ jobs: - script: | set "GIT_BRANCH=%BUILD_SOURCEBRANCHNAME%" set "FEEDSTOCK_NAME=%BUILD_REPOSITORY_NAME:*/=%" + set "TEMP=$(UPLOAD_TEMP)" + if not exist "%TEMP%\" md "%TEMP%" + set "TMP=%TEMP%" call activate base upload_package --validate --feedstock-name="%FEEDSTOCK_NAME%" .\ ".\recipe" .ci_support\%CONFIG%.yaml displayName: Upload package diff --git a/.ci_support/README b/.ci_support/README index 69c5db6..a47316b 100644 --- a/.ci_support/README +++ b/.ci_support/README @@ -1,6 +1,6 @@ -This file is automatically generated by conda-smithy. If any -particular build configuration is expected, but it is not found, -please make sure all dependencies are satisfiable. To add/modify any -matrix elements, you should create/change conda-smithy's input -recipe/conda_build_config.yaml and re-render the recipe, rather than -editing these files directly. +This file is automatically generated by conda-smithy. If any +particular build configuration is expected, but it is not found, +please make sure all dependencies are satisfiable. To add/modify any +matrix elements, you should create/change conda-smithy's input +recipe/conda_build_config.yaml and re-render the recipe, rather than +editing these files directly. diff --git a/.ci_support/linux_64_.yaml b/.ci_support/linux_64_.yaml index 1ce5c9b..6791666 100644 --- a/.ci_support/linux_64_.yaml +++ b/.ci_support/linux_64_.yaml @@ -1,7 +1,7 @@ c_compiler: - gcc c_compiler_version: -- '10' +- '11' cdt_name: - cos6 channel_sources: @@ -11,16 +11,11 @@ channel_targets: cxx_compiler: - gxx cxx_compiler_version: -- '10' +- '11' docker_image: - quay.io/condaforge/linux-anvil-cos7-x86_64 -pin_run_as_build: - zlib: - max_pin: x.x target_platform: - linux-64 -vc: -- '14' zip_keys: - - c_compiler_version - cxx_compiler_version diff --git a/.ci_support/linux_aarch64_.yaml b/.ci_support/linux_aarch64_.yaml index 3ca69f7..055512c 100644 --- a/.ci_support/linux_aarch64_.yaml +++ b/.ci_support/linux_aarch64_.yaml @@ -3,7 +3,7 @@ BUILD: c_compiler: - gcc c_compiler_version: -- '10' +- '11' cdt_arch: - aarch64 cdt_name: @@ -15,16 +15,11 @@ channel_targets: cxx_compiler: - gxx cxx_compiler_version: -- '10' +- '11' docker_image: - quay.io/condaforge/linux-anvil-aarch64 -pin_run_as_build: - zlib: - max_pin: x.x target_platform: - linux-aarch64 -vc: -- '14' zip_keys: - - c_compiler_version - cxx_compiler_version diff --git a/.ci_support/linux_ppc64le_.yaml b/.ci_support/linux_ppc64le_.yaml index 23568a5..0139e5f 100644 --- a/.ci_support/linux_ppc64le_.yaml +++ b/.ci_support/linux_ppc64le_.yaml @@ -1,7 +1,7 @@ c_compiler: - gcc c_compiler_version: -- '10' +- '11' cdt_name: - cos7 channel_sources: @@ -11,16 +11,11 @@ channel_targets: cxx_compiler: - gxx cxx_compiler_version: -- '10' +- '11' docker_image: - quay.io/condaforge/linux-anvil-ppc64le -pin_run_as_build: - zlib: - max_pin: x.x target_platform: - linux-ppc64le -vc: -- '14' zip_keys: - - c_compiler_version - cxx_compiler_version diff --git a/.ci_support/osx_64_.yaml b/.ci_support/osx_64_.yaml index 9687e3f..c1e1ed7 100644 --- a/.ci_support/osx_64_.yaml +++ b/.ci_support/osx_64_.yaml @@ -14,13 +14,8 @@ cxx_compiler_version: - '*' macos_machine: - x86_64-apple-darwin13.4.0 -pin_run_as_build: - zlib: - max_pin: x.x target_platform: - osx-64 -vc: -- '14' zip_keys: - - c_compiler_version - cxx_compiler_version diff --git a/.ci_support/osx_arm64_.yaml b/.ci_support/osx_arm64_.yaml index 3a30ab0..f207b62 100644 --- a/.ci_support/osx_arm64_.yaml +++ b/.ci_support/osx_arm64_.yaml @@ -14,13 +14,8 @@ cxx_compiler_version: - '*' macos_machine: - arm64-apple-darwin20.0.0 -pin_run_as_build: - zlib: - max_pin: x.x target_platform: - osx-arm64 -vc: -- '14' zip_keys: - - c_compiler_version - cxx_compiler_version diff --git a/.ci_support/win_64_.yaml b/.ci_support/win_64_.yaml index d240aaf..48fcb8b 100644 --- a/.ci_support/win_64_.yaml +++ b/.ci_support/win_64_.yaml @@ -7,12 +7,7 @@ channel_targets: cxx_compiler: - vs2019 libxml2: -- '2.9' -pin_run_as_build: - libxml2: - max_pin: x.x - zlib: - max_pin: x.x +- '2.10' target_platform: - win-64 vc: diff --git a/.circleci/config.yml b/.circleci/config.yml index 6ad461b..8b4ef2f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,13 +1,14 @@ # This file was generated automatically from conda-smithy. To update this configuration, # update the conda-forge.yml and/or the recipe/meta.yaml. -# -*- mode: yaml -*- +# -*- mode: jinja-yaml -*- version: 2 jobs: build: working_directory: ~/test - machine: true + machine: + image: ubuntu-2004:current steps: - run: # The Circle-CI build should not be active, but if this is not true for some reason, do a fast finish. diff --git a/.github/workflows/webservices.yml b/.github/workflows/webservices.yml index 2e5fe71..d6f06b5 100644 --- a/.github/workflows/webservices.yml +++ b/.github/workflows/webservices.yml @@ -7,7 +7,7 @@ jobs: steps: - name: webservices id: webservices - uses: conda-forge/webservices-dispatch-action@master + uses: conda-forge/webservices-dispatch-action@main with: github_token: ${{ secrets.GITHUB_TOKEN }} rerendering_github_token: ${{ secrets.RERENDERING_GITHUB_TOKEN }} diff --git a/.scripts/build_steps.sh b/.scripts/build_steps.sh index c6b23e8..84431a6 100755 --- a/.scripts/build_steps.sh +++ b/.scripts/build_steps.sh @@ -24,15 +24,18 @@ export CONFIG_FILE="${CI_SUPPORT}/${CONFIG}.yaml" cat >~/.condarc < /dev/null +if [[ -f "${FEEDSTOCK_ROOT}/LICENSE.txt" ]]; then + cp "${FEEDSTOCK_ROOT}/LICENSE.txt" "${RECIPE_ROOT}/recipe-scripts-license.txt" +fi + if [[ "${BUILD_WITH_CONDA_DEBUG:-0}" == 1 ]]; then if [[ "x${BUILD_OUTPUT_ID:-}" != "x" ]]; then EXTRA_CB_OPTIONS="${EXTRA_CB_OPTIONS:-} --output-id ${BUILD_OUTPUT_ID}" diff --git a/.scripts/run_osx_build.sh b/.scripts/run_osx_build.sh index 3d85505..b3abaeb 100755 --- a/.scripts/run_osx_build.sh +++ b/.scripts/run_osx_build.sh @@ -23,11 +23,10 @@ bash $MINIFORGE_FILE -b -p ${MINIFORGE_HOME} source ${MINIFORGE_HOME}/etc/profile.d/conda.sh conda activate base -echo -e "\n\nInstalling ['conda-forge-ci-setup=3'] and conda-build." mamba install --update-specs --quiet --yes --channel conda-forge \ - conda-build pip boa conda-forge-ci-setup=3 + conda-build pip boa conda-forge-ci-setup=3 "py-lief<0.12" mamba update --update-specs --yes --quiet --channel conda-forge \ - conda-build pip boa conda-forge-ci-setup=3 + conda-build pip boa conda-forge-ci-setup=3 "py-lief<0.12" @@ -61,6 +60,10 @@ if [[ "${HOST_PLATFORM}" != "${BUILD_PLATFORM}" ]]; then fi +if [[ -f LICENSE.txt ]]; then + cp LICENSE.txt "recipe/recipe-scripts-license.txt" +fi + if [[ "${BUILD_WITH_CONDA_DEBUG:-0}" == 1 ]]; then if [[ "x${BUILD_OUTPUT_ID:-}" != "x" ]]; then EXTRA_CB_OPTIONS="${EXTRA_CB_OPTIONS:-} --output-id ${BUILD_OUTPUT_ID}" diff --git a/LICENSE.txt b/LICENSE.txt index 6ec1401..2ec51d7 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,13 +1,27 @@ -BSD 3-clause license +BSD-3-Clause license Copyright (c) 2015-2022, conda-forge contributors All rights reserved. -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. diff --git a/README.md b/README.md index 0cdffc7..55decc7 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ About lld Home: https://lld.llvm.org/ -Package license: NCSA +Package license: Apache-2.0 WITH LLVM-exception -Feedstock license: [BSD-3-Clause](https://github.com/conda-forge/lld-feedstock/blob/master/LICENSE.txt) +Feedstock license: [BSD-3-Clause](https://github.com/conda-forge/lld-feedstock/blob/main/LICENSE.txt) Summary: The LLVM Linker @@ -22,8 +22,8 @@ Current build status
- - + + @@ -31,43 +31,43 @@ Current build status @@ -95,18 +95,43 @@ conda config --add channels conda-forge conda config --set channel_priority strict ``` -Once the `conda-forge` channel has been enabled, `lld` can be installed with: +Once the `conda-forge` channel has been enabled, `lld` can be installed with `conda`: ``` conda install lld ``` -It is possible to list all of the versions of `lld` available on your platform with: +or with `mamba`: + +``` +mamba install lld +``` + +It is possible to list all of the versions of `lld` available on your platform with `conda`: ``` conda search lld --channel conda-forge ``` +or with `mamba`: + +``` +mamba search lld --channel conda-forge +``` + +Alternatively, `mamba repoquery` may provide more information: + +``` +# Search all versions available on your platform: +mamba repoquery search lld --channel conda-forge + +# List packages depending on `lld`: +mamba repoquery whoneeds lld --channel conda-forge + +# List dependencies of `lld`: +mamba repoquery depends lld --channel conda-forge +``` + About conda-forge ================= @@ -122,10 +147,12 @@ for each of the installable packages. Such a repository is known as a *feedstock A feedstock is made up of a conda recipe (the instructions on what and how to build the package) and the necessary configurations for automatic building using freely available continuous integration services. Thanks to the awesome service provided by -[CircleCI](https://circleci.com/), [AppVeyor](https://www.appveyor.com/) -and [TravisCI](https://travis-ci.com/) it is possible to build and upload installable -packages to the [conda-forge](https://anaconda.org/conda-forge) -[Anaconda-Cloud](https://anaconda.org/) channel for Linux, Windows and OSX respectively. +[Azure](https://azure.microsoft.com/en-us/services/devops/), [GitHub](https://github.com/), +[CircleCI](https://circleci.com/), [AppVeyor](https://www.appveyor.com/), +[Drone](https://cloud.drone.io/welcome), and [TravisCI](https://travis-ci.com/) +it is possible to build and upload installable packages to the +[conda-forge](https://anaconda.org/conda-forge) [Anaconda-Cloud](https://anaconda.org/) +channel for Linux, Windows and OSX respectively. To manage the continuous integration and simplify feedstock maintenance [conda-smithy](https://github.com/conda-forge/conda-smithy) has been developed. diff --git a/build-locally.py b/build-locally.py index eec38a0..3f4b7a7 100755 --- a/build-locally.py +++ b/build-locally.py @@ -86,12 +86,19 @@ def main(args=None): verify_config(ns) setup_environment(ns) - if ns.config.startswith("linux") or ( - ns.config.startswith("osx") and platform.system() == "Linux" - ): - run_docker_build(ns) - elif ns.config.startswith("osx"): - run_osx_build(ns) + try: + if ns.config.startswith("linux") or ( + ns.config.startswith("osx") and platform.system() == "Linux" + ): + run_docker_build(ns) + elif ns.config.startswith("osx"): + run_osx_build(ns) + finally: + recipe_license_file = os.path.join( + "recipe", "recipe-scripts-license.txt" + ) + if os.path.exists(recipe_license_file): + os.remove(recipe_license_file) if __name__ == "__main__": diff --git a/conda-forge.yml b/conda-forge.yml index 6ee8929..51c3956 100644 --- a/conda-forge.yml +++ b/conda-forge.yml @@ -3,5 +3,8 @@ channel_priority: flexible conda_forge_output_validation: true provider: {linux_aarch64: azure, linux_ppc64le: azure} test_on_native_only: true +github: + branch_name: main + tooling_branch_name: main conda_build: pkg_format: '2' diff --git a/recipe/conda_build_config.yaml b/recipe/conda_build_config.yaml index 23a59c8..3468563 100644 --- a/recipe/conda_build_config.yaml +++ b/recipe/conda_build_config.yaml @@ -1,13 +1,10 @@ -c_compiler: +c_compiler: # [unix] - clang_bootstrap # [osx] - gcc # [linux] - - vs2019 # [win] -cxx_compiler: +cxx_compiler: # [unix] - clang_bootstrap # [osx] - gxx # [linux] - - vs2019 # [win] -vc: - - 14 + c_compiler_version: # [osx] - "*" # [osx] cxx_compiler_version: # [osx] diff --git a/recipe/meta.yaml b/recipe/meta.yaml index 48696c5..b3b5245 100644 --- a/recipe/meta.yaml +++ b/recipe/meta.yaml @@ -1,4 +1,4 @@ -{% set version = "14.0.0.rc4" %} +{% set version = "16.0.0.rc1" %} package: name: lld @@ -6,13 +6,12 @@ package: source: url: https://github.com/llvm/llvm-project/releases/download/llvmorg-{{ version.replace(".rc", "-rc") }}/llvm-project-{{ version.replace(".rc", "rc") }}.src.tar.xz - sha256: ca833d5ca97b2d46053f6d2759fcd9ec3201201275e0c2119a4680356f5b0a15 + sha256: 8399db003b223ce33e3d7a5ee9df8dc3574cedffa5d9be4783660643f8402900 patches: - patches/0001-point-header-inclusion-in-lld-MachO-CMakeLists.txt-t.patch build: number: 0 - skip: true # [win and vc<14] requirements: build: @@ -37,7 +36,7 @@ test: about: home: https://lld.llvm.org/ - license: NCSA + license: Apache-2.0 WITH LLVM-exception license_file: lld/LICENSE.TXT summary: The LLVM Linker dev_url: https://github.com/llvm/llvm-project/ diff --git a/recipe/patches/0001-point-header-inclusion-in-lld-MachO-CMakeLists.txt-t.patch b/recipe/patches/0001-point-header-inclusion-in-lld-MachO-CMakeLists.txt-t.patch index 02a3eab..46d729f 100644 --- a/recipe/patches/0001-point-header-inclusion-in-lld-MachO-CMakeLists.txt-t.patch +++ b/recipe/patches/0001-point-header-inclusion-in-lld-MachO-CMakeLists.txt-t.patch @@ -1,4 +1,4 @@ -From e5e986303e9b7d19483c1e1b3493122958dbeeee Mon Sep 17 00:00:00 2001 +From 14d6c677c1758066f1ef10635439754cc3161057 Mon Sep 17 00:00:00 2001 From: "H. Vetinari" Date: Wed, 14 Jul 2021 21:53:53 +0200 Subject: [PATCH] point header inclusion in lld/MachO/CMakeLists.txt to SRC_DIR @@ -8,7 +8,7 @@ Subject: [PATCH] point header inclusion in lld/MachO/CMakeLists.txt to SRC_DIR 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lld/MachO/CMakeLists.txt b/lld/MachO/CMakeLists.txt -index 4bd0816bca66..de31c47d38a8 100644 +index ea26889267..3e06eb78fc 100644 --- a/lld/MachO/CMakeLists.txt +++ b/lld/MachO/CMakeLists.txt @@ -2,7 +2,7 @@ set(LLVM_TARGET_DEFINITIONS Options.td) @@ -21,5 +21,5 @@ index 4bd0816bca66..de31c47d38a8 100644 add_lld_library(lldMachO Arch/ARM.cpp -- -2.32.0.windows.2 +2.38.1.windows.1
linux_64 - - variant + + variant
linux_aarch64 - - variant + + variant
linux_ppc64le - - variant + + variant
osx_64 - - variant + + variant
osx_arm64 - - variant + + variant
win_64 - - variant + + variant