Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions installer/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
/staging/sof*
265 changes: 265 additions & 0 deletions installer/GNUmakefile
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@

# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2021 Intel Corporation


.DEFAULT_GOAL := stage
.PHONY: clean stage rsync
.PHONY: signed unsigned ldicts topologies
.PHONY: compare signed_dummies

# Override ?= variables in config.mk
-include config.mk

UNSIGNED_list ?= bdw byt cht
SIGNED_list ?= apl cnl icl jsl tgl tgl-h
# older SOF versions
# SIGNED_list += hsw kbl skl sue

# In a Linux kernel git clone, try:
# git grep 'sof-.*\.ri' -- sound/soc/
ALIAS_list ?= glk cfl cml ehl

$(info UNSIGNED_list = ${UNSIGNED_list} )
$(info SIGNED_list = ${SIGNED_list} )
$(info ALIAS_list = ${ALIAS_list} )

# Same code, same Intel key
target_of_glk := apl
target_of_cfl := cnl
target_of_cml := cnl

# Same code, different Intel key
target_of_ehl := tgl

ifeq (,${TOOLCHAIN})
ifeq (,${XTENSA_TOOLS_ROOT})
TOOLCHAIN := gcc
else
TOOLCHAIN := xcc
endif
endif

TREE_OPTS ?= --sort=size --dirsfirst
INSTALL_OPTS ?= -D -p -m 0664

# Keep SOF_VERSION optional

SOF_VERSION ?= $(shell git describe --dirty)
ifneq (${SOF_VERSION},)
VERSION_DIR := ${SOF_VERSION}/
VERSION_SUFFIX := -${SOF_VERSION}
endif



################################
### Top-level directories ####
################################

# Our input: build_*_?cc/ directories
BUILDS_ROOT ?= ${CURDIR}/../installer-builds
BUILD_TOOLS ?= ${BUILDS_ROOT}/build_tools

STAGING_SOF ?= staging/sof
STAGING_SOF_VERSION := ${STAGING_SOF}${VERSION_SUFFIX}

STAGING_SOF_TPLG ?= staging/sof-tplg

stage: signed unsigned ldicts aliases topologies
ifneq (${STAGING_SOF_VERSION},${STAGING_SOF})
ln -sfT sof${VERSION_SUFFIX} ${STAGING_SOF}
test -e ${STAGING_SOF}
endif
@file ${STAGING_SOF}
@tree ${TREE_OPTS} ${STAGING_SOF_VERSION}

COMMUNITY := ${STAGING_SOF_VERSION}/community
INTEL_SIGNED := ${STAGING_SOF_VERSION}/intel-signed
${COMMUNITY} ${INTEL_SIGNED} ${BUILDS_ROOT} ${STAGING_SOF_VERSION}:
mkdir -p $@

# The noise for incremental, do-nothing builds is incredible otherwise,
# especially for build_tools
GNUMAKEFLAGS = --no-print-directory

#####################################
### rsync to local or remote ####
#####################################

# Default value
FW_DESTDIR ?= /lib/firmware/intel/
# We don't depend on any other target so:
# - it's possible to deploy a staging _subset_,
# - sudo never builds by accident
rsync:
rsync -a --info=progress2 staging/sof* "${FW_DESTDIR}"
ifneq (${USER_DESTDIR},)
# TODO: add more user space binaries: sof-ctl, probes,...
# absorbe scripts/sof-target-install.sh
rsync -a ${BUILD_TOOLS}/logger/sof-logger ${USER_DESTDIR}
endif

clean:
${RM} -r staging/sof*
${RM} ${BUILDS_ROOT}/staging_sof_tree.txt

cleanall: clean
${RM} -r "${BUILD_TOOLS}/" "${BUILDS_ROOT}"/build_*_?cc/

##########################################################
### Stage sof-*.ri firmware files and symbolic links ####
##########################################################

#
# 1. Stages all *.ri files
#
# 2. Create symbolic links, including (broken) intel-signed symbolic
# links that must be fixed in a final release, otherwise the release
# is incomplete. To check all symlinks: file $(find -type l)
#

