summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel <dmoody256@gmail.com>2019-01-30 18:32:45 (GMT)
committerDaniel <dmoody256@gmail.com>2019-01-30 18:32:45 (GMT)
commitdd340d59e070ff8fcff8a893b350a0dea5b4859b (patch)
treeebf5f2499a9c14046a072573322dda3e9dd5322a
parentb68e505d30e5b2f4ed366e6db10cdd14f14b8a80 (diff)
parent43d40021b7581c40c7dbd87e021a742f2a915102 (diff)
downloadSCons-dd340d59e070ff8fcff8a893b350a0dea5b4859b.zip
SCons-dd340d59e070ff8fcff8a893b350a0dea5b4859b.tar.gz
SCons-dd340d59e070ff8fcff8a893b350a0dea5b4859b.tar.bz2
Merge remote-tracking branch 'origin/master' into mingw_link_issue
-rw-r--r--.appveyor.yml222
-rw-r--r--.codecov.yml50
-rw-r--r--.travis.yml106
-rwxr-xr-xREADME.rst22
-rwxr-xr-xReleaseConfig2
-rw-r--r--SConstruct2
-rwxr-xr-xbin/upload-release-files.sh2
-rwxr-xr-xdebian/changelog8
-rw-r--r--doc/generated/examples/caching_ex-random_1.xml6
-rw-r--r--doc/generated/examples/troubleshoot_explain1_3.xml2
-rw-r--r--doc/generated/tools.gen12
-rw-r--r--doc/generated/tools.mod4
-rw-r--r--doc/generated/variables.gen51
-rw-r--r--doc/generated/variables.mod6
-rw-r--r--doc/man/scons.xml4
-rw-r--r--doc/user/copyright.xml2
-rwxr-xr-xsrc/Announce.txt14
-rwxr-xr-x[-rw-r--r--]src/CHANGES.txt22
-rwxr-xr-xsrc/RELEASE.txt4
-rw-r--r--src/engine/SCons/Platform/__init__.py34
-rw-r--r--src/engine/SCons/Platform/__init__.xml24
-rw-r--r--src/engine/SCons/Tool/MSCommon/common.py4
-rw-r--r--src/engine/SCons/Tool/MSCommon/vc.py290
-rw-r--r--src/engine/SCons/Tool/MSCommon/vs.py15
-rw-r--r--src/engine/SCons/Tool/gcc.py38
-rw-r--r--src/engine/SCons/Tool/midl.py2
-rw-r--r--src/engine/SCons/Tool/mslib.py2
-rw-r--r--src/engine/SCons/Tool/mslink.py2
-rw-r--r--src/engine/SCons/Tool/msvc.py2
-rw-r--r--src/engine/SCons/Tool/msvc.xml7
-rw-r--r--src/engine/SCons/Tool/msvs.py22
-rw-r--r--src/engine/SCons/Tool/msvsTests.py5
-rw-r--r--src/engine/SCons/Tool/swig.py20
-rw-r--r--src/engine/SCons/cpp.py9
-rw-r--r--src/engine/SCons/cppTests.py107
-rwxr-xr-x[-rw-r--r--]src/script/scons.py0
-rwxr-xr-x[-rw-r--r--]template/RELEASE.txt2
-rw-r--r--test/MSVC/MSVC_UWP_APP.py138
-rw-r--r--test/MSVC/TARGET_ARCH.py20
-rw-r--r--test/MSVS/vs-14.1-exec.py113
-rw-r--r--test/MSVS/vs-14.1-files.py108
-rw-r--r--test/MSVS/vs-14.1-scc-files.py113
-rw-r--r--test/MSVS/vs-14.1-scc-legacy-files.py96
-rw-r--r--test/TEMPFILEPREFIX.py7
-rw-r--r--test/TEMPFILESUFFIX.py126
-rw-r--r--testing/framework/TestSCons.py2
-rw-r--r--testing/framework/TestSConsMSVS.py108
47 files changed, 1672 insertions, 285 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
index 7f45e17..b8f0913 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -1,8 +1,12 @@
#version: '3.0.1.{build}'
-image: Visual Studio 2017
-shallow_clone: true
-
+image:
+ # linux builds disabled for now
+ # - Ubuntu
+ - Visual Studio 2015
+ - Visual Studio 2017
+
+
cache:
- downloads -> appveyor.yml
- '%LOCALAPPDATA%\pip\Cache'
@@ -10,69 +14,176 @@ cache:
- C:\ProgramData\chocolatey\lib -> appveyor.yml
install:
- - "set PATH=%PYTHON%;%PYTHON%\\Scripts;C:\\cygwin64\\bin;C:\\msys64;%PATH%"
- - python --version
- - pip install pypiwin32
- - set STATIC_DEPS=true & pip install lxml
- - choco install --allow-empty-checksums dmd
- - choco install --allow-empty-checksums ldc
- - choco install --allow-empty-checksums swig
- - choco install --allow-empty-checksums vswhere
- - choco install --allow-empty-checksums xsltproc
+ ### WINDOWS ###
+ # add python and python user-base to path for pip installs
+ - cmd: "C:\\%WINPYTHON%\\python.exe --version"
+ - cmd: for /F "tokens=*" %%g in ('C:\\%WINPYTHON%\\python.exe -m site --user-site') do (set PYSITEDIR=%%g)
+ - cmd: "set PATH=C:\\%WINPYTHON%;C:\\%WINPYTHON%\\Scripts;C:\\cygwin64\\bin;C:\\msys64;C:\\ProgramData\\chocolatey\\bin;%PATH%"
+ - cmd: "C:\\%WINPYTHON%\\python.exe -m pip install -U --progress-bar off pip setuptools wheel "
+ - cmd: "C:\\%WINPYTHON%\\python.exe -m pip install -U --progress-bar off pypiwin32 coverage codecov"
+ - cmd: set STATIC_DEPS=true & C:\\%WINPYTHON%\\python.exe -m pip install -U --progress-bar off lxml
+ # install 3rd party tools to test with
+ - cmd: choco install --allow-empty-checksums dmd ldc swig vswhere xsltproc
+ - cmd: set
+
+ ### LINUX ###
+ - sh: sudo add-apt-repository -y ppa:deadsnakes/ppa
+ # allow the CI to continue even if some pkg in the pkglist may not be up to date
+ - sh: sudo apt-get update || true
+ - sh: sudo apt-get -y install python$PYTHON
+ - sh: wget https://bootstrap.pypa.io/get-pip.py
+ - sh: sudo -H python$PYTHON get-pip.py
+ - sh: which python$PYTHON
+ - sh: python$PYTHON --version
+ - sh: export PYSITEDIR=$(python$PYTHON -m site --user-site)
+ - sh: python$PYTHON -m pip install --user -U --progress-bar off pip setuptools wheel
+ - sh: python$PYTHON -m pip install --user -U --progress-bar off coverage codecov
+ - sh: STATIC_DEPS=true python$PYTHON -m pip install --user -U --progress-bar off lxml
+ - sh: ./.travis/install.sh
+ - sh: printenv
environment:
matrix:
- - PYTHON: "C:\\Python27"
+ - WINPYTHON: "Python27"
+ PYTHON: "2.7"
+ PYVER: 27
BUILD_JOB_NUM: 1
- - PYTHON: "C:\\Python27"
+ COVERAGE: 1
+ - WINPYTHON: "Python27"
+ PYTHON: "2.7"
+ PYVER: 27
BUILD_JOB_NUM: 2
- - PYTHON: "C:\\Python27"
+ COVERAGE: 1
+ - WINPYTHON: "Python27"
+ PYTHON: "2.7"
+ PYVER: 27
BUILD_JOB_NUM: 3
- - PYTHON: "C:\\Python27"
+ COVERAGE: 1
+ - WINPYTHON: "Python27"
+ PYTHON: "2.7"
+ PYVER: 27
BUILD_JOB_NUM: 4
+ COVERAGE: 1
- - PYTHON: "C:\\Python35"
+ - WINPYTHON: "Python36"
+ PYTHON: "3.6"
+ PYVER: 36
BUILD_JOB_NUM: 1
- - PYTHON: "C:\\Python35"
+ COVERAGE: 1
+ - WINPYTHON: "Python36"
+ PYTHON: "3.6"
+ PYVER: 36
BUILD_JOB_NUM: 2
- - PYTHON: "C:\\Python35"
+ COVERAGE: 1
+ - WINPYTHON: "Python36"
+ PYTHON: "3.6"
+ PYVER: 36
BUILD_JOB_NUM: 3
- - PYTHON: "C:\\Python35"
+ COVERAGE: 1
+ - WINPYTHON: "Python36"
+ PYTHON: "3.6"
+ PYVER: 36
BUILD_JOB_NUM: 4
+ COVERAGE: 1
- - PYTHON: "C:\\Python36"
+ - WINPYTHON: "Python35"
+ PYTHON: "3.5"
+ PYVER: 35
BUILD_JOB_NUM: 1
- - PYTHON: "C:\\Python36"
+ COVERAGE: 0
+ - WINPYTHON: "Python35"
+ PYTHON: "3.5"
+ PYVER: 35
BUILD_JOB_NUM: 2
- - PYTHON: "C:\\Python36"
+ COVERAGE: 0
+ - WINPYTHON: "Python35"
+ PYTHON: "3.5"
+ PYVER: 35
BUILD_JOB_NUM: 3
- - PYTHON: "C:\\Python36"
+ COVERAGE: 0
+ - WINPYTHON: "Python35"
+ PYTHON: "3.5"
+ PYVER: 35
BUILD_JOB_NUM: 4
+ COVERAGE: 0
- - PYTHON: "C:\\Python37"
+ - WINPYTHON: "Python37"
+ PYTHON: "3.7"
+ PYVER: 37
BUILD_JOB_NUM: 1
- - PYTHON: "C:\\Python37"
+ COVERAGE: 0
+ - WINPYTHON: "Python37"
+ PYTHON: "3.7"
+ PYVER: 37
BUILD_JOB_NUM: 2
- - PYTHON: "C:\\Python37"
+ COVERAGE: 0
+ - WINPYTHON: "Python37"
+ PYTHON: "3.7"
+ PYVER: 37
BUILD_JOB_NUM: 3
- - PYTHON: "C:\\Python37"
+ COVERAGE: 0
+ - WINPYTHON: "Python37"
+ PYTHON: "3.7"
+ PYVER: 37
BUILD_JOB_NUM: 4
+ COVERAGE: 0
+
+matrix:
+ exclude:
+ # test python 3.6 on Visual Studio 2015 image
+ - image: Visual Studio 2015
+ WINPYTHON: "Python37"
+ - image: Visual Studio 2015
+ WINPYTHON: "Python35"
+ # test python 3.7 on Ubuntu
+ - image: Ubuntu
+ WINPYTHON: "Python27"
+ - image: Ubuntu
+ WINPYTHON: "Python35"
+ - image: Ubuntu
+ WINPYTHON: "Python36"
before_build:
- - ps: dir "C:\Program Files\Git\usr\bin\x*.exe"
- ps: |
- if (Test-Path "C:\Program Files\Git\usr\bin\xsltproc.EXE" ) {
- Remove-Item "C:\Program Files\Git\usr\bin\xsltproc.EXE" -ErrorAction Ignore
+ if ($isWindows)
+ {
+ dir "C:\Program Files\Git\usr\bin\x*.exe"
+ if (Test-Path "C:\Program Files\Git\usr\bin\xsltproc.EXE" ) {
+ Remove-Item "C:\Program Files\Git\usr\bin\xsltproc.EXE" -ErrorAction Ignore
+ }
+ dir "C:\Program Files\Git\usr\bin\x*.exe"
}
- - ps: dir "C:\Program Files\Git\usr\bin\x*.exe"
-
+
build: off
build_script:
- - cmd: python runtest.py -l -a > all_tests.txt
- - ps: >-
+ # get tests all tests
+ - cmd: "C:\\%WINPYTHON%\\python.exe runtest.py -l -a > all_tests.txt"
+ - sh: python$PYTHON runtest.py -l -a > all_tests.txt
+
+ # setup coverage is set in environment
+ - ps: |
+ if ($env:COVERAGE -eq 1){
+ $env:COVERAGE_PROCESS_START = "$($env:APPVEYOR_BUILD_FOLDER)/.coveragerc";
+ $env:PYTHONNOUSERSITE = "";
+ New-Item -ItemType Directory -Force -Path "$($env:PYSITEDIR)";
+ $env:COVERAGE_FILE = "$($env:APPVEYOR_BUILD_FOLDER)/.coverage";
+ $usercustomizeText = "import os`r`nos.environ['COVERAGE_PROCESS_START'] = '$($env:COVERAGE_PROCESS_START)'`r`nimport coverage`r`ncoverage.process_startup()";
+ $usercustomizeText|Set-Content "$($env:PYSITEDIR)/usercustomize.py";
+ if ($isWindows)
+ {
+ $coveragercFile = "[run]`r`nsource = $($env:APPVEYOR_BUILD_FOLDER)/src`r`nparallel = True`r`ndisable_warnings = trace-changed`r`nomit =`r`n`t*Tests.py`r`n`tsrc\test_*`r`n`tsrc\setup.py`r`n`r`n[path]`r`nsource = $($env:APPVEYOR_BUILD_FOLDER)`r`n[report]`r`nomit =`r`n`t*Tests.py`r`n`tsrc\test_*`r`n`tsrc\setup.py`r`n`r`n"
+ }
+ else
+ {
+ $coveragercFile = "[run]`nsource = $($env:APPVEYOR_BUILD_FOLDER)/src`nparallel = True`ndisable_warnings = trace-changed`nomit =`n`t*Tests.py`n`tsrc/test_*`n`tsrc/setup.py`n`n[path]`nsource = $($env:APPVEYOR_BUILD_FOLDER)`n[report]`nomit =`n`t*Tests.py`n`tsrc/test_*`n`tsrc/setup.py`n`n"
+ }
+ $coveragercFile|Set-Content "$($env:COVERAGE_PROCESS_START)";
+ }
+ # setup portion of tests for this build job (1-4)
+ - ps: |
$TOTAL_BUILD_JOBS = 4;
$Lines = (Get-Content all_tests.txt | Measure-Object -line).Lines;
$start = ($Lines / $TOTAL_BUILD_JOBS) * ($Env:BUILD_JOB_NUM - 1);
@@ -80,4 +191,43 @@ build_script:
if ( $Env:BUILD_JOB_NUM -eq $TOTAL_BUILD_JOBS){ $end = $Lines };
if ( $start -eq 0 ){ $start = 1 };
get-content all_tests.txt | select -first ($end - $start) -skip ($start - 1) | Out-File -Encoding ASCII build_tests.txt;
- - cmd: powershell -Command "& { python runtest.py -j 2 -f build_tests.txt; if($LastExitCode -eq 2 -Or $LastExitCode -eq 0) { $host.SetShouldExit(0 )} else {$host.SetShouldExit(1)}}" \ No newline at end of file
+
+ # exclude VS 10.0 because it hangs the testing until this is resolved:
+ # https://help.appveyor.com/discussions/problems/19283-visual-studio-2010-trial-license-has-expired
+ - ps: |
+ New-Item -Name exclude_list.txt -ItemType File
+ $workaround_image = "Visual Studio 2015"
+ if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq $workaround_image){
+ Add-Content -Path 'exclude_list.txt' -Value 'test\MSVS\vs-10.0-exec.py'
+ }
+
+ # NOTE: running powershell from cmd on purpose because it formats the output
+ # correctly
+ - cmd: powershell -Command "& { if($env:COVERAGE -eq 1) { coverage run -p --rcfile=$($env:COVERAGE_PROCESS_START) runtest.py --exclude-list exclude_list.txt -f build_tests.txt } else { C:\\%WINPYTHON%\\python.exe runtest.py -j 2 --exclude-list exclude_list.txt -f build_tests.txt }; if($LastExitCode -eq 2 -Or $LastExitCode -eq 0) { $host.SetShouldExit(0 )} else {$host.SetShouldExit(1)}}"
+
+ # unset JAVA_TOOL_OPTIONS because newer java prints this to stderr
+ - sh: |
+ unset JAVA_TOOL_OPTIONS
+ if [ "$COVERAGE" -eq "1" ]; then
+ coverage run -p --rcfile="$COVERAGE_PROCESS_START" runtest.py --exclude-list exclude_list.txt -f build_tests.txt || if [[ $? == 2 ]]; then true; else false; fi;
+ else
+ python$PYTHON runtest.py -j 2 --exclude-list exclude_list.txt -f build_tests.txt || if [[ $? == 2 ]]; then true; else false; fi;
+ fi
+
+ # run converage
+on_finish:
+ - ps: |
+ if ($env:COVERAGE -eq 1)
+ {
+ & coverage combine
+ & coverage report
+ & coverage xml -o coverage_xml.xml
+ }
+ # running in powershell causes an error so running in platform
+ # shells
+ - cmd: if %COVERAGE% equ 1 codecov -X gcov --file coverage_xml.xml
+ - sh: if [ $COVERAGE -eq 1 ]; then codecov -X gcov --file coverage_xml.xml; fi
+ # not using coveralls, so leaving it commented out in case we switch back
+ #- cmd: "C:\\%WINPYTHON%\\python.exe -m pip install --user -U coveralls"
+ #- sh: python$PYTHON -m pip install --user -U coveralls
+ #- ps: coveralls --rcfile="$($env:COVERAGE_PROCESS_START)"
diff --git a/.codecov.yml b/.codecov.yml
new file mode 100644
index 0000000..375b10f
--- /dev/null
+++ b/.codecov.yml
@@ -0,0 +1,50 @@
+codecov:
+ notify:
+ # calculate coverge even when we fail
+ require_ci_to_pass: no
+
+ignore:
+ # ignore test files in the source
+ # this is redundant and should not be in the report anyways
+ # because the coveragerc file ignores them
+ - "*Test.py"
+ - "setup.py"
+ - "test_*"
+
+coverage:
+ precision: 2
+ round: down
+ range: "70...100"
+
+ notify:
+ irc:
+ default:
+ server: "chat.freenode.net#scons"
+ branches: master
+ threshold: null
+ message: "Coverage {{changed}} for {{owner}}/{{repo}}" # customize the message
+ flags: null
+ paths: null
+
+ status:
+ project:
+ default:
+ # compare against the current coverage
+ # that PR is attempt to merge to
+ # don't consider a drop in coverage success
+ target: auto
+ threshold: null
+ base: pr
+
+ patch:
+ default:
+ # considering only the lines changed
+ # make sure all new lines in the PR are covered
+ # to consider a success
+ target: 100
+ threshold: null
+ base: pr
+
+ changes: no
+
+comment: off
diff --git a/.travis.yml b/.travis.yml
index e279ad9..fb48776 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -17,7 +17,7 @@ install:
# pypy is not passing, but allow failures for coverage stage to be reached
matrix:
allow_failures:
- - python: pypy
+ - stage: Test
jobs:
include:
@@ -27,46 +27,63 @@ jobs:
before_script: skip
after_success: skip
python: 2.7
- env: PYVER=27
+ env:
+ - PYVER=27
+ - PYTHON=2.7
sudo: required
-
+
- <<: *test_job
python: 3.5
- env: PYVER=35
+ env:
+ - PYVER=35
+ - PYTHON=3.5
sudo: required
- <<: *test_job
python: 3.6
- env: PYVER=36
+ env:
+ - PYVER=36
+ - PYTHON=3.6
sudo: required
- <<: *test_job
python: 3.7
env:
- PYVER=37
+ - PYTHON=3.7
sudo: required
dist: xenial # required for Python 3.7 (travis-ci/travis-ci#9069)
- <<: *test_job
python: pypy
- env: PYVER=pypy
+ env:
+ - PYVER=pypy
+ - PYTHON=pypy
sudo: required
- &coverage_jobs
stage: Coverage
-
+ python: 2.7
before_script:
- - sudo pip install coverage
- - sudo pip install coveralls
+ # install our own python so we can modify usercustomize.py
+ - deactivate
+ - sudo add-apt-repository -y ppa:deadsnakes/ppa
+ - sudo apt-get update || true
+ - sudo apt-get -y install python$PYTHON
+ - wget https://bootstrap.pypa.io/get-pip.py
+ - sudo -H python$PYTHON get-pip.py
+ - which python$PYTHON
+ - python$PYTHON --version
+ - python$PYTHON -m pip install --user -U coverage codecov
# set this ensure user sites are available
- export PYTHONNOUSERSITE=
# attempt to get a location where we can store the usercustomize.py file
- - python -m site
- - export PYSITEDIR=$(python -m site --user-site)
+ - python$PYTHON -m site
+ - export PYSITEDIR=$(python$PYTHON -m site --user-site)
- sudo mkdir -p $PYSITEDIR
- sudo touch ${PYSITEDIR}/usercustomize.py
- - export COVERAGE_FILE=$PWD/.coverage_file
+ - export COVERAGE_FILE=$PWD/.coverage
# write the usercustomize.py file so all python processes use coverage and know where the config file is
- echo "import os" | sudo tee --append ${PYSITEDIR}/usercustomize.py
- echo "os.environ['COVERAGE_PROCESS_START'] = '$PWD/.coveragerc'" | sudo tee --append ${PYSITEDIR}/usercustomize.py
@@ -74,42 +91,79 @@ jobs:
- echo "coverage.process_startup()" | sudo tee --append ${PYSITEDIR}/usercustomize.py
script:
- - export TOTAL_BUILD_JOBS=8
+ - export TOTAL_BUILD_JOBS=4
# write the coverage config file
- export COVERAGE_PROCESS_START=$PWD/.coveragerc
- echo "[run]" >> .coveragerc
- echo "source = $PWD/src" >> .coveragerc
- echo "parallel = True" >> .coveragerc
- printf "omit =\n\t*Tests.py\n\tsrc/test_*\n\tsrc/setup.py\n\n" >> .coveragerc
- - echo "[path] = $PWD" >> .coveragerc
+ - echo "[path]" >> .coveragerc
+ - echo "source = $PWD" >> .coveragerc
+ - echo "[report]" >> .coveragerc
+ - printf "omit =\n\t*Tests.py\n\tsrc/test_*\n\tsrc/setup.py\n\n" >> .coveragerc
# get a list of all the tests to split them up
- - python runtest.py -l -a > all_tests
+ - python$PYTHON runtest.py -l -a > all_tests
- let "start = ($(wc -l < all_tests) / ${TOTAL_BUILD_JOBS}) * (${BUILD_JOB_NUM} - 1)"; true;
- let "end = ($(wc -l < all_tests) / ${TOTAL_BUILD_JOBS}) * ${BUILD_JOB_NUM}"
- if (( ${BUILD_JOB_NUM} == ${TOTAL_BUILD_JOBS} )); then end=$(wc -l < all_tests); fi
- if (( ${start} == 0 )); then start=1; fi
- sed -n ${start},${end}p all_tests > build_tests
- coverage run -p --rcfile=$PWD/.coveragerc runtest.py -f build_tests || if [[ $? == 2 ]]; then true; else false; fi
-
- after_success:
+
+ after_script:
- coverage combine
- coverage report
- - coveralls --rcfile=$PWD/.coveragerc
+ - coverage xml -o coverage_xml.xml
+ - codecov -X gcov --file coverage_xml.xml
+ # not using coveralls but leaving it commented to
+ # make it easy to re-enable
+ #- python$PYTHON -m pip install --user -U coveralls
+ #- coveralls --rcfile=$PWD/.coveragerc
- env: BUILD_JOB_NUM=1
+ env:
+ - PYVER=27
+ - PYTHON=2.7
+ - BUILD_JOB_NUM=1
- <<: *coverage_jobs
- env: BUILD_JOB_NUM=2
+ env:
+ - PYVER=27
+ - PYTHON=2.7
+ - BUILD_JOB_NUM=2
- <<: *coverage_jobs
- env: BUILD_JOB_NUM=3
+ env:
+ - PYVER=27
+ - PYTHON=2.7
+ - BUILD_JOB_NUM=3
- <<: *coverage_jobs
- env: BUILD_JOB_NUM=4
+ env:
+ - PYVER=27
+ - PYTHON=2.7
+ - BUILD_JOB_NUM=4
+
- <<: *coverage_jobs
- env: BUILD_JOB_NUM=5
+ python: 3.6
+ env:
+ - PYVER=36
+ - PYTHON=3.6
+ - BUILD_JOB_NUM=1
- <<: *coverage_jobs
- env: BUILD_JOB_NUM=6
+ python: 3.6
+ env:
+ - PYVER=36
+ - PYTHON=3.6
+ - BUILD_JOB_NUM=2
- <<: *coverage_jobs
- env: BUILD_JOB_NUM=7
+ python: 3.6
+ env:
+ - PYVER=36
+ - PYTHON=3.6
+ - BUILD_JOB_NUM=3
- <<: *coverage_jobs
- env: BUILD_JOB_NUM=8
+ python: 3.6
+ env:
+ - PYVER=36
+ - PYTHON=3.6
+ - BUILD_JOB_NUM=4
diff --git a/README.rst b/README.rst
index ca66d51..cffd4f3 100755
--- a/README.rst
+++ b/README.rst
@@ -21,9 +21,9 @@ SCons - a software construction tool
:target: https://ci.appveyor.com/project/SCons/scons
:alt: AppVeyor CI build Status
-.. image:: https://coveralls.io/repos/github/SCons/scons/badge.svg?branch=master
- :target: https://coveralls.io/github/SCons/scons?branch=master
- :alt: Coveralls.io Coverage Status
+.. image:: https://codecov.io/gh/SCons/scons/branch/master/graph/badge.svg
+ :target: https://codecov.io/gh/SCons/scons
+ :alt: CodeCov Coverage Status
Welcome to the SCons development tree. The real purpose of this tree is to
@@ -499,13 +499,13 @@ about `Executing SCons Without Installing`_)::
Depending on the utilities installed on your system, any or all of the
following packages will be built::
- build/dist/scons-3.0.3.tar.gz
- build/dist/scons-3.0.3.zip
- build/dist/scons-doc-3.0.3.tar.gz
- build/dist/scons-local-3.0.3.tar.gz
- build/dist/scons-local-3.0.3.zip
- build/dist/scons-src-3.0.3.tar.gz
- build/dist/scons-src-3.0.3.zip
+ build/dist/scons-3.0.4.tar.gz
+ build/dist/scons-3.0.4.zip
+ build/dist/scons-doc-3.0.4.tar.gz
+ build/dist/scons-local-3.0.4.tar.gz
+ build/dist/scons-local-3.0.4.zip
+ build/dist/scons-src-3.0.4.tar.gz
+ build/dist/scons-src-3.0.4.zip
The SConstruct file is supposed to be smart enough to avoid trying to build
packages for which you don't have the proper utilities installed. For
@@ -765,5 +765,5 @@ many contributors, including but not at all limited to:
\... and many others.
-Copyright (c) 2001 - 2018 The SCons Foundation
+Copyright (c) 2001 - 2019 The SCons Foundation
diff --git a/ReleaseConfig b/ReleaseConfig
index 900e8b5..32707c7 100755
--- a/ReleaseConfig
+++ b/ReleaseConfig
@@ -32,7 +32,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
# 'final', the patchlevel is set to the release date. This value is
# mandatory and must be present in this file.
#version_tuple = (2, 2, 0, 'final', 0)
-version_tuple = (3, 0, 4, 'alpha', 0)
+version_tuple = (3, 0, 5, 'alpha', 0)
# Python versions prior to unsupported_python_version cause a fatal error
# when that version is used. Python versions prior to deprecate_python_version
diff --git a/SConstruct b/SConstruct
index a7eca26..3d93d1e 100644
--- a/SConstruct
+++ b/SConstruct
@@ -51,7 +51,7 @@ import textwrap
import bootstrap
project = 'scons'
-default_version = '3.0.3'
+default_version = '3.0.4'
copyright = "Copyright (c) %s The SCons Foundation" % copyright_years
SConsignFile()
diff --git a/bin/upload-release-files.sh b/bin/upload-release-files.sh
index 4748db1..014134a 100755
--- a/bin/upload-release-files.sh
+++ b/bin/upload-release-files.sh
@@ -73,7 +73,7 @@ ssh scons@scons.org "
cd ..
rm latest; ln -s $VERSION latest
rm production; ln -s $VERSION production
- for f in HTML PDF EPUB PS TEXT; do rm \$f; ln -s $VERSION/\$f \$f; done
+ for f in HTML PDF EPUB PS TEXT; do rm -f \$f; ln -s $VERSION/\$f \$f; done
"
echo '*****'
echo '***** Now manually update index.php, includes/versions.php and news-raw.xhtml on scons.org.'
diff --git a/debian/changelog b/debian/changelog
index 7ef3a14..7698b1e 100755
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,8 +1,14 @@
+scons (3.0.4) unstable; urgency=low
+
+ * Maintenance Release
+
+ -- William Deegan <bill@baddogconsulting.com> Sun, 20 Jan 2019 19:44:18 -0700
+
scons (3.0.3) unstable; urgency=low
* Maintenance Release
- -- William Deegan <bill@baddogconsulting.com> Sat, 07 Jan 2018 19:44:18 -0700
+ -- William Deegan <bill@baddogconsulting.com> Sat, 07 Jan 2019 19:44:18 -0700
scons (3.0.2) unstable; urgency=low
diff --git a/doc/generated/examples/caching_ex-random_1.xml b/doc/generated/examples/caching_ex-random_1.xml
index c821b48..0a432e9 100644
--- a/doc/generated/examples/caching_ex-random_1.xml
+++ b/doc/generated/examples/caching_ex-random_1.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<screen xmlns="http://www.scons.org/dbxsd/v1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0 http://www.scons.org/dbxsd/v1.0/scons.xsd">% <userinput>scons -Q</userinput>
-cc -o f3.o -c f3.c
-cc -o f4.o -c f4.c
-cc -o f1.o -c f1.c
cc -o f5.o -c f5.c
+cc -o f3.o -c f3.c
cc -o f2.o -c f2.c
+cc -o f1.o -c f1.c
+cc -o f4.o -c f4.c
cc -o prog f1.o f2.o f3.o f4.o f5.o
</screen>
diff --git a/doc/generated/examples/troubleshoot_explain1_3.xml b/doc/generated/examples/troubleshoot_explain1_3.xml
index a60ed80..ebc13f8 100644
--- a/doc/generated/examples/troubleshoot_explain1_3.xml
+++ b/doc/generated/examples/troubleshoot_explain1_3.xml
@@ -3,5 +3,5 @@
cp file.in file.oout
scons: warning: Cannot find target file.out after building
-File "/home/bdbaddog/scons/git/as_scons/src/script/scons.py", line 204, in &lt;module&gt;
+File "/home/bdeegan/devel/scons/git/as_scons/src/script/scons.py", line 204, in &lt;module&gt;
</screen>
diff --git a/doc/generated/tools.gen b/doc/generated/tools.gen
index 7ae66c5..7661110 100644
--- a/doc/generated/tools.gen
+++ b/doc/generated/tools.gen
@@ -778,19 +778,19 @@ Sets construction variables for the
</para>
<para>Sets: &cv-link-AS;, &cv-link-ASCOM;, &cv-link-ASFLAGS;, &cv-link-ASPPCOM;, &cv-link-ASPPFLAGS;.</para><para>Uses: &cv-link-ASCOMSTR;, &cv-link-ASPPCOMSTR;.</para></listitem>
</varlistentry>
- <varlistentry id="t-Packaging">
- <term>Packaging</term>
+ <varlistentry id="t-packaging">
+ <term>packaging</term>
<listitem>
<para xmlns="http://www.scons.org/dbxsd/v1.0">
-Sets construction variables for the <function xmlns="http://www.scons.org/dbxsd/v1.0">Package</function> Builder.
+A framework for building binary and source packages.
</para>
</listitem>
</varlistentry>
- <varlistentry id="t-packaging">
- <term>packaging</term>
+ <varlistentry id="t-Packaging">
+ <term>Packaging</term>
<listitem>
<para xmlns="http://www.scons.org/dbxsd/v1.0">
-A framework for building binary and source packages.
+Sets construction variables for the <function xmlns="http://www.scons.org/dbxsd/v1.0">Package</function> Builder.
</para>
</listitem>
</varlistentry>
diff --git a/doc/generated/tools.mod b/doc/generated/tools.mod
index 1209d74..f9bc1d7 100644
--- a/doc/generated/tools.mod
+++ b/doc/generated/tools.mod
@@ -78,8 +78,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!ENTITY t-mwcc "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>mwcc</literal>">
<!ENTITY t-mwld "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>mwld</literal>">
<!ENTITY t-nasm "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>nasm</literal>">
-<!ENTITY t-Packaging "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>Packaging</literal>">
<!ENTITY t-packaging "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>packaging</literal>">
+<!ENTITY t-Packaging "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>Packaging</literal>">
<!ENTITY t-pdf "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>pdf</literal>">
<!ENTITY t-pdflatex "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>pdflatex</literal>">
<!ENTITY t-pdftex "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>pdftex</literal>">
@@ -186,8 +186,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!ENTITY t-link-mwcc "<link linkend='t-mwcc' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>mwcc</literal></link>">
<!ENTITY t-link-mwld "<link linkend='t-mwld' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>mwld</literal></link>">
<!ENTITY t-link-nasm "<link linkend='t-nasm' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>nasm</literal></link>">
-<!ENTITY t-link-Packaging "<link linkend='t-Packaging' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>Packaging</literal></link>">
<!ENTITY t-link-packaging "<link linkend='t-packaging' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>packaging</literal></link>">
+<!ENTITY t-link-Packaging "<link linkend='t-Packaging' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>Packaging</literal></link>">
<!ENTITY t-link-pdf "<link linkend='t-pdf' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>pdf</literal></link>">
<!ENTITY t-link-pdflatex "<link linkend='t-pdflatex' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>pdflatex</literal></link>">
<!ENTITY t-link-pdftex "<link linkend='t-pdftex' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>pdftex</literal></link>">
diff --git a/doc/generated/variables.gen b/doc/generated/variables.gen
index 5ed8c2f..4e84fbc 100644
--- a/doc/generated/variables.gen
+++ b/doc/generated/variables.gen
@@ -4487,6 +4487,7 @@ constructor; setting it later has no effect.
<para xmlns="http://www.scons.org/dbxsd/v1.0">
Valid values for Windows are
+<literal>14.1</literal>,
<literal>14.0</literal>,
<literal>14.0Exp</literal>,
<literal>12.0</literal>,
@@ -6719,16 +6720,6 @@ Example <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-SHLIBVERSION">
</para>
</listitem>
</varlistentry>
- <varlistentry id="cv-SHLIBVERSIONFLAGS">
- <term>SHLIBVERSIONFLAGS</term>
- <listitem>
-<para xmlns="http://www.scons.org/dbxsd/v1.0">
-Extra flags added to <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-SHLINKCOM"><envar>$SHLINKCOM</envar></link> when building versioned
-<link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-SharedLibrary"><function>SharedLibrary</function></link>. These flags are only used when <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-SHLIBVERSION"><envar>$SHLIBVERSION</envar></link> is
-set.
-</para>
-</listitem>
- </varlistentry>
<varlistentry id="cv-_SHLIBVERSIONFLAGS">
<term>_SHLIBVERSIONFLAGS</term>
<listitem>
@@ -6742,6 +6733,16 @@ and some extra dynamically generated options (such as
</para>
</listitem>
</varlistentry>
+ <varlistentry id="cv-SHLIBVERSIONFLAGS">
+ <term>SHLIBVERSIONFLAGS</term>
+ <listitem>
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
+Extra flags added to <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-SHLINKCOM"><envar>$SHLINKCOM</envar></link> when building versioned
+<link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-SharedLibrary"><function>SharedLibrary</function></link>. These flags are only used when <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-SHLIBVERSION"><envar>$SHLIBVERSION</envar></link> is
+set.
+</para>
+</listitem>
+ </varlistentry>
<varlistentry id="cv-SHLINK">
<term>SHLINK</term>
<listitem>
@@ -7221,18 +7222,24 @@ This variable must be passed as an argument to the Environment()
constructor; setting it later has no effect.
This is currently only used on Windows, but in the future it will be
used on other OSes as well.
+If this is set and MSVC_VERSION is not set, this will search for
+all installed MSVC's that support the TARGET_ARCH, selecting the
+latest version for use.
</para>
<para xmlns="http://www.scons.org/dbxsd/v1.0">
Valid values for Windows are
<literal>x86</literal>,
+<literal>arm</literal>,
<literal>i386</literal>
(for 32 bits);
<literal>amd64</literal>,
+<literal>arm64</literal>,
<literal>emt64</literal>,
<literal>x86_64</literal>
(for 64 bits);
and <literal>ia64</literal> (Itanium).
+
For example, if you want to compile 64-bit binaries, you would set
<literal>TARGET_ARCH='x86_64'</literal> in your SCons environment.
</para>
@@ -7272,14 +7279,30 @@ The suffix used for tar file names.
<listitem>
<para xmlns="http://www.scons.org/dbxsd/v1.0">
The prefix for a temporary file used
-to execute lines longer than $MAXLINELENGTH.
-The default is '@'.
-This may be set for toolchains that use other values,
-such as '-@' for the diab compiler
+to store lines lines longer than $MAXLINELENGTH
+as operations which call out to a shell will fail
+if the line is too long, which particularly
+impacts linking.
+The default is '@', which works for the Microsoft
+and GNU toolchains on Windows.
+Set this appropriately for other toolchains,
+for example '-@' for the diab compiler
or '-via' for ARM toolchain.
</para>
</listitem>
</varlistentry>
+ <varlistentry id="cv-TEMPFILESUFFIX">
+ <term>TEMPFILESUFFIX</term>
+ <listitem>
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
+The suffix used for the temporary file name
+used for long command lines. The name should
+include the dot ('.') if one is wanted as
+it will not be added automatically.
+The default is '.lnk'.
+</para>
+</listitem>
+ </varlistentry>
<varlistentry id="cv-TEX">
<term>TEX</term>
<listitem>
diff --git a/doc/generated/variables.mod b/doc/generated/variables.mod
index 7dfb208..ffe4cf1 100644
--- a/doc/generated/variables.mod
+++ b/doc/generated/variables.mod
@@ -503,8 +503,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!ENTITY cv-_SHLIBSONAME "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$_SHLIBSONAME</envar>">
<!ENTITY cv-SHLIBSUFFIX "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$SHLIBSUFFIX</envar>">
<!ENTITY cv-SHLIBVERSION "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$SHLIBVERSION</envar>">
-<!ENTITY cv-SHLIBVERSIONFLAGS "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$SHLIBVERSIONFLAGS</envar>">
<!ENTITY cv-_SHLIBVERSIONFLAGS "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$_SHLIBVERSIONFLAGS</envar>">
+<!ENTITY cv-SHLIBVERSIONFLAGS "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$SHLIBVERSIONFLAGS</envar>">
<!ENTITY cv-SHLINK "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$SHLINK</envar>">
<!ENTITY cv-SHLINKCOM "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$SHLINKCOM</envar>">
<!ENTITY cv-SHLINKCOMSTR "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$SHLINKCOMSTR</envar>">
@@ -544,6 +544,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!ENTITY cv-TARGETS "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$TARGETS</envar>">
<!ENTITY cv-TARSUFFIX "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$TARSUFFIX</envar>">
<!ENTITY cv-TEMPFILEPREFIX "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$TEMPFILEPREFIX</envar>">
+<!ENTITY cv-TEMPFILESUFFIX "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$TEMPFILESUFFIX</envar>">
<!ENTITY cv-TEX "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$TEX</envar>">
<!ENTITY cv-TEXCOM "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$TEXCOM</envar>">
<!ENTITY cv-TEXCOMSTR "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$TEXCOMSTR</envar>">
@@ -1140,8 +1141,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!ENTITY cv-link-_SHLIBSONAME "<link linkend='cv-_SHLIBSONAME' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$_SHLIBSONAME</envar></link>">
<!ENTITY cv-link-SHLIBSUFFIX "<link linkend='cv-SHLIBSUFFIX' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$SHLIBSUFFIX</envar></link>">
<!ENTITY cv-link-SHLIBVERSION "<link linkend='cv-SHLIBVERSION' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$SHLIBVERSION</envar></link>">
-<!ENTITY cv-link-SHLIBVERSIONFLAGS "<link linkend='cv-SHLIBVERSIONFLAGS' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$SHLIBVERSIONFLAGS</envar></link>">
<!ENTITY cv-link-_SHLIBVERSIONFLAGS "<link linkend='cv-_SHLIBVERSIONFLAGS' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$_SHLIBVERSIONFLAGS</envar></link>">
+<!ENTITY cv-link-SHLIBVERSIONFLAGS "<link linkend='cv-SHLIBVERSIONFLAGS' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$SHLIBVERSIONFLAGS</envar></link>">
<!ENTITY cv-link-SHLINK "<link linkend='cv-SHLINK' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$SHLINK</envar></link>">
<!ENTITY cv-link-SHLINKCOM "<link linkend='cv-SHLINKCOM' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$SHLINKCOM</envar></link>">
<!ENTITY cv-link-SHLINKCOMSTR "<link linkend='cv-SHLINKCOMSTR' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$SHLINKCOMSTR</envar></link>">
@@ -1181,6 +1182,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
<!ENTITY cv-link-TARGETS "<link linkend='cv-TARGETS' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$TARGETS</envar></link>">
<!ENTITY cv-link-TARSUFFIX "<link linkend='cv-TARSUFFIX' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$TARSUFFIX</envar></link>">
<!ENTITY cv-link-TEMPFILEPREFIX "<link linkend='cv-TEMPFILEPREFIX' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$TEMPFILEPREFIX</envar></link>">
+<!ENTITY cv-link-TEMPFILESUFFIX "<link linkend='cv-TEMPFILESUFFIX' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$TEMPFILESUFFIX</envar></link>">
<!ENTITY cv-link-TEX "<link linkend='cv-TEX' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$TEX</envar></link>">
<!ENTITY cv-link-TEXCOM "<link linkend='cv-TEXCOM' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$TEXCOM</envar></link>">
<!ENTITY cv-link-TEXCOMSTR "<link linkend='cv-TEXCOMSTR' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$TEXCOMSTR</envar></link>">
diff --git a/doc/man/scons.xml b/doc/man/scons.xml
index 805164c..0f59967 100644
--- a/doc/man/scons.xml
+++ b/doc/man/scons.xml
@@ -54,10 +54,10 @@
<corpauthor>Steven Knight and the SCons Development Team</corpauthor>
- <pubdate>2004 - 2018</pubdate>
+ <pubdate>2004 - 2019</pubdate>
<copyright>
- <year>2004 - 2018</year>
+ <year>2004 - 2019</year>
<holder>The SCons Foundation</holder>
</copyright>
diff --git a/doc/user/copyright.xml b/doc/user/copyright.xml
index 588253c..d36ff1e 100644
--- a/doc/user/copyright.xml
+++ b/doc/user/copyright.xml
@@ -35,7 +35,7 @@
<blockquote>
<para>
- SCons User's Guide Copyright (c) 2004-2018 Steven Knight
+ SCons User's Guide Copyright (c) 2004-2019 Steven Knight
</para>
</blockquote>
diff --git a/src/Announce.txt b/src/Announce.txt
index c7948c0..7eb57ae 100755
--- a/src/Announce.txt
+++ b/src/Announce.txt
@@ -24,15 +24,21 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
release and consult the CHANGES.txt file for complete a list of changes
since last release. This announcement highlights only the important
changes.
+ Please note the following important changes since release 3.0.3:
+ - Added TEMPFILESUFFIX to allow user to specify suffix for tempfiles used for long command lines
+ - Initial support for ARM architectures with Microsoft Visual Studio 2017. You must set TARGET_ARCH
+ to arm or arm64 to enable.
+ - Fixed issue detecting installs of Microsoft Visual Studio 2017 as well as Microsoft build tools 2017.
+
Please note the following important changes since release 2.5.1:
This is the initial release supporting both python 3.5+ and 2.7.x and pypy
There are some important changes:
- - Properly support versioned shared libraries for MacOS. We've also introduced two
- new env variables APPLELINK_CURRENT_VERSION and APPLELINK_COMPATIBILITY_VERSION which will specify
- what is passed to the linkers -current_version and -compatibility_version flags. If not specified
- they will be derived from SHLIBVERSION as such:
+ - Properly support versioned shared libraries for MacOS. We've also introduced two
+ new env variables APPLELINK_CURRENT_VERSION and APPLELINK_COMPATIBILITY_VERSION which will specify
+ what is passed to the linkers -current_version and -compatibility_version flags. If not specified
+ they will be derived from SHLIBVERSION as such:
- APPLELINK_CURRENT_VERSION = SHLIBVERSION
- APPLELINK_COMPATIBILITY_VERSION = all but the last digit in SHLIBVERSION with .0 appended.
Note that the values of the above will be validated. Valid format for either APPLELINK variable is
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 02da450..8103fbd 100644..100755
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -8,13 +8,35 @@
RELEASE VERSION/DATE TO BE FILLED IN LATER
From John Doe:
+
- Whatever John Doe did.
+ From Mats Wichmann:
+ - Quiet open file ResourceWarnings on Python >= 3.6 caused by
+ not using a context manager around Popen.stdout
+
+
+RELEASE 3.0.4 - Mon, 20 Jan 2019 22:49:27 +0000
+
+ From Mats Wichmann:
+ - Improve finding of Microsoft compiler: add a 'products' wildcard
+ in case 2017 Build Tools only is installed as it is considered a separate
+ product from the default Visual Studio
+ - Add TEMPFILESUFFIX to allow a customizable filename extension, as
+ described in the patch attached to issue #2431.
+
From Daniel Moody:
+ - Improved support for VC14.1 and Visual Studio 2017, as well as arm and arm64 targets.
+ Issues #3268 & Issue #3222
+ - Initial support for ARM targets with Visual Studio 2017 - Issue #3182 (You must set TARGET_ARCH for this to work)
- Update TempFileMunge class to use PRINT_CMD_LINE_FUNC
- Update link tool to convert target to node before accessing node member
- Update mingw tool to remove MSVC like nologo CCFLAG
+ From Tobias Herzog
+ - Enhance cpp scanner regex logic to detect if/elif expressions without whitespaces but
+ parenthesis like "#if(defined FOO)" or "#elif!(BAR)" correctly.
+
RELEASE 3.0.3 - Mon, 07 Jan 2019 20:05:22 -0400
NOTE: 3.0.2 release was dropped because there was a packaging bug. Please consider all 3.0.2
content.
diff --git a/src/RELEASE.txt b/src/RELEASE.txt
index 8987ee2..28376a6 100755
--- a/src/RELEASE.txt
+++ b/src/RELEASE.txt
@@ -1,7 +1,7 @@
- A new SCons checkpoint release, 3.0.4.alpha.yyyymmdd, is now available
+ A new SCons checkpoint release, 3.0.5.alpha.yyyymmdd, is now available
on the SCons download page:
- http://www.scons.org/download.php
+ https://scons.org/pages/download.html
XXX The primary purpose of this release ... XXX
diff --git a/src/engine/SCons/Platform/__init__.py b/src/engine/SCons/Platform/__init__.py
index 8117e60..3168378 100644
--- a/src/engine/SCons/Platform/__init__.py
+++ b/src/engine/SCons/Platform/__init__.py
@@ -144,15 +144,20 @@ class TempFileMunge(object):
line limitation.
Example usage:
- env["TEMPFILE"] = TempFileMunge
- env["LINKCOM"] = "${TEMPFILE('$LINK $TARGET $SOURCES','$LINKCOMSTR')}"
+ env["TEMPFILE"] = TempFileMunge
+ env["LINKCOM"] = "${TEMPFILE('$LINK $TARGET $SOURCES','$LINKCOMSTR')}"
By default, the name of the temporary file used begins with a
- prefix of '@'. This may be configred for other tool chains by
- setting '$TEMPFILEPREFIX'.
-
- env["TEMPFILEPREFIX"] = '-@' # diab compiler
- env["TEMPFILEPREFIX"] = '-via' # arm tool chain
+ prefix of '@'. This may be configured for other tool chains by
+ setting '$TEMPFILEPREFIX':
+ env["TEMPFILEPREFIX"] = '-@' # diab compiler
+ env["TEMPFILEPREFIX"] = '-via' # arm tool chain
+ env["TEMPFILEPREFIX"] = '' # (the empty string) PC Lint
+
+ You can configure the extension of the temporary file through the
+ TEMPFILEEXTENSION variable, which defaults to '.lnk' (see comments
+ in the code below):
+ env["TEMPFILEEXTENSION"] = '.lnt' # PC Lint
"""
def __init__(self, cmd, cmdstr = None):
self.cmd = cmd
@@ -189,21 +194,26 @@ class TempFileMunge(object):
node = target[0] if SCons.Util.is_List(target) else target
cmdlist = getattr(node.attributes, 'tempfile_cmdlist', None) \
if node is not None else None
- if cmdlist is not None :
+ if cmdlist is not None:
return cmdlist
# We do a normpath because mktemp() has what appears to be
# a bug in Windows that will use a forward slash as a path
- # delimiter. Windows's link mistakes that for a command line
+ # delimiter. Windows' link mistakes that for a command line
# switch and barfs.
#
- # We use the .lnk suffix for the benefit of the Phar Lap
+ # Default to the .lnk suffix for the benefit of the Phar Lap
# linkloc linker, which likes to append an .lnk suffix if
# none is given.
- (fd, tmp) = tempfile.mkstemp('.lnk', text=True)
+ if env.has_key('TEMPFILESUFFIX'):
+ suffix = env.subst('$TEMPFILESUFFIX')
+ else:
+ suffix = '.lnk'
+
+ fd, tmp = tempfile.mkstemp(suffix, text=True)
native_tmp = SCons.Util.get_native_path(os.path.normpath(tmp))
- if env.get('SHELL',None) == 'sh':
+ if env.get('SHELL', None) == 'sh':
# The sh shell will try to escape the backslashes in the
# path, so unescape them.
native_tmp = native_tmp.replace('\\', r'\\\\')
diff --git a/src/engine/SCons/Platform/__init__.xml b/src/engine/SCons/Platform/__init__.xml
index 0802369..f113278 100644
--- a/src/engine/SCons/Platform/__init__.xml
+++ b/src/engine/SCons/Platform/__init__.xml
@@ -232,13 +232,29 @@ The suffix used for shared object file names.
<summary>
<para>
The prefix for a temporary file used
-to execute lines longer than $MAXLINELENGTH.
-The default is '@'.
-This may be set for toolchains that use other values,
-such as '-@' for the diab compiler
+to store lines lines longer than $MAXLINELENGTH
+as operations which call out to a shell will fail
+if the line is too long, which particularly
+impacts linking.
+The default is '@', which works for the Microsoft
+and GNU toolchains on Windows.
+Set this appropriately for other toolchains,
+for example '-@' for the diab compiler
or '-via' for ARM toolchain.
</para>
</summary>
</cvar>
+<cvar name="TEMPFILESUFFIX">
+<summary>
+<para>
+The suffix used for the temporary file name
+used for long command lines. The name should
+include the dot ('.') if one is wanted as
+it will not be added automatically.
+The default is '.lnk'.
+</para>
+</summary>
+</cvar>
+
</sconsdoc>
diff --git a/src/engine/SCons/Tool/MSCommon/common.py b/src/engine/SCons/Tool/MSCommon/common.py
index b60cd5b..f7c07b2 100644
--- a/src/engine/SCons/Tool/MSCommon/common.py
+++ b/src/engine/SCons/Tool/MSCommon/common.py
@@ -46,7 +46,7 @@ elif LOGFILE:
debug = lambda message: open(LOGFILE, 'a').write(message + '\n')
else:
logging.basicConfig(filename=LOGFILE, level=logging.DEBUG)
- debug = logging.debug
+ debug = logging.getLogger(name=__name__).debug
else:
debug = lambda x: None
@@ -206,7 +206,7 @@ def get_output(vcbat, args = None, env = None):
output = stdout.decode("mbcs")
return output
-def parse_output(output, keep=("INCLUDE", "LIB", "LIBPATH", "PATH")):
+def parse_output(output, keep=("INCLUDE", "LIB", "LIBPATH", "PATH", 'VSCMD_ARG_app_plat')):
"""
Parse output from running visual c++/studios vcvarsall.bat and running set
To capture the values listed in keep
diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py
index 32ee96f..c4ba803 100644
--- a/src/engine/SCons/Tool/MSCommon/vc.py
+++ b/src/engine/SCons/Tool/MSCommon/vc.py
@@ -80,15 +80,43 @@ _ARCH_TO_CANONICAL = {
"i486" : "x86",
"i586" : "x86",
"i686" : "x86",
- "ia64" : "ia64",
- "itanium" : "ia64",
+ "ia64" : "ia64", # deprecated
+ "itanium" : "ia64", # deprecated
"x86" : "x86",
"x86_64" : "amd64",
- "x86_amd64" : "x86_amd64", # Cross compile to 64 bit from 32bits
+ "arm" : "arm",
+ "arm64" : "arm64",
+ "aarch64" : "arm64",
+}
+
+# get path to the cl.exe dir for newer VS versions
+# based off a tuple of (host, target) platforms
+_HOST_TARGET_TO_CL_DIR_GREATER_THAN_14 = {
+ ("amd64","amd64") : "Hostx64\\x64",
+ ("amd64","x86") : "Hostx64\\x86",
+ ("amd64","arm") : "Hostx64\\arm",
+ ("amd64","arm64") : "Hostx64\\arm64",
+ ("x86","amd64") : "Hostx86\\x64",
+ ("x86","x86") : "Hostx86\\x86",
+ ("x86","arm") : "Hostx86\\arm",
+ ("x86","arm64") : "Hostx86\\arm64",
+}
+
+# get path to the cl.exe dir for older VS versions
+# based off a tuple of (host, target) platforms
+_HOST_TARGET_TO_CL_DIR = {
+ ("amd64","amd64") : "amd64",
+ ("amd64","x86") : "amd64_x86",
+ ("amd64","arm") : "amd64_arm",
+ ("amd64","arm64") : "amd64_arm64",
+ ("x86","amd64") : "x86_amd64",
+ ("x86","x86") : "",
+ ("x86","arm") : "x86_arm",
+ ("x86","arm64") : "x86_arm64",
}
-# Given a (host, target) tuple, return the argument for the bat file. Both host
-# and targets should be canonalized.
+# Given a (host, target) tuple, return the argument for the bat file.
+# Both host and targets should be canonalized.
_HOST_TARGET_ARCH_TO_BAT_ARCH = {
("x86", "x86"): "x86",
("x86", "amd64"): "x86_amd64",
@@ -96,9 +124,32 @@ _HOST_TARGET_ARCH_TO_BAT_ARCH = {
("amd64", "x86_amd64"): "x86_amd64", # This is present in (at least) VS2012 express
("amd64", "amd64"): "amd64",
("amd64", "x86"): "x86",
- ("x86", "ia64"): "x86_ia64"
+ ("x86", "ia64"): "x86_ia64", # gone since 14.0
+ ("arm", "arm"): "arm", # since 14.0, maybe gone 14.1?
+ ("x86", "arm"): "x86_arm", # since 14.0
+ ("x86", "arm64"): "x86_arm64", # since 14.1
+ ("amd64", "arm"): "amd64_arm", # since 14.0
+ ("amd64", "arm64"): "amd64_arm64", # since 14.1
}
+_CL_EXE_NAME = 'cl.exe'
+
+def get_msvc_version_numeric(msvc_version):
+ """Get the raw version numbers from a MSVC_VERSION string, so it
+ could be cast to float or other numeric values. For example, '14.0Exp'
+ would get converted to '14.0'.
+
+ Args:
+ msvc_version: str
+ string representing the version number, could contain non
+ digit characters
+
+ Returns:
+ str: the value converted to a numeric only string
+
+ """
+ return ''.join([x for x in msvc_version if x in string_digits + '.'])
+
def get_host_target(env):
debug('vc.py:get_host_target()')
@@ -189,7 +240,7 @@ _VCVER_TO_PRODUCT_DIR = {
}
def msvc_version_to_maj_min(msvc_version):
- msvc_version_numeric = ''.join([x for x in msvc_version if x in string_digits + '.'])
+ msvc_version_numeric = get_msvc_version_numeric(msvc_version)
t = msvc_version_numeric.split(".")
if not len(t) == 2:
@@ -202,21 +253,21 @@ def msvc_version_to_maj_min(msvc_version):
raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric))
def is_host_target_supported(host_target, msvc_version):
- """Return True if the given (host, target) tuple is supported given the
- msvc version.
-
- Parameters
- ----------
- host_target: tuple
- tuple of (canonalized) host-target, e.g. ("x86", "amd64") for cross
- compilation from 32 bits windows to 64 bits.
- msvc_version: str
- msvc version (major.minor, e.g. 10.0)
-
- Note
- ----
- This only check whether a given version *may* support the given (host,
- target), not that the toolchain is actually present on the machine.
+ """Check if the given (host, target) tuple is supported for given version.
+
+ Args:
+ host_target: tuple
+ tuple of (canonalized) host-targets, e.g. ("x86", "amd64")
+ for cross compilation from 32 bit Windows to 64 bits.
+ msvc_version: str
+ msvc version (major.minor, e.g. 10.0)
+
+ Returns:
+ bool:
+
+ Note:
+ This only checks whether a given version *may* support the given (host,
+ target), not that the toolchain is actually present on the machine.
"""
# We assume that any Visual Studio version supports x86 as a target
if host_target[1] != "x86":
@@ -229,10 +280,11 @@ def is_host_target_supported(host_target, msvc_version):
def find_vc_pdir_vswhere(msvc_version):
"""
- Find the MSVC product directory using vswhere.exe .
+ Find the MSVC product directory using vswhere.exe.
+
Run it asking for specified version and get MSVS install location
:param msvc_version:
- :return: MSVC install dir
+ :return: MSVC install dir or None
"""
vswhere_path = os.path.join(
'C:\\',
@@ -241,14 +293,17 @@ def find_vc_pdir_vswhere(msvc_version):
'Installer',
'vswhere.exe'
)
- vswhere_cmd = [vswhere_path, '-version', msvc_version, '-property', 'installationPath']
+ vswhere_cmd = [vswhere_path, '-products', '*', '-version', msvc_version, '-property', 'installationPath']
if os.path.exists(vswhere_path):
sp = subprocess.Popen(vswhere_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
vsdir, err = sp.communicate()
- vsdir = vsdir.decode("mbcs")
- vsdir = vsdir.rstrip()
- vc_pdir = os.path.join(vsdir, 'VC')
+ vsdir = vsdir.decode("mbcs").splitlines()
+ # vswhere could easily return multiple lines
+ # we could define a way to pick the one we prefer, but since
+ # this data is currently only used to make a check for existence,
+ # returning the first hit should be good enough for now.
+ vc_pdir = os.path.join(vsdir[0], 'VC')
return vc_pdir
else:
# No vswhere on system, no install info available
@@ -256,13 +311,25 @@ def find_vc_pdir_vswhere(msvc_version):
def find_vc_pdir(msvc_version):
- """Try to find the product directory for the given
- version.
+ """Find the product directory for the given version.
+
+ Tries to look up the path using a registry key from the table
+ _VCVER_TO_PRODUCT_DIR; if there is no key, calls find_vc_pdir_wshere
+ for help instead.
+
+ Args:
+ msvc_version: str
+ msvc version (major.minor, e.g. 10.0)
- Note
- ----
- If for some reason the requested version could not be found, an
- exception which inherits from VisualCException will be raised."""
+ Returns:
+ str: Path found in registry, or None
+
+ Raises:
+ UnsupportedVersion: if the version is not known by this file.
+ MissingConfiguration: found version but the directory is missing.
+
+ Both exceptions inherit from VisualCException.
+ """
root = 'Software\\'
try:
hkeys = _VCVER_TO_PRODUCT_DIR[msvc_version]
@@ -276,8 +343,10 @@ def find_vc_pdir(msvc_version):
if not key:
comps = find_vc_pdir_vswhere(msvc_version)
if not comps:
- debug('find_vc_dir(): no VC found via vswhere for version {}'.format(repr(key)))
+ debug('find_vc_pdir_vswhere(): no VC found for version {}'.format(repr(msvc_version)))
raise SCons.Util.WinError
+ debug('find_vc_pdir_vswhere(): VC found: {}'.format(repr(msvc_version)))
+ return comps
else:
if common.is_win64():
try:
@@ -309,10 +378,10 @@ def find_batch_file(env,msvc_version,host_arch,target_arch):
if pdir is None:
raise NoVersionFound("No version of Visual Studio found")
- debug('vc.py: find_batch_file() pdir:{}'.format(pdir))
+ debug('vc.py: find_batch_file() in {}'.format(pdir))
# filter out e.g. "Exp" from the version name
- msvc_ver_numeric = ''.join([x for x in msvc_version if x in string_digits + "."])
+ msvc_ver_numeric = get_msvc_version_numeric(msvc_version)
vernum = float(msvc_ver_numeric)
if 7 <= vernum < 8:
pdir = os.path.join(pdir, os.pardir, "Common7", "Tools")
@@ -344,29 +413,132 @@ def find_batch_file(env,msvc_version,host_arch,target_arch):
__INSTALLED_VCS_RUN = None
-def cached_get_installed_vcs():
+def _check_cl_exists_in_vc_dir(env, vc_dir, msvc_version):
+ """Find the cl.exe on the filesystem in the vc_dir depending on
+ TARGET_ARCH, HOST_ARCH and the msvc version. TARGET_ARCH and
+ HOST_ARCH can be extracted from the passed env, unless its None,
+ which then the native platform is assumed the host and target.
+
+ Args:
+ env: Environment
+ a construction environment, usually if this is passed its
+ because there is a desired TARGET_ARCH to be used when searching
+ for a cl.exe
+ vc_dir: str
+ the path to the VC dir in the MSVC installation
+ msvc_version: str
+ msvc version (major.minor, e.g. 10.0)
+
+ Returns:
+ bool:
+
+ """
+
+ # determine if there is a specific target platform we want to build for and
+ # use that to find a list of valid VCs, default is host platform == target platform
+ # and same for if no env is specified to extract target platform from
+ if env:
+ (host_platform, target_platform, req_target_platform) = get_host_target(env)
+ else:
+ host_platform = platform.machine().lower()
+ target_platform = host_platform
+
+ host_platform = _ARCH_TO_CANONICAL[host_platform]
+ target_platform = _ARCH_TO_CANONICAL[target_platform]
+
+ debug('_check_cl_exists_in_vc_dir(): host platform %s, target platform %s' % (host_platform, target_platform))
+
+ ver_num = float(get_msvc_version_numeric(msvc_version))
+
+ # make sure the cl.exe exists meaning the tool is installed
+ if ver_num > 14:
+ # 2017 and newer allowed multiple versions of the VC toolset to be installed at the same time.
+ # Just get the default tool version for now
+ #TODO: support setting a specific minor VC version
+ default_toolset_file = os.path.join(vc_dir, r'Auxiliary\Build\Microsoft.VCToolsVersion.default.txt')
+ try:
+ with open(default_toolset_file) as f:
+ vc_specific_version = f.readlines()[0].strip()
+ except IOError:
+ debug('_check_cl_exists_in_vc_dir(): failed to read ' + default_toolset_file)
+ return False
+ except IndexError:
+ debug('_check_cl_exists_in_vc_dir(): failed to find MSVC version in ' + default_toolset_file)
+ return False
+
+ host_trgt_dir = _HOST_TARGET_TO_CL_DIR_GREATER_THAN_14.get((host_platform, target_platform), None)
+ if not host_trgt_dir:
+ debug('_check_cl_exists_in_vc_dir(): unsupported host/target platform combo')
+ return False
+
+ cl_path = os.path.join(vc_dir, r'Tools\MSVC', vc_specific_version, 'bin', host_trgt_dir, _CL_EXE_NAME)
+ debug('_check_cl_exists_in_vc_dir(): checking for ' + _CL_EXE_NAME + ' at ' + cl_path)
+ if os.path.exists(cl_path):
+ debug('_check_cl_exists_in_vc_dir(): found ' + _CL_EXE_NAME + '!')
+ return True
+
+ elif ver_num <= 14 and ver_num >= 8:
+
+ host_trgt_dir = _HOST_TARGET_TO_CL_DIR.get((host_platform, target_platform), None)
+ if not host_trgt_dir:
+ debug('_check_cl_exists_in_vc_dir(): unsupported host/target platform combo')
+ return False
+
+ cl_path = os.path.join(vc_dir, 'bin', host_trgt_dir, _CL_EXE_NAME)
+ debug('_check_cl_exists_in_vc_dir(): checking for ' + _CL_EXE_NAME + ' at ' + cl_path)
+
+ cl_path_exists = os.path.exists(cl_path)
+ if not cl_path_exists and host_platform == 'amd64':
+ # older versions of visual studio only had x86 binaries,
+ # so if the host platform is amd64, we need to check cross
+ # compile options (x86 binary compiles some other target on a 64 bit os)
+ host_trgt_dir = _HOST_TARGET_TO_CL_DIR.get(('x86', target_platform), None)
+ if not host_trgt_dir:
+ return False
+
+ cl_path = os.path.join(vc_dir, 'bin', host_trgt_dir, _CL_EXE_NAME)
+ debug('_check_cl_exists_in_vc_dir(): checking for ' + _CL_EXE_NAME + ' at ' + cl_path)
+ cl_path_exists = os.path.exists(cl_path)
+
+ if cl_path_exists:
+ debug('_check_cl_exists_in_vc_dir(): found ' + _CL_EXE_NAME + '!')
+ return True
+
+ elif ver_num < 8 and ver_num >= 6:
+ # not sure about these versions so if a walk the VC dir (could be slow)
+ for root, _, files in os.walk(vc_dir):
+ if _CL_EXE_NAME in files:
+ debug('get_installed_vcs ' + _CL_EXE_NAME + ' found %s' % os.path.join(root, _CL_EXE_NAME))
+ return True
+ return False
+ else:
+ # version not support return false
+ debug('_check_cl_exists_in_vc_dir(): unsupported MSVC version: ' + str(ver_num))
+
+ return False
+
+def cached_get_installed_vcs(env=None):
global __INSTALLED_VCS_RUN
if __INSTALLED_VCS_RUN is None:
- ret = get_installed_vcs()
+ ret = get_installed_vcs(env)
__INSTALLED_VCS_RUN = ret
return __INSTALLED_VCS_RUN
-def get_installed_vcs():
+def get_installed_vcs(env=None):
installed_versions = []
+
for ver in _VCVER:
debug('trying to find VC %s' % ver)
try:
VC_DIR = find_vc_pdir(ver)
if VC_DIR:
debug('found VC %s' % ver)
- # check to see if the x86 or 64 bit compiler is in the bin dir
- if (os.path.exists(os.path.join(VC_DIR, r'bin\cl.exe'))
- or os.path.exists(os.path.join(VC_DIR, r'bin\amd64\cl.exe'))):
+ if _check_cl_exists_in_vc_dir(env, VC_DIR, ver):
installed_versions.append(ver)
else:
- debug('find_vc_pdir no cl.exe found %s' % ver)
+ debug('find_vc_pdir no compiler found %s' % ver)
else:
debug('find_vc_pdir return None for ver %s' % ver)
except VisualCException as e:
@@ -423,7 +595,7 @@ def get_default_version(env):
% (msvc_version, msvs_version))
return msvs_version
if not msvc_version:
- installed_vcs = cached_get_installed_vcs()
+ installed_vcs = cached_get_installed_vcs(env)
debug('installed_vcs:%s' % installed_vcs)
if not installed_vcs:
#msg = 'No installed VCs'
@@ -450,16 +622,17 @@ def msvc_find_valid_batch_script(env,version):
debug('vc.py:msvc_find_valid_batch_script()')
# Find the host platform, target platform, and if present the requested
# target platform
- (host_platform, target_platform,req_target_platform) = get_host_target(env)
+ platforms = get_host_target(env)
+ debug("vc.py: msvs_find_valid_batch_script(): host_platform %s, target_platform %s req_target_platform:%s" % platforms)
+ host_platform, target_platform, req_target_platform = platforms
try_target_archs = [target_platform]
- debug("msvs_find_valid_batch_script(): req_target_platform %s target_platform:%s"%(req_target_platform,target_platform))
# VS2012 has a "cross compile" environment to build 64 bit
# with x86_amd64 as the argument to the batch setup script
- if req_target_platform in ('amd64','x86_64'):
+ if req_target_platform in ('amd64', 'x86_64'):
try_target_archs.append('x86_amd64')
- elif not req_target_platform and target_platform in ['amd64','x86_64']:
+ elif not req_target_platform and target_platform in ['amd64', 'x86_64']:
# There may not be "native" amd64, but maybe "cross" x86_amd64 tools
try_target_archs.append('x86_amd64')
# If the user hasn't specifically requested a TARGET_ARCH, and
@@ -481,7 +654,7 @@ def msvc_find_valid_batch_script(env,version):
(host_target, version)
SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
arg = _HOST_TARGET_ARCH_TO_BAT_ARCH[host_target]
-
+
# Get just version numbers
maj, min = msvc_version_to_maj_min(version)
# VS2015+
@@ -500,15 +673,17 @@ def msvc_find_valid_batch_script(env,version):
warn_msg = "VC version %s not installed. " + \
"C/C++ compilers are most likely not set correctly.\n" + \
" Installed versions are: %s"
- warn_msg = warn_msg % (version, cached_get_installed_vcs())
+ warn_msg = warn_msg % (version, cached_get_installed_vcs(env))
SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
continue
# Try to use the located batch file for this host/target platform combo
debug('vc.py:msvc_find_valid_batch_script() use_script 2 %s, args:%s\n' % (repr(vc_script), arg))
+ found = None
if vc_script:
try:
d = script_env(vc_script, args=arg)
+ found = vc_script
except BatchFileExecutionError as e:
debug('vc.py:msvc_find_valid_batch_script() use_script 3: failed running VC script %s: %s: Error:%s'%(repr(vc_script),arg,e))
vc_script=None
@@ -517,6 +692,7 @@ def msvc_find_valid_batch_script(env,version):
debug('vc.py:msvc_find_valid_batch_script() use_script 4: trying sdk script: %s'%(sdk_script))
try:
d = script_env(sdk_script)
+ found = sdk_script
except BatchFileExecutionError as e:
debug('vc.py:msvc_find_valid_batch_script() use_script 5: failed running SDK script %s: Error:%s'%(repr(sdk_script),e))
continue
@@ -524,7 +700,7 @@ def msvc_find_valid_batch_script(env,version):
debug('vc.py:msvc_find_valid_batch_script() use_script 6: Neither VC script nor SDK script found')
continue
- debug("vc.py:msvc_find_valid_batch_script() Found a working script/target: %s %s"%(repr(sdk_script),arg))
+ debug("vc.py:msvc_find_valid_batch_script() Found a working script/target: %s/%s"%(repr(found),arg))
break # We've found a working target_platform, so stop looking
# If we cannot find a viable installed compiler, reset the TARGET_ARCH
@@ -572,15 +748,15 @@ def msvc_setup_env(env):
for k, v in d.items():
debug('vc.py:msvc_setup_env() env:%s -> %s'%(k,v))
env.PrependENVPath(k, v, delete_existing=True)
-
+
# final check to issue a warning if the compiler is not present
msvc_cl = find_program_path(env, 'cl')
if not msvc_cl:
- SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning,
- "Could not find MSVC compiler 'cl.exe', it may need to be installed separately with Visual Studio")
+ SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning,
+ "Could not find MSVC compiler 'cl', it may need to be installed separately with Visual Studio")
-def msvc_exists(version=None):
- vcs = cached_get_installed_vcs()
+def msvc_exists(env=None, version=None):
+ vcs = cached_get_installed_vcs(env)
if version is None:
return len(vcs) > 0
return version in vcs
diff --git a/src/engine/SCons/Tool/MSCommon/vs.py b/src/engine/SCons/Tool/MSCommon/vs.py
index f9382fb..8fd4ea0 100644
--- a/src/engine/SCons/Tool/MSCommon/vs.py
+++ b/src/engine/SCons/Tool/MSCommon/vs.py
@@ -68,9 +68,9 @@ class VisualStudio(object):
SCons.Tool.MSCommon.vc.get_installed_vcs()
dir = SCons.Tool.MSCommon.vc.find_vc_pdir(self.vc_version)
if not dir:
- debug('find_vs_dir(): no installed VC %s' % self.vc_version)
+ debug('find_vs_dir_by_vc(): no installed VC %s' % self.vc_version)
return None
- return dir
+ return os.path.abspath(os.path.join(dir, os.pardir))
def find_vs_dir_by_reg(self):
root = 'Software\\'
@@ -95,12 +95,11 @@ class VisualStudio(object):
First try to find by registry, and if that fails find via VC dir
"""
-
- if True:
- vs_dir=self.find_vs_dir_by_reg()
- return vs_dir
- else:
- return self.find_vs_dir_by_vc()
+ vs_dir=self.find_vs_dir_by_reg()
+ if not vs_dir:
+ vs_dir = self.find_vs_dir_by_vc()
+ debug('find_vs_dir(): found VS in ' + str(vs_dir ))
+ return vs_dir
def find_executable(self):
vs_dir = self.get_vs_dir()
diff --git a/src/engine/SCons/Tool/gcc.py b/src/engine/SCons/Tool/gcc.py
index fabcc96..79b64f0 100644
--- a/src/engine/SCons/Tool/gcc.py
+++ b/src/engine/SCons/Tool/gcc.py
@@ -68,32 +68,40 @@ def exists(env):
def detect_version(env, cc):
"""Return the version of the GNU compiler, or None if it is not a GNU compiler."""
+ version = None
cc = env.subst(cc)
if not cc:
- return None
- version = None
+ return version
+
+ # -dumpversion was added in GCC 3.0. As long as we're supporting
+ # GCC versions older than that, we should use --version and a
+ # regular expression.
# pipe = SCons.Action._subproc(env, SCons.Util.CLVar(cc) + ['-dumpversion'],
pipe = SCons.Action._subproc(env, SCons.Util.CLVar(cc) + ['--version'],
stdin='devnull',
stderr='devnull',
stdout=subprocess.PIPE)
- # -dumpversion was added in GCC 3.0. As long as we're supporting
- # GCC versions older than that, we should use --version and a
- # regular expression.
- # line = pipe.stdout.read().strip()
+ if pipe.wait() != 0:
+ return version
+
+ with pipe.stdout:
+ # -dumpversion variant:
+ # line = pipe.stdout.read().strip()
+ # --version variant:
+ line = SCons.Util.to_str(pipe.stdout.readline())
+ # Non-GNU compiler's output (like AIX xlc's) may exceed the stdout buffer:
+ # So continue with reading to let the child process actually terminate.
+ while SCons.Util.to_str(pipe.stdout.readline()):
+ pass
+
+ # -dumpversion variant:
# if line:
- # version = line
- line = SCons.Util.to_str(pipe.stdout.readline())
+ # version = line
+ # --version variant:
match = re.search(r'[0-9]+(\.[0-9]+)+', line)
if match:
version = match.group(0)
- # Non-GNU compiler's output (like AIX xlc's) may exceed the stdout buffer:
- # So continue with reading to let the child process actually terminate.
- while SCons.Util.to_str(pipe.stdout.readline()):
- pass
- ret = pipe.wait()
- if ret != 0:
- return None
+
return version
# Local Variables:
diff --git a/src/engine/SCons/Tool/midl.py b/src/engine/SCons/Tool/midl.py
index ed9ea94..2757c34 100644
--- a/src/engine/SCons/Tool/midl.py
+++ b/src/engine/SCons/Tool/midl.py
@@ -79,7 +79,7 @@ def generate(env):
env['BUILDERS']['TypeLibrary'] = midl_builder
def exists(env):
- return msvc_exists()
+ return msvc_exists(env)
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Tool/mslib.py b/src/engine/SCons/Tool/mslib.py
index c5a7a32..c901a75 100644
--- a/src/engine/SCons/Tool/mslib.py
+++ b/src/engine/SCons/Tool/mslib.py
@@ -55,7 +55,7 @@ def generate(env):
env['LIBSUFFIX'] = '.lib'
def exists(env):
- return msvc_exists()
+ return msvc_exists(env)
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Tool/mslink.py b/src/engine/SCons/Tool/mslink.py
index 55cf33f..c8b00d2 100644
--- a/src/engine/SCons/Tool/mslink.py
+++ b/src/engine/SCons/Tool/mslink.py
@@ -328,7 +328,7 @@ def generate(env):
env['LDMODULECOM'] = compositeLdmodAction
def exists(env):
- return msvc_exists()
+ return msvc_exists(env)
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Tool/msvc.py b/src/engine/SCons/Tool/msvc.py
index 1412cf7..9f3c1fa 100644
--- a/src/engine/SCons/Tool/msvc.py
+++ b/src/engine/SCons/Tool/msvc.py
@@ -289,7 +289,7 @@ def generate(env):
env['ENV']['SystemRoot'] = SCons.Platform.win32.get_system_root()
def exists(env):
- return msvc_exists()
+ return msvc_exists(env)
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Tool/msvc.xml b/src/engine/SCons/Tool/msvc.xml
index d4ffe0d..dacdcba 100644
--- a/src/engine/SCons/Tool/msvc.xml
+++ b/src/engine/SCons/Tool/msvc.xml
@@ -353,6 +353,7 @@ constructor; setting it later has no effect.
<para>
Valid values for Windows are
+<literal>14.1</literal>,
<literal>14.0</literal>,
<literal>14.0Exp</literal>,
<literal>12.0</literal>,
@@ -425,18 +426,24 @@ This variable must be passed as an argument to the Environment()
constructor; setting it later has no effect.
This is currently only used on Windows, but in the future it will be
used on other OSes as well.
+If this is set and MSVC_VERSION is not set, this will search for
+all installed MSVC's that support the TARGET_ARCH, selecting the
+latest version for use.
</para>
<para>
Valid values for Windows are
<literal>x86</literal>,
+<literal>arm</literal>,
<literal>i386</literal>
(for 32 bits);
<literal>amd64</literal>,
+<literal>arm64</literal>,
<literal>emt64</literal>,
<literal>x86_64</literal>
(for 64 bits);
and <literal>ia64</literal> (Itanium).
+
For example, if you want to compile 64-bit binaries, you would set
<literal>TARGET_ARCH='x86_64'</literal> in your SCons environment.
</para>
diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py
index 62f27f2..60ba278 100644
--- a/src/engine/SCons/Tool/msvs.py
+++ b/src/engine/SCons/Tool/msvs.py
@@ -1096,12 +1096,17 @@ V10DSPCommandLine = """\
\t\t<NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies>
"""
+V15DSPHeader = """\
+<?xml version="1.0" encoding="%(encoding)s"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+"""
+
class _GenerateV10DSP(_DSPGenerator, _GenerateV10User):
"""Generates a Project file for MSVS 2010"""
- def __init__(self, dspfile, source, env):
+ def __init__(self, dspfile, header, source, env):
_DSPGenerator.__init__(self, dspfile, source, env)
- self.dspheader = V10DSPHeader
+ self.dspheader = header
self.dspconfiguration = V10DSPProjectConfiguration
self.dspglobals = V10DSPGlobals
@@ -1501,7 +1506,9 @@ class _GenerateV7DSW(_DSWGenerator):
def PrintSolution(self):
"""Writes a solution file"""
self.file.write('Microsoft Visual Studio Solution File, Format Version %s\n' % self.versionstr)
- if self.version_num >= 12.0:
+ if self.version_num > 14.0:
+ self.file.write('# Visual Studio 15\n')
+ elif self.version_num >= 12.0:
self.file.write('# Visual Studio 14\n')
elif self.version_num >= 11.0:
self.file.write('# Visual Studio 11\n')
@@ -1679,8 +1686,11 @@ def GenerateDSP(dspfile, source, env):
version_num = 6.0
if 'MSVS_VERSION' in env:
version_num, suite = msvs_parse_version(env['MSVS_VERSION'])
- if version_num >= 10.0:
- g = _GenerateV10DSP(dspfile, source, env)
+ if version_num > 14.0:
+ g = _GenerateV10DSP(dspfile, V15DSPHeader, source, env)
+ g.Build()
+ elif version_num >= 10.0:
+ g = _GenerateV10DSP(dspfile, V10DSPHeader, source, env)
g.Build()
elif version_num >= 7.0:
g = _GenerateV7DSP(dspfile, source, env)
@@ -1990,7 +2000,7 @@ def generate(env):
env['SCONS_HOME'] = os.environ.get('SCONS_HOME')
def exists(env):
- return msvc_exists()
+ return msvc_exists(env)
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Tool/msvsTests.py b/src/engine/SCons/Tool/msvsTests.py
index bf82114..6adc598 100644
--- a/src/engine/SCons/Tool/msvsTests.py
+++ b/src/engine/SCons/Tool/msvsTests.py
@@ -540,6 +540,10 @@ def DummyQueryValue(key, value):
def DummyExists(path):
return 1
+def DummyVsWhere(msvc_version):
+ # not testing versions with vswhere, so return none
+ return None
+
class msvsTestCase(unittest.TestCase):
"""This test case is run several times with different defaults.
See its subclasses below."""
@@ -809,6 +813,7 @@ if __name__ == "__main__":
SCons.Util.RegEnumKey = DummyEnumKey
SCons.Util.RegEnumValue = DummyEnumValue
SCons.Util.RegQueryValueEx = DummyQueryValue
+ SCons.Tool.MSCommon.vc.find_vc_pdir_vswhere = DummyVsWhere
os.path.exists = DummyExists # make sure all files exist :-)
os.path.isfile = DummyExists # make sure all files are files :-)
diff --git a/src/engine/SCons/Tool/swig.py b/src/engine/SCons/Tool/swig.py
index 08881a0..77cfe1d 100644
--- a/src/engine/SCons/Tool/swig.py
+++ b/src/engine/SCons/Tool/swig.py
@@ -135,21 +135,31 @@ def _swigEmitter(target, source, env):
def _get_swig_version(env, swig):
"""Run the SWIG command line tool to get and return the version number"""
+ version = None
swig = env.subst(swig)
+ if not swig:
+ return version
pipe = SCons.Action._subproc(env, SCons.Util.CLVar(swig) + ['-version'],
stdin = 'devnull',
stderr = 'devnull',
stdout = subprocess.PIPE)
- if pipe.wait() != 0: return
+ if pipe.wait() != 0:
+ return version
# MAYBE: out = SCons.Util.to_str (pipe.stdout.read())
- out = SCons.Util.to_str(pipe.stdout.read())
+ with pipe.stdout:
+ out = SCons.Util.to_str(pipe.stdout.read())
+
match = re.search('SWIG Version\s+(\S+).*', out, re.MULTILINE)
if match:
- if verbose: print("Version is:%s"%match.group(1))
- return match.group(1)
+ version = match.group(1)
+ if verbose:
+ print("Version is: %s" % version)
else:
- if verbose: print("Unable to detect version: [%s]"%out)
+ if verbose:
+ print("Unable to detect version: [%s]" % out)
+
+ return version
def generate(env):
"""Add Builders and construction variables for swig to an Environment."""
diff --git a/src/engine/SCons/cpp.py b/src/engine/SCons/cpp.py
index d2178a7..cdd3923 100644
--- a/src/engine/SCons/cpp.py
+++ b/src/engine/SCons/cpp.py
@@ -43,10 +43,13 @@ import re
# that we want to fetch, using the regular expressions to which the lists
# of preprocessor directives map.
cpp_lines_dict = {
- # Fetch the rest of a #if/#elif/#ifdef/#ifndef as one argument,
+ # Fetch the rest of a #if/#elif as one argument,
+ # with white space optional.
+ ('if', 'elif') : '\s*(.+)',
+
+ # Fetch the rest of a #ifdef/#ifndef as one argument,
# separated from the keyword by white space.
- ('if', 'elif', 'ifdef', 'ifndef',)
- : '\s+(.+)',
+ ('ifdef', 'ifndef',): '\s+(.+)',
# Fetch the rest of a #import/#include/#include_next line as one
# argument, with white space optional.
diff --git a/src/engine/SCons/cppTests.py b/src/engine/SCons/cppTests.py
index d496273..ebf7fde 100644
--- a/src/engine/SCons/cppTests.py
+++ b/src/engine/SCons/cppTests.py
@@ -363,6 +363,62 @@ ifndef_input = """
"""
+if_defined_no_space_input = """
+#define DEFINED 0
+
+#if(defined DEFINED)
+#include "file47-yes"
+#endif
+
+#if(!defined DEFINED)
+#include <file48-no>
+#elif(!defined DEFINED)
+#include <file49-no>
+#else
+#include <file50-yes>
+#endif
+
+#if!(defined DEFINED)
+#include "file51-no"
+#elif!(defined DEFINED)
+#include <file52-no>
+#else
+#include "file53-yes"
+#endif
+"""
+
+if_no_space_input = """
+#define DEFINED 0
+
+#if(DEFINED)
+#include "file54-no"
+#endif
+
+#if!(DEFINED)
+#include <file55-yes>
+#elif!(DEFINED)
+#include <file56-no>
+#endif
+
+#if(DEFINED)
+#include "file57-no"
+#elif(!DEFINED)
+#include <file58-yes>
+#endif
+
+#if!( DEFINED)
+#include "file59-yes"
+#elif!( DEFINED)
+#include <file60-no>
+#endif
+
+#if( DEFINED)
+#include "file61-no"
+#elif(! DEFINED)
+#include <file62-yes>
+#endif
+"""
+
# pp_class = PreProcessor
# #pp_class = DumbPreProcessor
@@ -450,6 +506,19 @@ class cppTestCase(unittest.TestCase):
result = self.cpp.process_contents(ifndef_input)
assert expect == result, (expect, result)
+ def test_if_defined_no_space(self):
+ """Test #if(defined, i.e.without space but parenthesis"""
+ expect = self.if_defined_no_space_expect
+ result = self.cpp.process_contents(if_defined_no_space_input)
+ assert expect == result, (expect, result)
+
+ def test_if_no_space(self):
+ """Test #if(, i.e. without space but parenthesis"""
+ expect = self.if_no_space_expect
+ result = self.cpp.process_contents(if_no_space_input)
+ assert expect == result, (expect, result)
+
+
class cppAllTestCase(cppTestCase):
def setUp(self):
self.cpp = self.cpp_class(current = ".",
@@ -541,7 +610,20 @@ class PreProcessorTestCase(cppAllTestCase):
('include', '"', 'file45-yes'),
('include', '<', 'file46-yes'),
]
-
+
+ if_defined_no_space_expect = [
+ ('include', '"', 'file47-yes'),
+ ('include', '<', 'file50-yes'),
+ ('include', '"', 'file53-yes'),
+ ]
+
+ if_no_space_expect = [
+ ('include', '<', 'file55-yes'),
+ ('include', '<', 'file58-yes'),
+ ('include', '"', 'file59-yes'),
+ ('include', '<', 'file62-yes'),
+ ]
+
class DumbPreProcessorTestCase(cppAllTestCase):
cpp_class = cpp.DumbPreProcessor
@@ -654,7 +736,6 @@ class DumbPreProcessorTestCase(cppAllTestCase):
('include', '"', 'file7-yes')
]
-
ifndef_expect = [
('include', '"', 'file45-no'),
('include', '"', 'file45-yes'),
@@ -662,6 +743,28 @@ class DumbPreProcessorTestCase(cppAllTestCase):
('include', '<', 'file46-no'),
]
+ if_defined_no_space_expect = [
+ ('include', '"', 'file47-yes'),
+ ('include', '<', 'file48-no'),
+ ('include', '<', 'file49-no'),
+ ('include', '<', 'file50-yes'),
+ ('include', '"', 'file51-no'),
+ ('include', '<', 'file52-no'),
+ ('include', '"', 'file53-yes'),
+ ]
+
+ if_no_space_expect = [
+ ('include', '"', 'file54-no'),
+ ('include', '<', 'file55-yes'),
+ ('include', '<', 'file56-no'),
+ ('include', '"', 'file57-no'),
+ ('include', '<', 'file58-yes'),
+ ('include', '"', 'file59-yes'),
+ ('include', '<', 'file60-no'),
+ ('include', '"', 'file61-no'),
+ ('include', '<', 'file62-yes'),
+ ]
+
import os
import re
import shutil
diff --git a/src/script/scons.py b/src/script/scons.py
index d22e76b..d22e76b 100644..100755
--- a/src/script/scons.py
+++ b/src/script/scons.py
diff --git a/template/RELEASE.txt b/template/RELEASE.txt
index 17f11ca..3ebb0d0 100644..100755
--- a/template/RELEASE.txt
+++ b/template/RELEASE.txt
@@ -1,7 +1,7 @@
A new SCons checkpoint release, 2.0.0.beta.yyyymmdd, is now available
on the SCons download page:
- http://www.scons.org/download.php
+ https://scons.org/pages/download.html
XXX The primary purpose of this release ... XXX
diff --git a/test/MSVC/MSVC_UWP_APP.py b/test/MSVC/MSVC_UWP_APP.py
index c72c739..861edcd 100644
--- a/test/MSVC/MSVC_UWP_APP.py
+++ b/test/MSVC/MSVC_UWP_APP.py
@@ -31,22 +31,28 @@ the desired effect.
import TestSCons
import SCons.Tool.MSCommon.vc as msvc
+from SCons.Tool.MSCommon.vc import get_msvc_version_numeric
def AreVCStoreLibPathsInLIBPATH(output):
libpath = None
msvc_version = None
+ UWP_APP = None
lines = output.splitlines()
for line in lines:
if 'env[ENV][LIBPATH]=' in line:
libpath = line.split('=')[1]
elif 'env[MSVC_VERSION]=' in line:
msvc_version = line.split('=')[1]
+ elif 'env[ENV][VSCMD_ARG_app_plat]=' in line:
+ UWP_APP = line.split('=')[1]
if not libpath or not msvc_version:
# Couldn't find the libpath or msvc version in the output
return (False, False, None)
libpaths = libpath.lower().split(';')
+ msvc_num = float(get_msvc_version_numeric(msvc_version))
+
(vclibstore_path_present, vclibstorerefs_path_present) = (False, False)
for path in libpaths:
# Look for the Store VC Lib paths in the LIBPATH:
@@ -55,10 +61,18 @@ def AreVCStoreLibPathsInLIBPATH(output):
# For example,
# C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB\store\amd64
# C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB\store\references
- if r'vc\lib\store\references' in path:
- vclibstorerefs_path_present = True
- elif r'vc\lib\store' in path:
- vclibstore_path_present = True
+
+ if msvc_num <= 14:
+ if r'vc\lib\store\references' in path:
+ vclibstorerefs_path_present = True
+ elif r'vc\lib\store' in path:
+ vclibstore_path_present = True
+ elif msvc_num > 14:
+ if UWP_APP == "UWP":
+ if(r'\lib\x86\store\references' in path
+ or r'\lib\x64\store' in path):
+ vclibstorerefs_path_present = True
+ vclibstore_path_present = True
return (vclibstore_path_present, vclibstorerefs_path_present, msvc_version)
@@ -68,60 +82,88 @@ test = TestSCons.TestSCons()
test.skip_if_not_msvc()
-test.write('SConstruct', """
+installed_msvc_versions = msvc.cached_get_installed_vcs()
+# MSVC guaranteed to be at least one version on the system or else skip_if_not_msvc() function
+# would have skipped the test
+
+msvc_140 = '14.0' in installed_msvc_versions
+msvc_141 = '14.1' in installed_msvc_versions
+
+if not (msvc_140 or msvc_141):
+ test.skip_test("Available MSVC doesn't support App store")
+
+if msvc_140:
+
+ test.write('SConstruct', """
if ARGUMENTS.get('MSVC_UWP_APP'):
help_vars = Variables()
help_vars.Add(EnumVariable(
- 'MSVC_UWP_APP',
- 'Build for a Universal Windows Platform (UWP) Application',
- '0',
- allowed_values=('0', '1')))
+ 'MSVC_UWP_APP',
+ 'Build for a Universal Windows Platform (UWP) Application',
+ '0',
+ allowed_values=('0', '1')))
else:
help_vars = None
-env = Environment(tools=['default', 'msvc'], variables=help_vars)
+env = Environment(tools=['default', 'msvc'], variables=help_vars, MSVC_VERSION='14.0')
# Print the ENV LIBPATH to stdout
print('env[ENV][LIBPATH]=%s' % env.get('ENV').get('LIBPATH'))
print('env[MSVC_VERSION]=%s' % env.get('MSVC_VERSION'))
""")
-installed_msvc_versions = msvc.cached_get_installed_vcs()
-# MSVC guaranteed to be at least one version on the system or else skip_if_not_msvc() function
-# would have skipped the test
-greatest_msvc_version_on_system = installed_msvc_versions[0]
-maj, min = msvc.msvc_version_to_maj_min(greatest_msvc_version_on_system)
-
-# We always use the greatest MSVC version installed on the system
-
-if maj < 14:
- # Skip the test if MSVC version is less than VS2015
- test.skip_test("Available MSVC doesn't support App store ")
-
-# Test setting MSVC_UWP_APP is '1' (True)
-test.run(arguments = "MSVC_UWP_APP=1")
-(vclibstore_path_present, vclibstorerefs_path_present, msvc_version) = AreVCStoreLibPathsInLIBPATH(test.stdout())
-test.fail_test(msvc_version != greatest_msvc_version_on_system,
- message='MSVC_VERSION (%s) does not match expected greatest version on system (%s)' \
- % (msvc_version, greatest_msvc_version_on_system))
-test.fail_test((vclibstore_path_present is False) or (vclibstorerefs_path_present is False),
- message='VC Store LIBPATHs NOT present when MSVC_UWP_APP=1 (msvc_version=%s)' % msvc_version)
-
-# Test setting MSVC_UWP_APP is '0' (False)
-test.run(arguments = "MSVC_UWP_APP=0")
-(vclibstore_path_present, vclibstorerefs_path_present, msvc_version) = AreVCStoreLibPathsInLIBPATH(test.stdout())
-test.fail_test(msvc_version != greatest_msvc_version_on_system,
- message='MSVC_VERSION (%s) does not match expected greatest version on system (%s)' \
- % (msvc_version, greatest_msvc_version_on_system))
-test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True),
- message='VC Store LIBPATHs present when MSVC_UWP_APP=0 (msvc_version=%s)' % msvc_version)
-
-# Test not setting MSVC_UWP_APP
-test.run(arguments = "")
-(vclibstore_path_present, vclibstorerefs_path_present, msvc_version) = AreVCStoreLibPathsInLIBPATH(test.stdout())
-test.fail_test(msvc_version != greatest_msvc_version_on_system,
- message='MSVC_VERSION (%s) does not match expected greatest version on system (%s)' \
- % (msvc_version, greatest_msvc_version_on_system))
-test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True),
- message='VC Store LIBPATHs present when MSVC_UWP_APP not set (msvc_version=%s)' % msvc_version)
+ # Test setting MSVC_UWP_APP is '1' (True)
+ test.run(arguments = "MSVC_UWP_APP=1")
+ (vclibstore_path_present, vclibstorerefs_path_present, msvc_version) = AreVCStoreLibPathsInLIBPATH(test.stdout())
+ test.fail_test((vclibstore_path_present is False) or (vclibstorerefs_path_present is False),
+ message='VC Store LIBPATHs NOT present when MSVC_UWP_APP=1 (msvc_version=%s)' % msvc_version)
+
+ # Test setting MSVC_UWP_APP is '0' (False)
+ test.run(arguments = "MSVC_UWP_APP=0")
+ (vclibstore_path_present, vclibstorerefs_path_present, msvc_version) = AreVCStoreLibPathsInLIBPATH(test.stdout())
+ test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True),
+ message='VC Store LIBPATHs present when MSVC_UWP_APP=0 (msvc_version=%s)' % msvc_version)
+
+ # Test not setting MSVC_UWP_APP
+ test.run(arguments = "")
+ (vclibstore_path_present, vclibstorerefs_path_present, msvc_version) = AreVCStoreLibPathsInLIBPATH(test.stdout())
+ test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True),
+ message='VC Store LIBPATHs present when MSVC_UWP_APP not set (msvc_version=%s)' % msvc_version)
+
+if msvc_141:
+
+ test.write('SConstruct', """
+if ARGUMENTS.get('MSVC_UWP_APP'):
+ help_vars = Variables()
+ help_vars.Add(EnumVariable(
+ 'MSVC_UWP_APP',
+ 'Build for a Universal Windows Platform (UWP) Application',
+ '0',
+ allowed_values=('0', '1')))
+else:
+ help_vars = None
+env = Environment(tools=['default', 'msvc'], variables=help_vars, MSVC_VERSION='14.1')
+# Print the ENV LIBPATH to stdout
+print('env[ENV][LIBPATH]=%s' % env.get('ENV').get('LIBPATH'))
+print('env[MSVC_VERSION]=%s' % env.get('MSVC_VERSION'))
+print('env[ENV][VSCMD_ARG_app_plat]=%s' % env.get('ENV').get('VSCMD_ARG_app_plat'))
+""")
+
+ # Test setting MSVC_UWP_APP is '1' (True)
+ test.run(arguments = "MSVC_UWP_APP=1")
+ (vclibstore_path_present, vclibstorerefs_path_present, msvc_version) = AreVCStoreLibPathsInLIBPATH(test.stdout())
+ test.fail_test((vclibstore_path_present is False) or (vclibstorerefs_path_present is False),
+ message='VC Store LIBPATHs NOT present when MSVC_UWP_APP=1 (msvc_version=%s)' % msvc_version)
+
+ # Test setting MSVC_UWP_APP is '0' (False)
+ test.run(arguments = "MSVC_UWP_APP=0")
+ (vclibstore_path_present, vclibstorerefs_path_present, msvc_version) = AreVCStoreLibPathsInLIBPATH(test.stdout())
+ test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True),
+ message='VC Store LIBPATHs NOT present when MSVC_UWP_APP=1 (msvc_version=%s)' % msvc_version)
+
+ # Test not setting MSVC_UWP_APP
+ test.run(arguments = "")
+ (vclibstore_path_present, vclibstorerefs_path_present, msvc_version) = AreVCStoreLibPathsInLIBPATH(test.stdout())
+ test.fail_test((vclibstore_path_present is True) or (vclibstorerefs_path_present is True),
+ message='VC Store LIBPATHs NOT present when MSVC_UWP_APP=1 (msvc_version=%s)' % msvc_version)
test.pass_test()
diff --git a/test/MSVC/TARGET_ARCH.py b/test/MSVC/TARGET_ARCH.py
index 1df28d0..a960bd8 100644
--- a/test/MSVC/TARGET_ARCH.py
+++ b/test/MSVC/TARGET_ARCH.py
@@ -56,6 +56,26 @@ test.run(arguments = ".", status=2, stderr=None)
test.must_contain_any_line(test.stderr(), "Unrecognized target architecture")
test.must_contain_any_line(test.stderr(), "Valid architectures")
+test.write('SConstruct', """
+env = Environment(tools=['default', 'msvc'],
+ TARGET_ARCH = 'arm', MSVC_VERSION='11.0')
+if env.Detect('cl'):
+ env.Command('checkarm', [], 'cl')
+""" % locals())
+test.run(arguments = ".", stderr = None)
+if test.stderr().strip() is not "" and "ARM" not in test.stderr():
+ test.fail_test()
+
+test.write('SConstruct', """
+env = Environment(tools=['default', 'msvc'],
+ TARGET_ARCH = 'arm64', MSVC_VERSION='11.0')
+if env.Detect('cl'):
+ env.Command('checkarm64', [], 'cl')
+""" % locals())
+test.run(arguments = ".", stderr = None)
+if test.stderr().strip() is not "" and "ARM64" not in test.stderr():
+ test.fail_test()
+
test.pass_test()
# Local Variables:
diff --git a/test/MSVS/vs-14.1-exec.py b/test/MSVS/vs-14.1-exec.py
new file mode 100644
index 0000000..2f593e0
--- /dev/null
+++ b/test/MSVS/vs-14.1-exec.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test that we can actually build a simple program using our generated
+Visual Studio 14.1 project (.vcxproj) and solution (.sln) files
+using Visual Studio 14.1 (Professional edition).
+"""
+
+import os
+import sys
+
+import TestSConsMSVS
+
+test = TestSConsMSVS.TestSConsMSVS()
+
+if sys.platform != 'win32':
+ msg = "Skipping Visual Studio test on non-Windows platform '%s'\n" % sys.platform
+ test.skip_test(msg)
+
+msvs_version = '14.1'
+
+if msvs_version not in test.msvs_versions():
+ msg = "Visual Studio %s not installed; skipping test.\n" % msvs_version
+ test.skip_test(msg)
+
+
+
+# Let SCons figure out the Visual Studio environment variables for us and
+# print out a statement that we can exec to suck them into our external
+# environment so we can execute devenv and really try to build something.
+
+test.run(arguments = '-n -q -Q -f -', stdin = """\
+env = Environment(tools = ['msvc'], MSVS_VERSION='%(msvs_version)s')
+if env.WhereIs('cl'):
+ print("os.environ.update(%%s)" %% repr(env['ENV']))
+""" % locals())
+
+if(test.stdout() == ""):
+ msg = "Visual Studio %s missing cl.exe; skipping test.\n" % msvs_version
+ test.skip_test(msg)
+
+exec(test.stdout())
+
+
+
+test.subdir('sub dir')
+
+test.write(['sub dir', 'SConstruct'], """\
+env=Environment(MSVS_VERSION = '%(msvs_version)s')
+
+env.MSVSProject(target = 'foo.vcxproj',
+ srcs = ['foo.c'],
+ buildtarget = 'foo.exe',
+ variant = 'Release',
+ DebugSettings = {'LocalDebuggerCommandArguments':'echo "<foo.c>" > output.txt'})
+env.Program('foo.c')
+""" % locals())
+
+test.write(['sub dir', 'foo.c'], r"""
+int
+main(int argc, char *argv)
+{
+ printf("foo.c\n");
+ exit (0);
+}
+""")
+
+test.run(chdir='sub dir', arguments='.')
+
+test.vcproj_sys_path(test.workpath('sub dir', 'foo.vcxproj'))
+
+import SCons.Platform.win32
+system_dll_path = os.path.join( SCons.Platform.win32.get_system_root(), 'System32' )
+os.environ['PATH'] = os.environ['PATH'] + os.pathsep + system_dll_path
+
+test.run(chdir='sub dir',
+ program=[test.get_msvs_executable(msvs_version)],
+ arguments=['foo.sln', '/build', 'Release'])
+
+test.run(program=test.workpath('sub dir', 'foo'), stdout="foo.c\n")
+test.validate_msvs_file(test.workpath('sub dir', 'foo.vcxproj.user'))
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/MSVS/vs-14.1-files.py b/test/MSVS/vs-14.1-files.py
new file mode 100644
index 0000000..a7c8437
--- /dev/null
+++ b/test/MSVS/vs-14.1-files.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test that we can generate Visual Studio 14.1 project (.vcxproj) and
+solution (.sln) files that look correct.
+"""
+
+import os
+
+import TestSConsMSVS
+
+test = TestSConsMSVS.TestSConsMSVS()
+host_arch = test.get_vs_host_arch()
+
+
+# Make the test infrastructure think we have this version of MSVS installed.
+test._msvs_versions = ['14.1']
+
+
+
+expected_slnfile = TestSConsMSVS.expected_slnfile_14_1
+expected_vcprojfile = TestSConsMSVS.expected_vcprojfile_14_1
+SConscript_contents = TestSConsMSVS.SConscript_contents_14_1
+
+
+
+test.write('SConstruct', SConscript_contents%{'HOST_ARCH': host_arch})
+
+test.run(arguments="Test.vcxproj")
+
+test.must_exist(test.workpath('Test.vcxproj'))
+test.must_exist(test.workpath('Test.vcxproj.filters'))
+vcxproj = test.read('Test.vcxproj', 'r')
+expect = test.msvs_substitute(expected_vcprojfile, '14.1', None, 'SConstruct')
+# don't compare the pickled data
+assert vcxproj[:len(expect)] == expect, test.diff_substr(expect, vcxproj)
+
+test.must_exist(test.workpath('Test.sln'))
+sln = test.read('Test.sln', 'r')
+expect = test.msvs_substitute(expected_slnfile, '14.1', None, 'SConstruct')
+# don't compare the pickled data
+assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
+
+test.run(arguments='-c .')
+
+test.must_not_exist(test.workpath('Test.vcxproj'))
+test.must_not_exist(test.workpath('Test.vcxproj.filters'))
+test.must_not_exist(test.workpath('Test.sln'))
+
+test.run(arguments='Test.vcxproj')
+
+test.must_exist(test.workpath('Test.vcxproj'))
+test.must_exist(test.workpath('Test.vcxproj.filters'))
+test.must_exist(test.workpath('Test.sln'))
+
+test.run(arguments='-c Test.sln')
+
+test.must_not_exist(test.workpath('Test.vcxproj'))
+test.must_not_exist(test.workpath('Test.vcxproj.filters'))
+test.must_not_exist(test.workpath('Test.sln'))
+
+
+
+# Test that running SCons with $PYTHON_ROOT in the environment
+# changes the .vcxproj output as expected.
+os.environ['PYTHON_ROOT'] = 'xyzzy'
+python = os.path.join('$(PYTHON_ROOT)', os.path.split(TestSConsMSVS.python)[1])
+
+test.run(arguments='Test.vcxproj')
+
+test.must_exist(test.workpath('Test.vcxproj'))
+vcxproj = test.read('Test.vcxproj', 'r')
+expect = test.msvs_substitute(expected_vcprojfile, '14.1', None, 'SConstruct',
+ python=python)
+# don't compare the pickled data
+assert vcxproj[:len(expect)] == expect, test.diff_substr(expect, vcxproj)
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/MSVS/vs-14.1-scc-files.py b/test/MSVS/vs-14.1-scc-files.py
new file mode 100644
index 0000000..74e055e
--- /dev/null
+++ b/test/MSVS/vs-14.1-scc-files.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test that we can generate Visual Studio 14.1 project (.vcxproj) and
+solution (.sln) files that contain SCC information and look correct.
+"""
+
+import TestSConsMSVS
+
+test = TestSConsMSVS.TestSConsMSVS()
+
+# Make the test infrastructure think we have this version of MSVS installed.
+test._msvs_versions = ['14.1']
+
+
+
+expected_slnfile = TestSConsMSVS.expected_slnfile_14_1
+expected_vcprojfile = TestSConsMSVS.expected_vcprojfile_14_1
+SConscript_contents = """\
+env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='14.1',
+ CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
+ CPPPATH=['inc1', 'inc2'],
+ MSVS_SCC_CONNECTION_ROOT='.',
+ MSVS_SCC_PROVIDER='MSSCCI:Perforce SCM',
+ MSVS_SCC_PROJECT_NAME='Perforce Project')
+
+testsrc = ['test1.cpp', 'test2.cpp']
+testincs = ['sdk_dir\sdk.h']
+testlocalincs = ['test.h']
+testresources = ['test.rc']
+testmisc = ['readme.txt']
+
+env.MSVSProject(target = 'Test.vcxproj',
+ srcs = testsrc,
+ incs = testincs,
+ localincs = testlocalincs,
+ resources = testresources,
+ misc = testmisc,
+ buildtarget = 'Test.exe',
+ variant = 'Release')
+"""
+
+expected_sln_sccinfo = """\
+\tGlobalSection(SourceCodeControl) = preSolution
+\t\tSccNumberOfProjects = 2
+\t\tSccProjectName0 = Perforce\\u0020Project
+\t\tSccLocalPath0 = .
+\t\tSccProvider0 = MSSCCI:Perforce\\u0020SCM
+\t\tCanCheckoutShared = true
+\t\tSccProjectUniqueName1 = Test.vcxproj
+\t\tSccLocalPath1 = .
+\t\tCanCheckoutShared = true
+\t\tSccProjectFilePathRelativizedFromConnection1 = .\\\\
+\tEndGlobalSection
+"""
+
+expected_vcproj_sccinfo = """\
+\t\t<SccProjectName>Perforce Project</SccProjectName>
+\t\t<SccLocalPath>.</SccLocalPath>
+\t\t<SccProvider>MSSCCI:Perforce SCM</SccProvider>
+"""
+
+
+test.write('SConstruct', SConscript_contents)
+
+test.run(arguments="Test.vcxproj")
+
+test.must_exist(test.workpath('Test.vcxproj'))
+vcproj = test.read('Test.vcxproj', 'r')
+expect = test.msvs_substitute(expected_vcprojfile, '14.1', None, 'SConstruct',
+ vcproj_sccinfo=expected_vcproj_sccinfo)
+# don't compare the pickled data
+assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
+
+test.must_exist(test.workpath('Test.sln'))
+sln = test.read('Test.sln', 'r')
+expect = test.msvs_substitute(expected_slnfile, '14.1', None, 'SConstruct',
+ sln_sccinfo=expected_sln_sccinfo)
+# don't compare the pickled data
+assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
+
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/MSVS/vs-14.1-scc-legacy-files.py b/test/MSVS/vs-14.1-scc-legacy-files.py
new file mode 100644
index 0000000..0444b16
--- /dev/null
+++ b/test/MSVS/vs-14.1-scc-legacy-files.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test that we can generate Visual Studio 14.1 project (.vcxproj) and
+solution (.sln) files that contain SCC information and look correct.
+"""
+
+import TestSConsMSVS
+
+test = TestSConsMSVS.TestSConsMSVS()
+
+# Make the test infrastructure think we have this version of MSVS installed.
+test._msvs_versions = ['14.1']
+
+
+
+expected_slnfile = TestSConsMSVS.expected_slnfile_14_1
+expected_vcprojfile = TestSConsMSVS.expected_vcprojfile_14_1
+SConscript_contents = """\
+env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='14.1',
+ CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
+ CPPPATH=['inc1', 'inc2'],
+ MSVS_SCC_LOCAL_PATH='C:\\MyMsVsProjects',
+ MSVS_SCC_PROJECT_NAME='Perforce Project')
+
+testsrc = ['test1.cpp', 'test2.cpp']
+testincs = ['sdk_dir\sdk.h']
+testlocalincs = ['test.h']
+testresources = ['test.rc']
+testmisc = ['readme.txt']
+
+env.MSVSProject(target = 'Test.vcxproj',
+ srcs = testsrc,
+ incs = testincs,
+ localincs = testlocalincs,
+ resources = testresources,
+ misc = testmisc,
+ buildtarget = 'Test.exe',
+ variant = 'Release')
+"""
+
+expected_vcproj_sccinfo = """\
+\t\t<SccProjectName>Perforce Project</SccProjectName>
+\t\t<SccLocalPath>C:\\MyMsVsProjects</SccLocalPath>
+"""
+
+
+test.write('SConstruct', SConscript_contents)
+
+test.run(arguments="Test.vcxproj")
+
+test.must_exist(test.workpath('Test.vcxproj'))
+vcproj = test.read('Test.vcxproj', 'r')
+expect = test.msvs_substitute(expected_vcprojfile, '14.1', None, 'SConstruct',
+ vcproj_sccinfo=expected_vcproj_sccinfo)
+# don't compare the pickled data
+assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
+
+test.must_exist(test.workpath('Test.sln'))
+sln = test.read('Test.sln', 'r')
+expect = test.msvs_substitute(expected_slnfile, '14.1', None, 'SConstruct')
+# don't compare the pickled data
+assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
+
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/TEMPFILEPREFIX.py b/test/TEMPFILEPREFIX.py
index 7f4322b..f5093e1 100644
--- a/test/TEMPFILEPREFIX.py
+++ b/test/TEMPFILEPREFIX.py
@@ -25,8 +25,9 @@
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
"""
-Verify that setting the $TEMPFILEPREFIX variable will append to the
-beginning of the TEMPFILE invocation of a long command line.
+Verify that setting the $TEMPFILEPREFIX variable will cause
+it to appear at the front of name of the generated tempfile
+used for long command lines.
"""
import os
@@ -97,7 +98,7 @@ class TestTempFileMunge(TempFileMunge):
def _print_cmd_str(self, target, source, env, cmdstr):
super(TestTempFileMunge, self)._print_cmd_str(target, source, None, cmdstr)
-
+
env = Environment(
TEMPFILE = TestTempFileMunge,
BUILDCOM = '${TEMPFILE("xxx.py $TARGET $SOURCES")}',
diff --git a/test/TEMPFILESUFFIX.py b/test/TEMPFILESUFFIX.py
new file mode 100644
index 0000000..aee1e2d
--- /dev/null
+++ b/test/TEMPFILESUFFIX.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Verify that setting the $TEMPFILESUFFIX variable will cause
+it to appear at the end of name of the generated tempfile
+used for long command lines.
+"""
+
+import os
+import stat
+
+import TestSCons
+
+test = TestSCons.TestSCons(match=TestSCons.match_re)
+
+test.write('echo.py', """\
+from __future__ import print_function
+import sys
+print(sys.argv)
+""")
+
+echo_py = test.workpath('echo.py')
+
+st = os.stat(echo_py)
+os.chmod(echo_py, st[stat.ST_MODE] | 0o111)
+
+test.write('SConstruct', """
+import os
+env = Environment(
+ BUILDCOM = '${TEMPFILE("xxx.py $TARGET $SOURCES")}',
+ MAXLINELENGTH = 16,
+ TEMPFILESUFFIX = '.foo',
+)
+env.AppendENVPath('PATH', os.curdir)
+env.Command('foo.out', 'foo.in', '$BUILDCOM')
+""")
+
+test.write('foo.in', "foo.in\n")
+
+test.run(arguments = '-n -Q .',
+ stdout = """\
+Using tempfile \\S+ for command line:
+xxx.py foo.out foo.in
+xxx.py \\S+
+""")
+
+test.write('SConstruct', """
+import os
+
+def print_cmd_line(s, targets, sources, env):
+ pass
+
+env = Environment(
+ BUILDCOM = '${TEMPFILE("xxx.py $TARGET $SOURCES")}',
+ MAXLINELENGTH = 16,
+ TEMPFILESUFFIX = '.foo',
+ PRINT_CMD_LINE_FUNC=print_cmd_line
+)
+env.AppendENVPath('PATH', os.curdir)
+env.Command('foo.out', 'foo.in', '$BUILDCOM')
+""")
+
+test.run(arguments = '-n -Q .',
+ stdout = """""")
+
+test.write('SConstruct', """
+import os
+from SCons.Platform import TempFileMunge
+
+class TestTempFileMunge(TempFileMunge):
+
+ def __init__(self, cmd, cmdstr = None):
+ super(TestTempFileMunge, self).__init__(cmd, cmdstr)
+
+ def _print_cmd_str(self, target, source, env, cmdstr):
+ super(TestTempFileMunge, self)._print_cmd_str(target, source, None, cmdstr)
+
+env = Environment(
+ TEMPFILE = TestTempFileMunge,
+ BUILDCOM = '${TEMPFILE("xxx.py $TARGET $SOURCES")}',
+ MAXLINELENGTH = 16,
+ TEMPFILESUFFIX = '.foo',
+
+)
+env.AppendENVPath('PATH', os.curdir)
+env.Command('foo.out', 'foo.in', '$BUILDCOM')
+""")
+
+test.run(arguments = '-n -Q .',
+ stdout = """\
+Using tempfile \\S+ for command line:
+xxx.py foo.out foo.in
+xxx.py \\S+
+""")
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/testing/framework/TestSCons.py b/testing/framework/TestSCons.py
index b543c07..38ffd08 100644
--- a/testing/framework/TestSCons.py
+++ b/testing/framework/TestSCons.py
@@ -35,7 +35,7 @@ from TestCmd import PIPE
# here provides some independent verification that what we packaged
# conforms to what we expect.
-default_version = '3.0.3'
+default_version = '3.0.4'
python_version_unsupported = (2, 6, 0)
python_version_deprecated = (2, 7, 0)
diff --git a/testing/framework/TestSConsMSVS.py b/testing/framework/TestSConsMSVS.py
index 1e879d9..b975ebe 100644
--- a/testing/framework/TestSConsMSVS.py
+++ b/testing/framework/TestSConsMSVS.py
@@ -536,6 +536,26 @@ Global
EndGlobal
"""
+expected_slnfile_14_1 = """\
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test.vcxproj", "Test.vcxproj", "{39A97E1F-1A52-8954-A0B1-A10A8487545E}"
+EndProject
+Global
+<SCC_SLN_INFO>
+\tGlobalSection(SolutionConfigurationPlatforms) = preSolution
+\t\tRelease|Win32 = Release|Win32
+\tEndGlobalSection
+\tGlobalSection(ProjectConfigurationPlatforms) = postSolution
+\t\t{39A97E1F-1A52-8954-A0B1-A10A8487545E}.Release|Win32.ActiveCfg = Release|Win32
+\t\t{39A97E1F-1A52-8954-A0B1-A10A8487545E}.Release|Win32.Build.0 = Release|Win32
+\tEndGlobalSection
+\tGlobalSection(SolutionProperties) = preSolution
+\t\tHideSolutionNode = FALSE
+\tEndGlobalSection
+EndGlobal
+"""
+
expected_vcprojfile_8_0 = """\
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
@@ -907,6 +927,71 @@ expected_vcprojfile_14_0 = """\
</Project>
"""
+expected_vcprojfile_14_1 = """\
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+\t<ItemGroup Label="ProjectConfigurations">
+\t\t<ProjectConfiguration Include="Release|Win32">
+\t\t\t<Configuration>Release</Configuration>
+\t\t\t<Platform>Win32</Platform>
+\t\t</ProjectConfiguration>
+\t</ItemGroup>
+\t<PropertyGroup Label="Globals">
+\t\t<ProjectGuid>{39A97E1F-1A52-8954-A0B1-A10A8487545E}</ProjectGuid>
+<SCC_VCPROJ_INFO>
+\t\t<RootNamespace>Test</RootNamespace>
+\t\t<Keyword>MakeFileProj</Keyword>
+\t</PropertyGroup>
+\t<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
+\t<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+\t\t<ConfigurationType>Makefile</ConfigurationType>
+\t\t<UseOfMfc>false</UseOfMfc>
+\t\t<PlatformToolset>v141</PlatformToolset>
+\t</PropertyGroup>
+\t<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.props" />
+\t<ImportGroup Label="ExtensionSettings">
+\t</ImportGroup>
+\t<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+\t\t<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+\t</ImportGroup>
+\t<PropertyGroup Label="UserMacros" />
+\t<PropertyGroup>
+\t<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+\t\t<NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;</NMakeBuildCommandLine>
+\t\t<NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;</NMakeReBuildCommandLine>
+\t\t<NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct -c &quot;Test.exe&quot;</NMakeCleanCommandLine>
+\t\t<NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Test.exe</NMakeOutput>
+\t\t<NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">DEF1;DEF2;DEF3=1234</NMakePreprocessorDefinitions>
+\t\t<NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">inc1;inc2</NMakeIncludeSearchPath>
+\t\t<NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedIncludes)</NMakeForcedIncludes>
+\t\t<NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath>
+\t\t<NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies>
+\t</PropertyGroup>
+\t<ItemGroup>
+\t\t<ClInclude Include="sdk_dir\sdk.h" />
+\t</ItemGroup>
+\t<ItemGroup>
+\t\t<ClInclude Include="test.h" />
+\t</ItemGroup>
+\t<ItemGroup>
+\t\t<None Include="readme.txt" />
+\t</ItemGroup>
+\t<ItemGroup>
+\t\t<None Include="test.rc" />
+\t</ItemGroup>
+\t<ItemGroup>
+\t\t<ClCompile Include="test1.cpp" />
+\t\t<ClCompile Include="test2.cpp" />
+\t</ItemGroup>
+\t<ItemGroup>
+\t\t<None Include="SConstruct" />
+\t</ItemGroup>
+\t<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.targets" />
+\t<ImportGroup Label="ExtensionTargets">
+\t</ImportGroup>
+</Project>
+"""
+
SConscript_contents_8_0 = """\
env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='8.0',
CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
@@ -1022,6 +1107,29 @@ env.MSVSProject(target = 'Test.vcxproj',
variant = 'Release')
"""
+SConscript_contents_14_1 = """\
+env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='14.1',
+ CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
+ CPPPATH=['inc1', 'inc2'],
+ HOST_ARCH='%(HOST_ARCH)s')
+
+testsrc = ['test1.cpp', 'test2.cpp']
+testincs = ['sdk_dir\sdk.h']
+testlocalincs = ['test.h']
+testresources = ['test.rc']
+testmisc = ['readme.txt']
+
+env.MSVSProject(target = 'Test.vcxproj',
+ slnguid = '{SLNGUID}',
+ srcs = testsrc,
+ incs = testincs,
+ localincs = testlocalincs,
+ resources = testresources,
+ misc = testmisc,
+ buildtarget = 'Test.exe',
+ variant = 'Release')
+"""
+
class TestSConsMSVS(TestSCons):
"""Subclass for testing MSVS-specific portions of SCons."""