CMake: improve branding component macros

- document preferred component layout
 - simplify parameters to the branding macros
 - allow structured branding components with SUBDIRECTORIES
This commit is contained in:
Adriaan de Groot 2018-03-09 09:29:53 -05:00
parent f29da8e39e
commit 986c5f5a9a
2 changed files with 99 additions and 48 deletions

View File

@ -1,8 +1,24 @@
# Support macros for creating Calamares branding components.
#
# Calamares branding components have two parts:
# - a branding.desc file that tells Calamares how to describe the product
# (e.g. strings like "Generic GNU/Linux") and the name of a QML file
# (the "slideshow") that is displayed during installation.
# - the QML files themselves, plus supporting images etc.
#
# Branding components can be created inside the Calamares source tree
# (there is one example the `default/` branding, which is also connected
# to the default configuration shipped with Calamares), but they can be
# built outside of, and largely independently of, Calamares by using
# these CMake macros.
#
# See the calamares-examples repository for more examples.
#
include( CMakeParseArguments) include( CMakeParseArguments)
include( CMakeColors ) include( CMakeColors )
# Usage calamares_add_branding( NAME <name> [SUBDIRECTORY <dir>]) # Usage calamares_add_branding( <name> [DIRECTORY <dir>] [SUBDIRECTORIES <dir> ...])
# #
# Adds a branding component to the build: # Adds a branding component to the build:
# - the component's top-level files are copied into the build-dir; # - the component's top-level files are copied into the build-dir;
@ -14,29 +30,30 @@ include( CMakeColors )
# with the given <name>, which is usually the name of the # with the given <name>, which is usually the name of the
# directory containing the component, and which must match the # directory containing the component, and which must match the
# *componentName* in `branding.desc`. # *componentName* in `branding.desc`.
function( calamares_add_branding ) #
set( _CABT_SUBDIRECTORY "." ) # If SUBDIRECTORIES are given, then those are copied (each one level deep)
cmake_parse_arguments( _CABT "" "NAME;SUBDIRECTORY" "" ${ARGN} ) # to the installation location as well, preserving the subdirectory name.
if ( NOT _CABT_NAME ) function( calamares_add_branding NAME )
message( FATAL_ERROR "Branding component must have a NAME" ) set( _CABT_DIRECTORY "." )
endif() cmake_parse_arguments( _CABT "" "DIRECTORY" "SUBDIRECTORIES" ${ARGN} )
set( SUBDIRECTORY ${_CABT_DIRECTORY} )
set( NAME ${_CABT_NAME} ) set( _brand_dir ${_CABT_DIRECTORY} )
set( SUBDIRECTORY ${_CABT_SUBDIRECTORY} )
set( BRANDING_DIR share/calamares/branding ) set( BRANDING_DIR share/calamares/branding )
set( BRANDING_COMPONENT_DESTINATION ${BRANDING_DIR}/${NAME} ) set( BRANDING_COMPONENT_DESTINATION ${BRANDING_DIR}/${NAME} )
# We glob all the files inside the subdirectory, and we make sure they are foreach( _subdir "" ${_CABT_SUBDIRECTORIES} )
# synced with the bindir structure and installed. file( GLOB BRANDING_COMPONENT_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/${_brand_dir} "${_brand_dir}/${_subdir}/*" )
file( GLOB BRANDING_COMPONENT_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY} "${SUBDIRECTORY}/*" ) message(STATUS "${BRANDING_COMPONENT_FILES}")
foreach( BRANDING_COMPONENT_FILE ${BRANDING_COMPONENT_FILES} ) foreach( BRANDING_COMPONENT_FILE ${BRANDING_COMPONENT_FILES} )
if( NOT IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/${BRANDING_COMPONENT_FILE} ) set( _subpath ${_brand_dir}/${BRANDING_COMPONENT_FILE} )
configure_file( ${SUBDIRECTORY}/${BRANDING_COMPONENT_FILE} ${SUBDIRECTORY}/${BRANDING_COMPONENT_FILE} COPYONLY ) if( NOT IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${_subpath} )
configure_file( ${_subpath} ${_subpath} COPYONLY )
install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBDIRECTORY}/${BRANDING_COMPONENT_FILE} install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${_subpath}
DESTINATION ${BRANDING_COMPONENT_DESTINATION} ) DESTINATION ${BRANDING_COMPONENT_DESTINATION}/${_subdir}/ )
endif() endif()
endforeach()
endforeach() endforeach()
message( "-- ${BoldYellow}Found ${CALAMARES_APPLICATION_NAME} branding component: ${BoldRed}${NAME}${ColorReset}" ) message( "-- ${BoldYellow}Found ${CALAMARES_APPLICATION_NAME} branding component: ${BoldRed}${NAME}${ColorReset}" )
@ -46,7 +63,7 @@ function( calamares_add_branding )
endif() endif()
endfunction() endfunction()
# Usage calamares_add_branding_translations( NAME <name> [SUBDIRECTORY <dir>]) # Usage calamares_add_branding_translations( <name> [DIRECTORY <dir>])
# #
# Adds the translations for a branding component to the build: # Adds the translations for a branding component to the build:
# - the component's lang/ directory is scanned for .ts files # - the component's lang/ directory is scanned for .ts files
@ -55,15 +72,11 @@ endfunction()
# Translation files must be called calamares-<name>_<lang>.ts . Optionally # Translation files must be called calamares-<name>_<lang>.ts . Optionally
# the lang/ dir is found in the given <dir> instead of the current source # the lang/ dir is found in the given <dir> instead of the current source
# directory. # directory.
function( calamares_add_branding_translations ) function( calamares_add_branding_translations NAME )
set( _CABT_SUBDIRECTORY "." ) set( _CABT_DIRECTORY "." )
cmake_parse_arguments( _CABT "" "NAME;SUBDIRECTORY" "" ${ARGN} ) cmake_parse_arguments( _CABT "" "DIRECTORY" "" ${ARGN} )
if ( NOT _CABT_NAME ) set( SUBDIRECTORY ${_CABT_DIRECTORY} )
message( FATAL_ERROR "Branding component must have a NAME" ) set( _brand_dir ${_CABT_DIRECTORY} )
endif()
set( NAME ${_CABT_NAME} )
set( SUBDIRECTORY ${_CABT_SUBDIRECTORY} )
set( BRANDING_DIR share/calamares/branding ) set( BRANDING_DIR share/calamares/branding )
set( BRANDING_COMPONENT_DESTINATION ${BRANDING_DIR}/${NAME} ) set( BRANDING_COMPONENT_DESTINATION ${BRANDING_DIR}/${NAME} )
@ -78,19 +91,23 @@ function( calamares_add_branding_translations )
endif() endif()
endfunction() endfunction()
# Usage calamares_add_branding_subdirectory( <dir> ) # Usage calamares_add_branding_subdirectory( <dir> [SUBDIRECTORIES <dir> ...])
# #
# Adds a branding component from a subdirectory: # Adds a branding component from a subdirectory:
# - if there is a CMakeLists.txt, use that # - if there is a CMakeLists.txt, use that
# - otherwise assume a "standard" setup with top-level files and a lang/ dir for translations # - otherwise assume a "standard" setup with top-level files and a lang/ dir for translations
# #
# If SUBDIRECTORIES are given, they are relative to <dir>, and are
# copied (one level deep) to the install location as well.
function( calamares_add_branding_subdirectory SUBDIRECTORY ) function( calamares_add_branding_subdirectory SUBDIRECTORY )
cmake_parse_arguments( _CABS "" "" "SUBDIRECTORIES" ${ARGN} )
if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/CMakeLists.txt" ) if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/CMakeLists.txt" )
add_subdirectory( ${SUBDIRECTORY} ) add_subdirectory( ${SUBDIRECTORY} )
elseif( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/branding.desc" ) elseif( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/branding.desc" )
calamares_add_branding( NAME ${SUBDIRECTORY} SUBDIRECTORY ${SUBDIRECTORY} ) calamares_add_branding( ${SUBDIRECTORY} DIRECTORY ${SUBDIRECTORY} SUBDIRECTORIES ${_CABS_SUBDIRECTORIES} )
if( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/lang" ) if( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/lang" )
calamares_add_branding_translations( NAME ${SUBDIRECTORY} SUBDIRECTORY ${SUBDIRECTORY} ) calamares_add_branding_translations( ${SUBDIRECTORY} DIRECTORY ${SUBDIRECTORY} )
endif() endif()
else() else()
message( "-- ${BoldYellow}Warning:${ColorReset} tried to add branding component subdirectory ${BoldRed}${SUBDIRECTORY}${ColorReset} which has no branding.desc." ) message( "-- ${BoldYellow}Warning:${ColorReset} tried to add branding component subdirectory ${BoldRed}${SUBDIRECTORY}${ColorReset} which has no branding.desc." )

