Issue by light2yellow
Saturday Aug 19, 2017 at 01:58 GMT
Originally opened as mattanger/ckb-next#281
This pull request replaces qmake with CMake.
It is done due to multiple reasons:
- possibility to work on ckb-next using IDEs (e.g. Clion, Xcode) and editors with CMake integration (e.g. Visual Studio Code) different from Qt Creator
- lack of extensibility and features by qmake
- macOS toolchain bugs of qmake that prevent patch-free compilation
- CMake in 2017 has become a standard when speaking of build systems
So, below is (hopefully) a more or less complete description of the changes. Please, note that the majority of decisions were made by my own vision of project ecosystem and are based on some reasoning, having pros and cons. I am willing to read justified views as this is my first experience with CMake and, in general, with a project of this size. I learned a lot about CMake and init systems during this work and rewrote listfiles from scratch multiple times. So, every next sentence describing rationale should be read as if it would start with "IMO".
Executables
The names of binary executables were changed:
ckb
-> ckb-next
ckb-daemon
-> ckb-next-daemon
The above ones were promised in the 0.2.8 release note and finally create a distinction between ckb-next
and ckb
.
On the other hand, animations were shortened as the ckb-
prefix for binaries would be inappropriate considering the above changes and ckb-next-<foo>
would be needlessly long, as the binaries can only be called by the GUI and are installed under own separate directory:
ckb-gradient
-> gradient
- ...
Project structure
The layout of files has changed:
tree -d .
.
├── cmake
│ └── modules
├── linux
│ ├── openrc
│ ├── systemd
│ └── upstart
├── macos
│ └── pkgproj
└── src
├── animations
│ ├── gradient
│ ├── heat
│ ├── mviz
│ ├── pinwheel
│ ├── rain
│ ├── random
│ ├── ripple
│ └── wave
├── daemon
├── gui
│ └── resources
└── libs
├── ckbnext
│ ├── cmake
│ └── include
│ └── ckb-next
├── kissfft
│ └── include
│ └── kissfft
└── quazip
-
cmake/modules
contains CMake modules that are used in this project and can be reused later by other projects
-
linux
and macos
contain Linux-specific and macOS-specific files that do not make sense otherwise
-
src
:
animations
- obvious
daemon
- obvious
gui
- obvious
I used short and self-descriptive names instead of targets for ckb-next-daemon and ckb-next because it makes the project more intuitive for a newcomer (own experience). The targets being named like that themselves raise questions for me, but that's another story.
-
resources
- all files that belong on both Linux and macOS and to the GUI exclusively, but were cluttering the sources.
Speaking of resources, QRCs are now generated. For example, it is enough to add a png featuring a new device under resources
and CMake will compile it into the GUI.
libs
- our library and 3-rd party libraries
ckbnext
: a prototype of ckb-next library. ckb-anim.h
was removed from ckb-next
and now spans its own library. CMake configs are installed as part of a normal installation, which allows downstream to use the library natively. All the downstream is supposed to do is simply find_package(Animation)
in listfiles, receiving CkbNext::Animation
IMPORTED
target and #include <ckb-next/animation.h>
in source files. Note that the names are a subject to change, because Animation
is clearly ambiguous and should instead be at least CkbNextAnimation
. However, it would be better to create a component-wise system (Qt5 is a good example), but it will take more time and effort. As this was created with extensibility in mind, a list of CkbNext::
libraries can be exported if ckb-next obtains more APIs to provide. In general, this is somewhat a WIP, but already perfectly usable.
kissfft
- a library used to live inside ckb-mviz
. It is unpopular, i.e. is not in package repositories, and only few source files are used, so it's better to ship it.
quazip
- a library used to live inside ckb
. It is popular, however, because so far there is an agreement to support Ubuntu 14.04 LTS which lacks QuaZip for Qt5 in the repositories, it is shipped together with ckb-next.
There is ckbnextconfig.h
now. It is used to pass animation paths and define build-time "defines". For example:
+#include <ckbnextconfig.h>
//...
QString AnimScript::path(){
-#ifdef __APPLE__
- return QDir(QApplication::applicationDirPath() + "/../Resources").absoluteFilePath("ckb-animations");
-#else
- return QDir("/usr/lib").absoluteFilePath("ckb-animations");
-#endif
+ return QString(CKB_NEXT_ANIMATIONS_PATH);
}
Similar simplifications should be done in future to other OS-dependent files.
License headers
Most of the listfiles ship with a license header. As this PR will hang some time, I'll populate the rest of them. As I got a little bit carried, I populated few non-listfiles with licenses as well, e.g. kissfft
library already contains proper headers and acknowledgements. The default GNU headers were altered: firstly, "GPL version 2 or any later" replaced with "version 2", secondly, the link links directly at GPLv2.0. Note that the headers for listfiles authored by me will be changed to BSD 3-clause and current ones are supposed to appear in .c[pp]/.h[pp]
files in future. To learn more about open-source software licensing, see softwarefreedom's articles.
Compilation flags and build types
-Wall
and -Wextra
are essential flags and a list of other useful warnings was added on top of that for Debug
build type. The developers should read the warnings and fix them with code and not by disabling them (except for some obvious false positive cases).
Current list of flags for almost all targets:
-fsigned-char
-Wall
-Wextra
-Winit-self
$<$<CONFIG:Debug>:-Wfloat-equal>
$<$<CONFIG:Debug>:-Wundef>
$<$<CONFIG:Debug>:-Wshadow>
$<$<CONFIG:Debug>:-Wpointer-arith>
$<$<CONFIG:Debug>:-Wcast-align>
$<$<CONFIG:Debug>:-Wstrict-prototypes>
$<$<CONFIG:Debug>:-Wstrict-overflow=5>
$<$<CONFIG:Debug>:-Wwrite-strings>
$<$<CONFIG:Debug>:-Wcast-qual>
$<$<CONFIG:Debug>:-Wswitch-default>
$<$<CONFIG:Debug>:-Wswitch-enum>
$<$<CONFIG:Debug>:-Wconversion>
$<$<CONFIG:Debug>:-Wformat=2>
$<$<CONFIG:Debug>:-save-temps>
$<$<CONFIG:Debug>:${opt_lvl}>
$<CONFIG:Debug>
means the flag is enabled only with Debug
build type. ${opt_level}
is optimization level, expands either to -Og
if compiler supports it, or -O0
.
The default build type is RelWithDebInfo
, however, for developers it is recommended to use Debug
and for users it is recommended to use Release
. List of additional flags appended by every build type:
CMAKE_C[XX]_FLAGS_DEBUG is -g
CMAKE_C[XX]_FLAGS_RELEASE is -O3 -DNDEBUG
CMAKE_C[XX]_FLAGS_RELWITHDEBINFO is -O2 -g -DNDEBUG
CMAKE_C[XX]_FLAGS_MINSIZEREL is -Os -DNDEBUG
Versioning
VERSION
file was removed, instead a maintainer is supposed to increment ckb-next version in the main listfile.
Git is used to determine a more precise version with git describe
. That's why all how-to documents mention git cloning. I highly recommend to stop advicing people to download a ZIP code archive instead of cloning as it leaves versioning in a useless state when it comes to anything but release builds. Every non-release build is enhanced with revision and commit. When the .git
directory is missing the build is versioned with MAJOR.MINOR.PATCH
numbers hardcoded in the main listfile.
See Maintainers wiki article for more details about versioning and what CMake/git treats as a new version number. It has not been updated to reflect CMake-specific changes at the moment of writing this PR yet, but inevitably will.
Documentation
README
became very short and on the point, most of the subsections were moved to the wiki. The ones not edited are marked with (stub)
in the naming. Regarding CMake, installation sections for OSes were rewritten. Full list of written articles:
These articles contain additional information not mentioned here and are considered as a part of the PR. macOS installer ships with much longer README
version. This is something to generate in future from wiki articles. Nevertheless, documentation is still an open question in regards to everything but CMake. The only thing was done is relaxing README
so that there's no need to pollute it even more with CMake information. Troubleshooting
definitely needs a rewrite and the list of supported devices should be updated and enhanced with information linking to issues depicting current support status of each device.
Installation
Most significant achievement is the SAFE_INSTALL
option. It guarantees few things (indepent on the init system: systemd, Upstart, OpenRC and launchd are supported, independent on the OS):
- whatever the state of ckb/ckb-next GUI is, it will be closed before installation
- whatever the state of ckb-daemon/ckb-next-daemon is, it will be properly terminated to release a device before installation
- the daemon will be stopped and permanently disabled though a service file, if this makes sense to the current init system
- ckb/ckb-next GUI autostart files will be removed
- except the above none of the old ckb files will be removed except those which overlap (they will be overwritten)
- the daemon will be started and enabled though a service file, if this makes sense to the current init system
All in all, SAFE_INSTALL
is just perfect for instant reinstalls or lazy people that don't want to stop the services/don't know how to do it/don't know why to do it. Because ckb-next is still poor in distro-specific packages this is a great option for everyone who used to execute ./quickinstall
. The existence of uninstall
target is based off same considerations, although the latter is a bit limited currently in comparison to what SAFE_INSTALL
can do.
SAFE_INSTALL
has its tradeoffs. From CMake configuration time output:
Privileged access is required for operations upon the daemon at
configure time as it is owned by root. If this is unacceptable,
disable SAFE_INSTALL and prepare the filesystem manually.
So, one may have to enter a password requested by sudo. However, note that maintainers of distro-specific packages are supposed to disable this option and provide distro-specific ways to ensure the behaviour described above. For example, in Arch Linux pkgbuild
s post_*()
and pre_*()
functions are used. Therefore a minimal example for package maintainers is:
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DSAFE_INSTALL=OFF ..
See wiki for the whole list of options as it contains some important ones. For example, ckb-next follows GNU Coding Standards and by default the path to animations is ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBEXECDIR}/ckb-next-animations
which results into /usr/local/libexec/ckb-next-animations
by default.
Testing
Most work and time went into making auxiliary files flexible or figuring out why they don't work together. However, in the end it's all for the sake of outer simplicity. Because there are so many pieces to it and something is usually overlooked, I ask the community to test this as much as possible:
- if you know CMake, review it. Describe what you like/don't like about they way it is implemented.
- read the above mentioned wiki pages to get familiar with CMake options and commands to execute
- try different Linux/macOS starting conditions: enabled daemon, disabled daemon, started daemon, stopped daemon, running GUI, GUI started at login etc.
- try the above permutation in combination with different platforms and init systems. I have tested systemd on Manjaro-systemd, launchd on Hackintosh 10.12.6, Upstart on Ubuntu 14.04 and OpenRC on Manjaro-openrc.
- proofread the documentation if it's incorrect or missing anything. All CMake options are gathered in the main listfile.
- if you are a native English speaker or just decent at it, don't hesitate to edit language errors in the wiki on the above mentioned articles, if you have the access. If you don't, use IRC chat or the mailing list to contact someone who has it.
Some features have not been tested due to time restrictions, e.g. sanitizers.
Closes #32.
If something has been forgotten, don't hesitate to point this out.
CC @hevanaa, @mrueg as ones who will be directly affected by this. You might want to read only the "Installation" & "Testing" sections and then the wiki pages.
light2yellow included the following code: https://github.com/mattanger/ckb-next/pull/281/commits