Developers guide
Checklists for developing new things in Corrade itself.
Contents
- Checklist for adding / removing a library
- Checklist for adding / removing a plugin
- Checklist for adding / removing a plugin interface
- Checklist for adding / removing a tool
- Checklist for adding / removing an example
- Checklist for adding / removing a new source / header file
- Checklist for adding / removing a symbol
- Checklist for adding a new CMake documentation page
- Checklist for deprecating a feature
- Checklist for removing a feature
- Checklist for adding, removing or updating a dependency
- Checklist for adding or removing a port
- Checklist for updating copyright year
- Checklist for uploading documentation
- Checklist for merging a PR
- Checklist for making a release
This guide is meant mainly for core Corrade developers to avoid forgetting about things. If you are contributing a pull-request, you can use these checklists as a guide and save the maintainers a bit of work — but you are not strictly required to follow them to the point.
Checklist for adding / removing a library
- Add a
WITH_LIBRARYNAMECMake option to:- root
CMakeLists.txt(if it has some inter-library dependencies, update the others / convert them tocmake_dependent_option(), addingNOT WITH_LIBRARYNAMEto their condition — note the conditions are ANDed so they need to be specified in reverse) - the list in
doc/building.dox(and similar files in other repos)
- root
- Update
FindCorrade.cmake(or similar in other repos):- mention the new lib in the list of components in the docs
- if it has some inter-library dependencies, add a corresponding
_CORRADE_${_COMPONENT}_DEPENDENCIESentry - add its name to the
_CORRADE_LIBRARY_COMPONENTSregex - add a new
elseif(_component STREQUAL LibraryName)section with special setup of includes or dependencies or explicitly say# No special setup for LibraryName library
- Add the library to the list in
doc/corrade-cmake.dox - Add a conditional
add_subdirectory()tosrc/Corrade/CMakeLists.txt - Create a new
src/Corrade/LibraryName/CMakeLists.txt, copy over up-to-date license header from other CMake files, add your name to it and populate it:- add source files to
CorradeLibraryName_SRCSvariable - add installable headers to
CorradeLibraryName_HEADERSvariable - add private headers to
CorradeLibraryName_PRIVATE_HEADERSvariable (if any) - if the test needs some extra setup (such as e.g.
CORRADE_NO_ASSERTenabled for particular files), create a newCorradeLibraryNameObjectsOBJECTlibrary with files that can be compiled the same way in both cases to speed up compilation - verify that the
add_library()command references all input files (needed so QtCreator lists all project files properly) - verify that debug postfix is set (
set_target_properties(CorradeLibraryName PROPERTIES DEBUG_POSTFIX "-d")) - verify that folder is set for all libraries and
OBJECTlibraries to avoid cluttering project tree view in IDEs (set_target_properties(CorradeLibraryName PROPERTIES FOLDER "Corrade/LibraryName")) - verify that target installation is done in proper places (separate
RUNTIME/LIBRARY/ARCHIVEdestinations) - verify that
set_target_properties(CorradeLibraryName PROPERTIES VERSION ${CORRADE_LIBRARY_VERSION} SOVERSION ${CORRADE_LIBRARY_SOVERSION})is done in caseBUILD_STATICis not set - verify that
set_target_properties(CorradeLibraryName PROPERTIES POSITION_INDEPENDENT_CODE ON)is done in caseBUILD_STATIC_PICis set - verify that
add_library(Corrade::LibraryName ALIAS CorradeLibraryName)(or equivalent) is added to make the library visible for CMake subprojects
- add source files to
- Create a new
src/Corrade/LibraryName/Test/directory:- add a
CMakeLists.txtwith pre-populated license header, add your name to it - conditionally
add_subdirectory()it ifBUILD_TESTSis enabled
- add a
- Create a new
src/Corrade/LibraryName/LibraryName.hheader for forward declarations (if needed), add a file-level doc block withForward declarations for the @ref Corrade::LibraryName namespaceas brief docs - Create a new
src/Corrade/LibraryName/visibility.hheader withCORRADE_LIBRARYNAME_EXPORTandCORRADE_LIBRARYNAME_LOCALmacros by copypasting it from another library:- adapt
#ifdef CorradeLibraryName_EXPORTSso it matches CMake target name - if the library is combined from an
OBJECTlibrary, add its name to the above#ifdefas well (and then explicitly addtarget_compile_definitions(ĆorradeLibraryNameObjects PRIVATE "CorradeLibraryNameObjects_EXPORTS")toCMakeLists.txtin caseBUILD_STATICis not set)
- adapt
- Mention the directory and namespace in
doc/namespaces.dox, basically copy-pasting the following from existing documentation:- directory-level doc block referencing the namespace
- namespace-level doc block mentioning the
WITH_LIBRARYNAMEoption, dependencies (if any) and a code snippet showing how to use it with CMake
- Code and test the rest of the library, see Checklist for adding / removing a new source / header file and Checklist for adding / removing a symbol for more information
- Add the
WITH_LIBRARYNAMEoption to all files inpackage/directory, explicitly saying eitherONorOFFbased on platform support:- all
package/archlinux/PKGBUILD*files (and the AUR package(s)) - the
package/debian/rulesfile (watch out, tabs!) - the
package/gentoo/*.ebuildfile - the
package/homebrew/*.rbfile (watch out, Ruby!) - all
package/ci/appveyor-*.batfiles (^is a line continuation) - all
package/ci/travis-*.shfiles (\is a line continuation)
- all
- If the library has dependencies:
- make sure they are mentioned in the library documentation
- make sure they are mentioned in building and CMake docs
- make sure they are mentioned in
CREDITS.md - make sure AppVeyor and Travis downloads them (based on platform support)
- Mention the library in
doc/corrade-changelog.dox - Build documentation:
- run dox2html5.py on
Doxyfile-mcssand verify there are no new warnings - eyeball the namespace and directory docs, fix suspicious things, look also in the building and cmake docs
- run dox2html5.py on
- Build a coverage build (
package/archlinux/PKGBUILD-coverage), or abuse the CI for that later - Push to a temporary branch (e.g.,
next) - Iterate until the CIs are green and the code coverage is good enough
- Merge to
master
In order to remove a library, be sure to touch all places mentioned above, only in inverse — but usually deprecate first.
Checklist for adding / removing a plugin
Similarly to Checklist for adding / removing a library except points 2 and 5, with:
- Update
FindCorrade.cmake(replaces point 2 in Checklist for adding / removing a library):- mention the new plugin in the list of components in the docs
- add its name to the
_CORRADE_PLUGIN_COMPONENTSregex - add a new
elseif(_component STREQUAL PluginName)section with special setup of includes or dependencies or explicitly say# PluginName has no dependencies
- Create
PluginName.confand list all plugin dependencies (if any). The file has to be present even if empty. - Create
pluginRegistration.cppby copypasting it from another plugin and adapting plugin name and plugin interface string. It's needed to be in a separate file that gets compiled only to the plugin library, not to the test library. - Create
configure.h.cmakefor plugin-specific information about whether the library was built as static or not - Create a new
src/CorradePlugins/PluginName/CMakeLists.txt, copy over up-to-date license header from other CMake files and populate it (replaces point 5 in Checklist for adding / removing a library):- add source files to
PluginName_SRCSvariable - add installable headers to
PluginName_HEADERSvariable - add private headers to
PluginName_PRIVATE_HEADERSvariable (if any) - create a
PluginNameObjectslibrary that contains all files that are common for the plugin library and test library (usually everything exceptpluginRegistration.cpp), add atarget_compile_definitions(PluginNameObjects PRIVATE "PluginNameObjects_EXPORTS")for it - use
add_plugin()command (which is aliased to either corrade_add_ plugin() or corrade_ add_ static_ plugin()) to create the PluginNamelibrary, use${CORRADE_PLUGINS_*_DEBUG_BINARY_INSTALL_DIR}/${CORRADE_PLUGINS_*_RELEASE_BINARY_INSTALL_DIR}and${CORRADE_PLUGINS_*_DEBUG_LIBRARY_INSTALL_DIR}/${CORRADE_PLUGINS_*_RELEASE_LIBRARY_INSTALL_DIR}variables that correspond to given plugin interface - verify that both
add_library()andadd_plugin()commands reference all input files (needed so QtCreator lists all project files properly) - verify that folder is set for the
OBJECTlibrary and the test library to avoid cluttering project tree view in IDEs (set_target_properties(PluginNameObjects PROPERTIES FOLDER "CorradePlugins/PluginName")) — for the plugin library it's done automatically insideadd_plugin() - verify that
set_target_properties(PluginName PROPERTIES POSITION_INDEPENDENT_CODE ON)is done in caseBUILD_STATIC_PICis set - verify that
add_library(Corrade::PluginName ALIAS PluginName)(or equivalent) is added to make the library visible for CMake subprojects
- add source files to
- If there is more than one interface header (other than just
PluginName.hbeing installed), add a newvisibility.hheader. Otherwise put the visibility macros directly inPluginName.h.
In order to remove a plugin, be sure to touch all places mentioned above, only in inverse — but usually deprecate first.
Checklist for adding / removing a plugin interface
In order to remove a plugin interface, be sure to touch all places mentioned above, only in inverse — but usually deprecate first.
Checklist for adding / removing a tool
In order to remove a tool, be sure to touch all places mentioned above, only in inverse — but usually deprecate first.
Checklist for adding / removing an example
- Add a new
src/examples/namedirectory, copy up-to-date UNLICENSE headers from other files in the repo - Verify that
src/examples/name/CMakeLists.txtcontainscmake_minimum_required(),project()and allcmake_policy()commands so it can be used as a top-level project level - Add a new
doc/name.doxpage with@brief,@m_footernavigationand@pagename equivalent to filename, describe what the example is doing - Add a new
examplename-sourcesection with:- link to GitHub
- referencing all textual example sources as
- @ref example-name/file.ext "file.ext" - breadcrumb and navigation setup for all example sources as
@example example-name/file.ext @m_examplenavigation{examples-example-name,example-name/} @m_footernavigation
- Update
doc/corrade-example-index.doxand list the example there - Mention the example in
doc/corrade-changelog.dox - Push to a temporary branch (e.g.,
nextorports-next) - Iterate until the CIs are green
- Merge to
master/ports
In order to remove an example, be sure to touch all places mentioned above, but in inverse.
Checklist for adding / removing a new source / header file
- Copy over a up-to-date license header (note that example code uses UNLICENSE instead of MIT) and add your name + year to it, if not already there
- Add a
@file-level documentation block, with@brieflisting all classes, functions, typedefs, enums, macros etc. that are in the file - Add the file to corresponding
*_SRCS,*_HEADERS,*_PRIVATE_HEADERSlist inCMakeLists.txt - If applicable, add a new test class file in the
Test/directory- name it
FileNameTest.cpp, put a class namedFileNameTestinside, wrapped in aTestsubnamespace of the original file namespace - use
corrade_add_test()to add it to tests - if some tests need GL context, add a separate test with
GLTestsuffix, wrapping the correspondingcorrade_add_test()inif(BUILD_GL_TESTS)
- name it
- Populate the file, see Checklist for adding / removing a symbol and Coding style for more information.
- Mention the new functionality in
doc/corrade-changelog.dox - Build documentation:
- run dox2html5.py on
Doxyfile-mcssand verify there are no new warnings - eyeball the relevant docs and fix suspicious things
- run dox2html5.py on
- Build a coverage build (
package/archlinux/PKGBUILD-coverage), or abuse the CI for that later - Push to a temporary branch (e.g.,
next) - Iterate until the CIs are green and the code coverage is good enough
- Merge to
master
In order to remove a file, be sure to touch all places mentioned above, only in inverse — but usually deprecate first.
Checklist for adding / removing a symbol
- If the symbol is standalone (i.e., not member of a class), list it in the
@file-level@briefdocs - Document it
- Add a test for it to corresponding file, verify the test gets actually run
- Mention the new functionality in
doc/changelog.dox(and similar files in other repos) - Build documentation:
- run dox2html5.py on
Doxyfile-mcssand verify there are no new warnings - eyeball the relevant docs and fix suspicious things
- run dox2html5.py on
- Build a coverage build (
package/archlinux/PKGBUILD-coverage), or abuse the CI for that later - Push to a temporary branch (e.g.,
next) - Iterate until the CIs are green and the code coverage is good enough
- Merge to
master
In order to remove a symbol, be sure to touch all places mentioned above, only in inverse — but usually deprecate first.
Checklist for adding a new CMake documentation page
- Add a
doc/pagename.doxfile, copy up-to-date license header and add your name + year to it, if not already there - If the page is top-level, list it in
doc/00-page-order.doxto ensure it gets listed at a proper place - If the page is not top-level, list it using
@subpagein its parent page and add@m_footernavigationfor automatic linking to parent and prev/next pages - Add a
@briefdocumentation, if applicable - Populate it, see Coding style for more information
- Mention the new page in
doc/changelog.dox(and similar files in other repos) - Build documentation:
- run dox2html5.py on
Doxyfile-mcssand verify there are no new warnings - eyeball the relevant docs and fix suspicious things
- run dox2html5.py on
- Push to
master
Checklist for deprecating a feature
- If the feature is publicly exposed, think about the best way of deprecation that preserves source compatibility:
- Add a compatibility
typedef/usingfor a renamed symbol, marking it with CORRADE_DEPRECATED() / CORRADE_ DEPRECATED_ ALIAS() - Add a compatibility header for a renamed include, including the original file from it and marking it with CORRADE_
DEPRECATED_ FILE() - Add a compatibility inline function for a function that got renamed or its arguments changed, mark it with CORRADE_
DEPRECATED() - Add a compatibility enum value for a value that got renamed or deleted, mark it with CORRADE_
DEPRECATED_ ENUM() - Don't ever change semantics of function arguments without changing the function signature. That would silently break with no possibility to let the user know.
- Function return type changes are hard. One possibility is working around that by returning a wrapper type that's implicitly convertible to both the old and new type, another is introducing a differently named function instead. The last resort is breaking the API without preserving backwards compatibility — but that makes people angry, so avoid that if possible.
- Add a compatibility
- Add just a
@brief @copybrieffrom the replacement functionality together with a@deprecatedline to the deprecated feature - Reference the replacement functionality in both the deprecation macro and in the
@deprecatedline to make porting easier - Ensure the deprecated symbol is wrapped in
#ifndef CORRADE_BUILD_DEPRECATED, - Ensure deprecated files
#errorin case they get used in non-deprecated build, ensure they are not installed in non-deprecated builds - Build all tests and dependent projects and verify that:
- using the old functionality still compiles and works as intended
- deprecation warnings are emitted in proper places
- Upon verifying the above, start updating dependent code
- Mention the deprecated API in the deprecation section of
doc/corrade-changelog.dox - Build documentation:
- run dox2html5.py on
Doxyfile-mcssand verify there are no new warnings - eyeball the relevant docs and fix suspicious things
- run dox2html5.py on
- Push to a temporary branch (e.g.,
next) - Iterate until the CIs are green
- Merge to
master - If possible, trigger builds of dependent projects (where they are still using the old API) and verify they are still green (and red in non-deprecated build)
- Update dependent projects
Checklist for removing a feature
- Check that it was in deprecated state for more than a year with at least one release in between. Check that no important clients depend on it anymore. If not, wait a bit more.
- Remove relevant blocks wrapped in
#ifndef CORRADE_BUILD_DEPRECATED, remove relevant deprecated files and updateCMakeLists.txt - Mention the removed API in the compatibility section of
doc/changelog.dox(or similar files in other repos) - Build documentation:
- run dox2html5.py on
Doxyfile-mcssand verify there are no new warnings — sometimes it happens that a deprecated API is still being referenced
- run dox2html5.py on
- Push to a temporary branch (e.g.,
next) - Iterate until the CIs are green
- Merge to
master - If possible, trigger builds of dependent projects and verify they are still green (or wait for the scheduled builds)
Checklist for adding, removing or updating a dependency
- Verify that there are no important clients stuck on the old version with no easy way to upgrade
- In case of CMake:
- it's usually possible to jump more than one version, check what's the version on the oldest supported system
- bump all
cmake_minimum_required()in all repos - remove
cmake_policy()calls that are not needed anymore - remove old workarounds, check changelogs for functionality that can be used now
- update building docs to say what version is required now
- add an entry to the dependencies section in
doc/changelog.dox - update
package/ci/travis.ymlto download a newer version, possibly removing 32-bit compat libraries
- In case of a compiler:
- remove everything related to
CORRADE_GCCXY_COMPATIBILITYof the old version, if applicable - update building docs to say what version is required now
- add an entry to the dependencies section in
doc/changelog.dox - update files in
package/ci/to use a newer version
- remove everything related to
- In case given dependency is external:
- Create a dedicated
Find*.cmakemodule and does not have a builtin one in CMake - update packages in
package/to depend on the new library - update files in
package/ci/to install it
- Create a dedicated
- In case given dependency is single-file:
- verify it's reasonably small (<50kB is okay,
nlohmann/jsonis a prime example of not okay) - add it to
src/external/without any modifications except for trailing whitespace cleanup - add it in a separate Git commit, mentioning its version (or Git hash) for easier upgrades later
- verify it's reasonably small (<50kB is okay,
- Update
CREDITS.mdof affected repo to mention the added/removed dependency, its homepage and its license
In order to remove a dependency, be sure to touch all places mentioned above, only in inverse.
Checklist for adding or removing a port
- Add a new
TARGET_*variable:- to root
CMakeLists.txt, which either gets enabled automatically based on system introspection or is exposed through aoption()command - to the list of variables extracted out of
configure.hinmodules/FindCorrade.cmake
- to root
- Add a
CORRADE_TARGET_*variable:- set it in root
CMakeLists.txtin caseTARGET_*is enabled - add it as a
#cmakedefinemacro tosrc/Corrade/configure.h.cmake - add documentation for it to
src/Corrade/Corrade.h - mention it in
modules/FindCorrade.cmakedocs - mention it in
doc/corrade-cmake.doxanddoc/building-corrade.dox
- set it in root
- Add a new Travis / AppVeyor matrix build for this port (or update existing)
- Add a new
PKGBUILD-*file inpackage/archlinuxfor testing (or update existing) - Enable or disable functionality using
if(CORRADE_TARGET_*)in CMake and#ifdef CORRADE_TARGET_*in C++ - Mention the new stuff in
doc/corrade-changelog.dox - Push to a temporary branch (e.g.,
next) - Iterate until the CIs are green
- Merge to
master
In order to remove a port, be sure to touch all places mentioned above, only in inverse.
Checklist for updating copyright year
- Verify there are no uncommitted changes in any repos, as that would significantly complicate reverting a potential fuck-up
- Use msrp to batch replace copyright info in all files, replacing existing
Copyright © ...withCopyright © ..., 20XZin the root directory of every project, so nothing gets left out - Examples use partially MIT (mainly in docs) and partially UNLICENSE, replace
... —with..., 20XZ —there as well - Copy all
Find*.cmakemodules to dependent projects to update the copyright year in these as well - Update
package/debian/copyrightto say the new year as well - Use
git diffto verify the change went well and the new year is specified exactly once everywhere - Do a local verification build, push to
master
Checklist for uploading documentation
- (Optionally) remove
build/doc-publicto get rid of stale files - Verify there are no untracked files, modifications or branches different than
masterchecked out that could mess up the docs - Run dox2html5.py on
Doxyfile-public, look for suspicious warnings - Upload contents of
build/doc-public/html/todoc/corrade-new/and removedoc/corrade-old/if any - Once the upload is finished, rename
doc/corrade/todoc/corrade-old/anddoc/corrade-new/todoc/corrade/ - Quickly check that the docs still look as they should, if not, revert the backup and try again
Checklist for merging a PR
- After the public round of review, pull the changes locally to a temporary branch (i.e.,
next) - Verify a coverage build, verify that there are no compiler warnings
- Go over and fix issues that slipped through cracks in the public review
- Verify the contributor is mentioned in all relevant license headers, add if necessary
- Add the contributor to
CREDITS.md, if not already there - Update
doc/corrade-changelog.dox, if not already done - Build documentation:
- run dox2html5.py on
Doxyfile-mcssand verify there are no new warnings - eyeball the relevant docs and fix suspicious things
- run dox2html5.py on
- Push to a temporary branch (e.g.,
next) - Iterate until the CIs are green
- Merge to
master, put a "thank you" comment to the PR, explaining additional changes if necessary
Checklist for making a release
- Open a new
20XY.acmilestone - Verify that there are no blocking issues in the current (
20XY.ab) milestone, either fix them or move to the next milestone - Verify that all CIs are green
- Go through
doc/corrade-changelog.doxand update it, in case it doesn't contain all changes (usegitkto check when it was last updated) - Go through fixed issues and merged PRs and add either a changelog mention added (and add a mention to the changelog), scrapped or no action needed label to wrap them up
- Update changelog for the next release:
- change section names for the latest release from
latestto20XY-ab - change the title from
Changes since 20XY.aato20XY.ab - add a paragraph stating date of release and referencing the to-be-added tag on GitHub
- change section names for the latest release from
- Bump
CORRADE_LIBRARY_VERSIONandCORRADE_LIBRARY_SOVERSIONin all projects, if needed — ensure consistency with Magnum releases - Rebuild all projects with the new shared library version numbers, verify all tools and examples still behave properly
- Build and upload public docs (see Checklist for uploading documentation), verify that there are no new warnings and the changelog looks correct
- Push all new changes to a temporary branch (e.g.,
next) - Wait for the CIs to get green
- Tag a new version using
git tag -a v20XY.ab, say justVersion 20XY.abas a message - Push the tag, verify that the CIs are still green
- Add content to the corresponding Magnum release announcement
- Update versions of ArchLinux AUR packages:
- run
makepkginpackage/archlinux/corrade-git, verify it builds and says correct version, ideally withr0at the ennd - copy the updated
PKGBUILDto the AUR package repo, runmakepkg --printsrcinfo > .SRCINFOthere - commit the updated
PKGBUILDand.SRCINFO, push - after pushing all, verify that the version is updated in the AUR web interface as well
- run
- Update Debian package changelog in
package/debian/changelog, copypasting the last entry, updating it and using the Git tag date+time for it (note that the date format is slightly different) - Update Homebrew package versions
- Ask someone to update Vcpkg packages
- Close the 20XY.ab GitHub milestone
- Add link to the release notes to the tag on GitHub