View File

@ -12,6 +12,20 @@ forking Calamares just for adding some files. Calamares installs
CMake support macros to help create branding packages. See the CMake support macros to help create branding packages. See the
calamares-branding repository for examples of stand-alone branding. calamares-branding repository for examples of stand-alone branding.
## Examples
There is one example of a branding component included with Calamares,
so that it can be run directly from the build directory for testing purposes:
- `default/` is a sample brand for the Generic Linux distribution. It uses
the default Calamares icons and a as start-page splash it provides a
tag-cloud view of languages. The slideshow is a basic one with a few
slides of text and a single image. No translations are provided.
Since the slideshow can be **any** QML, it is limited only by your designers
imagination and your QML experience. For straightforward presentations,
see the documentation below. There are more examples in the *calamares-branding*
repository.
## Translations ## Translations
@ -28,22 +42,6 @@ file) should be enclosed in this form for translations
text: qsTr("This is an example text.") text: qsTr("This is an example text.")
``` ```
## Examples
There are two examples of branding content:
- `default/` is a sample brand for the Generic Linux distribution. It uses
the default Calamares icons and a as start-page splash it provides a
tag-cloud view of languages. The slideshow is a basic one with a few
slides of text and a single image. No translations are provided.
- `fancy/` uses translations and offers navigation arrows. These are
provided by the standard Calamares QML classes.
Since the slideshow can be **any** QML, it is limited only by your designers
imagination and your QML experience. For straightforward presentations,
see the documentation below. There are more examples in the *calamares-branding*
repository.
## Presentation ## Presentation
The default QML classes provided by Calamares can be used for a simple The default QML classes provided by Calamares can be used for a simple
@ -97,3 +95,39 @@ standard properties for a boring "static text" slideshow, though:
The presentation classes can be used to produce a fairly dry slideshow The presentation classes can be used to produce a fairly dry slideshow
for the installation process; it is recommended to experiment with the for the installation process; it is recommended to experiment with the
visual effects and classes available in QtQuick. visual effects and classes available in QtQuick.
## Project Layout
A branding component that is created and installed outside of Calamares
will have a top-level `CMakeLists.txt` that includes some boilerplate
to find Calamares, and then adds a subdirectory which contains the
actual branding component.
Adding the subdirectory can be done as follows:
- If the directory contains files only, and optionally has a single
subdirectory lang/ which contains the translation files for the
component, then `calamares_add_branding_subdirectory()` can be
used, which takes only the name of the subdirectory.
The file layout in a typical branding component repository is:
```
/
- CMakeLists.txt
- componentname/
- show.qml
- image1.png
...
- lang/
- calamares-componentname_en.ts
- calamares-componentname_de.ts
...
```
- If the branding component has many files which are organized into
subdirectories, use the SUBDIRECTORIES argument to the CMake function
to additionally install files from those subdirectories. For example,
if the component places all of its images in an `img/` subdirectory,
then call `calamares_add_branding_subdirectory( ... SUBDIRECTORIES img)`.
It is a bad idea to include `lang/` in the SUBDIRECTORIES list.