12 Commits

Author SHA1 Message Date
Ralph Lange
e91a588370 travis: copy RELEASE.local to top of checkout
- closes #32
  (fix is in AppVeyor do.py script as per 88831439)
2020-04-27 11:34:01 +02:00
Ralph Lange
29e657d585 Run tests using parallel make (reducing build time) 2020-04-27 11:34:01 +02:00
Ralph Lange
4413c7d75e travis: fix build.sh (set EPICS_BASE correctly) for BASE=SELF 2020-04-24 19:16:12 +02:00
Ralph Lange
48b15417a6 travis: fix RTEMS cross builds for Base 3.15 2020-04-24 19:12:20 +02:00
Ralph Lange
1ac8bf7479 appveyor: fix behavior when BASE set in setup file 2020-04-24 16:16:50 +02:00
Ralph Lange
d0f93f1920 travis: fix for EXTRA arguments with spaces/quotes
- feed EXTRA variables into an array to be properly expanded
2020-04-24 12:27:30 +02:00
Ralph Lange
27f823139a appveyor: don't walk() through the file system in host_info()
- was taking ~3min on AppVeyor builders
2020-04-23 14:12:03 +02:00
Ralph Lange
88831439b1 appveyor: consider base build (BASE=SELF) 2020-04-23 14:11:18 +02:00
Ralph Lange
177dfd4615 travis: fix /etc/hosts issue on bionic image 2020-04-23 14:11:17 +02:00
Ralph Lange
3bd2bb6dff travis: consider base build (BASE=SELF) 2020-04-22 13:36:16 +02:00
Ralph Lange
393a470d05 appveyor: add CMP doc to README 2020-04-22 10:25:18 +02:00
Ralph Lange
519b75aef2 appveyor: use pre-installed strawberry perl on vs2019 image 2020-04-22 10:25:18 +02:00
6 changed files with 148 additions and 95 deletions

View File

@@ -377,7 +377,7 @@ class TestSetupForBuild(unittest.TestCase):
def test_StrawberryInPath(self): def test_StrawberryInPath(self):
os.environ['CMP'] = 'vs2019' os.environ['CMP'] = 'vs2019'
do.setup_for_build(self.args) do.setup_for_build(self.args)
self.assertTrue(re.search('strawberry', os.environ['PATH']), self.assertTrue(re.search('strawberry', os.environ['PATH'], flags=re.IGNORECASE),
'Strawberry Perl location not in PATH for vs2019') 'Strawberry Perl location not in PATH for vs2019')

View File

