Compare commits
54 Commits
v3.3.0-10-
...
v3.4.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
261f218e09 | ||
|
|
a096fe1b76 | ||
|
|
63f979bf5c | ||
|
|
4e4f33e54f | ||
|
|
df2367fcd3 | ||
|
|
3f77ee12af | ||
|
|
e952bb9cf4 | ||
|
|
fe1e31e527 | ||
|
|
b2b4e777f7 | ||
|
|
0e93b70855 | ||
|
|
fe29811d26 | ||
|
|
dead44c3cb | ||
|
|
ca8fde2eaf | ||
|
|
130e88b709 | ||
|
|
20f8e05393 | ||
|
|
2246ee79e4 | ||
|
|
7def04dc0e | ||
|
|
c153c10a11 | ||
|
|
a133e160ee | ||
|
|
f57c9d5930 | ||
|
|
dffe32c23e | ||
|
|
afeb69564c | ||
|
|
6ec067da78 | ||
|
|
899b18336b | ||
|
|
8e0cb61c12 | ||
|
|
4028a10be9 | ||
|
|
b61f5079b7 | ||
| e79a7fbf1e | |||
|
|
e0a7c52160 | ||
|
|
6e190542d6 | ||
|
|
a8bffdcfb7 | ||
|
|
8ea51154c0 | ||
|
|
4248dffeca | ||
| 9721faa716 | |||
|
|
c8b2773316 | ||
|
|
1e0e326f74 | ||
|
|
bd0cd5434c | ||
|
|
819c2abba0 | ||
|
|
6491f0116f | ||
|
|
f47280547b | ||
|
|
e32822b9a3 | ||
|
|
918feccf51 | ||
|
|
fd925d83b6 | ||
|
|
cd21488ec7 | ||
|
|
aea7906839 | ||
|
|
c6bc90b06a | ||
|
|
af1ecbabae | ||
|
|
22b2e3f796 | ||
|
|
d36800b2e0 | ||
|
|
b6723d0be4 | ||
|
|
db7677a48e | ||
|
|
ee9d6b3497 | ||
|
|
91fb22b79a | ||
|
|
514737a106 |
@@ -45,9 +45,9 @@ skip_commits:
|
||||
|
||||
install:
|
||||
# fetch submodules (like ci-scripts)
|
||||
- cmd: git submodule update --init --recursive
|
||||
- git submodule update --init --recursive
|
||||
# for the sequencer
|
||||
- cinst re2c
|
||||
- choco install re2c
|
||||
|
||||
#---------------------------------#
|
||||
# build matrix configuration #
|
||||
|
||||
99
.github/workflows/build-and-test.yml
vendored
99
.github/workflows/build-and-test.yml
vendored
@@ -19,13 +19,13 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-22.04, ubuntu-20.04, ubuntu-18.04, windows-2022, windows-2019, windows-2016, macos-12, macos-11, macos-10.15]
|
||||
os: [ubuntu-24.04, ubuntu-22.04, windows-2025, windows-2022, macos-15, macos-14]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- name: Show initial environment
|
||||
run: python cue-test.py env
|
||||
run: python3 cue-test.py env
|
||||
- name: Run unit tests
|
||||
run: python cue-test.py
|
||||
run: python3 cue-test.py
|
||||
|
||||
build-linux:
|
||||
name: ${{ matrix.cmp }} / ${{ matrix.configuration }} / ${{ matrix.os }}
|
||||
@@ -36,11 +36,11 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-22.04, ubuntu-20.04, ubuntu-18.04]
|
||||
os: [ubuntu-24.04, ubuntu-22.04]
|
||||
cmp: [gcc, clang]
|
||||
configuration: [default, static, debug, static-debug]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- name: Prepare and compile dependencies
|
||||
run: python cue.py prepare
|
||||
- name: Build main module (example app)
|
||||
@@ -59,11 +59,11 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-12, macos-11, macos-10.15]
|
||||
os: [macos-15, macos-14]
|
||||
cmp: [clang]
|
||||
configuration: [default, debug]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- name: Prepare and compile dependencies
|
||||
run: python cue.py prepare
|
||||
- name: Build main module (example app)
|
||||
@@ -82,26 +82,12 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [windows-2022, windows-2019, windows-2016]
|
||||
cmp: [gcc, vs2022, vs2019, vs2017]
|
||||
os: [windows-2025, windows-2022]
|
||||
cmp: [gcc, vs2022]
|
||||
configuration: [default, static, debug, static-debug]
|
||||
exclude:
|
||||
- os: windows-2022
|
||||
cmp: vs2019
|
||||
- os: windows-2022
|
||||
cmp: vs2017
|
||||
|
||||
- os: windows-2019
|
||||
cmp: vs2022
|
||||
- os: windows-2019
|
||||
cmp: vs2017
|
||||
|
||||
- os: windows-2016
|
||||
cmp: vs2022
|
||||
- os: windows-2016
|
||||
cmp: vs2019
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- name: Prepare and compile dependencies
|
||||
run: python cue.py prepare
|
||||
- name: Build main module (example app)
|
||||
@@ -111,55 +97,36 @@ jobs:
|
||||
- name: Collect and show test results
|
||||
run: python cue.py test-results
|
||||
|
||||
build-rtems:
|
||||
name: RTEMS${{ matrix.rtems }} / ${{ matrix.rtems_target }}
|
||||
runs-on: ubuntu-20.04
|
||||
build-cross:
|
||||
name: cross ${{ matrix.cross }} / ${{ matrix.cmp }} / ${{ matrix.configuration }}
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CMP: gcc
|
||||
BCFG: default
|
||||
RTEMS: ${{ matrix.rtems }}
|
||||
RTEMS_TARGET: ${{ matrix.rtems_target }}
|
||||
APT: re2c g++-mingw-w64-i686 g++-mingw-w64-x86-64 qemu-system-x86
|
||||
CI_CROSS_TARGETS: ${{ matrix.cross }}
|
||||
TEST: ${{ matrix.test }}
|
||||
APT: re2c
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# configuration: [default, static, debug, static-debug]
|
||||
configuration: [default]
|
||||
cross:
|
||||
- linux-aarch64
|
||||
- linux-arm@arm-linux-gnueabi
|
||||
- linux-arm@arm-linux-gnueabihf
|
||||
- linux-ppc
|
||||
- linux-ppc64
|
||||
- win32-x86-mingw
|
||||
- windows-x64-mingw
|
||||
- RTEMS-pc386-qemu@4.9
|
||||
- RTEMS-pc386-qemu@4.10
|
||||
- RTEMS-pc686-qemu@5
|
||||
include:
|
||||
- rtems: "4.9"
|
||||
rtems_target: RTEMS-pc386-qemu
|
||||
|
||||
- rtems: "4.10"
|
||||
rtems_target: RTEMS-pc386-qemu
|
||||
|
||||
- rtems: "5"
|
||||
rtems_target: RTEMS-pc686-qemu
|
||||
- cross: RTEMS-pc386-qemu@4.10
|
||||
test: NO
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Prepare and compile dependencies
|
||||
run: python cue.py prepare
|
||||
- name: Build main module (example app)
|
||||
run: python cue.py build
|
||||
- name: Run main module tests
|
||||
run: python cue.py -T 15M test
|
||||
- name: Collect and show test results
|
||||
run: python cue.py test-results
|
||||
|
||||
build-wine:
|
||||
name: WINE${{ matrix.wine }} / ${{ matrix.configuration }} / ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CMP: ${{ matrix.cmp }}
|
||||
BCFG: ${{ matrix.configuration }}
|
||||
WINE: ${{ matrix.wine }}
|
||||
APT: re2c g++-mingw-w64-i686 g++-mingw-w64-x86-64
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-18.04]
|
||||
cmp: [gcc]
|
||||
configuration: [default, static, debug, static-debug]
|
||||
wine: [32, 64]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- name: Prepare and compile dependencies
|
||||
run: python cue.py prepare
|
||||
- name: Build main module (example app)
|
||||
|
||||
50
README.md
50
README.md
@@ -95,10 +95,10 @@ for more details.
|
||||
|
||||
### [GitHub Actions](https://github.com/)
|
||||
- 20 parallel runners on Linux/Windows (5 runners on MacOS)
|
||||
- Ubuntu 16/18/20, MacOS 10.15, Windows Server 2016/2019/2022
|
||||
- Ubuntu 18/20/22, MacOS 11/12, Windows Server 2019/2022
|
||||
- Compile natively on Linux (gcc, clang)
|
||||
- Compile natively on MacOS (clang)
|
||||
- Compile natively on Windows (gcc/MinGW, Visual Studio 2017/2019/2022)
|
||||
- Compile natively on Windows (gcc/MinGW, Visual Studio 2019/2022)
|
||||
- Cross-compile for Windows 32bit and 64bit using MinGW and WINE
|
||||
- Cross-compile for RTEMS 4.9 and 4.10 (pc386, Base >= 3.15)
|
||||
- Cross-compile for RTEMS 5 (10 BSPs, Base >= 7.0.5.1)
|
||||
@@ -189,6 +189,19 @@ Collect the results of your tests and print a summary.
|
||||
`exec`\
|
||||
Execute the remainder of the line using the default command shell.
|
||||
|
||||
## Extra arguments to `make`
|
||||
|
||||
You can add additional arguments to the make runs that the `cue.py` script
|
||||
starts. Put your additional arguments into environment variables named
|
||||
`EXTRA`, `EXTRA1`, ... `EXTRA5`.
|
||||
|
||||
The variables may contain multiple arguments, separated by whitespace.
|
||||
Use regular shell script quoting (single/double quotes, backslash escapes)
|
||||
if you need spaces inside an extra argument.
|
||||
|
||||
The YAML syntax needed to set environment variables depends on the CI
|
||||
service and platform. (See the full example configuration file.)
|
||||
|
||||
## Setup Files
|
||||
|
||||
Your module might depend on EPICS Base and a few other support modules.
|
||||
@@ -283,8 +296,8 @@ Feel free to suggest more default settings using a Pull Request.
|
||||
|
||||
## RTEMS
|
||||
|
||||
Setting `RTEMS` to the RTEMS version number (`4.9`, `4.10` or `5`)
|
||||
enables cross-compiling to RTEMS on supported CI services.
|
||||
Cross-compiling to RTEMS versions 4.9, 4.10 or 5 is supported
|
||||
on supported CI services. For configuration see below.
|
||||
Tests can also be run cross-platform, using `qemu`.
|
||||
|
||||
The RTEMS 5 builds now include most of the BSPs with configuration in Base:
|
||||
@@ -301,15 +314,38 @@ The RTEMS 5 builds now include most of the BSPs with configuration in Base:
|
||||
- xilinx_zynq_a9_qemu w/ libbsd
|
||||
|
||||
Build configuration [can be found here][ref.rtems5build].
|
||||
Set `RTEMS_TARGET` to configure the EPICS target architecture and
|
||||
`RSB_BUILD` to select the RTEMS toolchain release name/data from
|
||||
Set `RSB_BUILD` to select the RTEMS toolchain release name/data from
|
||||
https://github.com/mdavidsaver/rsb/releases.
|
||||
|
||||
RTEMS 5 builds need to be switched to a newer ubuntu version
|
||||
RTEMS 5 builds need to be switched to ubuntu version >= 20
|
||||
(aka. **os: ubuntu-20.04** with GitHub Actions,
|
||||
**dist: focal** with Travis-CI or
|
||||
**image: ubuntu:focal** with GitLab CI/CD).
|
||||
|
||||
## Cross Compilation
|
||||
|
||||
Setting the `CI_CROSS_TARGETS` environment variable enables cross-compiling
|
||||
from Linux to the provided targets architectures.
|
||||
The value of the environment variable must contain the EPICS architecture
|
||||
and - depending on the target - may contain additional information like
|
||||
the compiler prefix to be used or the version of the target OS.
|
||||
|
||||
Multiple cross-targets can be added to the `CI_CROSS_TARGETS` variable
|
||||
by separating them with a colon (`:`) character.
|
||||
|
||||
For example, possible values are:
|
||||
|
||||
- linux-aarch64
|
||||
- linux-arm@arm-linux-gnueabi
|
||||
- linux-arm@arm-linux-gnueabihf
|
||||
- linux-ppc
|
||||
- linux-ppc64
|
||||
- win32-x86-mingw
|
||||
- windows-x64-mingw
|
||||
- RTEMS-pc386-qemu@4.9
|
||||
- RTEMS-pc386-qemu@4.10
|
||||
- RTEMS-pc686-qemu@5
|
||||
|
||||
## Debugging
|
||||
|
||||
Setting `VV=1` in your service configuration (e.g., `.travis.yml`) for a
|
||||
|
||||
@@ -41,9 +41,9 @@ skip_commits:
|
||||
|
||||
install:
|
||||
# fetch submodules (like ci-scripts)
|
||||
- cmd: git submodule update --init --recursive
|
||||
- git submodule update --init --recursive
|
||||
# for the sequencer
|
||||
- cinst re2c
|
||||
- choco install re2c
|
||||
|
||||
#---------------------------------#
|
||||
# build matrix configuration #
|
||||
|
||||
@@ -18,7 +18,7 @@ skip_commits:
|
||||
- '.travis.yml'
|
||||
|
||||
install:
|
||||
- cmd: git submodule update --init --recursive
|
||||
- git submodule update --init --recursive
|
||||
|
||||
image: Visual Studio 2022
|
||||
|
||||
|
||||
106
cue-test.py
106
cue-test.py
@@ -8,11 +8,11 @@
|
||||
from __future__ import print_function
|
||||
|
||||
import sys, os, shutil, fileinput
|
||||
import distutils.util
|
||||
import re
|
||||
import subprocess as sp
|
||||
import unittest
|
||||
import logging
|
||||
import fnmatch
|
||||
from argparse import Namespace
|
||||
|
||||
builddir = os.getcwd()
|
||||
@@ -66,6 +66,8 @@ import cue
|
||||
# we're working with tags (detached heads) a lot: suppress advice
|
||||
cue.call_git(['config', '--global', 'advice.detachedHead', 'false'])
|
||||
|
||||
# Don't build dependencies when running unit tests
|
||||
cue.skip_dep_builds = True
|
||||
|
||||
class TestSourceSet(unittest.TestCase):
|
||||
|
||||
@@ -78,10 +80,10 @@ class TestSourceSet(unittest.TestCase):
|
||||
|
||||
def test_EmptySetupDirsPath(self):
|
||||
del os.environ['SETUP_PATH']
|
||||
self.assertRaisesRegexp(NameError, '\(SETUP_PATH\) is empty', cue.source_set, 'test01')
|
||||
self.assertRaisesRegex(NameError, '\(SETUP_PATH\) is empty', cue.source_set, 'test01')
|
||||
|
||||
def test_InvalidSetupName(self):
|
||||
self.assertRaisesRegexp(NameError, 'does not exist in SETUP_PATH', cue.source_set, 'xxdoesnotexistxx')
|
||||
self.assertRaisesRegex(NameError, 'does not exist in SETUP_PATH', cue.source_set, 'xxdoesnotexistxx')
|
||||
|
||||
def test_ValidSetupName(self):
|
||||
capturedOutput = getStringIO()
|
||||
@@ -118,7 +120,7 @@ class TestSourceSet(unittest.TestCase):
|
||||
sys.stdout = capturedOutput
|
||||
cue.source_set('test03')
|
||||
sys.stdout = sys.__stdout__
|
||||
self.assertRegexpMatches(capturedOutput.getvalue(), 'Ignoring already included setup file')
|
||||
self.assertRegex(capturedOutput.getvalue(), 'Ignoring already included setup file')
|
||||
|
||||
|
||||
class TestUpdateReleaseLocal(unittest.TestCase):
|
||||
@@ -267,12 +269,12 @@ class TestAddDependencyOptions(unittest.TestCase):
|
||||
cue.detect_context()
|
||||
if os.path.exists(cue.ci['cachedir']):
|
||||
shutil.rmtree(cue.ci['cachedir'], onerror=cue.remove_readonly)
|
||||
self.location = os.path.join(cue.ci['cachedir'], 'mcoreutils-master')
|
||||
self.location = os.path.join(cue.ci['cachedir'], 'mcoreutils-main')
|
||||
self.testfile = os.path.join(self.location, '.ci', 'LICENSE')
|
||||
os.path.join(cue.ci['cachedir'], 'mcoreutils-master')
|
||||
os.path.join(cue.ci['cachedir'], 'mcoreutils-main')
|
||||
cue.source_set('defaults')
|
||||
cue.complete_setup('MCoreUtils')
|
||||
cue.setup['MCoreUtils'] = 'master'
|
||||
cue.setup['MCoreUtils'] = 'main'
|
||||
|
||||
def test_Default(self):
|
||||
cue.add_dependency('MCoreUtils')
|
||||
@@ -527,7 +529,7 @@ class TestTravisDetectContext(unittest.TestCase):
|
||||
sys.stdout = capturedOutput
|
||||
cue.detect_context()
|
||||
sys.stdout = sys.__stdout__
|
||||
self.assertRegexpMatches(capturedOutput.getvalue(), "Variable 'STATIC' not supported anymore")
|
||||
self.assertRegex(capturedOutput.getvalue(), "Variable 'STATIC' not supported anymore")
|
||||
|
||||
def test_MisspelledBcfgGetsWarning(self):
|
||||
os.environ['BCFG'] = 'static-dubug'
|
||||
@@ -535,7 +537,7 @@ class TestTravisDetectContext(unittest.TestCase):
|
||||
sys.stdout = capturedOutput
|
||||
cue.detect_context()
|
||||
sys.stdout = sys.__stdout__
|
||||
self.assertRegexpMatches(capturedOutput.getvalue(), "Unrecognized build configuration setting")
|
||||
self.assertRegex(capturedOutput.getvalue(), "Unrecognized build configuration setting")
|
||||
|
||||
|
||||
@unittest.skipIf(ci_service != 'appveyor', 'Run appveyor tests only on appveyor')
|
||||
@@ -688,7 +690,7 @@ class TestAppveyorDetectContext(unittest.TestCase):
|
||||
sys.stdout = capturedOutput
|
||||
cue.detect_context()
|
||||
sys.stdout = sys.__stdout__
|
||||
self.assertRegexpMatches(capturedOutput.getvalue(), "Variable 'STATIC' not supported anymore")
|
||||
self.assertRegex(capturedOutput.getvalue(), "Variable 'STATIC' not supported anymore")
|
||||
|
||||
def test_MisspelledConfigurationGetsWarning(self):
|
||||
os.environ['CONFIGURATION'] = 'static-dubug'
|
||||
@@ -696,12 +698,11 @@ class TestAppveyorDetectContext(unittest.TestCase):
|
||||
sys.stdout = capturedOutput
|
||||
cue.detect_context()
|
||||
sys.stdout = sys.__stdout__
|
||||
self.assertRegexpMatches(capturedOutput.getvalue(), "Unrecognized build configuration setting")
|
||||
self.assertRegex(capturedOutput.getvalue(), "Unrecognized build configuration setting")
|
||||
|
||||
|
||||
class TestSetupForBuild(unittest.TestCase):
|
||||
args = Namespace(paths=[])
|
||||
cue.building_base = True
|
||||
args = Namespace(extra_env_vars=[])
|
||||
if ci_os == 'windows':
|
||||
choco_installs = ['make']
|
||||
if ci_service != 'appveyor':
|
||||
@@ -709,6 +710,7 @@ class TestSetupForBuild(unittest.TestCase):
|
||||
sp.check_call(['choco', 'install', '-ry'] + choco_installs)
|
||||
|
||||
def setUp(self):
|
||||
cue.building_base = True
|
||||
if ci_service == 'appveyor':
|
||||
os.environ['CONFIGURATION'] = 'default'
|
||||
cue.detect_context()
|
||||
@@ -719,7 +721,7 @@ class TestSetupForBuild(unittest.TestCase):
|
||||
|
||||
def test_AddPathsOption(self):
|
||||
os.environ['FOOBAR'] = 'BAR'
|
||||
args = Namespace(paths=['/my/{FOOBAR}/dir', '/my/foobar'])
|
||||
args = Namespace(extra_env_vars=['PATH=/my/{FOOBAR}/dir', 'PATH=/my/foobar'])
|
||||
cue.setup_for_build(args)
|
||||
self.assertTrue(re.search('/my/BAR/dir', os.environ['PATH']), 'Expanded path not in PATH')
|
||||
self.assertTrue(re.search('/foobar', os.environ['PATH']), 'Plain path not in PATH')
|
||||
@@ -838,7 +840,7 @@ class TestSetupForBuild(unittest.TestCase):
|
||||
def test_ExtraMakeArgs(self):
|
||||
os.environ['EXTRA'] = 'bla'
|
||||
for ind in range(1,5):
|
||||
os.environ['EXTRA{0}'.format(ind)] = 'bla {0}'.format(ind)
|
||||
os.environ['EXTRA{0}'.format(ind)] = '"bla {0}"'.format(ind)
|
||||
cue.setup_for_build(self.args)
|
||||
self.assertTrue(cue.extra_makeargs[0] == 'bla', 'Extra make arg [0] not set')
|
||||
for ind in range(1,5):
|
||||
@@ -861,7 +863,8 @@ class TestHooks(unittest.TestCase):
|
||||
pass
|
||||
with open(self.bla_file, 'w') as f:
|
||||
f.write('''LINE1=YES
|
||||
LINE2=NO''')
|
||||
LINE2=NO
|
||||
''')
|
||||
|
||||
def test_patchfile(self):
|
||||
hook = os.path.join(builddir, 'test.patch')
|
||||
@@ -883,6 +886,77 @@ LINE2=NO''')
|
||||
cue.extract_archive(hook, cwd=self.location)
|
||||
self.assertTrue(os.path.exists(self.new_file), "archive extract didn't add new file")
|
||||
|
||||
@unittest.skipIf(ci_os != 'linux', 'CrossCompatibilityHandling tests only apply to linux')
|
||||
class TestCrossCompatibilityHandling(unittest.TestCase):
|
||||
args = Namespace(extra_env_vars=[])
|
||||
|
||||
def setUp(self):
|
||||
cue.clear_lists()
|
||||
os.environ.pop('CI_CROSS_TARGETS', None)
|
||||
os.environ.pop('RTEMS_TARGET', None)
|
||||
os.environ.pop('RTEMS', None)
|
||||
os.environ.pop('WINE', None)
|
||||
os.environ['MODULES'] = ''
|
||||
cue.detect_context()
|
||||
# Make cue.prepare() reconfigure base
|
||||
for root, dirs, files in os.walk(cue.ci['cachedir']):
|
||||
if 'checked_out' in files:
|
||||
if fnmatch.fnmatch(root, '*/base-*'):
|
||||
os.remove(os.path.join(root, 'checked_out'))
|
||||
|
||||
def runtest_rtems(self, arch, ver):
|
||||
cue.prepare(self.args)
|
||||
self.assertTrue('CI_CROSS_TARGETS' in os.environ, "CI_CROSS_TARGETS has not been set")
|
||||
self.assertTrue(os.environ['CI_CROSS_TARGETS'].startswith(':' + arch),
|
||||
"CI_CROSS_TARGETS is {0} (expected: :{1}...)"
|
||||
.format(os.environ['CI_CROSS_TARGETS'], arch))
|
||||
self.assertTrue(os.environ['CI_CROSS_TARGETS'].endswith('@' + ver),
|
||||
"CI_CROSS_TARGETS is {0} (expected: ...@{1})"
|
||||
.format(os.environ['CI_CROSS_TARGETS'], ver))
|
||||
|
||||
def test_RTEMS49_no_target(self):
|
||||
os.environ['RTEMS'] = '4.9'
|
||||
self.runtest_rtems('RTEMS-pc386', '4.9')
|
||||
|
||||
def test_RTEMS49_with_target(self):
|
||||
os.environ['RTEMS'] = '4.9'
|
||||
os.environ['RTEMS_TARGET'] = 'RTEMS-pc386'
|
||||
self.runtest_rtems('RTEMS-pc386', '4.9')
|
||||
|
||||
def test_RTEMS410_no_target(self):
|
||||
os.environ['RTEMS'] = '4.10'
|
||||
self.runtest_rtems('RTEMS-pc386', '4.10')
|
||||
|
||||
def test_RTEMS410_with_target(self):
|
||||
os.environ['RTEMS'] = '4.10'
|
||||
os.environ['RTEMS_TARGET'] = 'RTEMS-pc386'
|
||||
self.runtest_rtems('RTEMS-pc386', '4.10')
|
||||
|
||||
def test_RTEMS5_no_target(self):
|
||||
os.environ['RTEMS'] = '5'
|
||||
self.runtest_rtems('RTEMS-pc686', '5')
|
||||
|
||||
def test_RTEMS5_with_target(self):
|
||||
os.environ['RTEMS'] = '5'
|
||||
os.environ['RTEMS_TARGET'] = 'RTEMS-pc686'
|
||||
self.runtest_rtems('RTEMS-pc686', '5')
|
||||
|
||||
def test_WINE32(self):
|
||||
os.environ['WINE'] = '32'
|
||||
cue.prepare(self.args)
|
||||
self.assertTrue('CI_CROSS_TARGETS' in os.environ, "CI_CROSS_TARGETS has not been set")
|
||||
self.assertEqual(os.environ['CI_CROSS_TARGETS'], ':win32-x86-mingw',
|
||||
"CI_CROSS_TARGETS is {0} (expected: :win32-x86-mingw)"
|
||||
.format(os.environ['CI_CROSS_TARGETS']))
|
||||
|
||||
def test_WINE64(self):
|
||||
os.environ['WINE'] = '64'
|
||||
cue.prepare(self.args)
|
||||
self.assertTrue('CI_CROSS_TARGETS' in os.environ, "CI_CROSS_TARGETS has not been set")
|
||||
self.assertEqual(os.environ['CI_CROSS_TARGETS'], ':windows-x64-mingw',
|
||||
"CI_CROSS_TARGETS is {0} (expected: :windows-x64-mingw)"
|
||||
.format(os.environ['CI_CROSS_TARGETS']))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if 'VV' in os.environ and os.environ['VV'] == '1':
|
||||
|
||||
477
cue.py
477
cue.py
@@ -1,17 +1,25 @@
|
||||
#!/usr/bin/env python
|
||||
"""CI build script for Linux/MacOS/Windows on Travis/AppVeyor/GitHub-Actions
|
||||
"""EPICS CI build script for Linux/MacOS/Windows on Travis/GitLab/AppVeyor/GitHub-Actions
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import sys, os, stat, shutil
|
||||
import sys, os, stat, shlex, shutil
|
||||
import fileinput
|
||||
import logging
|
||||
import re
|
||||
import time
|
||||
import threading
|
||||
from glob import glob
|
||||
import subprocess as sp
|
||||
import distutils.util
|
||||
import sysconfig
|
||||
import shutil
|
||||
|
||||
try:
|
||||
from os import cpu_count
|
||||
except ImportError:
|
||||
def cpu_count():
|
||||
pass # undetermined
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -31,6 +39,11 @@ def log_modified():
|
||||
sys.stdout.write(F.read())
|
||||
sys.stdout.write(os.linesep)
|
||||
|
||||
def whereis(cmd):
|
||||
if hasattr(shutil, 'which'): # >= py3.3
|
||||
loc = shutil.which(cmd)
|
||||
print('{0}Found exec {1} at {2!r} {3}'.format(ANSI_CYAN, cmd, loc, ANSI_RESET))
|
||||
|
||||
def prepare_env():
|
||||
'''HACK
|
||||
github actions yaml configuration doesn't allow
|
||||
@@ -129,7 +142,10 @@ def detect_context():
|
||||
ci['cachedir'] = os.environ['CACHEDIR']
|
||||
|
||||
if 'CHOCO' in os.environ:
|
||||
ci['choco'].extend(os.environ['CHOCO'].split())
|
||||
if os.environ['CHOCO'] == 'NO':
|
||||
ci['choco'] = []
|
||||
else:
|
||||
ci['choco'].extend(os.environ['CHOCO'].split())
|
||||
|
||||
if 'APT' in os.environ:
|
||||
ci['apt'].extend(os.environ['APT'].split())
|
||||
@@ -141,7 +157,7 @@ def detect_context():
|
||||
if 'TEST' in os.environ and os.environ['TEST'].lower() == 'no':
|
||||
ci['test'] = False
|
||||
|
||||
ci['parallel_make'] = 2
|
||||
ci['parallel_make'] = cpu_count() or 2
|
||||
if 'PARALLEL_MAKE' in os.environ:
|
||||
ci['parallel_make'] = int(os.environ['PARALLEL_MAKE'])
|
||||
|
||||
@@ -163,17 +179,20 @@ modules_to_compile = []
|
||||
setup = {}
|
||||
places = {}
|
||||
extra_makeargs = []
|
||||
make_timeout = 0.
|
||||
|
||||
is_base314 = False
|
||||
is_make3 = False
|
||||
has_test_results = False
|
||||
silent_dep_builds = True
|
||||
skip_dep_builds = False
|
||||
do_recompile = False
|
||||
installed_7z = False
|
||||
|
||||
|
||||
def clear_lists():
|
||||
global is_base314, has_test_results, silent_dep_builds, is_make3
|
||||
global _modified_files, do_recompile, building_base
|
||||
del seen_setups[:]
|
||||
del modules_to_compile[:]
|
||||
del extra_makeargs[:]
|
||||
@@ -184,6 +203,8 @@ def clear_lists():
|
||||
has_test_results = False
|
||||
silent_dep_builds = True
|
||||
do_recompile = False
|
||||
building_base = False
|
||||
_modified_files = set()
|
||||
ci['service'] = '<none>'
|
||||
ci['os'] = '<unknown>'
|
||||
ci['platform'] = '<unknown>'
|
||||
@@ -203,9 +224,8 @@ clear_lists()
|
||||
|
||||
if 'BASE' in os.environ and os.environ['BASE'] == 'SELF':
|
||||
building_base = True
|
||||
skip_dep_builds = True
|
||||
places['EPICS_BASE'] = curdir
|
||||
else:
|
||||
building_base = False
|
||||
|
||||
# Setup ANSI Colors
|
||||
ANSI_RED = "\033[31;1m"
|
||||
@@ -309,7 +329,7 @@ def host_info():
|
||||
print('PYTHONPATH')
|
||||
for dname in sys.path:
|
||||
print(' ', dname)
|
||||
print('platform =', distutils.util.get_platform())
|
||||
print('platform =', sysconfig.get_platform())
|
||||
|
||||
if ci['os'] == 'windows':
|
||||
print('{0}Available Visual Studio versions{1}'.format(ANSI_CYAN, ANSI_RESET))
|
||||
@@ -417,9 +437,11 @@ def update_release_local(var, location):
|
||||
def set_setup_from_env(dep):
|
||||
for postf in ['', '_DIRNAME', '_REPONAME', '_REPOOWNER', '_REPOURL',
|
||||
'_VARNAME', '_RECURSIVE', '_DEPTH', '_HOOK']:
|
||||
if dep + postf in os.environ:
|
||||
setup[dep + postf] = os.environ[dep + postf]
|
||||
logger.debug('ENV assignment: %s = %s', dep + postf, setup[dep + postf])
|
||||
env = dep + postf
|
||||
val = os.environ.get(env)
|
||||
if val:
|
||||
setup[env] = val
|
||||
logger.debug('ENV assignment: %s = %s', env, setup[env])
|
||||
|
||||
|
||||
def call_git(args, **kws):
|
||||
@@ -607,15 +629,21 @@ def add_dependency(dep):
|
||||
if dep + '_HOOK' in setup:
|
||||
hook = setup[dep + '_HOOK']
|
||||
hook_file = os.path.join(curdir, hook)
|
||||
hook_ext = os.path.splitext(hook_file)[1]
|
||||
if os.path.exists(hook_file):
|
||||
if re.match(r'.+\.patch$', hook):
|
||||
if hook_ext == '.patch':
|
||||
apply_patch(hook_file, cwd=place)
|
||||
elif re.match(r'.+\.(zip|7z)$', hook):
|
||||
elif hook_ext in ('.zip', '.7z'):
|
||||
extract_archive(hook_file, cwd=place)
|
||||
elif hook_ext == '.py':
|
||||
print('Running py hook {0} in {1}'.format(hook, place))
|
||||
sp.check_call([sys.executable, hook_file], cwd=place)
|
||||
else:
|
||||
print('Running hook {0} in {1}'.format(hook, place))
|
||||
sys.stdout.flush()
|
||||
sp.check_call(hook_file, shell=True, cwd=place)
|
||||
else:
|
||||
print('Skipping invalid hook {0} in {1}'.format(hook, place))
|
||||
|
||||
# write checked out commit hash to marker file
|
||||
head = get_git_hash(place)
|
||||
@@ -676,8 +704,10 @@ def setup_for_build(args):
|
||||
if ci['os'] == 'windows':
|
||||
if os.path.exists(r'C:\Strawberry\perl\bin'):
|
||||
# Put strawberry perl in front of the PATH (so that Git Perl is further behind)
|
||||
# Put Chocolatey\bin ahead to select correct make.exe
|
||||
logger.debug('Adding Strawberry Perl in front of the PATH')
|
||||
os.environ['PATH'] = os.pathsep.join([r'C:\Strawberry\c\bin',
|
||||
os.environ['PATH'] = os.pathsep.join([r'C:\ProgramData\Chocolatey\bin',
|
||||
r'C:\Strawberry\c\bin',
|
||||
r'C:\Strawberry\perl\site\bin',
|
||||
r'C:\Strawberry\perl\bin',
|
||||
os.environ['PATH']])
|
||||
@@ -745,30 +775,52 @@ def setup_for_build(args):
|
||||
if re.match('^test-results:', line):
|
||||
has_test_results = True
|
||||
|
||||
# Check make version
|
||||
if re.match(r'^GNU Make 3', sp.check_output(['make', '-v']).decode('ascii')):
|
||||
is_make3 = True
|
||||
logger.debug('Check if make is a 3.x series: %s', is_make3)
|
||||
|
||||
# apparently %CD% is handled automagically
|
||||
# apparently %CD% is handled automagically, so use getcwd() instead
|
||||
os.environ['TOP'] = os.getcwd()
|
||||
os.environ['MAKE'] = 'make'
|
||||
os.environ['EPICS_BASE'] = places['EPICS_BASE']
|
||||
|
||||
addpaths = []
|
||||
for path in args.paths:
|
||||
changed_vars = set()
|
||||
|
||||
for extra_env_var in args.extra_env_vars:
|
||||
try:
|
||||
addpaths.append(path.format(**os.environ))
|
||||
key_value = extra_env_var.split('=')
|
||||
key = key_value[0]
|
||||
value = key_value[1]
|
||||
expanded_value = value.format(**os.environ)
|
||||
|
||||
# Update the environment right now so later variables have access
|
||||
if key in os.environ:
|
||||
old_value = [os.environ[key]]
|
||||
else:
|
||||
old_value = []
|
||||
|
||||
os.environ[key] = os.pathsep.join(old_value + [expanded_value])
|
||||
changed_vars.add(key)
|
||||
except KeyError:
|
||||
print('Environment')
|
||||
[print(' ', K, '=', repr(V)) for K, V in os.environ.items()]
|
||||
raise
|
||||
|
||||
os.environ['PATH'] = os.pathsep.join([os.environ['PATH']] + addpaths)
|
||||
for key in changed_vars:
|
||||
print("{0}{2} = {3}{1}".format(ANSI_CYAN, ANSI_RESET, key, os.environ[key]))
|
||||
|
||||
# os.environ completely updated at this point
|
||||
|
||||
logger.debug('Final PATH')
|
||||
for loc in os.environ['PATH'].split(os.pathsep):
|
||||
logger.debug(' %r', loc)
|
||||
|
||||
# Check make version
|
||||
if re.match(r'^GNU Make 3', sp.check_output(['make', '-v']).decode('ascii')):
|
||||
is_make3 = True
|
||||
logger.debug('Check if make is a 3.x series: %s', is_make3)
|
||||
|
||||
# Add EXTRA make arguments
|
||||
for tag in ['EXTRA', 'EXTRA1', 'EXTRA2', 'EXTRA3', 'EXTRA4', 'EXTRA5']:
|
||||
val = os.environ.get(tag, "")
|
||||
if len(val)>0:
|
||||
extra_makeargs.append(val)
|
||||
extra_makeargs.extend(shlex.split(val))
|
||||
|
||||
|
||||
def fix_etc_hosts():
|
||||
@@ -786,6 +838,267 @@ def fix_etc_hosts():
|
||||
logger.debug('EXEC DONE')
|
||||
|
||||
|
||||
def edit_make_file(mode, path, values):
|
||||
"""Edit an EPICS Make file.
|
||||
|
||||
mode should be either "a" or "w", as for the open function.
|
||||
|
||||
path should be a list, e.g. ["configure", "CONFIG_SITE"]
|
||||
|
||||
values should be a dictionary of values to edit. If the value starts with
|
||||
a "+" the value will be appended.
|
||||
|
||||
Example usage:
|
||||
|
||||
edit_make_file("a", ["configure", "CONFIG_SITE"], {
|
||||
"VARIABLE": "value",
|
||||
"APPENDED_VARIABLE": "+value",
|
||||
})
|
||||
"""
|
||||
with open(os.path.join(places["EPICS_BASE"], *path), mode) as f:
|
||||
for variable, value in values.items():
|
||||
if value.startswith("+"):
|
||||
op = "+="
|
||||
value = value[1:]
|
||||
else:
|
||||
op = "="
|
||||
|
||||
f.write(variable + op + value + "\n")
|
||||
|
||||
|
||||
def handle_old_cross_variables():
|
||||
if "CI_CROSS_TARGETS" not in os.environ:
|
||||
os.environ["CI_CROSS_TARGETS"] = ""
|
||||
|
||||
if "RTEMS" in os.environ:
|
||||
rtems_target = os.environ.get('RTEMS_TARGET')
|
||||
if not rtems_target:
|
||||
if os.environ['RTEMS'] == '5':
|
||||
rtems_target = 'RTEMS-pc686-qemu'
|
||||
else:
|
||||
rtems_target = 'RTEMS-pc386'
|
||||
if os.path.exists(os.path.join(places['EPICS_BASE'], 'configure', 'os',
|
||||
'CONFIG.Common.RTEMS-pc386-qemu')):
|
||||
# Base 3.15 doesn't have -qemu target architecture
|
||||
rtems_target = 'RTEMS-pc386-qemu'
|
||||
|
||||
new_cross_target = ":" + rtems_target + "@" + os.environ["RTEMS"]
|
||||
os.environ["CI_CROSS_TARGETS"] += new_cross_target
|
||||
|
||||
print(
|
||||
"{0}WARNING: deprecated RTEMS environment variable was specified." \
|
||||
" Please add '{1}' to CI_CROSS_TARGETS instead.{2}".format(
|
||||
ANSI_RED, new_cross_target, ANSI_RESET
|
||||
)
|
||||
)
|
||||
logger.debug('Replaced deprecated RTEMS target with new entry in CI_CROSS_TARGETS: %s', new_cross_target)
|
||||
|
||||
if "WINE" in os.environ:
|
||||
if os.environ['WINE'] == '32':
|
||||
new_cross_target = ":win32-x86-mingw"
|
||||
elif os.environ['WINE'] == '64':
|
||||
new_cross_target = ":windows-x64-mingw"
|
||||
else:
|
||||
raise RuntimeError("Invalid $WINE, must be 32/64")
|
||||
os.environ["CI_CROSS_TARGETS"] += new_cross_target
|
||||
|
||||
print(
|
||||
"{0}WARNING: deprecated WINE environment variable was specified." \
|
||||
" Please add '{1}' to CI_CROSS_TARGETS instead.{2}".format(
|
||||
ANSI_RED, new_cross_target, ANSI_RESET
|
||||
)
|
||||
)
|
||||
logger.debug('Replaced deprecated WINE target with new entry in CI_CROSS_TARGETS: %s', new_cross_target)
|
||||
|
||||
|
||||
def prepare_cross_compilation(cross_target_info):
|
||||
"""Prepare the configuration for a single value of the CI_CROSS_TARGETS
|
||||
variable.
|
||||
|
||||
See the README.md file for more information on this variable."""
|
||||
cross_target_info = cross_target_info.split("@")
|
||||
if len(cross_target_info) == 2:
|
||||
target_param = cross_target_info[1]
|
||||
else:
|
||||
target_param = None
|
||||
|
||||
target = cross_target_info[0]
|
||||
|
||||
if target.startswith("RTEMS-"):
|
||||
prepare_rtems_cross(target, target_param)
|
||||
elif target.endswith("-mingw"):
|
||||
prepare_wine_cross(target)
|
||||
elif target.startswith("linux-"):
|
||||
prepare_linux_cross(target, target_param)
|
||||
else:
|
||||
raise ValueError(
|
||||
"Unknown CI_CROSS_TARGETS {0}. "
|
||||
"Please see the ci-scripts README for available values.".format(target)
|
||||
)
|
||||
|
||||
|
||||
def prepare_rtems_cross(epics_arch, version):
|
||||
"""Prepare the configuration for RTEMS cross-compilation for the given
|
||||
RTEMS version.
|
||||
|
||||
If version is None, it defaults to version 5 for RTEMS-pc686-*, 4.10
|
||||
otherwise."""
|
||||
if version is None:
|
||||
if epics_arch.startswith("RTEMS-pc686"):
|
||||
version = "5"
|
||||
else:
|
||||
version = "4.10"
|
||||
|
||||
# eg. "RTEMS-pc386" or "RTEMS-pc386-qemu" -> "pc386"
|
||||
rtems_bsp = re.match("^RTEMS-([^-]*)(?:-qemu)?$", epics_arch).group(1)
|
||||
|
||||
print("Cross compiler RTEMS{0} @ {1}".format(version, epics_arch))
|
||||
|
||||
if ci["os"] == "linux":
|
||||
download_rtems(version, rtems_bsp)
|
||||
|
||||
edit_make_file(
|
||||
"a",
|
||||
["configure", "os", "CONFIG_SITE.Common.RTEMS"],
|
||||
{
|
||||
"RTEMS_VERSION": version,
|
||||
"RTEMS_BASE": "/opt/rtems/" + version,
|
||||
},
|
||||
)
|
||||
|
||||
edit_make_file(
|
||||
"a",
|
||||
["configure", "CONFIG_SITE"],
|
||||
{"CROSS_COMPILER_TARGET_ARCHS": epics_arch},
|
||||
)
|
||||
|
||||
ci["apt"].extend(
|
||||
["re2c", "g++-mingw-w64-i686", "g++-mingw-w64-x86-64", "qemu-system-x86"]
|
||||
)
|
||||
|
||||
def download_rtems(version, rtems_bsp):
|
||||
rsb_release = os.environ.get("RSB_BUILD", "20210306")
|
||||
tar_name = "{0}-rtems{1}.tar.xz".format(rtems_bsp, version)
|
||||
print("Downloading RTEMS {0} cross compiler: {1}".format(version, tar_name))
|
||||
sys.stdout.flush()
|
||||
sp.check_call(
|
||||
[
|
||||
"curl",
|
||||
"-fsSL",
|
||||
"--retry",
|
||||
"3",
|
||||
"-o",
|
||||
tar_name,
|
||||
"https://github.com/mdavidsaver/rsb/releases/download/{0}%2F{1}/{2}".format(
|
||||
version, rsb_release, tar_name
|
||||
),
|
||||
],
|
||||
cwd=toolsdir,
|
||||
)
|
||||
sudo_prefix = []
|
||||
if ci["service"] == "github-actions":
|
||||
sudo_prefix = ["sudo"]
|
||||
sp.check_call(
|
||||
sudo_prefix + ["tar", "-C", "/", "-xmJ", "-f", os.path.join(toolsdir, tar_name)]
|
||||
)
|
||||
os.remove(os.path.join(toolsdir, tar_name))
|
||||
for rtems_cc in glob("/opt/rtems/*/bin/*-gcc"):
|
||||
print("{0}{1} --version{2}".format(ANSI_CYAN, rtems_cc, ANSI_RESET))
|
||||
sys.stdout.flush()
|
||||
sp.check_call([rtems_cc, "--version"])
|
||||
|
||||
|
||||
def prepare_wine_cross(epics_arch):
|
||||
"""Prepare the configuration for Wine cross-compilation for the given mingw
|
||||
architecture."""
|
||||
|
||||
if epics_arch == "win32-x86-mingw":
|
||||
gnu_arch = "i686-w64-mingw32"
|
||||
deb_arch = "mingw-w64-i686"
|
||||
bits = "32"
|
||||
elif epics_arch == "windows-x64-mingw":
|
||||
gnu_arch = "x86_64-w64-mingw32"
|
||||
deb_arch = "mingw-w64-x86-64"
|
||||
bits = "64"
|
||||
else:
|
||||
raise ValueError(
|
||||
"Unknown architecture '{0}' for WINE target. "
|
||||
"Please see the ci-scripts README for available values.".format(epics_arch)
|
||||
)
|
||||
|
||||
print("Cross compiler mingw{} / Wine".format(bits))
|
||||
|
||||
edit_make_file(
|
||||
"a",
|
||||
["configure", "os", "CONFIG.linux-x86." + epics_arch],
|
||||
{"CMPLR_PREFIX": gnu_arch + "-"},
|
||||
)
|
||||
|
||||
edit_make_file(
|
||||
"a",
|
||||
["configure", "CONFIG_SITE"],
|
||||
{"CROSS_COMPILER_TARGET_ARCHS": "+" + epics_arch},
|
||||
)
|
||||
|
||||
ci['apt'].extend(["re2c", "g++-" + deb_arch])
|
||||
|
||||
|
||||
def prepare_linux_cross(epics_arch, gnu_arch):
|
||||
"""Prepare the configuration for Linux cross-compilation for the given
|
||||
architecture.
|
||||
|
||||
If gnu_arch is None, this function will try to guess it using the
|
||||
epics_arch value.
|
||||
|
||||
linux-arm architecture defaults to arm-linux-gnueabi (soft floats)."""
|
||||
# This list is kind of an intersection between the set of cross-compilers
|
||||
# provided by Ubuntu[1] and the list of architectures found in
|
||||
# `epics-base/configure/os`
|
||||
#
|
||||
# [1]: https://packages.ubuntu.com/source/focal/gcc-10-cross
|
||||
if gnu_arch is None:
|
||||
if epics_arch == "linux-x86":
|
||||
gnu_arch = "i686-linux-gnu"
|
||||
elif epics_arch == "linux-arm":
|
||||
gnu_arch = "arm-linux-gnueabi"
|
||||
elif epics_arch == "linux-aarch64":
|
||||
gnu_arch = "aarch64-linux-gnu"
|
||||
elif epics_arch == "linux-ppc":
|
||||
gnu_arch = "powerpc-linux-gnu"
|
||||
elif epics_arch == "linux-ppc64":
|
||||
gnu_arch = "powerpc64le-linux-gnu"
|
||||
else:
|
||||
raise ValueError(
|
||||
"Could not guess the GNU architecture for EPICS arch: {}. "
|
||||
"Please use the '@' syntax of the 'CI_CROSS_TARGETS' variable".format(
|
||||
epics_arch
|
||||
)
|
||||
)
|
||||
|
||||
print(
|
||||
"Setting up Linux cross-compiling arch {0} with GNU arch {1}".format(
|
||||
epics_arch, gnu_arch
|
||||
)
|
||||
)
|
||||
|
||||
edit_make_file(
|
||||
"w",
|
||||
["configure", "os", "CONFIG_SITE.linux-x86_64." + epics_arch],
|
||||
{
|
||||
"GNU_TARGET": gnu_arch,
|
||||
"COMMANDLINE_LIBRARY": "EPICS",
|
||||
},
|
||||
)
|
||||
|
||||
edit_make_file(
|
||||
"a",
|
||||
["configure", "CONFIG_SITE"],
|
||||
{"CROSS_COMPILER_TARGET_ARCHS": "+" + epics_arch},
|
||||
)
|
||||
|
||||
ci["apt"].extend(["re2c", "g++-" + gnu_arch])
|
||||
|
||||
|
||||
def prepare(args):
|
||||
host_info()
|
||||
|
||||
@@ -831,20 +1144,8 @@ def prepare(args):
|
||||
elif ci['compiler'].startswith('gcc'):
|
||||
cxx = re.sub(r'gcc', r'g++', ci['compiler'])
|
||||
|
||||
# Cross compilation on Linux to RTEMS (set RTEMS to version "4.9", "4.10")
|
||||
# requires qemu, bison, flex, texinfo, install-info
|
||||
# rtems_bsp is needed also if Base is from cache
|
||||
if 'RTEMS' in os.environ:
|
||||
if 'RTEMS_TARGET' in os.environ:
|
||||
rtems_target = os.environ['RTEMS_TARGET']
|
||||
elif os.path.exists(os.path.join(places['EPICS_BASE'], 'configure', 'os',
|
||||
'CONFIG.Common.RTEMS-pc386-qemu')):
|
||||
# Base 3.15 doesn't have -qemu target architecture
|
||||
rtems_target = 'RTEMS-pc386-qemu'
|
||||
else:
|
||||
rtems_target = 'RTEMS-pc386'
|
||||
# eg. "RTEMS-pc386" or "RTEMS-pc386-qemu" -> "pc386"
|
||||
rtems_bsp = re.match('^RTEMS-([^-]*)(?:-qemu)?$', rtems_target).group(1)
|
||||
if not os.path.isdir(toolsdir):
|
||||
os.makedirs(toolsdir)
|
||||
|
||||
if 'BASE' in modules_to_compile or building_base:
|
||||
fold_start('set.up.epics_build', 'Configuring EPICS build system')
|
||||
@@ -895,44 +1196,12 @@ endif''')
|
||||
|
||||
# Cross-compilations from Linux platform
|
||||
if ci['os'] == 'linux':
|
||||
handle_old_cross_variables()
|
||||
|
||||
# Cross compilation to Windows/Wine (set WINE to architecture "32", "64")
|
||||
# requires wine and g++-mingw-w64-i686 / g++-mingw-w64-x86-64
|
||||
if 'WINE' in os.environ:
|
||||
if os.environ['WINE'] == '32':
|
||||
print('Cross compiler mingw32 / Wine')
|
||||
with open(os.path.join(places['EPICS_BASE'], 'configure', 'os',
|
||||
'CONFIG.linux-x86.win32-x86-mingw'), 'a') as f:
|
||||
f.write('''
|
||||
CMPLR_PREFIX=i686-w64-mingw32-''')
|
||||
with open(os.path.join(places['EPICS_BASE'], 'configure', 'CONFIG_SITE'), 'a') as f:
|
||||
f.write('''
|
||||
CROSS_COMPILER_TARGET_ARCHS+=win32-x86-mingw''')
|
||||
|
||||
if os.environ['WINE'] == '64':
|
||||
print('Cross compiler mingw64 / Wine')
|
||||
with open(os.path.join(places['EPICS_BASE'], 'configure', 'os',
|
||||
'CONFIG.linux-x86.windows-x64-mingw'), 'a') as f:
|
||||
f.write('''
|
||||
CMPLR_PREFIX=x86_64-w64-mingw32-''')
|
||||
with open(os.path.join(places['EPICS_BASE'], 'configure', 'CONFIG_SITE'), 'a') as f:
|
||||
f.write('''
|
||||
CROSS_COMPILER_TARGET_ARCHS += windows-x64-mingw''')
|
||||
|
||||
# Cross compilation on Linux to RTEMS (set RTEMS to version "4.9", "4.10")
|
||||
# requires qemu, bison, flex, texinfo, install-info
|
||||
if 'RTEMS' in os.environ:
|
||||
print('Cross compiler RTEMS{0} @ {1}'.format(os.environ['RTEMS'], rtems_target))
|
||||
with open(os.path.join(places['EPICS_BASE'], 'configure', 'os',
|
||||
'CONFIG_SITE.Common.RTEMS'), 'a') as f:
|
||||
f.write('''
|
||||
RTEMS_VERSION={0}
|
||||
RTEMS_BASE=/opt/rtems/{0}'''.format(os.environ['RTEMS']))
|
||||
|
||||
with open(os.path.join(places['EPICS_BASE'], 'configure', 'CONFIG_SITE'), 'a') as f:
|
||||
f.write('''
|
||||
CROSS_COMPILER_TARGET_ARCHS += {0}
|
||||
'''.format(rtems_target))
|
||||
for cross_target_info in os.environ.get("CI_CROSS_TARGETS", "").split(":"):
|
||||
if cross_target_info == "":
|
||||
continue
|
||||
prepare_cross_compilation(cross_target_info)
|
||||
|
||||
print('Host compiler', ci['compiler'])
|
||||
|
||||
@@ -982,14 +1251,27 @@ PERL = C:/Strawberry/perl/bin/perl -CSD'''
|
||||
with open(os.path.join(places['EPICS_BASE'], 'configure', 'CONFIG_SITE'), 'a') as f:
|
||||
f.write(extra_config)
|
||||
|
||||
fold_end('set.up.epics_build', 'Configuring EPICS build system')
|
||||
# enable color in error and warning messages if the (cross) compiler supports it
|
||||
with open(os.path.join(places['EPICS_BASE'], 'configure', 'CONFIG'), 'a') as f:
|
||||
f.write('''
|
||||
ifdef T_A
|
||||
COLOR_FLAG_$(T_A) := $(shell $(CPP) -fdiagnostics-color -E - </dev/null >/dev/null 2>/dev/null && echo -fdiagnostics-color)
|
||||
USR_CPPFLAGS += $(COLOR_FLAG_$(T_A))
|
||||
endif''')
|
||||
|
||||
if not os.path.isdir(toolsdir):
|
||||
os.makedirs(toolsdir)
|
||||
fold_end('set.up.epics_build', 'Configuring EPICS build system')
|
||||
|
||||
if ci['os'] == 'windows' and ci['choco']:
|
||||
fold_start('install.choco', 'Installing CHOCO packages')
|
||||
sp.check_call(['choco', 'install'] + ci['choco'] + ['-y', '--limitoutput', '--no-progress'])
|
||||
for i in range(0,3):
|
||||
try:
|
||||
sp.check_call(['choco', 'install'] + ci['choco'] + ['-y', '--limitoutput', '--no-progress'])
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print("Retrying choco install attempt {} after 30 seconds".format(i+1))
|
||||
time.sleep(30)
|
||||
else:
|
||||
break
|
||||
fold_end('install.choco', 'Installing CHOCO packages')
|
||||
|
||||
if ci['os'] == 'linux' and ci['apt']:
|
||||
@@ -1003,46 +1285,31 @@ PERL = C:/Strawberry/perl/bin/perl -CSD'''
|
||||
sp.check_call(['brew', 'install'] + ci['homebrew'])
|
||||
fold_end('install.homebrew', 'Installing Homebrew packages')
|
||||
|
||||
if ci['os'] == 'linux' and 'RTEMS' in os.environ:
|
||||
rsb_release = os.environ.get('RSB_BUILD', '20210306')
|
||||
tar_name = '{0}-rtems{1}.tar.xz'.format(rtems_bsp, os.environ['RTEMS'])
|
||||
print('Downloading RTEMS {0} cross compiler: {1}'
|
||||
.format(os.environ['RTEMS'], tar_name))
|
||||
sys.stdout.flush()
|
||||
sp.check_call(['curl', '-fsSL', '--retry', '3', '-o', tar_name,
|
||||
'https://github.com/mdavidsaver/rsb/releases/download/{0}%2F{1}/{2}'
|
||||
.format(os.environ['RTEMS'], rsb_release, tar_name)],
|
||||
cwd=toolsdir)
|
||||
sudo_prefix = []
|
||||
if ci['service'] == 'github-actions':
|
||||
sudo_prefix = ['sudo']
|
||||
sp.check_call(sudo_prefix + ['tar', '-C', '/', '-xmJ', '-f', os.path.join(toolsdir, tar_name)])
|
||||
os.remove(os.path.join(toolsdir, tar_name))
|
||||
for rtems_cc in glob('/opt/rtems/*/bin/*-gcc'):
|
||||
print('{0}{1} --version{2}'.format(ANSI_CYAN, rtems_cc, ANSI_RESET))
|
||||
sys.stdout.flush()
|
||||
sp.check_call([rtems_cc, '--version'])
|
||||
|
||||
setup_for_build(args)
|
||||
|
||||
print('{0}EPICS_HOST_ARCH = {1}{2}'.format(ANSI_CYAN, os.environ['EPICS_HOST_ARCH'], ANSI_RESET))
|
||||
whereis('make')
|
||||
print('{0}$ make --version{1}'.format(ANSI_CYAN, ANSI_RESET))
|
||||
sys.stdout.flush()
|
||||
call_make(['--version'], parallel=0)
|
||||
whereis('perl')
|
||||
print('{0}$ perl --version{1}'.format(ANSI_CYAN, ANSI_RESET))
|
||||
sys.stdout.flush()
|
||||
sp.check_call(['perl', '--version'])
|
||||
|
||||
if re.match(r'^vs', ci['compiler']):
|
||||
whereis('cl')
|
||||
print('{0}$ cl{1}'.format(ANSI_CYAN, ANSI_RESET))
|
||||
sys.stdout.flush()
|
||||
sp.check_call(['cl'])
|
||||
else:
|
||||
cc = ci['compiler']
|
||||
whereis(cc)
|
||||
print('{0}$ {1} --version{2}'.format(ANSI_CYAN, cc, ANSI_RESET))
|
||||
sys.stdout.flush()
|
||||
sp.check_call([cc, '--version'])
|
||||
if cxx:
|
||||
whereis(cxx)
|
||||
print('{0}$ {1} --version{2}'.format(ANSI_CYAN, cxx, ANSI_RESET))
|
||||
sys.stdout.flush()
|
||||
sp.check_call([cxx, '--version'])
|
||||
@@ -1050,7 +1317,7 @@ PERL = C:/Strawberry/perl/bin/perl -CSD'''
|
||||
if logging.getLogger().isEnabledFor(logging.DEBUG):
|
||||
log_modified()
|
||||
|
||||
if not building_base:
|
||||
if not skip_dep_builds:
|
||||
fold_start('build.dependencies', 'Build missing/outdated dependencies')
|
||||
for mod in modules_to_compile:
|
||||
place = places[setup[mod + "_VARNAME"]]
|
||||
@@ -1115,8 +1382,6 @@ def test_results(args):
|
||||
def doExec(args):
|
||||
'exec user command with vcvars'
|
||||
setup_for_build(args)
|
||||
os.environ['MAKE'] = 'make'
|
||||
os.environ['EPICS_BASE'] = places['EPICS_BASE']
|
||||
fold_start('exec.command', 'Execute command {}'.format(args.cmd))
|
||||
sp.check_call(' '.join(args.cmd), shell=True)
|
||||
fold_end('exec.command', 'Execute command {}'.format(args.cmd))
|
||||
@@ -1186,8 +1451,10 @@ def getargs():
|
||||
p = ArgumentParser()
|
||||
p.add_argument('--no-vcvars', dest='vcvars', default=True, action='store_false',
|
||||
help='Assume vcvarsall.bat has already been run')
|
||||
p.add_argument('--add-path', dest='paths', default=[], action='append',
|
||||
help='Append directory to $PATH or %%PATH%%. Expands {ENVVAR}')
|
||||
p.add_argument('--add-path', dest='extra_env_vars', type=lambda x: "PATH={}".format(x), default=[], action='append',
|
||||
help='Append directory to $PATH or %%PATH%%. Expands {ENVVAR}. Equivalent to: "--add-env PATH=<PATHS>"')
|
||||
p.add_argument('--add-env', dest='extra_env_vars', default=[], action='append',
|
||||
help='Append directory to the specified $ENVVAR or %%ENVVAR%%. Expands {OTHER_ENVVAR}. Example: "--add-env \'LD_LIBRARY_PATH={EPICS_BASE}/lib/{EPICS_HOST_ARCH}\'"')
|
||||
p.add_argument('-T', '--timeout', type=timespec, metavar='DLY',
|
||||
help='Terminate make after delay. DLY interpreted as second, or may be qualified with "S", "M", or "H". (default no timeout)')
|
||||
subp = p.add_subparsers()
|
||||
|
||||
@@ -18,7 +18,7 @@ NTYPES_REPONAME=normativeTypesCPP
|
||||
NTYPES_REPOOWNER=epics-base
|
||||
|
||||
# Sequencer
|
||||
SNCSEQ_REPOURL=https://www-csr.bessy.de/control/SoftDist/sequencer/repo/branch-2-2.git
|
||||
SNCSEQ_REPOURL=https://github.com/mdavidsaver/sequencer-mirror.git
|
||||
SNCSEQ_DEPTH=0
|
||||
SNCSEQ_DIRNAME=seq
|
||||
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
## Features
|
||||
|
||||
- 20 parallel runners on Linux/Windows (5 runners on MacOS)
|
||||
- Ubuntu 16/18/20, MacOS 10.15, Windows Server 2016/2019
|
||||
- Ubuntu 18/20/22, MacOS 11/12, Windows Server 2019/2022
|
||||
- Compile natively on Linux (gcc, clang)
|
||||
- Compile natively on MacOS (clang)
|
||||
- Compile natively on Windows (gcc/MinGW, Visual Studio 2017/2019/2022)
|
||||
- Compile natively on Windows (gcc/MinGW, Visual Studio 2019/2022)
|
||||
- Cross-compile for Windows 32bit and 64bit using MinGW and WINE
|
||||
- Cross-compile for RTEMS 4.9 and 4.10 (pc386, Base >= 3.15)
|
||||
- Cross-compile for RTEMS 5 (10 BSPs, Base >= 7.0.5.1)
|
||||
|
||||
@@ -41,118 +41,57 @@ jobs:
|
||||
matrix:
|
||||
# Job names also name artifacts, character limitations apply
|
||||
include:
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-24.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
wine: "64"
|
||||
name: "Ub-20 gcc-9 + MinGW"
|
||||
name: "Ub-24 gcc + MinGW"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-24.04
|
||||
cmp: gcc
|
||||
configuration: static
|
||||
wine: "64"
|
||||
name: "Ub-20 gcc-9 + MinGW, static"
|
||||
name: "Ub-24 gcc + MinGW, static"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-24.04
|
||||
cmp: gcc
|
||||
configuration: static
|
||||
extra: "CMD_CXXFLAGS=-std=c++11"
|
||||
name: "Ub-20 gcc-9 C++11, static"
|
||||
name: "Ub-24 gcc C++11, static"
|
||||
|
||||
- os: ubuntu-18.04
|
||||
cmp: clang
|
||||
configuration: default
|
||||
name: "Ub-18 clang-9"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-24.04
|
||||
cmp: clang
|
||||
configuration: default
|
||||
extra: "CMD_CXXFLAGS=-std=c++11"
|
||||
name: "Ub-20 clang-10 C++11"
|
||||
name: "Ub-24 clang C++11"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-22.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
rtems: "4.10"
|
||||
name: "Ub-20 gcc-9 + RT-4.10"
|
||||
cross: "RTEMS-pc686-qemu@5"
|
||||
name: "Ub-22 gcc + RT-5.1 pc686"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-22.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
rtems: "4.9"
|
||||
name: "Ub-20 gcc-9 + RT-4.9"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
rtems: "5"
|
||||
rtems_target: RTEMS-pc686-qemu
|
||||
name: "Ub-20 gcc-9 + RT-5.1 pc686"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
rtems: "5"
|
||||
rtems_target: RTEMS-beatnik
|
||||
cross: "RTEMS-beatnik@5"
|
||||
test: NO
|
||||
name: "Ub-20 gcc-9 + RT-5.1 beatnik"
|
||||
|
||||
- os: ubuntu-18.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
name: "Ub-18 gcc-7"
|
||||
|
||||
- os: ubuntu-18.04
|
||||
cmp: gcc-8
|
||||
utoolchain: true
|
||||
configuration: default
|
||||
name: "Ub-18 gcc-8"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc-8
|
||||
utoolchain: true
|
||||
configuration: default
|
||||
name: "Ub-20 gcc-8"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: clang
|
||||
configuration: default
|
||||
name: "Ub-20 clang-10"
|
||||
name: "Ub-22 gcc + RT-5.1 beatnik"
|
||||
|
||||
- os: macos-latest
|
||||
cmp: clang
|
||||
configuration: default
|
||||
name: "MacOS clang-12"
|
||||
name: "MacOS clang"
|
||||
|
||||
- os: windows-2016
|
||||
cmp: vs2017
|
||||
configuration: default
|
||||
name: "Win2016 MSC-17"
|
||||
|
||||
- os: windows-2016
|
||||
cmp: vs2017
|
||||
configuration: static
|
||||
name: "Win2016 MSC-17, static"
|
||||
|
||||
- os: windows-2019
|
||||
- os: windows-2022
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
name: "Win2019 MinGW"
|
||||
name: "Win2022 MinGW"
|
||||
|
||||
- os: windows-2019
|
||||
- os: windows-2022
|
||||
cmp: gcc
|
||||
configuration: static
|
||||
name: "Win2019 MinGW, static"
|
||||
|
||||
- os: windows-2019
|
||||
cmp: vs2019
|
||||
configuration: default
|
||||
name: "Win2019 MSC-19"
|
||||
|
||||
- os: windows-2019
|
||||
cmp: vs2019
|
||||
configuration: static
|
||||
name: "Win2019 MSC-19, static"
|
||||
name: "Win2022 MinGW, static"
|
||||
|
||||
- os: windows-2022
|
||||
cmp: vs2022
|
||||
@@ -164,8 +103,14 @@ jobs:
|
||||
configuration: static
|
||||
name: "Win2022 MSC-22, static"
|
||||
|
||||
- os: ubuntu-latest
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
name: "Cross linux-aarch64"
|
||||
cross: linux-aarch64
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- name: Automatic core dumper analysis
|
||||
@@ -175,23 +120,17 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install qemu-system-x86 g++-mingw-w64-x86-64 gdb
|
||||
if: runner.os == 'Linux'
|
||||
- name: "apt-get install ${{ matrix.cmp }}"
|
||||
run: |
|
||||
sudo apt-get -y install software-properties-common
|
||||
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install ${{ matrix.cmp }}
|
||||
if: matrix.utoolchain
|
||||
- name: Prepare and compile dependencies
|
||||
run: python .ci/cue.py prepare
|
||||
- name: Build main module
|
||||
run: python .ci/cue.py build
|
||||
- name: Run main module tests
|
||||
run: python .ci/cue.py test
|
||||
run: python .ci/cue.py -T 15M test
|
||||
- name: Upload tapfiles Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: tapfiles ${{ matrix.name }}
|
||||
path: '**/O.*/*.tap'
|
||||
- name: Collect and show test results
|
||||
run: python .ci/cue.py test-results
|
||||
if: ${{ always() }}
|
||||
run: python .ci/cue.py -T 5M test-results
|
||||
|
||||
@@ -31,44 +31,39 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
- os: ubuntu-18.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
base: "7.0"
|
||||
name: "7.0 Ub-18 gcc-7"
|
||||
|
||||
- os: ubuntu-18.04
|
||||
cmp: gcc
|
||||
configuration: static
|
||||
base: "7.0"
|
||||
name: "7.0 Ub-18 gcc-7 static"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
include:
|
||||
- os: ubuntu-24.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
base: "3.15"
|
||||
name: "3.15 Ub-20 gcc-9"
|
||||
name: "3.15 Ub-24 gcc"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-24.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
base: "7.0"
|
||||
name: "7.0 Ub-24 gcc"
|
||||
|
||||
- os: ubuntu-24.04
|
||||
cmp: gcc
|
||||
configuration: static
|
||||
base: "3.15"
|
||||
name: "3.15 Ub-20 gcc-9 static"
|
||||
name: "3.15 Ub-24 gcc static"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-24.04
|
||||
cmp: gcc
|
||||
configuration: debug
|
||||
base: "3.15"
|
||||
name: "3.15 Ub-20 gcc-9 debug"
|
||||
name: "3.15 Ub-24 gcc debug"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-24.04
|
||||
cmp: clang
|
||||
configuration: default
|
||||
base: "3.15"
|
||||
name: "3.15 Ub-20 clang-10"
|
||||
name: "3.15 Ub-24 clang"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- name: Prepare and compile dependencies
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
diff -ruN a/bla.txt b/bla.txt
|
||||
--- a/bla.txt 2020-06-19 18:54:43.129076711 +0200
|
||||
+++ b/bla.txt 2020-06-19 18:55:05.093948316 +0200
|
||||
@@ -1,3 +1,3 @@
|
||||
@@ -1,2 +1,2 @@
|
||||
-LINE1=YES
|
||||
+LINE1=NO
|
||||
LINE2=NO
|
||||
|
||||
Reference in New Issue
Block a user