aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.coveragerc50
-rw-r--r--.github/workflows/cygwin.yml7
-rw-r--r--.github/workflows/macos.yml13
-rw-r--r--.github/workflows/msys2.yml7
-rw-r--r--.github/workflows/nonative.yml5
-rw-r--r--.github/workflows/os_comp.yml9
-rw-r--r--.github/workflows/unusedargs_missingreturn.yml12
-rw-r--r--.gitignore3
-rw-r--r--azure-pipelines.yml1
-rw-r--r--ci/run.ps119
-rwxr-xr-xci/upload_cov.sh13
-rw-r--r--ci/usercustomize.py19
-rw-r--r--data/.coveragerc.in25
-rw-r--r--docs/markdown/Builtin-options.md2
-rw-r--r--docs/markdown/Reference-manual.md19
-rw-r--r--docs/markdown/snippets/build-target-found.md16
-rw-r--r--docs/markdown/snippets/compiler_argument_checking.md6
-rw-r--r--docs/markdown/snippets/newvsbackends.md15
-rw-r--r--mesonbuild/backend/backends.py6
-rw-r--r--mesonbuild/backend/vs2010backend.py40
-rw-r--r--mesonbuild/backend/vs2012backend.py38
-rw-r--r--mesonbuild/backend/vs2013backend.py38
-rw-r--r--mesonbuild/build.py10
-rw-r--r--mesonbuild/cmake/common.py4
-rw-r--r--mesonbuild/cmake/interpreter.py4
-rw-r--r--mesonbuild/compilers/compilers.py2
-rw-r--r--mesonbuild/coredata.py2
-rw-r--r--mesonbuild/interpreter/compiler.py20
-rw-r--r--mesonbuild/interpreter/interpreter.py2
-rw-r--r--mesonbuild/interpreter/interpreterobjects.py25
-rw-r--r--mesonbuild/interpreterbase/baseobjects.py2
-rwxr-xr-xrun_project_tests.py7
-rwxr-xr-xrun_tests.py78
-rwxr-xr-xrun_unittests.py7
-rw-r--r--test cases/cmake/25 assembler/main.c18
-rw-r--r--test cases/cmake/25 assembler/meson.build9
-rw-r--r--test cases/cmake/25 assembler/subprojects/cmTest/CMakeLists.txt45
-rw-r--r--test cases/cmake/25 assembler/subprojects/cmTest/cmTest.c8
-rw-r--r--test cases/cmake/25 assembler/subprojects/cmTest/cmTestAsm.s4
-rw-r--r--test cases/common/137 whole archive/meson.build11
-rw-r--r--test cases/common/182 find override/meson.build10
-rw-r--r--test cases/common/182 find override/otherdir/meson.build4
-rw-r--r--test cases/common/22 object extraction/check-obj.py21
-rw-r--r--test cases/common/22 object extraction/header.h1
-rw-r--r--test cases/common/22 object extraction/meson.build14
-rw-r--r--test cases/failing/115 compiler argument checking/meson.build4
-rw-r--r--test cases/failing/115 compiler argument checking/test.json7
-rwxr-xr-xtools/run_with_cov.py53
48 files changed, 579 insertions, 156 deletions
diff --git a/.coveragerc b/.coveragerc
deleted file mode 100644
index c3d41d4..0000000
--- a/.coveragerc
+++ /dev/null
@@ -1,50 +0,0 @@
-[run]
-branch = True
-concurrency =
- multiprocessing
-data_file = .coverage/coverage
-parallel = True
-source =
- meson.py
- mesonbuild/
- mesonconf.py
- mesonintrospect.py
- mesonrewriter.py
- mesontest.py
- run_cross_test.py
- run_project_tests.py
- run_tests.py
- run_unittests.py
-
-# Aliases to /root/ are needed because Travis runs in docker at /root/.
-[paths]
-meson =
- meson.py
- /root/meson.py
-mesonbuild =
- mesonbuild/
- /root/mesonbuild/
-mesonconf =
- mesonconf.py
- /root/mesonconf.py
-mesonintrospect =
- mesonintrospect.py
- /root/mesonintrospect.py
-mesonrewriter =
- mesonrewriter.py
- /root/mesonrewriter.py
-mesontest =
- mesontest.py
- /root/mesontest.py
-run_cross_test =
- run_cross_test.py
- /root/run_cross_test.py
-run_project_tests =
- run_project_tests.py
- /root/run_project_tests.py
-run_tests =
- run_tests.py
- /root/run_tests.py
-run_unittests =
- run_unittests.py
- /root/run_unittests.py
diff --git a/.github/workflows/cygwin.yml b/.github/workflows/cygwin.yml
index 32d33d8..3954094 100644
--- a/.github/workflows/cygwin.yml
+++ b/.github/workflows/cygwin.yml
@@ -68,13 +68,13 @@ jobs:
- name: Run pip
run: |
export PATH=/usr/bin:/usr/local/bin:$(cygpath ${SYSTEMROOT})/system32
- python3 -m pip --disable-pip-version-check install gcovr jsonschema pefile pytest pytest-xdist
+ python3 -m pip --disable-pip-version-check install gcovr jsonschema pefile pytest pytest-xdist coverage codecov
shell: C:\cygwin\bin\bash.exe --noprofile --norc -o igncr -eo pipefail '{0}'
- name: Run tests
run: |
export PATH=/usr/bin:/usr/local/bin:$(cygpath ${SYSTEMROOT})/system32
- python3 run_tests.py --backend=ninja
+ python3 ./tools/run_with_cov.py run_tests.py --backend=ninja
env:
# Cygwin's static boost installation is broken (some static library
# variants such as boost_thread are not present)
@@ -87,3 +87,6 @@ jobs:
path: meson-test-run.*
# test log should be saved on failure
if: ${{ !cancelled() }}
+
+ - name: Upload coverage report
+ run: ./ci/upload_cov.sh "${{ matrix.NAME }}"
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index faff3ae..c7ef7d3 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -24,7 +24,7 @@ jobs:
python-version: '3.x'
- run: |
python -m pip install --upgrade pip
- python -m pip install pytest pytest-xdist jsonschema
+ python -m pip install pytest pytest-xdist jsonschema coverage codecov
- run: brew install pkg-config ninja llvm qt@5
- env:
CPPFLAGS: "-I/usr/local/include"
@@ -35,7 +35,10 @@ jobs:
export SDKROOT="$(xcodebuild -version -sdk macosx Path)"
export PATH="$HOME/tools:/usr/local/opt/qt@5/bin:$PATH:$(brew --prefix llvm)/bin"
export PKG_CONFIG_PATH="/usr/local/opt/qt@5/lib/pkgconfig:$PKG_CONFIG_PATH"
- ./run_unittests.py
+ ./tools/run_with_cov.py ./run_unittests.py
+ - name: Upload coverage report
+ run: ./ci/upload_cov.sh "appleclang [unit tests]"
+
project-tests-appleclang:
runs-on: macos-latest
@@ -50,7 +53,7 @@ jobs:
- run: |
python3 -m pip install --upgrade setuptools
python3 -m pip install --upgrade pip
- python3 -m pip install cython
+ python3 -m pip install cython coverage codecov
- env:
CPPFLAGS: "-I/usr/local/include"
LDFLAGS: "-L/usr/local/lib"
@@ -61,7 +64,9 @@ jobs:
export SDKROOT="$(xcodebuild -version -sdk macosx Path)"
export PATH="$HOME/tools:/usr/local/opt/qt@5/bin:$PATH:$(brew --prefix llvm)/bin"
export PKG_CONFIG_PATH="/usr/local/opt/qt@5/lib/pkgconfig:$PKG_CONFIG_PATH"
- ./run_project_tests.py --backend=ninja
+ ./tools/run_with_cov.py ./run_project_tests.py --backend=ninja
+ - name: Upload coverage report
+ run: ./ci/upload_cov.sh "appleclang [project tests; unity=${{ matrix.unity }}]"
Qt4macos:
runs-on: macos-latest
diff --git a/.github/workflows/msys2.yml b/.github/workflows/msys2.yml
index cbab904..64a0979 100644
--- a/.github/workflows/msys2.yml
+++ b/.github/workflows/msys2.yml
@@ -71,7 +71,7 @@ jobs:
- name: Install dependencies
run: |
- python3 -m pip --disable-pip-version-check install gcovr jsonschema pefile pytest pytest-xdist
+ python3 -m pip --disable-pip-version-check install gcovr jsonschema pefile pytest pytest-xdist coverage codecov
- name: Run Tests
run: |
@@ -89,9 +89,12 @@ jobs:
pacman --noconfirm --needed -S mingw-w64-${{ matrix.MSYS2_ARCH }}-${{ matrix.MSYS2_CURSES }}
fi
- MSYSTEM= python3 run_tests.py --backend=ninja
+ MSYSTEM= python3 ./tools/run_with_cov.py run_tests.py --backend=ninja
- uses: actions/upload-artifact@v2
with:
name: ${{ matrix.NAME }}
path: meson-test-run.*
+
+ - name: Upload coverage report
+ run: ./ci/upload_cov.sh "${{ matrix.NAME }}"
diff --git a/.github/workflows/nonative.yml b/.github/workflows/nonative.yml
index 1fc43b4..c4bad95 100644
--- a/.github/workflows/nonative.yml
+++ b/.github/workflows/nonative.yml
@@ -26,6 +26,9 @@ jobs:
- run: |
apt-get -y purge clang gcc gdc
apt-get -y autoremove
+ python3 -m pip install coverage codecov
- uses: actions/checkout@v2
- name: Run tests
- run: bash -c 'source /ci/env_vars.sh; cd $GITHUB_WORKSPACE; ./run_tests.py $CI_ARGS --cross ubuntu-armhf.json --cross-only'
+ run: bash -c 'source /ci/env_vars.sh; cd $GITHUB_WORKSPACE; ./tools/run_with_cov.py ./run_tests.py $CI_ARGS --cross ubuntu-armhf.json --cross-only'
+ - name: Upload coverage report
+ run: ./ci/upload_cov.sh "Ubuntu nonnative"
diff --git a/.github/workflows/os_comp.yml b/.github/workflows/os_comp.yml
index 5b49142..94d1b01 100644
--- a/.github/workflows/os_comp.yml
+++ b/.github/workflows/os_comp.yml
@@ -40,7 +40,9 @@ jobs:
# All environment variables are stored inside the docker image in /ci/env_vars.sh
# They are defined in the `env` section in each image.json. CI_ARGS should be set
# via the `args` array ub the image.json
- run: bash -c 'source /ci/env_vars.sh; cd $GITHUB_WORKSPACE; ./run_tests.py $CI_ARGS'
+ run: bash -c 'source /ci/env_vars.sh; cd $GITHUB_WORKSPACE; ./tools/run_with_cov.py ./run_tests.py $CI_ARGS'
+ - name: Upload coverage report
+ run: ./ci/upload_cov.sh "OS Comp [${{ matrix.cfg.name }}]"
ubuntu-rolling:
name: 'Ubuntu Rolling'
@@ -106,4 +108,7 @@ jobs:
update-alternatives --set i686-w64-mingw32-gcc /usr/bin/i686-w64-mingw32-gcc-posix
update-alternatives --set i686-w64-mingw32-g++ /usr/bin/i686-w64-mingw32-g++-posix
- ./run_tests.py $RUN_TESTS_ARGS -- $MESON_ARGS
+ ./tools/run_with_cov.py ./run_tests.py $RUN_TESTS_ARGS -- $MESON_ARGS
+
+ - name: Upload coverage report
+ run: ./ci/upload_cov.sh "Ubuntu [${{ matrix.cfg.CC }} ${{ matrix.cfg.RUN_TESTS_ARGS }} ${{ matrix.cfg.MESON_ARGS }}]"
diff --git a/.github/workflows/unusedargs_missingreturn.yml b/.github/workflows/unusedargs_missingreturn.yml
index 3e82568..8e6e42d 100644
--- a/.github/workflows/unusedargs_missingreturn.yml
+++ b/.github/workflows/unusedargs_missingreturn.yml
@@ -45,7 +45,10 @@ jobs:
run: |
sudo apt update -yq
sudo apt install -yq --no-install-recommends g++ gfortran ninja-build gobjc gobjc++
- - run: python run_project_tests.py --only cmake common fortran platform-linux "objective c" "objective c++"
+ python -m pip install coverage codecov
+ - run: ./tools/run_with_cov.py run_project_tests.py --only cmake common fortran platform-linux "objective c" "objective c++"
+ - name: Upload coverage report
+ run: ./ci/upload_cov.sh "UnusedMissingReturn"
windows:
runs-on: windows-latest
@@ -55,10 +58,13 @@ jobs:
with:
python-version: '3.x'
- - run: pip install ninja pefile
+ - run: pip install ninja pefile coverage codecov
- - run: python run_project_tests.py --only platform-windows
+ - run: python ./tools/run_with_cov.py run_project_tests.py --only platform-windows
env:
CC: gcc
CXX: g++
FC: gfortran
+
+ - name: Upload coverage report
+ run: ./ci/upload_cov.sh "UnusedMissingReturn Windows"
diff --git a/.gitignore b/.gitignore
index fea337e..8ff5e78 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,7 +8,8 @@
/.vscode
__pycache__
-.coverage
+/.coverage/
+/.coveragerc
/install dir
/work area
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 14ff1bd..614f344 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -9,6 +9,7 @@ trigger:
variables:
CI: 1
+ SOURCE_VERSION: $(Build.SourceVersion)
jobs:
diff --git a/ci/run.ps1 b/ci/run.ps1
index 424af72..961c423 100644
--- a/ci/run.ps1
+++ b/ci/run.ps1
@@ -68,11 +68,26 @@ python --version
# Needed for running unit tests in parallel.
echo ""
-python -m pip --disable-pip-version-check install --upgrade pefile pytest-xdist jsonschema
+python -m pip --disable-pip-version-check install --upgrade pefile pytest-xdist jsonschema coverage
echo ""
echo "=== Start running tests ==="
# Starting from VS2019 Powershell(?) will fail the test run
# if it prints anything to stderr. Python's test runner
# does that by default so we need to forward it.
-cmd /c "python 2>&1 run_tests.py --backend $env:backend $env:extraargs"
+cmd /c "python 2>&1 ./tools/run_with_cov.py run_tests.py --backend $env:backend $env:extraargs"
+
+echo ""
+echo ""
+echo "=== Gathering coverage report ==="
+echo ""
+
+python3 -m coverage combine
+python3 -m coverage xml
+python3 -m coverage report
+
+# Currently codecov.py does not handle Azure, use this fork of a fork to get it
+# working without requireing a token
+git clone https://github.com/mensinda/codecov-python
+python3 -m pip install --ignore-installed ./codecov-python
+python3 -m codecov -f .coverage/coverage.xml -n "VS$env:compiler $env:arch $env:backend" -c $env:SOURCE_VERSION
diff --git a/ci/upload_cov.sh b/ci/upload_cov.sh
new file mode 100755
index 0000000..089641b
--- /dev/null
+++ b/ci/upload_cov.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+echo "Combining coverage reports..."
+coverage combine
+
+echo "Generating XML report..."
+coverage xml
+
+echo "Printing report"
+coverage report
+
+echo "Uploading to codecov..."
+codecov -f .coverage/coverage.xml -n "$1"
diff --git a/ci/usercustomize.py b/ci/usercustomize.py
new file mode 100644
index 0000000..72421ba
--- /dev/null
+++ b/ci/usercustomize.py
@@ -0,0 +1,19 @@
+# Copyright 2021 The Meson development team
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This script is used by coverage (see tools/run_with_cov.py) to enable coverage
+# reports in python subprocesses
+
+import coverage
+coverage.process_startup()
diff --git a/data/.coveragerc.in b/data/.coveragerc.in
new file mode 100644
index 0000000..328e13c
--- /dev/null
+++ b/data/.coveragerc.in
@@ -0,0 +1,25 @@
+[run]
+branch = True
+parallel = True
+concurrency = multiprocessing
+data_file = @ROOT@/.coverage/coverage
+source = @ROOT@/mesonbuild/
+
+[report]
+exclude_lines =
+ if T.TYPE_CHECKING:
+
+[paths]
+mesonbuild =
+ mesonbuild/
+ __w/meson/meson/mesonbuild/
+ @ROOT@/mesonbuild/
+
+[html]
+directory = @ROOT@/.coverage/html
+
+[xml]
+output = @ROOT@/.coverage/coverage.xml
+
+[json]
+output = @ROOT@/.coverage/coverage.json
diff --git a/docs/markdown/Builtin-options.md b/docs/markdown/Builtin-options.md
index ce33fce..0536e77 100644
--- a/docs/markdown/Builtin-options.md
+++ b/docs/markdown/Builtin-options.md
@@ -69,7 +69,7 @@ machine](#specifying-options-per-machine) section for details.
| Option | Default value | Description | Is per machine | Is per subproject |
| ------ | ------------- | ----------- | -------------- | ----------------- |
| auto_features {enabled, disabled, auto} | auto | Override value of all 'auto' features | no | no |
-| backend {ninja, vs,<br>vs2010, vs2015, vs2017, vs2019, xcode} | ninja | Backend to use | no | no |
+| backend {ninja, vs,<br>vs2010, vs2012, vs2013, vs2015, vs2017, vs2019, xcode} | ninja | Backend to use | no | no |
| buildtype {plain, debug,<br>debugoptimized, release, minsize, custom} | debug | Build type to use | no | no |
| debug | true | Debug | no | no |
| default_library {shared, static, both} | shared | Default library type | no | yes |
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index fec4e74..388c975 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -1984,8 +1984,8 @@ the following methods.
*used as the `script_name` parameter.
- `backend()` *(since 0.37.0)*: returns a string representing the
- current backend: `ninja`, `vs2010`, `vs2015`, `vs2017`, `vs2019`,
- or `xcode`.
+ current backend: `ninja`, `vs2010`, `vs2012`, `vs2013`, `vs2015`,
+ `vs2017`, `vs2019`, or `xcode`.
- `build_root()`: returns a string with the absolute path to the build
root directory. *(deprecated since 0.56.0)*: this function will return the
@@ -2554,13 +2554,21 @@ module](#shared_module).
object files generated for those source files. This is typically used
to take single object files and link them to unit tests or to compile
some source files with custom flags. To use the object file(s)
- in another build target, use the `objects:` keyword argument.
+ in another build target, use the [`objects:`](#executable) keyword
+ argument or include them in the command line of a
+ [`custom_target`](#custom_target)`.
- `full_path()`: returns a full path pointing to the result target file.
NOTE: In most cases using the object itself will do the same job as
this and will also allow Meson to setup inter-target dependencies
correctly. Please file a bug if that doesn't work for you.
+- `path()` *(since 0.59.0)* **(deprecated)**: does the exact same
+ as `full_path()`. **NOTE:** This function is solely kept for compatebility
+ with [`external program`](#external-program-object) objects. It will be
+ removed once the, also deprecated, corresponding `path()` function in the
+ `external program` object is removed.
+
- `private_dir_include()`: returns a opaque value that works like
`include_directories` but points to the private directory of this
target, usually only needed if an another target needs to access
@@ -2568,6 +2576,11 @@ module](#shared_module).
- `name()` *(since 0.54.0)*: returns the target name.
+- `found()` *(since 0.59.0)*: Always returns `true`. This function is meant
+ to make executables objects feature compatible with
+ [`external program`](#external-program-object) objects. This simplifies
+ use-cases where an executable is used instead of an external program.
+
### `configuration` data object
diff --git a/docs/markdown/snippets/build-target-found.md b/docs/markdown/snippets/build-target-found.md
new file mode 100644
index 0000000..60c5083
--- /dev/null
+++ b/docs/markdown/snippets/build-target-found.md
@@ -0,0 +1,16 @@
+## New `build target` methods
+
+The [`build target` object](Reference-manual.md#build-target-object) now supports
+the following two functions, to ensure feature compatebility with
+[`external program` objects](Reference-manual.html#external-program-object):
+
+- `found()`: Always returns `true`. This function is meant
+ to make executables objects feature compatible with
+ `external program` objects. This simplifies
+ use-cases where an executable is used instead of an external program.
+
+- `path()`: **(deprecated)** does the exact same as `full_path()`.
+ **NOTE:** This function is solely kept for compatebility
+ with `external program` objects. It will be
+ removed once the, also deprecated, corresponding `path()` function in the
+ `external program` object is removed.
diff --git a/docs/markdown/snippets/compiler_argument_checking.md b/docs/markdown/snippets/compiler_argument_checking.md
new file mode 100644
index 0000000..0e038ec
--- /dev/null
+++ b/docs/markdown/snippets/compiler_argument_checking.md
@@ -0,0 +1,6 @@
+## Compiler argument checking for `get_supported_arguments`
+
+The compiler method `get_supported_arguments` now supports
+a new keyword argument named `checked` that can be set to
+one of `warn`, `require` or `off` (defaults to `off`) to
+enforce argument checks.
diff --git a/docs/markdown/snippets/newvsbackends.md b/docs/markdown/snippets/newvsbackends.md
new file mode 100644
index 0000000..cb7437a
--- /dev/null
+++ b/docs/markdown/snippets/newvsbackends.md
@@ -0,0 +1,15 @@
+## New `vs2012` and `vs2013` backend options
+
+Adds the ability to generate Visual Studio 2012 and 2013 projects. This is an
+extension to the existing Visual Studio 2010 projects so that it is no longer
+required to manually upgrade the generated Visual Studio 2010 projects.
+
+Generating Visual Studio 2010 projects has also been fixed since its developer
+command prompt does not provide a `%VisualStudioVersion%` envvar.
+
+## Developer environment
+
+Expand the support for the `link_whole:` project option for pre-Visual Studio 2015
+Update 2, where previously Visual Studio 2015 Update 2 or later was required for
+this, for the Ninja backend as well as the vs2010 (as well as the newly-added
+vs2012 and vs2013 backends).
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 2652ae6..2239fdd 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -199,6 +199,12 @@ def get_backend_from_name(backend: str, build: T.Optional[build.Build] = None, i
elif backend == 'vs2010':
from . import vs2010backend
return vs2010backend.Vs2010Backend(build, interpreter)
+ elif backend == 'vs2012':
+ from . import vs2012backend
+ return vs2012backend.Vs2012Backend(build, interpreter)
+ elif backend == 'vs2013':
+ from . import vs2013backend
+ return vs2013backend.Vs2013Backend(build, interpreter)
elif backend == 'vs2015':
from . import vs2015backend
return vs2015backend.Vs2015Backend(build, interpreter)
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index 2d3197a..5595fd0 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -27,7 +27,7 @@ from .. import mlog
from .. import compilers
from ..interpreter import Interpreter
from ..mesonlib import (
- MesonException, python_command, replace_if_different, OptionKey,
+ File, MesonException, python_command, replace_if_different, OptionKey, version_compare,
)
from ..environment import Environment, build_filename
@@ -37,8 +37,14 @@ def autodetect_vs_version(build: T.Optional[build.Build], interpreter: T.Optiona
if not vs_install_dir:
raise MesonException('Could not detect Visual Studio: Environment variable VSINSTALLDIR is not set!\n'
'Are you running meson from the Visual Studio Developer Command Prompt?')
- # VisualStudioVersion is set since Visual Studio 12.0, but sometimes
+ # VisualStudioVersion is set since Visual Studio 11.0, but sometimes
# vcvarsall.bat doesn't set it, so also use VSINSTALLDIR
+ if vs_version == '11.0' or 'Visual Studio 11' in vs_install_dir:
+ from mesonbuild.backend.vs2012backend import Vs2012Backend
+ return Vs2012Backend(build, interpreter)
+ if vs_version == '12.0' or 'Visual Studio 12' in vs_install_dir:
+ from mesonbuild.backend.vs2013backend import Vs2013Backend
+ return Vs2013Backend(build, interpreter)
if vs_version == '14.0' or 'Visual Studio 14' in vs_install_dir:
from mesonbuild.backend.vs2015backend import Vs2015Backend
return Vs2015Backend(build, interpreter)
@@ -210,7 +216,7 @@ class Vs2010Backend(backends.Backend):
if 'VCINSTALLDIR' in os.environ:
vs_version = os.environ['VisualStudioVersion'] \
if 'VisualStudioVersion' in os.environ else None
- relative_path = 'Auxiliary\\Build\\' if vs_version >= '15.0' else ''
+ relative_path = 'Auxiliary\\Build\\' if vs_version is not None and vs_version >= '15.0' else ''
script_path = os.environ['VCINSTALLDIR'] + relative_path + 'vcvarsall.bat'
if os.path.exists(script_path):
if has_arch_values:
@@ -1149,8 +1155,32 @@ class Vs2010Backend(backends.Backend):
lobj = self.build.targets[t.get_id()]
linkname = os.path.join(down, self.get_target_filename_for_linking(lobj))
if t in target.link_whole_targets:
- # /WHOLEARCHIVE:foo must go into AdditionalOptions
- extra_link_args += compiler.get_link_whole_for(linkname)
+ if compiler.id == 'msvc' and version_compare(compiler.version, '<19.00.23918'):
+ # Expand our object lists manually if we are on pre-Visual Studio 2015 Update 2
+ l = t.extract_all_objects(False)
+
+ # Unforunately, we can't use self.object_filename_from_source()
+ gensrclist: T.List[File] = []
+ for gen in l.genlist:
+ for src in gen.get_outputs():
+ if self.environment.is_source(src) and not self.environment.is_header(src):
+ path = self.get_target_generated_dir(t, gen, src)
+ gen_src_ext = '.' + os.path.splitext(path)[1][1:]
+ extra_link_args.append(path[:-len(gen_src_ext)] + '.obj')
+
+ for src in l.srclist:
+ obj_basename = None
+ if self.environment.is_source(src) and not self.environment.is_header(src):
+ obj_basename = self.object_filename_from_source(t, src)
+ target_private_dir = self.relpath(self.get_target_private_dir(t),
+ self.get_target_dir(t))
+ rel_obj = os.path.join(target_private_dir, obj_basename)
+ extra_link_args.append(rel_obj)
+
+ extra_link_args.extend(self.flatten_object_list(t))
+ else:
+ # /WHOLEARCHIVE:foo must go into AdditionalOptions
+ extra_link_args += compiler.get_link_whole_for(linkname)
# To force Visual Studio to build this project even though it
# has no sources, we include a reference to the vcxproj file
# that builds this target. Technically we should add this only
diff --git a/mesonbuild/backend/vs2012backend.py b/mesonbuild/backend/vs2012backend.py
new file mode 100644
index 0000000..a9ba5f4
--- /dev/null
+++ b/mesonbuild/backend/vs2012backend.py
@@ -0,0 +1,38 @@
+# Copyright 2014-2016 The Meson development team
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from .vs2010backend import Vs2010Backend
+from ..mesonlib import MesonException
+from ..interpreter import Interpreter
+from ..build import Build
+import typing as T
+
+
+class Vs2012Backend(Vs2010Backend):
+ def __init__(self, build: T.Optional[Build], interpreter: T.Optional[Interpreter]):
+ super().__init__(build, interpreter)
+ self.name = 'vs2012'
+ self.vs_version = '2012'
+ if self.environment is not None:
+ # TODO: we assume host == build
+ comps = self.environment.coredata.compilers.host
+ if comps and all(c.id == 'intel-cl' for c in comps.values()):
+ c = list(comps.values())[0]
+ if c.version.startswith('19'):
+ self.platform_toolset = 'Intel C++ Compiler 19.0'
+ else:
+ # We don't have support for versions older than 2019 right now.
+ raise MesonException('There is currently no support for ICL before 19, patches welcome.')
+ if self.platform_toolset is None:
+ self.platform_toolset = 'v110'
diff --git a/mesonbuild/backend/vs2013backend.py b/mesonbuild/backend/vs2013backend.py
new file mode 100644
index 0000000..0f2c8bd
--- /dev/null
+++ b/mesonbuild/backend/vs2013backend.py
@@ -0,0 +1,38 @@
+# Copyright 2014-2016 The Meson development team
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from .vs2010backend import Vs2010Backend
+from ..mesonlib import MesonException
+from ..interpreter import Interpreter
+from ..build import Build
+import typing as T
+
+
+class Vs2013Backend(Vs2010Backend):
+ def __init__(self, build: T.Optional[Build], interpreter: T.Optional[Interpreter]):
+ super().__init__(build, interpreter)
+ self.name = 'vs2013'
+ self.vs_version = '2013'
+ if self.environment is not None:
+ # TODO: we assume host == build
+ comps = self.environment.coredata.compilers.host
+ if comps and all(c.id == 'intel-cl' for c in comps.values()):
+ c = list(comps.values())[0]
+ if c.version.startswith('19'):
+ self.platform_toolset = 'Intel C++ Compiler 19.0'
+ else:
+ # We don't have support for versions older than 2019 right now.
+ raise MesonException('There is currently no support for ICL before 19, patches welcome.')
+ if self.platform_toolset is None:
+ self.platform_toolset = 'v120'
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 414a4f8..03f97b2 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -378,7 +378,8 @@ class ExtractedObjects(HoldableObject):
r = '<{0} {1!r}: {2}>'
return r.format(self.__class__.__name__, self.target.name, self.srclist)
- def classify_all_sources(self, sources, generated_sources):
+ @staticmethod
+ def get_sources(sources, generated_sources):
# Merge sources and generated sources
sources = list(sources)
for gensrc in generated_sources:
@@ -389,8 +390,10 @@ class ExtractedObjects(HoldableObject):
sources.append(s)
# Filter out headers and all non-source files
- sources = [s for s in sources if environment.is_source(s) and not environment.is_header(s)]
+ return [s for s in sources if environment.is_source(s) and not environment.is_header(s)]
+ def classify_all_sources(self, sources, generated_sources):
+ sources = self.get_sources(sources, generated_sources)
return classify_unity_sources(self.target.compilers.values(), sources)
def check_unity_compatible(self):
@@ -410,10 +413,9 @@ class ExtractedObjects(HoldableObject):
'the object files for each compiler at once.')
def get_outputs(self, backend):
- # TODO: Consider if we need to handle genlist here
return [
backend.object_filename_from_source(self.target, source)
- for source in self.srclist
+ for source in self.get_sources(self.srclist, self.genlist)
]
class EnvironmentVariables(HoldableObject):
diff --git a/mesonbuild/cmake/common.py b/mesonbuild/cmake/common.py
index d1f86f0..5cc154c 100644
--- a/mesonbuild/cmake/common.py
+++ b/mesonbuild/cmake/common.py
@@ -39,7 +39,9 @@ backend_generator_map = {
'ninja': 'Ninja',
'xcode': 'Xcode',
'vs2010': 'Visual Studio 10 2010',
- 'vs2015': 'Visual Studio 15 2017',
+ 'vs2012': 'Visual Studio 11 2012',
+ 'vs2013': 'Visual Studio 12 2013',
+ 'vs2015': 'Visual Studio 14 2015',
'vs2017': 'Visual Studio 15 2017',
'vs2019': 'Visual Studio 16 2019',
}
diff --git a/mesonbuild/cmake/interpreter.py b/mesonbuild/cmake/interpreter.py
index f79f7d2..745def1 100644
--- a/mesonbuild/cmake/interpreter.py
+++ b/mesonbuild/cmake/interpreter.py
@@ -24,7 +24,7 @@ from .traceparser import CMakeTraceParser, CMakeGeneratorTarget
from .. import mlog, mesonlib
from ..mesonlib import MachineChoice, OrderedSet, version_compare, path_is_in_root, relative_to_if_possible, OptionKey
from ..mesondata import mesondata
-from ..compilers.compilers import lang_suffixes, header_suffixes, obj_suffixes, lib_suffixes, is_header
+from ..compilers.compilers import assembler_suffixes, lang_suffixes, header_suffixes, obj_suffixes, lib_suffixes, is_header
from ..programs import ExternalProgram
from enum import Enum
from functools import lru_cache
@@ -435,7 +435,7 @@ class ConverterTarget:
self.link_libraries = temp
# Filter out files that are not supported by the language
- supported = list(header_suffixes) + list(obj_suffixes)
+ supported = list(assembler_suffixes) + list(header_suffixes) + list(obj_suffixes)
for i in self.languages:
supported += list(lang_suffixes[i])
supported = [f'.{x}' for x in supported]
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index efe521c..ff87819 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -73,6 +73,8 @@ c_suffixes = lang_suffixes['c'] + ('h',) # type: T.Tuple[str, ...]
# List of languages that by default consume and output libraries following the
# C ABI; these can generally be used interchangeably
clib_langs = ('objcpp', 'cpp', 'objc', 'c', 'fortran',) # type: T.Tuple[str, ...]
+# List of assembler suffixes that can be linked with C code directly by the linker
+assembler_suffixes: T.Tuple[str, ...] = ('s', 'S')
# List of languages that can be linked with C code directly by the linker
# used in build.py:process_compilers() and build.py:get_dynamic_linker()
clink_langs = ('d', 'cuda') + clib_langs # type: T.Tuple[str, ...]
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 107e4b8..a0ee7df 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -44,7 +44,7 @@ if T.TYPE_CHECKING:
CompilerCheckCacheKey = T.Tuple[T.Tuple[str, ...], str, str, T.Tuple[str, ...], str]
version = '0.58.999'
-backendlist = ['ninja', 'vs', 'vs2010', 'vs2015', 'vs2017', 'vs2019', 'xcode']
+backendlist = ['ninja', 'vs', 'vs2010', 'vs2012', 'vs2013', 'vs2015', 'vs2017', 'vs2019', 'xcode']
default_yielding = False
diff --git a/mesonbuild/interpreter/compiler.py b/mesonbuild/interpreter/compiler.py
index bf32be3..b1eef2f 100644
--- a/mesonbuild/interpreter/compiler.py
+++ b/mesonbuild/interpreter/compiler.py
@@ -1,5 +1,7 @@
import functools
+from ..interpreterbase.decorators import typed_kwargs, KwargInfo
+
from .interpreterobjects import (extract_required_kwarg, extract_search_dirs)
from .. import mesonlib
@@ -684,12 +686,24 @@ class CompilerHolder(ObjectHolder['Compiler']):
return result
@FeatureNew('compiler.get_supported_arguments', '0.43.0')
- @permittedKwargs({})
- def get_supported_arguments_method(self, args, kwargs):
+ @typed_kwargs(
+ 'compiler.get_supported_arguments',
+ KwargInfo('checked', str, default='off', since='0.59.0',
+ validator=lambda s: 'must be one of "warn", "require" or "off"' if s not in ['warn', 'require', 'off'] else None)
+ )
+ def get_supported_arguments_method(self, args: T.Sequence[str], kwargs: T.Dict[str, T.Any]):
args = mesonlib.stringlistify(args)
supported_args = []
+ checked = kwargs.pop('checked')
+
for arg in args:
- if self.has_argument_method(arg, kwargs):
+ if not self.has_argument_method(arg, kwargs):
+ msg = f'Compiler for {self.compiler.get_display_language()} does not support "{arg}"'
+ if checked == 'warn':
+ mlog.warning(msg)
+ elif checked == 'require':
+ raise mesonlib.MesonException(msg)
+ else:
supported_args.append(arg)
return supported_args
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index 7d1ac79..fac0032 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -2329,7 +2329,7 @@ This will become a hard error in the future.''' % kwargs['input'], location=self
self._add_global_arguments(node, self.build.global_link_args[kwargs['native']], args[0], kwargs)
@typed_pos_args('add_project_arguments', varargs=str)
- @typed_kwargs('add_global_arguments', _NATIVE_KW, _LANGUAGE_KW)
+ @typed_kwargs('add_project_arguments', _NATIVE_KW, _LANGUAGE_KW)
def func_add_project_arguments(self, node: mparser.FunctionNode, args: T.Tuple[T.List[str]], kwargs: 'kwargs.FuncAddProjectArgs') -> None:
self._add_project_arguments(node, self.build.projects_args[kwargs['native']], args[0], kwargs)
diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py
index 7c4e75e..744f69c 100644
--- a/mesonbuild/interpreter/interpreterobjects.py
+++ b/mesonbuild/interpreter/interpreterobjects.py
@@ -582,19 +582,14 @@ class ExternalProgramHolder(ObjectHolder[ExternalProgram]):
return self._full_path()
def _full_path(self) -> str:
- exe = self.held_object
- # TODO: How is this case even possible? Why can this hold a build.Executable?
- if isinstance(exe, build.Executable):
- assert self.interpreter.backend is not None
- return self.interpreter.backend.get_target_filename_abs(exe)
if not self.found():
raise InterpreterException('Unable to get the path of a not-found external program')
- path = exe.get_path()
+ path = self.held_object.get_path()
assert path is not None
- return exe.get_path()
+ return path
def found(self) -> bool:
- return isinstance(self.held_object, build.Executable) or self.held_object.found()
+ return self.held_object.found()
class ExternalLibraryHolder(ObjectHolder[ExternalLibrary]):
def __init__(self, el: ExternalLibrary, interpreter: 'Interpreter'):
@@ -790,6 +785,8 @@ class BuildTargetHolder(ObjectHolder[_BuildTarget]):
'get_id': self.get_id_method,
'outdir': self.outdir_method,
'full_path': self.full_path_method,
+ 'path': self.path_method,
+ 'found': self.found_method,
'private_dir_include': self.private_dir_include_method,
})
@@ -810,6 +807,12 @@ class BuildTargetHolder(ObjectHolder[_BuildTarget]):
@noPosargs
@noKwargs
+ @FeatureNew('BuildTarget.found', '0.59.0')
+ def found_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> bool:
+ return True
+
+ @noPosargs
+ @noKwargs
def private_dir_include_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> build.IncludeDirs:
return build.IncludeDirs('', [], False, [self.interpreter.backend.get_target_private_dir(self._target_object)])
@@ -820,6 +823,12 @@ class BuildTargetHolder(ObjectHolder[_BuildTarget]):
@noPosargs
@noKwargs
+ @FeatureDeprecated('BuildTarget.path', '0.55.0', 'Use BuildTarget.full_path instead')
+ def path_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
+ return self.interpreter.backend.get_target_filename_abs(self._target_object)
+
+ @noPosargs
+ @noKwargs
def outdir_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str:
return self.interpreter.backend.get_target_dir(self._target_object)
diff --git a/mesonbuild/interpreterbase/baseobjects.py b/mesonbuild/interpreterbase/baseobjects.py
index d910e51..d82aad2 100644
--- a/mesonbuild/interpreterbase/baseobjects.py
+++ b/mesonbuild/interpreterbase/baseobjects.py
@@ -58,7 +58,7 @@ class InterpreterObject:
if not getattr(method, 'no-args-flattening', False):
args = flatten(args)
return method(args, kwargs)
- raise InvalidCode('Unknown method "%s" in object.' % method_name)
+ raise InvalidCode(f'Unknown method "{method_name}" in object {self} of type {type(self).__name__}.')
class MesonInterpreterObject(InterpreterObject):
''' All non-elementary objects and non-object-holders should be derived from this '''
diff --git a/run_project_tests.py b/run_project_tests.py
index 2e9992a..3522009 100755
--- a/run_project_tests.py
+++ b/run_project_tests.py
@@ -224,6 +224,7 @@ class InstalledFile:
@functools.total_ordering
class TestDef:
def __init__(self, path: Path, name: T.Optional[str], args: T.List[str], skip: bool = False):
+ self.category = path.parts[1]
self.path = path
self.name = name
self.args = args
@@ -1270,9 +1271,9 @@ def _run_tests(all_tests: T.List[T.Tuple[str, T.List[TestDef], bool]],
continue
# Handle skipped tests
- if (result is None) or (('MESON_SKIP_TEST' in result.stdo) and (skippable(name, t.path.as_posix()))):
+ if (result is None) or (('MESON_SKIP_TEST' in result.stdo) and (skippable(t.category, t.path.as_posix()))):
f.update_log(TestStatus.SKIP)
- current_test = ET.SubElement(current_suite, 'testcase', {'name': testname, 'classname': name})
+ current_test = ET.SubElement(current_suite, 'testcase', {'name': testname, 'classname': t.category})
ET.SubElement(current_test, 'skipped', {})
skipped_tests += 1
continue
@@ -1323,7 +1324,7 @@ def _run_tests(all_tests: T.List[T.Tuple[str, T.List[TestDef], bool]],
current_test = ET.SubElement(
current_suite,
'testcase',
- {'name': testname, 'classname': name, 'time': '%.3f' % total_time}
+ {'name': testname, 'classname': t.category, 'time': '%.3f' % total_time}
)
if result.msg != '':
ET.SubElement(current_test, 'failure', {'message': result.msg})
diff --git a/run_tests.py b/run_tests.py
index 10d63df..ae96bfa 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -20,7 +20,6 @@ import sys
import time
import shutil
import subprocess
-import tempfile
import platform
import argparse
import traceback
@@ -311,7 +310,6 @@ def print_system_info():
def main():
print_system_info()
parser = argparse.ArgumentParser()
- parser.add_argument('--cov', action='store_true')
parser.add_argument('--backend', default=None, dest='backend',
choices=backendlist)
parser.add_argument('--cross', default=[], dest='cross', action='append')
@@ -319,13 +317,6 @@ def main():
parser.add_argument('--failfast', action='store_true')
parser.add_argument('--no-unittests', action='store_true', default=False)
(options, _) = parser.parse_known_args()
- # Enable coverage early...
- enable_coverage = options.cov
- if enable_coverage:
- os.makedirs('.coverage', exist_ok=True)
- sys.argv.remove('--cov')
- import coverage
- coverage.process_startup()
returncode = 0
backend, _ = guess_backend(options.backend, shutil.which('msbuild'))
no_unittests = options.no_unittests
@@ -349,52 +340,41 @@ def main():
# Run tests
# Can't pass arguments to unit tests, so set the backend to use in the environment
env = os.environ.copy()
- with tempfile.TemporaryDirectory() as temp_dir:
- # Enable coverage on all subsequent processes.
- if enable_coverage:
- Path(temp_dir, 'usercustomize.py').open('w').write(
- 'import coverage\n'
- 'coverage.process_startup()\n')
- env['COVERAGE_PROCESS_START'] = '.coveragerc'
- if 'PYTHONPATH' in env:
- env['PYTHONPATH'] = os.pathsep.join([temp_dir, env.get('PYTHONPATH')])
- else:
- env['PYTHONPATH'] = temp_dir
- if not options.cross:
- cmd = mesonlib.python_command + ['run_meson_command_tests.py', '-v']
+ if not options.cross:
+ cmd = mesonlib.python_command + ['run_meson_command_tests.py', '-v']
+ if options.failfast:
+ cmd += ['--failfast']
+ returncode += subprocess.call(cmd, env=env)
+ if options.failfast and returncode != 0:
+ return returncode
+ if no_unittests:
+ print('Skipping all unit tests.')
+ print(flush=True)
+ returncode = 0
+ else:
+ print(mlog.bold('Running unittests.'))
+ print(flush=True)
+ cmd = mesonlib.python_command + ['run_unittests.py', '--backend=' + backend.name, '-v']
if options.failfast:
cmd += ['--failfast']
returncode += subprocess.call(cmd, env=env)
if options.failfast and returncode != 0:
return returncode
- if no_unittests:
- print('Skipping all unit tests.')
- print(flush=True)
- returncode = 0
- else:
- print(mlog.bold('Running unittests.'))
- print(flush=True)
- cmd = mesonlib.python_command + ['run_unittests.py', '--backend=' + backend.name, '-v']
- if options.failfast:
- cmd += ['--failfast']
- returncode += subprocess.call(cmd, env=env)
- if options.failfast and returncode != 0:
- return returncode
- cmd = mesonlib.python_command + ['run_project_tests.py'] + sys.argv[1:]
+ cmd = mesonlib.python_command + ['run_project_tests.py'] + sys.argv[1:]
+ returncode += subprocess.call(cmd, env=env)
+ else:
+ cross_test_args = mesonlib.python_command + ['run_cross_test.py']
+ for cf in options.cross:
+ print(mlog.bold(f'Running {cf} cross tests.'))
+ print(flush=True)
+ cmd = cross_test_args + ['cross/' + cf]
+ if options.failfast:
+ cmd += ['--failfast']
+ if options.cross_only:
+ cmd += ['--cross-only']
returncode += subprocess.call(cmd, env=env)
- else:
- cross_test_args = mesonlib.python_command + ['run_cross_test.py']
- for cf in options.cross:
- print(mlog.bold(f'Running {cf} cross tests.'))
- print(flush=True)
- cmd = cross_test_args + ['cross/' + cf]
- if options.failfast:
- cmd += ['--failfast']
- if options.cross_only:
- cmd += ['--cross-only']
- returncode += subprocess.call(cmd, env=env)
- if options.failfast and returncode != 0:
- return returncode
+ if options.failfast and returncode != 0:
+ return returncode
return returncode
if __name__ == '__main__':
diff --git a/run_unittests.py b/run_unittests.py
index b55ba96..13149ce 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -10302,6 +10302,13 @@ def main():
pytest_args += ['--color=yes']
pytest_args += ['./run_unittests.py']
pytest_args += convert_args(sys.argv[1:])
+ # Always disable pytest-cov because we use a custom setup
+ try:
+ import pytest_cov # noqa: F401
+ print('Disabling pytest-cov')
+ pytest_args += ['-p' 'no:cov']
+ except ImportError:
+ pass
return subprocess.run(python_command + ['-m', 'pytest'] + pytest_args).returncode
except ImportError:
print('pytest-xdist not found, using unittest instead')
diff --git a/test cases/cmake/25 assembler/main.c b/test cases/cmake/25 assembler/main.c
new file mode 100644
index 0000000..5aef967
--- /dev/null
+++ b/test cases/cmake/25 assembler/main.c
@@ -0,0 +1,18 @@
+#include <stdint.h>
+#include <stdio.h>
+
+int32_t cmTestFunc(void);
+
+int main(void)
+{
+ if (cmTestFunc() > 4200)
+ {
+ printf("Test success.\n");
+ return 0;
+ }
+ else
+ {
+ printf("Test failure.\n");
+ return 1;
+ }
+}
diff --git a/test cases/cmake/25 assembler/meson.build b/test cases/cmake/25 assembler/meson.build
new file mode 100644
index 0000000..7180356
--- /dev/null
+++ b/test cases/cmake/25 assembler/meson.build
@@ -0,0 +1,9 @@
+project('assembler test', ['c', 'cpp'])
+
+cm = import('cmake')
+
+sub_pro = cm.subproject('cmTest')
+sub_dep = sub_pro.dependency('cmTest')
+
+exe1 = executable('exe1', ['main.c'], dependencies: [sub_dep])
+test('test1', exe1)
diff --git a/test cases/cmake/25 assembler/subprojects/cmTest/CMakeLists.txt b/test cases/cmake/25 assembler/subprojects/cmTest/CMakeLists.txt
new file mode 100644
index 0000000..5fb7cd6
--- /dev/null
+++ b/test cases/cmake/25 assembler/subprojects/cmTest/CMakeLists.txt
@@ -0,0 +1,45 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmTest)
+
+#Detect processor
+if ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "amd64")
+ SET(TEST_PROCESSOR "x86_64")
+elseif ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "x86_64")
+ SET(TEST_PROCESSOR "x86_64")
+elseif ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "i386")
+ SET(TEST_PROCESSOR "x86")
+elseif ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "i686")
+ SET(TEST_PROCESSOR "x86")
+elseif ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "arm")
+ SET(TEST_PROCESSOR "arm")
+elseif ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "aarch64")
+ SET(TEST_PROCESSOR "arm")
+else ()
+ message(FATAL_ERROR, 'MESON_SKIP_TEST: Unsupported Assembler Platform')
+endif ()
+
+#Detect ABI
+if ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
+ SET(TEST_ABI "sysv")
+elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD")
+ SET(TEST_ABI "sysv")
+elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "NetBSD")
+ SET(TEST_ABI "sysv")
+elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "OpenBSD")
+ SET(TEST_ABI "sysv")
+else ()
+ message(FATAL_ERROR, 'MESON_SKIP_TEST: Unsupported Assembler Platform')
+endif ()
+
+SET(TEST_PLATFORM "${TEST_PROCESSOR}-${TEST_ABI}")
+
+if ( ("${TEST_PLATFORM}" MATCHES "x86_64-sysv")
+ OR ("${TEST_PLATFORM}" MATCHES "x86-sysv")
+ OR ("${TEST_PLATFORM}" MATCHES "arm-sysv"))
+ SET(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
+ enable_language(ASM)
+ SET(TEST_SOURCE "cmTestAsm.s")
+endif ()
+
+add_library(cmTest STATIC cmTest.c ${TEST_SOURCE})
diff --git a/test cases/cmake/25 assembler/subprojects/cmTest/cmTest.c b/test cases/cmake/25 assembler/subprojects/cmTest/cmTest.c
new file mode 100644
index 0000000..e32415c
--- /dev/null
+++ b/test cases/cmake/25 assembler/subprojects/cmTest/cmTest.c
@@ -0,0 +1,8 @@
+#include <stdint.h>
+
+extern const int32_t cmTestArea;
+
+int32_t cmTestFunc(void)
+{
+ return cmTestArea;
+}
diff --git a/test cases/cmake/25 assembler/subprojects/cmTest/cmTestAsm.s b/test cases/cmake/25 assembler/subprojects/cmTest/cmTestAsm.s
new file mode 100644
index 0000000..8aa83a6
--- /dev/null
+++ b/test cases/cmake/25 assembler/subprojects/cmTest/cmTestAsm.s
@@ -0,0 +1,4 @@
+.text
+.globl cmTestArea
+cmTestArea:
+ .long 4242
diff --git a/test cases/common/137 whole archive/meson.build b/test cases/common/137 whole archive/meson.build
index 133146b..d4cbb83 100644
--- a/test cases/common/137 whole archive/meson.build
+++ b/test cases/common/137 whole archive/meson.build
@@ -1,15 +1,14 @@
project('whole archive', 'c')
-if meson.backend() == 'xcode'
- error('MESON_SKIP_TEST: whole-archive not supported in Xcode. Patches welcome.')
+if meson.backend() == 'xcode' or \
+ meson.backend() == 'vs2010' or \
+ meson.backend() == 'vs2012' or \
+ meson.backend() == 'vs2013'
+ error('MESON_SKIP_TEST: whole-archive not supported in Xcode nor pre-VS2015 IDE. Patches welcome.')
endif
add_project_arguments('-I' + meson.source_root(), language : 'c')
-if meson.backend() == 'vs2010'
- error('MESON_SKIP_TEST whole-archive not supported in VS2010. Patches welcome.')
-endif
-
# Test 1: link_whole keeps all symbols
# Make static func1
subdir('st_func1')
diff --git a/test cases/common/182 find override/meson.build b/test cases/common/182 find override/meson.build
index b277459..8dcbac7 100644
--- a/test cases/common/182 find override/meson.build
+++ b/test cases/common/182 find override/meson.build
@@ -1,8 +1,10 @@
project('find program override', 'c')
gencodegen = find_program('gencodegen', required : false)
+six_prog = find_program('six_meson_exe', required : false)
assert(not gencodegen.found(), 'gencodegen is an internal program, should not be found')
+assert(not six_prog.found(), 'six_meson_exe is an internal program, should not be found')
# Test the check-if-found-else-override workflow
if not gencodegen.found()
@@ -13,3 +15,11 @@ subdir('otherdir')
tool = find_program('sometool')
assert(tool.found())
+assert(tool.full_path() != '')
+assert(tool.full_path() == tool.path())
+
+# six_meson_exe is an overritten project executable
+six_prog = find_program('six_meson_exe')
+assert(six_prog.found())
+assert(six_prog.full_path() != '')
+assert(six_prog.full_path() == six_prog.path())
diff --git a/test cases/common/182 find override/otherdir/meson.build b/test cases/common/182 find override/otherdir/meson.build
index 5cefc88..7deff40 100644
--- a/test cases/common/182 find override/otherdir/meson.build
+++ b/test cases/common/182 find override/otherdir/meson.build
@@ -10,6 +10,10 @@ e = executable('six', 'main.c', src)
test('six', e)
+# Override stuff with an executables
+meson.override_find_program('six_meson_exe', e)
+
+
# The same again, but this time with a program that was generated
# with configure_file.
diff --git a/test cases/common/22 object extraction/check-obj.py b/test cases/common/22 object extraction/check-obj.py
new file mode 100644
index 0000000..99c2cc5
--- /dev/null
+++ b/test cases/common/22 object extraction/check-obj.py
@@ -0,0 +1,21 @@
+#! /usr/bin/env python3
+
+import json
+import sys
+import os
+
+cc = None
+output = None
+
+# Only the ninja backend produces compile_commands.json
+if sys.argv[1] == 'ninja':
+ with open('compile_commands.json', 'r') as f:
+ cc = json.load(f)
+ output = set((x['output'] for x in cc))
+
+for obj in sys.argv[2:]:
+ if not os.path.exists(obj):
+ sys.exit(1)
+ if sys.argv[1] == 'ninja' and obj not in output:
+ sys.exit(1)
+ print('Verified', obj)
diff --git a/test cases/common/22 object extraction/header.h b/test cases/common/22 object extraction/header.h
new file mode 100644
index 0000000..50403ce
--- /dev/null
+++ b/test cases/common/22 object extraction/header.h
@@ -0,0 +1 @@
+/* Check that extract_all_objects works with headers. */
diff --git a/test cases/common/22 object extraction/meson.build b/test cases/common/22 object extraction/meson.build
index 18be1db..fd4af8c 100644
--- a/test cases/common/22 object extraction/meson.build
+++ b/test cases/common/22 object extraction/meson.build
@@ -4,20 +4,32 @@ if meson.is_unity()
message('Skipping extraction test because this is a Unity build.')
else
lib1 = shared_library('somelib', 'src/lib.c')
- lib2 = shared_library('somelib2', 'lib.c', 'lib2.c')
+ lib2 = shared_library('somelib2', 'lib.c', 'header.h', 'lib2.c')
obj1 = lib1.extract_objects('src/lib.c')
obj2 = lib2.extract_objects(['lib.c'])
obj3 = lib2.extract_objects(files('lib.c'))
obj4 = lib2.extract_objects(['lib.c', 'lib.c'])
+ obj5 = lib2.extract_objects(['lib.c', 'header.h'])
+ obj6 = lib2.extract_all_objects(recursive: true)
e1 = executable('main1', 'main.c', objects : obj1)
e2 = executable('main2', 'main.c', objects : obj2)
e3 = executable('main3', 'main.c', objects : obj3)
e4 = executable('main4', 'main.c', objects : obj4)
+ e5 = executable('main5', 'main.c', objects : obj5)
+ e6 = executable('main6', 'main.c', objects : obj6)
+
+ custom_target('custom_target with object inputs', output: 'objs',
+ input: [obj1, obj2, obj3, obj5, obj6],
+ build_by_default: true,
+ command: [find_program('check-obj.py'), meson.backend(), '@INPUT@'],
+ capture: true)
test('extraction test 1', e1)
test('extraction test 2', e2)
test('extraction test 3', e3)
test('extraction test 4', e4)
+ test('extraction test 5', e5)
+ test('extraction test 6', e6)
endif
diff --git a/test cases/failing/115 compiler argument checking/meson.build b/test cases/failing/115 compiler argument checking/meson.build
new file mode 100644
index 0000000..bb1f447
--- /dev/null
+++ b/test cases/failing/115 compiler argument checking/meson.build
@@ -0,0 +1,4 @@
+project('compiler argument checking test', 'c')
+
+cc = meson.get_compiler('c')
+add_project_arguments(cc.get_supported_arguments('-meson-goober-arg-for-testing', checked : 'require'), language : 'c')
diff --git a/test cases/failing/115 compiler argument checking/test.json b/test cases/failing/115 compiler argument checking/test.json
new file mode 100644
index 0000000..93f9476
--- /dev/null
+++ b/test cases/failing/115 compiler argument checking/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/115 compiler argument checking/meson.build:4:0: ERROR: Compiler for C does not support \"-meson-goober-arg-for-testing\""
+ }
+ ]
+}
diff --git a/tools/run_with_cov.py b/tools/run_with_cov.py
new file mode 100755
index 0000000..17fb300
--- /dev/null
+++ b/tools/run_with_cov.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python3
+# Copyright 2021 The Meson development team
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import subprocess
+import coverage
+import os
+import sys
+from pathlib import Path
+
+root_path = Path(__file__).parent.parent.absolute()
+
+# Python magic so we can import mesonlib
+sys.path.append(root_path.as_posix())
+from mesonbuild import mesonlib
+
+def generate_coveragerc() -> Path:
+ i_file = (root_path / 'data' / '.coveragerc.in')
+ o_file = (root_path / '.coveragerc')
+ raw = i_file.read_text()
+ raw = raw.replace('@ROOT@', root_path.as_posix())
+ o_file.write_text(raw)
+ return o_file
+
+def main() -> int:
+ # Remove old run data
+ out_dir = root_path / '.coverage'
+ mesonlib.windows_proof_rmtree(out_dir.as_posix())
+ out_dir.mkdir(parents=True, exist_ok=True)
+
+ # Setup coverage
+ python_path = (root_path / 'ci').as_posix()
+ os.environ['PYTHONPATH'] = os.pathsep.join([python_path, os.environ.get('PYTHONPATH', '')])
+ os.environ['COVERAGE_PROCESS_START'] = generate_coveragerc().as_posix()
+ coverage.process_startup()
+
+ # Run the actual command
+ cmd = mesonlib.python_command + sys.argv[1:]
+ return subprocess.run(cmd, env=os.environ.copy()).returncode
+
+if __name__ == '__main__':
+ raise SystemExit(main())