background

building software how?

gcc source1.c source2.c -o myprogram

more like:

  • build eng
  • release eng
  • build config
  • build automate
  • dependency management
  • CI/CD
  • etc

what building truly means

what truly means to build software:

  • version control
  • dependency
  • build command in diff modes and env
  • writing instruction to config and build
  • test config and execution
  • automated code quality check
  • scalable compilation
  • deployment

at least ask:

  • tools
  • workflow
  • painful points
  • risks
  • benefits
  • how to make less painful

modeling a build

first consider:

  • components and objectives
  • dependencies
    • good dependency graph - DAG
    • modern build management uses DAG to drive build process

-> means depends on

for each component, build management requires:

  • direct build req
  • transitive usage req
  • goal: separate interface from impl

dependency graph - infer to build component correctly based on deps - change only if deps change

cmake

cross-platform build management tool used by large projects

what does:

  • input: spec and config of project
  • output: build command for you
  • like autoconf but easier

why not manual?

  • need diff makefiles for different OS, compilers, libs
  • spec can capture almost everything and its semantics

benefits:

  • scalability
  • easier tool integration

make sure it’s out-of-source builds

in source bad because

  • need multiple build anyways
  • pollutes vcs
  • make clean build harder

using cmake

CMakeLists.txt - script in every dir to control how to build things

simple syntax and case insensitive

targets and commands

  • add_executable(helloworld)
  • add_library(hellohelper STATIC)
  • can add custom command to build

specifying requirements

target_* commands

target_sources(hellohelper
	PRIVATE helloworld.cpp)
 
target_include_directories(hellohelper
	INTERFACE ${dir}/include/)
 
target_link_libraries(helloworld
	PRIVATE hellohelper)

using libraries

  • transitive interface dependencies - linked as required
  • affects program structure and design

general project management

  • specifying project properties
    • project(name)
  • print info during build process
    • message("Built with flags: ${flag}")
  • control where things build
    • set(CMAKE_DIR ${PROJECT_DIR}/bin)

more commands

  • find resource to be used
    • `find_package(external_proj)
    • find_library(library)
  • installation
    • install(TARGETS target1 target2 DESTINATION /tmp/)
  • control structure - if, loop

pulling remote dependencies

include(cmake/CPM.cmake)
 
CPMAddPackage(
	NAME something
	GIT_REPO link
	GIT_TAG v0.0.1
)
 
target_link_libraries(demo
	PRIVATE something)

analyzing project structure

cmake can dump out dep graph in graphviz format

cmake -graphviz=deps.gv <path-to-proj>
dot -Tpng deps.gv -o deps.svg

advanced build issues

build systems - foundation of workflow and devops

  • choke point for controlling dev
  • can be expensive and has bottleneck

adding control

  • automated testing
  • code analysis and metrics

improve performance

  • parallel and distributed
  • caching
  • unification

summary

modern build system leverage dependency graph of project

dependency graph allows

  • inference of build and usage
  • compositional reasoning about modules and build management