@@ -27,7 +27,7 @@
``` ```
$ cp .ci/appveyor/.appveyor.yml.example-full .appveyor.yml $ cp .ci/appveyor/.appveyor.yml.example-full .appveyor.yml
``` ```
5. Edit the `.appveyor.yml` configuration to include the jobs you want 5. Edit the `.appveyor.yml` configuration to include the jobs you want
AppVeyor to run. AppVeyor to run.
@@ -38,16 +38,18 @@
Select 32bit or 64bit processor architecture. Select 32bit or 64bit processor architecture.
3. `environment: / matrix:` \ 3. `environment: / matrix:` \
List of environment variable settings. Each list element (starting with List of environment variable settings. Each list element (starting with
a dash) is one step on the axis of the build matrix. a dash) is one step on the axis of the build matrix. \
Set `CMP` to select the compiler: `mingw` for the native
Your builds will take long. [MinGW](http://mingw-w64.org/) GNU compiler, `vs2008` ...`vs2019`
(options listed above) for the Microsoft Visual Studio compilers.
Your builds will take long. \
AppVeyor only grants a single worker VM - all jobs of the matrix are AppVeyor only grants a single worker VM - all jobs of the matrix are
executed sequentially. Each job will take around 10 minutes. executed sequentially. Each job will take around 10 minutes.
The `matrix: / exclude:` setting can be used to reduce the number of The `matrix: / exclude:` setting can be used to reduce the number of
jobs. Check the [AppVeyor docs](https://www.appveyor.com/docs/build-configuration/#build-matrix) jobs. Check the [AppVeyor docs](https://www.appveyor.com/docs/build-configuration/#build-matrix)
for more ways to reduce the build matrix size. for more ways to reduce the build matrix size.
6. Push your changes and check 6. Push your changes and check
[ci.appveyor.com](https://ci.appveyor.com/) for your build results. [ci.appveyor.com](https://ci.appveyor.com/) for your build results.

View File

@@ -41,17 +41,37 @@ else:
if 'CACHEDIR' in os.environ: if 'CACHEDIR' in os.environ:
cachedir = os.environ['CACHEDIR'] cachedir = os.environ['CACHEDIR']
vcvars_table = {
# https://en.wikipedia.org/wiki/Microsoft_Visual_Studio#History
'vs2019':r'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat',
'vs2017':r'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat',
'vs2015':r'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat',
'vs2013':r'C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat',
'vs2012':r'C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat',
'vs2010':r'C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat',
'vs2008':r'C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat',
}
ciscriptsdir = os.path.abspath(os.path.dirname(sys.argv[0])) ciscriptsdir = os.path.abspath(os.path.dirname(sys.argv[0]))
if os.path.basename(ciscriptsdir) == 'appveyor': if os.path.basename(ciscriptsdir) == 'appveyor':
ciscriptsdir = ciscriptsdir.rstrip(os.pathsep+'appveyor') ciscriptsdir = ciscriptsdir.rstrip(os.pathsep+'appveyor')
if 'BASE' in os.environ and os.environ['BASE'] == 'SELF':
building_base = True
places['EPICS_BASE'] = '.'
else:
building_base = False
def modlist(): def modlist():
for var in ['ADD_MODULES', 'MODULES']: if building_base:
setup.setdefault(var, '') ret = []
if var in os.environ: else:
setup[var] = os.environ[var] for var in ['ADD_MODULES', 'MODULES']:
logger.debug('ENV assignment: %s = %s', var, setup[var]) setup.setdefault(var, '')
ret = ['BASE'] + setup['ADD_MODULES'].upper().split() + setup['MODULES'].upper().split() if var in os.environ:
setup[var] = os.environ[var]
logger.debug('ENV assignment: %s = %s', var, setup[var])
ret = ['BASE'] + setup['ADD_MODULES'].upper().split() + setup['MODULES'].upper().split()
logger.debug('Effective module list: %s', ret) logger.debug('Effective module list: %s', ret)
return ret return ret
@@ -69,12 +89,9 @@ def host_info():
print('platform =', distutils.util.get_platform()) print('platform =', distutils.util.get_platform())
print('{0}Available Visual Studio versions{1}'.format(ANSI_CYAN, ANSI_RESET)) print('{0}Available Visual Studio versions{1}'.format(ANSI_CYAN, ANSI_RESET))
from fnmatch import fnmatch for key in vcvars_table:
for base in (r'C:\Program Files (x86)', r'C:\Program Files'): if os.path.exists(vcvars_table[key]):
for root, dirs, files in os.walk(base): print('Found', key, 'in', vcvars_table[key])
for fname in files:
if fnmatch(fname, 'vcvarsall.bat'):
print('Found', os.path.join(root, fname))
sys.stdout.flush() sys.stdout.flush()
# Used from unittests # Used from unittests
@@ -355,9 +372,9 @@ def setup_for_build(args):
os.environ['EPICS_HOST_ARCH'] = 'windows-x64' + hostarchsuffix os.environ['EPICS_HOST_ARCH'] = 'windows-x64' + hostarchsuffix
if os.environ['CMP'] == 'vs2019': if os.environ['CMP'] == 'vs2019':
# put our strawberry 'perl' in the PATH # put strawberry perl in the PATH
os.environ['PATH'] = os.pathsep.join([os.path.join(toolsdir, 'strawberry', 'perl', 'site', 'bin'), os.environ['PATH'] = os.pathsep.join([os.path.join(r'C:\Strawberry\perl\site\bin'),
os.path.join(toolsdir, 'strawberry', 'perl', 'bin'), os.path.join(r'C:\Strawberry\perl\bin'),
os.environ['PATH']]) os.environ['PATH']])
if os.environ['CMP'] == 'mingw': if os.environ['CMP'] == 'mingw':
if 'INCLUDE' not in os.environ: if 'INCLUDE' not in os.environ:
@@ -377,18 +394,23 @@ def setup_for_build(args):
make = os.path.join(toolsdir, 'make.exe') make = os.path.join(toolsdir, 'make.exe')
with open(os.path.join(cachedir, 'RELEASE.local'), 'r') as f: base_place = '.'
lines = f.readlines() if not building_base:
for line in lines: with open(os.path.join(cachedir, 'RELEASE.local'), 'r') as f:
(mod, place) = line.strip().split('=') lines = f.readlines()
bindir = os.path.join(place, 'bin', os.environ['EPICS_HOST_ARCH']) for line in lines:
if os.path.isdir(bindir): (mod, place) = line.strip().split('=')
dllpaths.append(bindir) bindir = os.path.join(place, 'bin', os.environ['EPICS_HOST_ARCH'])
if mod == 'EPICS_BASE': if os.path.isdir(bindir):
base_place = place dllpaths.append(bindir)
with open(os.path.join(base_place, 'configure', 'CONFIG_BASE_VERSION')) as myfile: if mod == 'EPICS_BASE':
if 'BASE_3_14=YES' in myfile.read(): base_place = place
isbase314 = True
cfg_base_version = os.path.join(base_place, 'configure', 'CONFIG_BASE_VERSION')
if os.path.exists(cfg_base_version):
with open(cfg_base_version) as myfile:
if 'BASE_3_14=YES' in myfile.read():
isbase314 = True
bindir = os.path.join(os.getcwd(), 'bin', os.environ['EPICS_HOST_ARCH']) bindir = os.path.join(os.getcwd(), 'bin', os.environ['EPICS_HOST_ARCH'])
if os.path.isdir(bindir): if os.path.isdir(bindir):
@@ -433,9 +455,12 @@ def prepare(args):
[add_dependency(mod) for mod in modlist()] [add_dependency(mod) for mod in modlist()]
if os.path.isdir('configure'): if not building_base:
release_local = os.path.join(cachedir, 'RELEASE.local') if os.path.isdir('configure'):
shutil.copy(release_local, 'configure') targetdir = 'configure'
else:
targetdir = '.'
shutil.copy(os.path.join(cachedir, 'RELEASE.local'), targetdir)
print('{0}Configuring EPICS build system{1}'.format(ANSI_YELLOW, ANSI_RESET)) print('{0}Configuring EPICS build system{1}'.format(ANSI_YELLOW, ANSI_RESET))
@@ -468,20 +493,6 @@ def prepare(args):
sp.check_call([zip7, 'e', 'make-{0}.zip'.format(makever)], cwd=toolsdir) sp.check_call([zip7, 'e', 'make-{0}.zip'.format(makever)], cwd=toolsdir)
os.remove(os.path.join(toolsdir, 'make-{0}.zip'.format(makever))) os.remove(os.path.join(toolsdir, 'make-{0}.zip'.format(makever)))
perlver = '5.30.0.1'
if os.environ['CMP'] == 'vs2019':
if not os.path.isdir(os.path.join(toolsdir, 'strawberry')):
print('Installing Strawberry Perl {0}'.format(perlver))
sys.stdout.flush()
sp.check_call(['curl', '-fsS', '--retry', '3', '-o', 'perl-{0}.zip'.format(perlver),
'http://strawberryperl.com/download/{0}/strawberry-perl-{0}-64bit.zip'.format(perlver)],
cwd=toolsdir)
sp.check_call([zip7, 'x', 'perl-{0}.zip'.format(perlver), '-ostrawberry'], cwd=toolsdir)
os.remove(os.path.join(toolsdir, 'perl-{0}.zip'.format(perlver)))
with open(os.devnull, 'w') as devnull:
sp.check_call('relocation.pl.bat', shell=True, stdout=devnull,
cwd=os.path.join(toolsdir, 'strawberry'))
setup_for_build(args) setup_for_build(args)
print('{0}EPICS_HOST_ARCH = {1}{2}'.format(ANSI_CYAN, os.environ['EPICS_HOST_ARCH'], ANSI_RESET)) print('{0}EPICS_HOST_ARCH = {1}{2}'.format(ANSI_CYAN, os.environ['EPICS_HOST_ARCH'], ANSI_RESET))
@@ -501,21 +512,22 @@ def prepare(args):
sys.stdout.flush() sys.stdout.flush()
sp.check_call(['cl']) sp.check_call(['cl'])
for mod in modlist(): if not building_base:
place = places[setup[mod+"_VARNAME"]] for mod in modlist():
print('{0}Building dependency {1} in {2}{3}'.format(ANSI_YELLOW, mod, place, ANSI_RESET)) place = places[setup[mod+"_VARNAME"]]
call_make(cwd=place, silent=silent_dep_builds) print('{0}Building dependency {1} in {2}{3}'.format(ANSI_YELLOW, mod, place, ANSI_RESET))
call_make(cwd=place, silent=silent_dep_builds)
print('{0}Dependency module information{1}'.format(ANSI_CYAN, ANSI_RESET)) print('{0}Dependency module information{1}'.format(ANSI_CYAN, ANSI_RESET))
print('Module Tag Binaries Commit') print('Module Tag Binaries Commit')
print(100 * '-') print(100 * '-')
for mod in modlist(): for mod in modlist():
commit = sp.check_output(['git', 'log', '-n1', '--oneline'], cwd=places[setup[mod+"_VARNAME"]]).strip() commit = sp.check_output(['git', 'log', '-n1', '--oneline'], cwd=places[setup[mod+"_VARNAME"]]).strip()
print("%-10s %-12s %-11s %s" % (mod, setup[mod], 'rebuilt', commit)) print("%-10s %-12s %-11s %s" % (mod, setup[mod], 'rebuilt', commit))
print('{0}Contents of RELEASE.local{1}'.format(ANSI_CYAN, ANSI_RESET)) print('{0}Contents of RELEASE.local{1}'.format(ANSI_CYAN, ANSI_RESET))
with open(os.path.join(cachedir, 'RELEASE.local'), 'r') as f: with open(os.path.join(cachedir, 'RELEASE.local'), 'r') as f:
print(f.read().strip()) print(f.read().strip())
def build(args): def build(args):
setup_for_build(args) setup_for_build(args)
@@ -525,7 +537,7 @@ def build(args):
def test(args): def test(args):
setup_for_build(args) setup_for_build(args)
print('{0}Running the main module tests{1}'.format(ANSI_YELLOW, ANSI_RESET)) print('{0}Running the main module tests{1}'.format(ANSI_YELLOW, ANSI_RESET))
call_make(['tapfiles'], parallel=0) call_make(['tapfiles'])
call_make(['test-results'], parallel=0, silent=True) call_make(['test-results'], parallel=0, silent=True)
def doExec(args): def doExec(args):
@@ -544,26 +556,17 @@ def with_vcvars(cmd):
# cf. https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line # cf. https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line
info = { info = {
'python':sys.executable, 'python': sys.executable,
'self':sys.argv[0], 'self': sys.argv[0],
'cmd':cmd, 'cmd':cmd,
} }
info['arch'] = { info['arch'] = {
'x86':'x86', # 'amd64_x86' ?? 'x86': 'x86', # 'amd64_x86' ??
'x64':'amd64', 'x64': 'amd64',
}[os.environ['PLATFORM'].lower()] # 'x86' or 'x64' }[os.environ['PLATFORM'].lower()] # 'x86' or 'x64'
info['vcvars'] = { info['vcvars'] = vcvars_table[CC]
# https://en.wikipedia.org/wiki/Microsoft_Visual_Studio#History
'vs2019':r'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat',
'vs2017':r'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat',
'vs2015':r'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat',
'vs2013':r'C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat',
'vs2012':r'C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat',
'vs2010':r'C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat',
'vs2008':r'C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat',
}[CC]
script=''' script='''
call "{vcvars}" {arch} call "{vcvars}" {arch}

View File

@@ -53,6 +53,8 @@ script:
# SET source setup file # SET source setup file
# ADD_MODULES extra modules (for a specific job) # ADD_MODULES extra modules (for a specific job)
# EXTRA content will be added to make command line # EXTRA content will be added to make command line
# EXTRA1..5 additional arguments for the make command
# (one argument per variable)
# STATIC set to YES for static build (default: NO) # STATIC set to YES for static build (default: NO)
# TEST set to NO to skip running the tests (default: YES) # TEST set to NO to skip running the tests (default: YES)
# VV set to make build scripts verbose (default: unset) # VV set to make build scripts verbose (default: unset)

View File

@@ -6,22 +6,38 @@ set -e
CACHEDIR=${CACHEDIR:-${HOME}/.cache} CACHEDIR=${CACHEDIR:-${HOME}/.cache}
eval $(grep "EPICS_BASE=" ${CACHEDIR}/RELEASE.local) if [ "$BASE" = "SELF" ]
then
EPICS_BASE=$CURDIR
else
eval $(grep "EPICS_BASE=" ${CACHEDIR}/RELEASE.local)
fi
export EPICS_BASE export EPICS_BASE
[ -z "$EPICS_HOST_ARCH" -a -f $EPICS_BASE/src/tools/EpicsHostArch.pl ] && EPICS_HOST_ARCH=$(perl $EPICS_BASE/src/tools/EpicsHostArch.pl) [ -z "$EPICS_HOST_ARCH" -a -f $EPICS_BASE/src/tools/EpicsHostArch.pl ] && EPICS_HOST_ARCH=$(perl $EPICS_BASE/src/tools/EpicsHostArch.pl)
[ -z "$EPICS_HOST_ARCH" -a -f $EPICS_BASE/startup/EpicsHostArch.pl ] && EPICS_HOST_ARCH=$(perl $EPICS_BASE/startup/EpicsHostArch.pl) [ -z "$EPICS_HOST_ARCH" -a -f $EPICS_BASE/startup/EpicsHostArch.pl ] && EPICS_HOST_ARCH=$(perl $EPICS_BASE/startup/EpicsHostArch.pl)
export EPICS_HOST_ARCH export EPICS_HOST_ARCH
make -j2 $EXTRA # Base 3.15 doesn't have -qemu target architecture and needs an extra define
[ -e $EPICS_BASE/configure/os/CONFIG.Common.RTEMS-pc386-qemu ] || EXTRA_QEMU=RTEMS_QEMU_FIXUPS=YES
# use array variable to get the quoting right while using separate words for arguments
[ -n "$EXTRA0" ] && EXTRA[0]="$EXTRA0"
[ -n "$EXTRA1" ] && EXTRA[1]="$EXTRA1"
[ -n "$EXTRA2" ] && EXTRA[2]="$EXTRA2"
[ -n "$EXTRA3" ] && EXTRA[3]="$EXTRA3"
[ -n "$EXTRA4" ] && EXTRA[4]="$EXTRA4"
[ -n "$EXTRA5" ] && EXTRA[5]="$EXTRA5"
make -j2 $EXTRA_QEMU "${EXTRA[@]}"
ret=0 ret=0
if [ "$TEST" != "NO" ] if [ "$TEST" != "NO" ]
then then
make tapfiles || ret=$? make -j2 tapfiles || ret=$?
make -s test-results make -sk test-results
fi fi
exit $ret exit $ret

View File

@@ -29,6 +29,23 @@ CACHEDIR=${CACHEDIR:-${HOME}/.cache}
echo -e "${ANSI_YELLOW}Using bash version $BASH_VERSION${ANSI_RESET}" echo -e "${ANSI_YELLOW}Using bash version $BASH_VERSION${ANSI_RESET}"
if [ -f /etc/hosts ]
then
# The travis-ci "bionic" image throws us a curveball in /etc/hosts
# by including two entries for localhost. The first for 127.0.1.1
# which causes epicsSockResolveTest to fail.
# cat /etc/hosts
# ...
# 127.0.1.1 localhost localhost ip4-loopback
# 127.0.0.1 localhost nettuno travis vagrant travis-job-....
sudo sed -i -e '/^127\.0\.1\.1/ s|localhost\s*||g' /etc/hosts
echo "==== /etc/hosts"
cat /etc/hosts
echo "===="
fi
# Load settings # Load settings
# ------------- # -------------
@@ -45,23 +62,32 @@ fold_end load.settings
# Check out dependencies # Check out dependencies
# ---------------------- # ----------------------
fold_start check.out.dependencies "Checking/cloning dependencies" if [ "$BASE" != "SELF" ]
then
fold_start check.out.dependencies "Checking/cloning dependencies"
for mod in BASE $ADD_MODULES $MODULES for mod in BASE $ADD_MODULES $MODULES
do do
mod_uc=${mod^^} mod_uc=${mod^^}
eval add_dependency $mod_uc \${${mod_uc}:=master} eval add_dependency $mod_uc \${${mod_uc}:=master}
done done
[ -e ./configure ] && cp ${CACHEDIR}/RELEASE.local ./configure/RELEASE.local [ -d ./configure ] && target=./configure/RELEASE.local || target=./RELEASE.local
cp ${CACHEDIR}/RELEASE.local $target
fold_end check.out.dependencies fold_end check.out.dependencies
fi
# Set up compiler # Set up compiler
# --------------- # ---------------
fold_start set.up.epics_build "Setting up EPICS build system" fold_start set.up.epics_build "Setting up EPICS build system"
eval $(grep "EPICS_BASE=" ${CACHEDIR}/RELEASE.local) if [ "$BASE" = "SELF" ]
then
EPICS_BASE=$CURDIR
else
eval $(grep "EPICS_BASE=" ${CACHEDIR}/RELEASE.local)
fi
export EPICS_BASE export EPICS_BASE
echo "EPICS_BASE=$EPICS_BASE" echo "EPICS_BASE=$EPICS_BASE"
@@ -70,7 +96,7 @@ echo "EPICS_BASE=$EPICS_BASE"
export EPICS_HOST_ARCH export EPICS_HOST_ARCH
echo "EPICS_HOST_ARCH=$EPICS_HOST_ARCH" echo "EPICS_HOST_ARCH=$EPICS_HOST_ARCH"
if echo ${modules_to_compile} | grep -q "$EPICS_BASE" if echo ${modules_to_compile} | grep -q "$EPICS_BASE" || [ "$BASE" = "SELF" ]
then then
# requires wine and g++-mingw-w64-i686 # requires wine and g++-mingw-w64-i686
@@ -158,8 +184,10 @@ EOF
RTEMS_VERSION=$RTEMS RTEMS_VERSION=$RTEMS
RTEMS_BASE=$HOME/.rtems RTEMS_BASE=$HOME/.rtems
EOF EOF
# Base 3.15 doesn't have -qemu target architecture
[ -e $EPICS_BASE/configure/os/CONFIG.Common.RTEMS-pc386-qemu ] && QEMU=-qemu
cat << EOF >> $EPICS_BASE/configure/CONFIG_SITE cat << EOF >> $EPICS_BASE/configure/CONFIG_SITE
CROSS_COMPILER_TARGET_ARCHS += RTEMS-pc386-qemu CROSS_COMPILER_TARGET_ARCHS += RTEMS-pc386$QEMU
EOF EOF
fi fi
@@ -180,6 +208,8 @@ fold_end set.up.compiler
echo "\$ make --version" echo "\$ make --version"
make --version make --version
[ "$BASE" = "SELF" ] && exit 0
# Build required dependencies # Build required dependencies
# --------------------------- # ---------------------------