aboutsummaryrefslogtreecommitdiffstats
path: root/docs/gettingstarted/developers/buildsystem/cmakeandninja.rst
blob: 580d261bdac8267848c13b2199d581462c97c1f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
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 <http://cmake.org>`_, and the `ninja website
<https://ninja-build.org>`_ 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/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.