# '%' is the platform name
SIGNED_FWS := ${SIGNED_list:%=${COMMUNITY}/sof-%.ri}
# $(info SIGNED_FWS = ${SIGNED_FWS})
signed: ${SIGNED_FWS}
${SIGNED_FWS}: ${COMMUNITY}/sof-%.ri: \
${BUILDS_ROOT}/build_%_${TOOLCHAIN}/sof.ri \
| ${COMMUNITY} ${INTEL_SIGNED}
install ${INSTALL_OPTS} $< $@
ln -sfT intel-signed/sof-$*.ri ${STAGING_SOF_VERSION}/sof-$*.ri

# '%' is the platform name
UNSIGNED_FWS := ${UNSIGNED_list:%=${STAGING_SOF_VERSION}/sof-%.ri}
# $(info UNSIGNED_FWS = ${UNSIGNED_FWS})
unsigned: ${UNSIGNED_FWS}
${UNSIGNED_FWS}: ${STAGING_SOF_VERSION}/sof-%.ri: \
${BUILDS_ROOT}/build_%_${TOOLCHAIN}/sof.ri
install ${INSTALL_OPTS} $< $@


BUILD_SOF_RIS := \
${UNSIGNED_list:%=${BUILDS_ROOT}/build_%_${TOOLCHAIN}/sof.ri} \
${SIGNED_list:%=${BUILDS_ROOT}/build_%_${TOOLCHAIN}/sof.ri}

# The build is not deterministic; use this to reduce noise when testing
# this Makefile.
# Also very useful with XCC, see next comment.
ifneq (true,${BUILD_ONLY_ONCE})
.PHONY: ${BUILD_SOF_RIS}
endif

# Incremental builds are not possible with XCC because the entire
# toolchain requires $XTENSA_SYSTEM but CMake does not support
# build-time environment variables. In the future we could move the
# XTENSA_SYSTEM values out of xtensa-build-all.sh and into some shared
# config file included here.
${BUILD_SOF_RIS}: ${BUILDS_ROOT}/build_%_${TOOLCHAIN}/sof.ri: | ${BUILDS_ROOT}
cd ${BUILDS_ROOT} && bdir="$$(dirname $@)" && \
if [ -d $${bdir} ] && [ xcc != "${TOOLCHAIN}" ] ; then \
cmake --build $${bdir} -- bin; else \
$(CURDIR)/../scripts/xtensa-build-all.sh $*; fi


########################################
### Stage *.ldc logger dictionaries ###
########################################

# '%' is the platform name
LDICTS := ${UNSIGNED_list:%=${STAGING_SOF_VERSION}/sof-%.ldc} \
${SIGNED_list:%=${STAGING_SOF_VERSION}/sof-%.ldc}
# $(info LDICTS = ${LDICTS})
ldicts: ${LDICTS}
${LDICTS}: ${STAGING_SOF_VERSION}/sof-%.ldc: \
${BUILDS_ROOT}/build_%_${TOOLCHAIN}/sof.ri
install ${INSTALL_OPTS} ${BUILDS_ROOT}/build_$*_${TOOLCHAIN}/sof.ldc $@


#######################################
### Platform -> platform aliases ####
#######################################

# '%' is the platform name
COMM_ALIASES := ${ALIAS_list:%=${STAGING_SOF_VERSION}/community/sof-%.ri}
DICT_ALIASES := ${ALIAS_list:%=${STAGING_SOF_VERSION}/sof-%.ldc}
SIGNED_ALIASES := ${ALIAS_list:%=${STAGING_SOF_VERSION}/sof-%.ri}
aliases: ${SIGNED_ALIASES} ${COMM_ALIASES} ${DICT_ALIASES}

${COMM_ALIASES}: ${STAGING_SOF_VERSION}/community/sof-%.ri: | ${COMMUNITY}
ln -sfT sof-${target_of_$*}.ri $@

${DICT_ALIASES}: ${STAGING_SOF_VERSION}/sof-%.ldc: | ${STAGING_SOF_VERSION}
ln -sfT sof-${target_of_$*}.ldc $@

