diff --git a/.gitignore b/.gitignore index 564fdfa..52d2fa1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.orig *.log .*.swp +*.autosave diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..0ede48a --- /dev/null +++ b/.travis.yml @@ -0,0 +1,178 @@ +# .travis.yml for testing EPICS Base ci-scripts +# (see: https://github.com/epics-base/ci-scripts) + +# Note: +# Paths to scripts are different in this test configuration +# (your module has one more directory level: .ci) + +language: cpp +compiler: gcc +dist: xenial + +cache: + directories: + - $HOME/.cache + +env: + global: + - SETUP_PATH=.:.ci + +addons: + apt: + packages: + - libreadline6-dev + - libncurses5-dev + - perl + - clang + - g++-mingw-w64-i686 + - g++-mingw-w64-x86-64 + - qemu-system-x86 + +install: + - ./travis/prepare.sh + +script: + - ./travis-test.sh + +# If you need to do more during install and build, +# add a local directory to your module and do e.g. +# - ./.ci-local/travis/install-extras.sh + +# Define build jobs + +# Well-known variables to use +# SET source setup file +# EXTRA content will be added to make command line +# STATIC set to YES for static build (default: NO) +# TEST set to NO to skip running the tests (default: YES) +# VV set to make build scripts verbose (default: unset) + +# Usually from setup files, but may be specified or overridden +# on a job line +# MODULES list of dependency modules +# BASE branch or release tag name of the EPICS Base to use +# branch or release tag for a specific module +# ... see README for setup file syntax description + +jobs: + include: + +# Run unit tests on Linux and Mac + + - env: SET=test00 + + - env: SET=test00 + os: osx + +# Compile the example application +# using the build configurations from full makeBaseApp example + + - env: SET=test01 + + - env: SET=test01 + compiler: clang + + - env: VV="" SET=test01 + + - env: SET=test01 EXTRA="CMD_CXXFLAGS=-std=c++11" + + - env: SET=test01 EXTRA="CMD_CXXFLAGS=-std=c++11" + compiler: clang + +# trusty is pretty close to RHEL7 + - env: SET=test01 + dist: trusty + + - env: SET=test01 EXTRA="CMD_CXXFLAGS=-std=c++11" + dist: trusty + +# Cross-compilation to Windows using MinGW and WINE + + - env: SET=test01 WINE=32 TEST=NO STATIC=YES + compiler: mingw + + - env: SET=test01 WINE=64 TEST=NO STATIC=YES + compiler: mingw + +# dynamic (DLL) builds are broken on xenial + - env: SET=test01 WINE=32 TEST=NO STATIC=NO + dist: bionic + compiler: mingw + + - env: SET=test01 WINE=64 TEST=NO STATIC=NO + dist: bionic + compiler: mingw + +# Cross-compilation to RTEMS +# (needs EPICS Base >= 3.16.2) + + - env: SET=test01 RTEMS=4.10 TEST=NO + + - env: SET=test01 RTEMS=4.9 TEST=NO + +# Other gcc versions (adding as an extra package) + + - env: SET=test01 + compiler: gcc-6 + addons: { apt: { packages: ["g++-6"], sources: ["ubuntu-toolchain-r-test"] } } + + - env: SET=test01 + compiler: gcc-7 + addons: { apt: { packages: ["g++-7"], sources: ["ubuntu-toolchain-r-test"] } } + +# MacOS build + +# SNCSEQ 2.2.7 fails to build on MacOS; currently needs master + - env: SET=test01 SNCSEQ=master + os: osx + compiler: clang + addons: { homebrew: { packages: ["re2c"], update: true } } + +# Base 3.15 builds +# ================ + + - env: BASE=R3.15.7 SET=test01 + + - env: BASE=R3.15.7 SET=test01 WINE=64 TEST=NO STATIC=YES + dist: bionic + compiler: mingw + +# The DLL build for this Base version is known to fail +# - env: BASE=R3.15.7 SET=test01 WINE=64 TEST=NO STATIC=NO +# dist: bionic +# compiler: mingw + +# Cross-compilation to RTEMS +# (needs EPICS Base >= 3.16.2) + + - env: BASE=R3.16.2 SET=test01 RTEMS=4.10 TEST=NO + dist: trusty + + - env: BASE=R3.16.2 SET=test01 RTEMS=4.9 TEST=NO + dist: trusty + +# SNCSEQ 2.2.7 fails to build on MacOS; currently needs master + - env: BASE=R3.15.7 SET=test01 SNCSEQ=master + os: osx + compiler: clang + addons: { homebrew: { packages: ["re2c"], update: true } } + +# Base 3.14 builds +# ================ + + - env: BASE=R3.14.12.8 SET=test01 + + - env: BASE=R3.14.12.8 SET=test01 WINE=64 TEST=NO STATIC=YES + dist: bionic + compiler: mingw + +# The DLL build for this Base version is known to fail +# - env: BASE=R3.14.12.8 SET=test01 WINE=64 TEST=NO STATIC=NO +# dist: bionic +# compiler: mingw + +# SNCSEQ 2.2.7 fails to build on MacOS; currently needs master + - env: BASE=R3.14.12.8 SET=test01 SNCSEQ=master + os: osx + compiler: clang + addons: { homebrew: { packages: ["re2c"], update: true } } diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..19c9068 --- /dev/null +++ b/Makefile @@ -0,0 +1,31 @@ +# Makefile at top of application tree +TOP = . +include $(TOP)/configure/CONFIG + +# Directories to build, any order +DIRS += configure +DIRS += $(wildcard *Sup) +DIRS += $(wildcard *App) +DIRS += $(wildcard *Top) +DIRS += $(wildcard iocBoot) + +# The build order is controlled by these dependency rules: + +# All dirs except configure depend on configure +$(foreach dir, $(filter-out configure, $(DIRS)), \ + $(eval $(dir)_DEPEND_DIRS += configure)) + +# Any *App dirs depend on all *Sup dirs +$(foreach dir, $(filter %App, $(DIRS)), \ + $(eval $(dir)_DEPEND_DIRS += $(filter %Sup, $(DIRS)))) + +# Any *Top dirs depend on all *Sup and *App dirs +$(foreach dir, $(filter %Top, $(DIRS)), \ + $(eval $(dir)_DEPEND_DIRS += $(filter %Sup %App, $(DIRS)))) + +# iocBoot depends on all *App dirs +iocBoot_DEPEND_DIRS += $(filter %App,$(DIRS)) + +# Add any additional dependency rules here: + +include $(TOP)/configure/RULES_TOP diff --git a/README.md b/README.md index 4cb7568..f17e85b 100644 --- a/README.md +++ b/README.md @@ -1,62 +1,198 @@ # Continuous Integration Scripts for EPICS Modules -The scripts in this repository are intended to provide a common, +The scripts inside this repository are intended to provide a common, easy-to-use and flexible way to add Continuous Integration to EPICS -software modules, e.g. Device Support modules. +software modules, e.g. Device or Driver Support modules. -By including this repository as a Git Submodule, your module will -always use an explicit commit, i.e. a fixed version of the scripts. -That ensures that further development of these scripts cannot break -your setup. +By including this repository as a Git Submodule, you will be able to +use the same flexible, powerful CI setup that EPICS Bases uses, +including a mechanism to specify sets of dependent modules +(with versions) that you want to compile your module against. -## Travis-CI +By using the submodule mechnism, your module will always use an +explicit commit, i.e. a fixed version of the scripts. +This ensures that any further development of the ci-scripts will +never break existing use. -### Features +## This Repository - - Compile against different branches or releases of EPICS Base - - Use different versions of compilers (gcc, clang) - - Cross-compile for Windows 32bit and 64bit using MinGW and WINE - - Cross-compile for RTEMS 4.9 and 4.10 - - Compile on MacOS +In addition to the scripts themselves (in the subdirectories), +this repository contains the test suite that is used to verify +functionality and features of the ci-scripts. + +You are welcome to use the test suite as a reference, but keep in +mind that in your module the path to the scripts has one level more +(e.g., `./travis/abc` here would be `./.ci/travis/abc` in your +module). +Also, a test suite might not show the same level of quality as an +example. + +## Features + + - Compile against different branches or releases of EPICS Base and + additional dependencies (modules like asyn, std, etc.). + + - Define settings files that declare sets of dependencies + with their versions and locations. + + - Define hook scripts for any dependency. + Hooks are run on the dependency module before it is compiled, so + the module can be patched or further configured. + + - Define static or shared builds (executables, libraries). + + - Run tests (using the EPICS unit test suite). + +## Supported CI Services + +### Travis-CI + - Use different compilers (gcc, clang) + - Use different gcc versions + - Cross-compile for Windows 32bit and 64bit using MinGW and WINE + - Cross-compile for RTEMS 4.9 and 4.10 (Base >= 3.16.2) + - Compile on MacOS + - Built dependencies are cached (for faster builds) -### How to Use these Scripts +### How to Use the CI-Scripts - 1. Get an account on [Travis-CI](https://travis-ci.org/), connect - it to your GitHub account and activate your support module's - repository. For more details, please refer to the - [Travis-CI Tutorial](https://docs.travis-ci.com/user/tutorial/). - Make sure to use `travis-ci.org` and not their `.com` site. + 1. Get an account on a supported CI service provider platform. + (e.g. [Travis-CI](https://travis-ci.org/), + Appveyor, Azure Pipelines...) - 1. In your Support Module, add this respository as a Git Submodule - (name suggestion: `.ci`). + (More details in the specific README of the subdirectory.) + + 2. In your Support Module, add this ci-scripts respository + as a Git Submodule (name suggestion: `.ci`). ``` $ git submodule add https://github.com/epics-base/ci-scripts .ci ``` - - 1. Create a Travis configuration by copying one of the examples. - ``` - $ cp .ci/.travis.yml.example-full .travis.yml - ``` - - 1. Edit the `.travis.yml` configuration to include the jobs you want - Travis to run. - - 1. Push your changes and check - [travis-ci.org](https://travis-ci.org/) for your build results. + 3. Create setup files for different sets of dependencies you + want to compile against. (See below.) -## Releases and Numbering + E.g., a setup file `stable.set` specifying + ``` + MODULES=sncseq asyn + + BASE=R3.15.6 + ASYN=R4-34 + SNCSEQ=R2-2-7 + ``` + will compile against the EPICS Base release 3.15.6, the Sequencer + release 2.2.7 and release 4.34 of asyn. + (Any settings can be overridden from `.travis.yml`.) + + 4. Create a configuration for the CI service by copying one of + the examples provided in the service specific subdirectory + and editing it to include the jobs you want the service to run. + Use your setup by defining e.g. `SET=stable` in the environment of + a job. + + 5. Push your changes and check the CI service for your build results. + +## Setup Files + +Your module might depend on EPICS Base and a few other support modules. +(E.g., a specific driver might need StreamDevice, ASYN and the Sequencer.) +In that case, building against every possible combination of released +versions of those dependencies is not possible: +Base (37) x StreamDevice (50) x ASYN (40) x Sequencer (51) would produce +more than 3.7 million different combinations, i.e. build jobs. + +A more reasonable approach is to create a few setups, each being a +combination of dependency releases, that do a few scans of the available +"version space". One for the oldest versions you want to support, one or two +for stable versions that many of your users have in production, one for the +latest released versions and one for the development branches. + +## Setup File Syntax + +Setup files are loaded by the bash scripts. They are found by searching +the locations in `SETUP_PATH` (space or colon separated list of directories, +relative to your module's root directory). + +Setup files can include other setup files by calling `include ` +(omitting the `.set` extension of the setup file). The configured +`SETUP_PATH` is searched for the include. + +Any `VAR=value` setting of a variable is only executed if `VAR` is unset or +empty. That way any settings can be overridden by settings in `.travis.yml`. + +Empty lines or lines starting with `#` are ignored. + +`MODULES=""` should list the dependencies (software modules) +by using their well-known slugs, separated by spaces. +EPICS Base (slug: `base`) will always be a dependency and will be added and +compiled first. The other dependencies are added and compiled in the order +they are defined in `MODULES`. + +`REPOOWNER=` sets the default GitHub owner (or organization) for all +dependency modules. Useful if you want to compile against a complete set +of dependencies forked into your private GitHub area. + +For any module mentioned as `foo` in the `MODULES` setting (and for `BASE`), +the following settings can be configured: + +`FOO=` Set version of the module that should be used. Must either +be a *tag* name (in that case the module is checked out into Travis' cache +system) or a *branch* name (in that case the module is always checked out +and recompiled as part of the job). [default: `master`] + +`FOO_REPONAME=` Set the name of the remote repository as `.git`. +[default is the slug in lower case: `foo`] + +`FOO_REPOOWNER=` Set the name of the GitHub owner (or organization) +that the module repository can be found under. + +`FOO_REPOURL=""` Set the complete URL of the remote repository. + +The default URL for the repository is pointing to GitHub, under +`$FOO_REPOOWNER` else `$REPOOWNER` else `epics-modules`, +using `$FOO_REPONAME` else `foo` and the extension`.git`. + +`FOO_DEPTH=` Set the depth of the git clone operation. Use 0 for a +full clone. [default: 5] + +`FOO_RECURSIVE=YES/NO` Set to `NO` (or `0`) for a flat clone without +recursing into submodules. [default is including submodules: `YES`] + +`FOO_DIRNAME=` Set the local directory name for the checkout. This will +be always be extended by the release or branch name as `-`. +[default is the slug in lower case: `foo`] + +`FOO_HOOK=