Software Engineering

Build Files

Michael L. Collard, Ph.D.

Department of Computer Science, The University of Akron

Possible Variations for libxml2 include directory

Platform / installation Directory
Ubuntu / Debian, Fedora / RHEL / Rocky / Alma, Arch Linux, openSUSE, Alpine Linux, Gentoo, Cygwin /usr/include/libxml2
FreeBSD, OpenBSD, macOS Homebrew (Intel), local Unix installation /usr/local/include/libxml2
NetBSD / pkgsrc /usr/pkg/include/libxml2
macOS / MacPorts /opt/local/include/libxml2
macOS / Homebrew (Apple Silicon) /opt/homebrew/include/libxml2
Windows / vcpkg <vcpkg-root>\installed\<triplet>\include\libxml2
Windows / MSYS2 MinGW <MSYS2>\mingw64\include\libxml2
Windows / MSYS2 UCRT64 <MSYS2>\ucrt64\include\libxml2
Windows / MSYS2 CLANG64 <MSYS2>\clang64\include\libxml2
Conda (Linux, macOS, Windows) <conda-prefix>/include/libxml2
Cross-compilation / sysroot <sysroot>/usr/include/libxml2
Custom installation <prefix>/include/libxml2

Creating a Makefile is challenging:

  • Must list all prerequisite include files (i.e., .h and .hpp files)
  • Straightforward for an in-source build, more difficult for an out-of-source build
  • Prefer an out-of-source build
  • Make is Turing Complete, but conditional (e.g., if-statements) and repetition (e.g., for-statements) statements have an unfamiliar syntax
  • Does not easily handle multiple platforms or multiple build configurations
  • Limited internal and external libraries and additional support software

CMake

  • CMake is a build-file generator and can generate build files for many platforms and environments
  • cmake --help shows a list of Generators
  • Related tools: ctest, cpack
  • Has both command-line and GUI tools
  • Under constant improvement
  • Works well on Linux, macOS, and Windows MSVC

Using CMake

Build languages are declarative

Example: Using C++20

There is always more to learn

Multiple structural design decisions to make

  • srcML build file structure
  • Full View
  • Build file structure follows the source file tree structure
  • Alternative: A single large CMakeLists.txt that knows the tree structure of the source (and prevents any change to that structure)

Types of CMake Files

  • Full View
  • CMakeLists.txt - The default name, found in the top directory and often in subdirectories
  • CMakePresets.json JSON file with presets to use with the CMake option --preset. Much of the platform-specific build configuration has been moved from the CMakeLists.txt to these files, including the ones in the directory presets.
  • CMakeUserPresets.json A JSON file with personal presets to use with the CMake option --preset. It is not committed to the repository and is developer-specific.
  • toolchain-gcc.cmake CMake commands for a specific platform
  • macos-libarchive.cmake Separates out specific processing from CMakeLists.txt
  • srcMLConfig.cmake.in - Input for generating files for other CMake projects to be able to use find_package(srcML) (as with find_package(LibXml2 REQUIRED))
  • CTestConfig.cmake - CDash configuration
  • wix-cpack.cmake CPack configuration for a Windows WiX installer (generates an MSI installer). Custom naming convention so that installers can be loaded automatically.
  • vcpkg.json A JSON file with a list of dependencies for vcpkg builds. vcpkg primarily aims to allow Windows developers to easily use open-source libraries in their applications. It integrates easily into CMake builds.

Build File Comparison: srcML

File Type File Number LOC
C++ files, C files, ANTLR files 195 (19%) 64 KLOC (38%)
Build Files 40 (4%) 3 KLOC (2%)
Test Files 707 (68%) 91 KLOC (54%)
Other 93 (9%) 9 KLOC (5%)
Total 1,035 (100%) 168 KLOC (100%)

Summation

  • Always use a build tool to build programs. Do not use direct entry of compiler commands unless it is part of a class where you are learning the commands. Build your knowledge into the build file instead of having to remember.
  • Things don't always work the same on all platforms, so you have to experiment
  • While CMake and other tools may be difficult, the main problem is that building code into an executable or installer has many difficult situations
  • In some ways, build files are static and dynamic. They tend to be created and left alone for a long time, but then change drastically when the project structure or platforms change.