# Some have the same key, others just the code. We don't make any
# difference here and let the intel-signed/ directory handle this.
${SIGNED_ALIASES}: ${STAGING_SOF_VERSION}/sof-%.ri: | ${STAGING_SOF_VERSION}
ln -sfT intel-signed/sof-$*.ri $@


##################################
### Stage sof-tplg/ topologies ###
##################################

# The build is not deterministic; use this to reduce noise when testing
# this Makefile
ifneq (true,${BUILD_ONLY_ONCE})
.PHONY: ${BUILD_TOOLS}
endif

topologies: ${BUILD_TOOLS}
install ${INSTALL_OPTS} -t ${STAGING_SOF_TPLG}${VERSION_SUFFIX}/ \
${BUILD_TOOLS}/topology/sof-*.tplg
ifneq (,${VERSION_SUFFIX})
ln -sfT sof-tplg${VERSION_SUFFIX} ${STAGING_SOF_TPLG}
test -e ${STAGING_SOF_TPLG}
endif
@file ${STAGING_SOF_TPLG}
@tree ${TREE_OPTS} ${STAGING_SOF_TPLG}${VERSION_SUFFIX} | \
head -n 10; printf '├── ...\n..\n'

# We should use more targets rather than set -e and a multi-lines script
# but that would be verbose.
${BUILD_TOOLS}:
set -e; if test -d ${BUILD_TOOLS}; then \
for i in topologies sof-logger; do \
cmake --build ${BUILD_TOOLS} -- $$i; done; else \
BUILD_TOOLS_DIR=${BUILD_TOOLS} ../scripts/build-tools.sh -T -l ; \
fi


####################
### Self-Testing ###
####################

COMPARE_REFS ?= /lib/firmware/intel

checktree:
cd ${STAGING_SOF_VERSION} && \
tree -a --dirsfirst . > ${BUILDS_ROOT}/staging_sof_tree.txt
# Update sof-apl-nocodec.tplg when adding or removing a default platform
diff -u tests/staging_sof_ref.txt ${BUILDS_ROOT}/staging_sof_tree.txt
# Check two random topologies are there
test -f ${STAGING_SOF_TPLG}/sof-apl-nocodec.tplg
test -f ${STAGING_SOF_TPLG}/sof-imx8qxp-nocodec.tplg

# Useful for testing this Makefile. COMPARE_REFS can be /lib/firmware,
# sof-bin, a previous version of this Makefile,...
# As the first arguments maybe symbolic links, their trailing slash is
# critical.
compare: stage
! diff -qr --no-dereference ${COMPARE_REFS}/sof/ \
${STAGING_SOF_VERSION}/ \
| grep -v ' differ$$' # || true
! diff -qr --no-dereference ${COMPARE_REFS}/sof-tplg/ \
${STAGING_SOF_TPLG}${VERSION_SUFFIX}/ \
| grep -v ' differ$$'

# Invoke this manually to check symbolic links are correct
SIGNED_DUMMIES := ${SIGNED_list:%=${INTEL_SIGNED}/sof-%.ri} \
${ALIAS_list:%=${INTEL_SIGNED}/sof-%.ri}
signed_dummies: ${SIGNED_DUMMIES}
! file $$(find . -type l) | grep -i broken

${SIGNED_DUMMIES}: | ${INTEL_SIGNED}
touch $@
85 changes: 85 additions & 0 deletions installer/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
The GNUmakefile in this directory prepares ``/lib/firmware/intel/sof/`` and
``/lib/firmware/intel/sof-tplg/`` directories.

It extracts what's needed from the output of the scripts
``./scripts/xtensa-build-all.sh`` and ``./scripts/build-tools.sh -T
-l``. It automatically runs these scripts when needed for the platforms
listed in config.mk and performs incremental builds when they have
already been run.

It does not copy anything to ``/lib/firmware/`` directly but to local,
"staging" subdirectory first. The staging area can then be installed with
rsync to a local or remote ``/lib/firmware/intel/`` or to a release
location. This gives an opportunity to inspect the staging area and
avoids running everything as root.

