Introduction to cmake and ninja =============================== Cmake plus ninja is approximately equal to GNU autotools plus GNU make, respectively. Both cmake and GNU autotools support self and cross-compilation, checking for required components and versions. - For a decent-sized project - such as vpp - build performance is drastically better with (cmake, ninja). - The cmake input language looks like an actual language, rather than a shell scripting scheme on steroids. - Ninja doesn't pretend to support manually-generated input files. Think of it as a fast, dumb robot which eats mildly legible byte-code. See the `cmake website `_, and the `ninja website `_ for additional information. vpp cmake configuration files ----------------------------- The top of the vpp project cmake hierarchy lives in .../src/CMakeLists.txt. This file defines the vpp project, and (recursively) includes two kinds of files: rule/function definitions, and target lists. - Rule/function definitions live in .../src/cmake/{\*.cmake}. Although the contents of these files is simple enough to read, it shouldn't be necessary to modify them very often - Build target lists come from CMakeLists.txt files found in subdirectories, which are named in the SUBDIRS list in .../src/CMakeLists.txt :: ############################################################################## # subdirs - order matters ############################################################################## if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") find_package(OpenSSL REQUIRED) set(SUBDIRS vppinfra svm vlib vlibmemory vlibapi vnet vpp vat vcl plugins vpp-api tools/vppapigen tools/g2 tools/elftool tools/perftool) elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") set(SUBDIRS vppinfra) else() message(FATAL_ERROR "Unsupported system: ${CMAKE_SYSTEM_NAME}") endif() foreach(DIR ${SUBDIRS}) add_subdirectory(${DIR}) endforeach() - The vpp cmake configuration hierarchy discovers the list of plugins to be built by searching for subdirectories in .../src/plugins which contain CMakeLists.txt files :: ############################################################################## # find and add all plugin subdirs ############################################################################## FILE(GLOB files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*/CMakeLists.txt ) foreach (f ${files}) get_filename_component(dir ${f} DIRECTORY) add_subdirectory(${dir}) endforeach() How to write a plugin CMakeLists.txt file ----------------------------------------- It's really quite simple. Follow the pattern: :: add_vpp_plugin(mactime SOURCES mactime.c node.c API_FILES mactime.api INSTALL_HEADERS mactime_all_api_h.h mactime_msg_enum.h API_TEST_SOURCES mactime_test.c ) Adding a target elsewhere in the source tree -------------------------------------------- Within reason, adding a subdirectory to the SUBDIRS list in .../src/CMakeLists.txt is perfectly OK. The indicated directory will need a CMakeLists.txt file. .. _building-g2: Here's how we build the g2 event data visualization tool: :: option(VPP_BUILD_G2 "Build g2 tool." OFF) if(VPP_BUILD_G2) find_package(GTK2 COMPONENTS gtk) if(GTK2_FOUND) include_directories(${GTK2_INCLUDE_DIRS}) add_vpp_executable(g2 SOURCES clib.c cpel.c events.c main.c menu1.c pointsel.c props.c g2version.c view1.c LINK_LIBRARIES vppinfra Threads::Threads m ${GTK2_LIBRARIES} NO_INSTALL ) endif() endif() The g2 component is optional, and is not built by default. There are a couple of ways to tell cmake to include it in build.ninja [or in Makefile.] When invoking cmake manually [rarely done and not very easy], specify -DVPP_BUILD_G2=ON: :: $ cmake ... -DVPP_BUILD_G2=ON Take a good look at .../build-data/packages/vpp.mk to see where and how the top-level Makefile and .../build-root/Makefile set all of the cmake arguments. One strategy to enable an optional component is fairly obvious. Add -DVPP_BUILD_G2=ON to vpp_cmake_args. That would work, of course, but it's not a particularly elegant solution. Tinkering with build options: ccmake ------------------------------------ The easy way to set VPP_BUILD_G2 - or frankly **any** cmake parameter - is to install the "cmake-curses-gui" package and use it. - Do a straightforward vpp build using the top level Makefile, "make build" or "make build-release" - Ajourn to .../build-root/build-vpp-native/vpp or .../build-root/build-vpp_debug-native/vpp - Invoke "ccmake ." to reconfigure the project as desired Here's approximately what you'll see: :: CCACHE_FOUND /usr/bin/ccache CMAKE_BUILD_TYPE CMAKE_INSTALL_PREFIX /scratch/vpp-gate/build-root/install-vpp-nati DPDK_INCLUDE_DIR /scratch/vpp-gate/build-root/install-vpp-nati DPDK_LIB /scratch/vpp-gate/build-root/install-vpp-nati MBEDTLS_INCLUDE_DIR /usr/include MBEDTLS_LIB1 /usr/lib/x86_64-linux-gnu/libmbedtls.so MBEDTLS_LIB2 /usr/lib/x86_64-linux-gnu/libmbedx509.so MBEDTLS_LIB3 /usr/lib/x86_64-linux-gnu/libmbedcrypto.so MUSDK_INCLUDE_DIR MUSDK_INCLUDE_DIR-NOTFOUND MUSDK_LIB MUSDK_LIB-NOTFOUND PRE_DATA_SIZE 128 VPP_API_TEST_BUILTIN ON VPP_BUILD_G2 OFF VPP_BUILD_PERFTOOL OFF VPP_BUILD_VCL_TESTS ON VPP_BUILD_VPPINFRA_TESTS OFF CCACHE_FOUND: Path to a program. Press [enter] to edit option Press [d] to delete an entry CMake Version 3.10.2 Press [c] to configure Press [h] for help Press [q] to quit without generating Press [t] to toggle advanced mode (Currently Off) Use the cursor to point at the VPP_BUILD_G2 line. Press the return key to change OFF to ON. Press "c" to regenerate build.ninja, etc. At that point "make build" or "make build-release" will build g2. And so on. Note that toggling advanced mode ["t"] gives access to substantially all of the cmake option, discovered directories and paths.