The default target (re-)generates the staging area:

make -C installer/

Then, to install the staging area:

sudo make -C installer/ rsync

By default, the "rsync" target installs to the local
``/lib/firmware/intel/`` directory. To install to a different host or
different directory, copy the ``sample-config.mk`` file to ``config.mk``
and follow the instructions inside the file. ``config.mk`` can also be
used to change the list of platforms installed and a number of other
Make variables. As usual with Make, many parameters can also be
overridden on the command line.

To stage and install in one go:

make -C installer/ stage rsync

"stage" is the default target and it tries to stage everything:
firmware, dictionaries and topologies. As usual with Make, it's possible
to invoke individual targets. Find a list of targets at the top of
GNUMakefile.

You can use `make -jN stage` to build multiple platforms faster but do
*not* `make -jN stage rsync` as this will start deploying before the
builds are all complete. That's because we want the rsync target to be
able to deploy subsets. Instead do: `make -jN somethings && make rsync`.

Sample output:

staging/sof: symbolic link to sof-v1.6.1
staging/sof-v1.6.1/
├── community/
│ ├── sof-tgl.ri
│ ├── sof-cnl.ri
│ ├── sof-icl.ri
│ ├── sof-jsl.ri
│ ├── sof-apl.ri
│ ├── sof-cfl.ri -> sof-cnl.ri
│ ├── sof-cml.ri -> sof-cnl.ri
│ ├── sof-ehl.ri -> sof-tgl.ri
│ └── sof-glk.ri -> sof-apl.ri
├── intel-signed/
├── sof-bdw.ri
├── sof-cht.ri
├── sof-byt.ri
├── sof-cnl.ldc
├── sof-tgl.ldc
├── sof-icl.ldc
├── sof-jsl.ldc
├── sof-apl.ldc
├── sof-bdw.ldc
├── sof-byt.ldc
├── sof-cht.ldc
├── sof-apl.ri -> intel-signed/sof-apl.ri
├── sof-cfl.ri -> intel-signed/sof-cfl.ri
├── sof-cml.ri -> intel-signed/sof-cml.ri
├── sof-cnl.ri -> intel-signed/sof-cnl.ri
├── sof-ehl.ri -> intel-signed/sof-ehl.ri
├── sof-glk.ri -> intel-signed/sof-glk.ri
├── sof-icl.ri -> intel-signed/sof-icl.ri
├── sof-jsl.ri -> intel-signed/sof-jsl.ri
├── sof-tgl.ri -> intel-signed/sof-tgl.ri
├── sof-cfl.ldc -> sof-cnl.ldc
├── sof-cml.ldc -> sof-cnl.ldc
├── sof-ehl.ldc -> sof-tgl.ldc
└── sof-glk.ldc -> sof-apl.ldc

30 changes: 30 additions & 0 deletions installer/sample-config.mk
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
# To customize the installation, copy this file to config.mk and edit
# it. Leave undefined to use default values.

# As usual with Make, all these can also be passed as either CLI
# arguments or environment variables. Warning: undefined is NOT the
# same as blank!

# Everything is installed by default. To install and deploy fewer
# patforms override the default lists like this:
# UNSIGNED_list :=
# SIGNED_list := apl tgl

# The default FW_DESTDIR is the local /lib/firmware/intel directory
# _remote := test-system.local
# FW_DESTDIR := root@${_remote}:/lib/firmware/intel
# USER_DESTDIR := ${_remote}:bin/

# Define this empty for a plain sof/ directory and no sof -> sof-v1.2.3
# symbolic links.
# SOF_VERSION :=
#
# SOF_VERSION := $(shell git describe --tags )
# SOF_VERSION := v1.6.14

# Uncomment this to have the build_*_?cc/ directories at the top-level
# BUILDS_ROOT := ${CURDIR}/..

# The build is not deterministic; use this to reduce noise when testing
# the installer/ itself
# BUILD_ONLY_ONCE := true
Loading