Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 1 | # |
| 2 | # Copyright 2018, Data61 |
| 3 | # Commonwealth Scientific and Industrial Research Organisation (CSIRO) |
| 4 | # ABN 41 687 119 230. |
| 5 | # |
| 6 | # This software may be distributed and modified according to the terms of |
| 7 | # the BSD 2-Clause license. Note that NO WARRANTY is provided. |
| 8 | # See "LICENSE_BSD2.txt" for details. |
| 9 | # |
| 10 | # @TAG(DATA61_BSD) |
| 11 | # |
| 12 | |
| 13 | cmake_minimum_required(VERSION 3.7.2) |
| 14 | |
| 15 | include(ExternalProject) |
| 16 | |
| 17 | include(${KERNEL_HELPERS_PATH}) |
| 18 | |
| 19 | set(configure_string "") |
| 20 | |
| 21 | config_string(CAmkESDefaultStackSize CAMKES_DEFAULT_STACK_SIZE |
| 22 | "Stack size to allocate per-component, in bytes. Note that this value |
| 23 | should be page-aligned. If not, it will be rounded up." |
| 24 | DEFAULT 16384 |
| 25 | UNQUOTE |
| 26 | ) |
| 27 | |
| 28 | config_string(CAmkESDefaultHeapSize CAMKES_DEFAULT_HEAP_SIZE |
| 29 | "Heap size to allocate per-component, in bytes." |
| 30 | DEFAULT 1048576 |
| 31 | UNQUOTE |
| 32 | ) |
| 33 | |
| 34 | config_choice(CAmkESErrorHandlingMode CAMKES_ERROR_HANDLING_MODE |
| 35 | "Select the mode of error handling used in the glue code. It should only |
| 36 | be necessary to adjust this setting if you are doing verification. |
| 37 | Otherwise, the default error handling mechanism allows for |
| 38 | configuration at runtime. |
| 39 | |
| 40 | Standard -> Standard error handling mechanism, that is configurable by the user at |
| 41 | runtime. See the documentation for details of the API for this. |
| 42 | |
| 43 | Guards -> Use verification-visible guards at the site of each potential error. |
| 44 | Note that this assumes that none of the error conditions are possible. |
| 45 | If you are trying to verify code, you will be forced to prove that none |
| 46 | of the error conditions can ever actually occur. |
| 47 | |
| 48 | Abort -> Call 'abort' inline when an error occurs. For debugging purposes, this |
| 49 | is probably not the behaviour you want as it will give you no |
| 50 | information about the error. The standard error handling mechanism has |
| 51 | a nicer default for debugging. This mode is primarily useful when you |
| 52 | want to verify code whose error handlers are unreachable for |
| 53 | non-trivial reasons. |
| 54 | |
| 55 | Discard -> Perform the 'discard' action on any error that occurs. The advantage of |
| 56 | this over simply configuring this behaviour via the standard mechanism |
| 57 | is that you will not need to reason about any of the complicated error |
| 58 | handling structures or control flow. This has no implementation |
| 59 | advantages over the standard mechanism." |
| 60 | "Standard;CAmkESErrorHandlingConfigurable;CAMKES_ERROR_HANDLER_CONFIGURABLE" |
| 61 | "Guards;CAmkESErrorHandlingGuard;CAMKES_ERROR_HANDLER_GUARD" |
| 62 | "Abort;CAmkESErrorHandlingAbort;CAMKES_ERROR_HANDLER_ABORT" |
| 63 | "Discard;CAmkESErrorHandlingDiscard;CAMKES_ERROR_HANDLER_DISCARD" |
| 64 | ) |
| 65 | |
| 66 | config_option(CAmkESConnectorTiming CAMKES_CONNECTOR_TIMING |
| 67 | "Enable timing points within connector templates that take cycle counter |
| 68 | values as they are passed. This timing data can then be retrieved after |
| 69 | execution." |
| 70 | DEFAULT OFF |
| 71 | ) |
| 72 | |
| 73 | config_option(CAmkESProvideTCBCaps CAMKES_PROVIDE_TCB_CAPS |
| 74 | "Hand out TCB caps to components. These caps are used by the component |
| 75 | to exit cleanly by suspending. Disabling this option leaves components |
| 76 | with an empty slot in place of their TCB cap. This means they will cap |
| 77 | fault when attempting to exit. The advantage is that your resulting |
| 78 | CapDL specification contains no TCB caps and is thus easier to reason |
| 79 | about." |
| 80 | DEFAULT ON |
| 81 | ) |
| 82 | |
| 83 | config_choice(CAmkESTLSModel CAMKES_TLS_MODEL |
| 84 | "The CAmkES glue code uses thread-local variables for marshalling and |
| 85 | unmarshalling of RPC parameters. This setting controls how this thread- |
| 86 | local storage is implemented. |
| 87 | |
| 88 | standard -> Allocate thread-local variables on the stack or the heap as appropriate. |
| 89 | This is the default and will hold the fewest surprises for C |
| 90 | programmers. |
| 91 | |
| 92 | per-thread -> Allocate per-thread global variables for use as thread-local storage. |
| 93 | The main purpose of this implementation is to avoid taking the address |
| 94 | of local variables, an idiom that cannot be handled by the verification |
| 95 | C parser." |
| 96 | "standard;CAmkESTLSStandard;CAMKES_TLS_STANDARD" |
| 97 | "per-thread;CAmkESTLSPerThreadGlobal;CAMKES_TLS_PTG" |
| 98 | ) |
| 99 | |
Adrian Danis | 4a99eb3 | 2018-03-07 15:58:12 +1100 | [diff] [blame] | 100 | config_string(CAmkESDefaultPriority CAMKES_DEFAULT_PRIORITY |
| 101 | "Default priority for component threads if this is not overridden via an |
| 102 | attribute. Generally you want to set this as high as possible due to |
| 103 | the suboptimal seL4 scheduler." |
| 104 | # Default to one less than max prio to avoid interleaving with the CapDL intialiser |
| 105 | DEFAULT 254 |
| 106 | UNQUOTE |
| 107 | ) |
| 108 | if ((${CAmkESDefaultPriority} LESS 0) OR (${CAmkESDefaultPriority} GREATER 255)) |
| 109 | message(FATAL_ERROR "CAmkESDefaultPriority must be [0, 255]") |
| 110 | endif() |
| 111 | |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 112 | add_config_library(camkes_config "${configure_string}") |
| 113 | |
| 114 | # These options are not declared with the config_* system because they only need to exist |
| 115 | # in the build system, and not appear in a configuration library |
| 116 | set(CAmkESCPP OFF CACHE BOOL |
| 117 | "Run CPP on the input specification(s) before parsing them into an AST. |
| 118 | This can allow you to write parameterised specs in the case of more |
| 119 | complex system" |
| 120 | ) |
| 121 | |
| 122 | set(CAmkESImportPath "" CACHE STRING |
| 123 | "CAmkES can include components and interfaces stored outside the current application |
| 124 | directory. This option is a space delimited list of absolute paths to directories |
| 125 | to be searched for components or interfaces included with angle brackets." |
| 126 | ) |
| 127 | |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 128 | set(CAmkESDefaultAffinity 0 CACHE STRING |
| 129 | # Default to 0 as this is the index assigned to the BSP (Boot Strap Processor) by seL4 |
| 130 | "Default affinity for component threads if this is not overridden via an |
| 131 | attribute. Think carefully when organizing your applications for |
| 132 | multiprocessor operation" |
| 133 | ) |
| 134 | math(EXPR MaxNumNodesMin1 "${KernelMaxNumNodes} - 1") |
| 135 | if((${CAmkESDefaultAffinity} < 0) OR (${CAmkESDefaultAffinity} GREATER ${MaxNumNodesMin1})) |
| 136 | message(FATAL_ERROR "Invalid CAmkESDefaultAffinity") |
| 137 | endif() |
| 138 | |
| 139 | set(CAmkESAllowForwardReferences OFF CACHE BOOL |
| 140 | "By default, you can only refer to objects in your specification which |
| 141 | have been defined before the point at which you reference them. |
| 142 | Selecting this option allows you to also reference objects that are |
| 143 | defined below the point at which the reference occurs. This option is |
| 144 | off by default because it leads to a slight performance degradation in |
| 145 | parsing specification" |
| 146 | ) |
| 147 | |
| 148 | set(CAmkESObjdumpMethod "auto" CACHE STRING |
| 149 | "Instead of using the internal ELF parsing functionality, it is |
| 150 | possible to call out to your toolchain's objdump to perform |
| 151 | required operations. This is more fragile than using internal |
| 152 | functionality, but can provide a performance boost in compilation |
| 153 | times. If you set this to auto (default), CAmkES will use your |
| 154 | toolchain's objdump if it is in your PATH. |
| 155 | |
| 156 | off -> Disable the use of objdump for ELF symbol lookups. Lookups will be |
| 157 | done via standard built-in CAmkES mechanisms. This may be slightly |
| 158 | slower. |
| 159 | |
| 160 | auto -> Automatically detect whether objdump is available for use for ELF |
| 161 | symbol lookups, and use it if so. This will result in the fastest |
| 162 | available method for ELF symbol lookup being used automatically and |
| 163 | is the recommended default. |
| 164 | |
| 165 | on -> Use objdump for ELF symbol lookups. Lookups will be done by calling |
| 166 | out to your toolchain's objdump binary. This is fastest at the |
| 167 | expense of some robustness." |
| 168 | ) |
| 169 | set_property(CACHE CAmkESObjdumpMethod PROPERTY STRINGS "auto;on;off") |
| 170 | |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 171 | set(CAmkESRPCLockElision ON CACHE BOOL |
| 172 | "Detect when it is safe to exclude locking operations in the seL4RPC connector and |
| 173 | automatically do so. This is an optimisation that can improve the performance of |
| 174 | this connector." |
| 175 | ) |
| 176 | |
| 177 | set(CAmkESSpecialiseSyscallStubs ON CACHE BOOL |
| 178 | "Detect when glue code overhead could be reduced with a custom syscall |
| 179 | stub and generate and use this instead of the libsel4 stubs. This does |
| 180 | not affect whether a given IPC will hit the fastpath, but it does |
| 181 | reduce the userlevel overhead of these system calls. In ideal |
| 182 | conditions this will give you RPC as fast as native seL4 IPC. This only |
| 183 | has an effect on ARM." |
| 184 | ) |
| 185 | |
| 186 | set(CAmkESLargeFramePromotion ON CACHE BOOL |
| 187 | "Some hardware platforms support multiple page sizes. In components with |
| 188 | large virtual address spaces, it is possible to reduce memory usage |
| 189 | (and consequent load time) by backing the component's address space with |
| 190 | pages of these larger sizes. When this setting is enabled, small |
| 191 | consecutive page mappings will be promoted to fewer consecutive large |
| 192 | mappings. Note that larger frame sizes are directly mapped into page |
| 193 | directories and can also save the overhead of an accompanying page |
| 194 | table." |
| 195 | ) |
| 196 | |
| 197 | set(CAmkESDMALargeFramePromotion OFF CACHE BOOL |
| 198 | "For components with a configured DMA pool, the frames backing this |
| 199 | are not automatically promoted to large frames even if the pool is |
| 200 | sufficiently large. Select this option to enable such promotion |
| 201 | automatically. This is off by default because it requires support |
| 202 | for large alignments in your toolchain's assembler, which is often |
| 203 | absent in ARM toolchains." |
| 204 | ) |
| 205 | |
| 206 | set(CAmkESPythonOptimisation "none" CACHE STRING |
| 207 | "Select the optimisation flag to pass to the Python interpreter. The |
| 208 | default is for no optimisation because profiling has suggested this |
| 209 | has a detrimental effect for CAmkES. However, you may find |
| 210 | different results depending on your wor |
| 211 | |
| 212 | none -> Do not pass any optimisation flags to the Python interpreter. |
| 213 | |
| 214 | -O -> Enable basic optimisations. This disables assertions and is not |
| 215 | recommended if you are working on the internals of CAmkES itself. |
| 216 | |
| 217 | -OO -> Enable basic optimisations and also strip docstrings." |
| 218 | ) |
| 219 | set_property(CACHE CAmkESPythonOptimisation PROPERTY STRINGS "none;-O;-OO") |
| 220 | |
| 221 | set(CAmkESPythonInterpreter "cpython" CACHE STRING |
| 222 | "Select the Python interpreter used for executing CAmkES. The default |
| 223 | CPython interpreter should be acceptable for any normal use, but you |
| 224 | may find PyPy provides better build system performance under some |
| 225 | circumstances. To use PyPy, obviously you need it installed. The other |
| 226 | interpreters are for profiling or dynamic analysis. |
| 227 | |
| 228 | cpython -> Use CPython, the default Python interpreter. This is what will be |
| 229 | most familiar to Python users. |
| 230 | |
| 231 | cpython2 -> Force the use of Python 2, instead of the default Python |
| 232 | executable. |
| 233 | |
| 234 | cpython3 -> Force the use of Python 3, instead of the default Python |
| 235 | executable. Note that Python 3 support is currently experimental |
| 236 | and should not be expected to work without tweaks. |
| 237 | |
| 238 | pypy -> Use PyPy, an optimised Python interpreter. PyPy is intended to be |
| 239 | faster than CPython with maximum compatibility, but it is not |
| 240 | recommended for use with CAmkES because profiling has indicated it |
| 241 | is actually *slower* in general for CAmkES' workload. |
| 242 | |
| 243 | figleaf -> Use Figleaf, an interpreter that reports code coverage statistics. |
| 244 | This interpreter is primarily useful for profiling or debugging |
| 245 | CAmkES itself. |
| 246 | |
| 247 | coverage -> Use Python-coverage, an interpreter that reports code coverage |
| 248 | statistics. This interpreter is primarily useful for profiling or |
| 249 | debugging CAmkES itself." |
| 250 | ) |
| 251 | set_property(CACHE CAmkESPythonInterpreter PROPERTY STRINGS "cpython;cpython2;cpython3;pypy;figleaf;coverage") |
| 252 | |
| 253 | set(CAmkESFaultHandlers ON CACHE BOOL |
| 254 | "When a component references invalid virtual memory or an invalid |
| 255 | capability, the access generates a fault. With this option selected |
| 256 | a handler is provided that decodes this fault for debugging |
| 257 | purposes. You will want to disable this in a production system or in |
| 258 | a system where you want to handle your own faults." |
| 259 | ) |
| 260 | |
| 261 | set(CAmkESSupportInit ON CACHE BOOL |
| 262 | "Support the pre_init, post_init and interface init functions as part of |
| 263 | component startup. These functions allow extra functionality, but |
| 264 | introduce some endpoint caps for synchronisation. You probably want |
| 265 | this option enabled unless you are targetting verification." |
| 266 | ) |
| 267 | |
Anna Lyons | 44adb6d | 2018-08-02 14:39:50 +1000 | [diff] [blame] | 268 | set(CAmkESDTS OFF CACHE BOOL |
| 269 | "Support using a device tree (.dts) file, which camkes can query |
| 270 | for device properties. A file path can be provided by as an argument |
| 271 | to DeclareCAmkESRootserver as DTS_FILE_PATH, otherwise the a dts file |
| 272 | matching the platform will be found in seL4/tools." |
| 273 | ) |
| 274 | |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 275 | # TODO: The following options are not yet supported in cmake build template, as a result |
| 276 | # these are currently commented out to as not to confuse users. They should be uncommented |
| 277 | # as support is added |
| 278 | #set(CAmkESPruneGenerated OFF CACHE BOOL |
| 279 | # "Prune generated C files |
| 280 | # When selected, this option minimises the number of C functions in a |
| 281 | # given generated file. This can be done because the CAmkES generation |
| 282 | # logic knows which functions are required by the user's components and |
| 283 | # which are not. This option implies a separate pre-process step on the |
| 284 | # generated files prior to pruning/compilation, otherwise the generated |
| 285 | # C files are already minimal. Note, you will need libclang-dev installed |
| 286 | # to enable this option." |
| 287 | #) |
| 288 | |
| 289 | #set(CAmkESThys OFF CACHE BOOL |
| 290 | # "Generate correctness proofs |
| 291 | # Generate AutoCorres-based theories of connector correctness during |
| 292 | # compilation." |
| 293 | #) |
| 294 | |
| 295 | #set(CAmkESUnifiedThy OFF CACHE BOOL |
| 296 | # "Generate unified correctness proof |
| 297 | # Generate an AutoCorred-based theory combining the two glue code halves |
| 298 | # of a connector, resulting in a final correctness statement." |
| 299 | # DEPENDS CAmkESPruneGenerated |
| 300 | #) |
| 301 | |
| 302 | #set(CAmkESArchThy OFF CACHE BOOL |
| 303 | # "Generate architectural specification |
| 304 | # Generate an Isabelle theory specifying the architecture of the |
| 305 | # system, using the l4.verified formal model of ADL." |
| 306 | #) |
| 307 | |
| 308 | #set(CAmkESCImpThy OFF CACHE BOOL |
| 309 | # "Generate dynamic behavioural specification |
| 310 | # Generate an Isabelle theory specifying the dynamic behaviour of the |
| 311 | # system. This theory builds on top of the CIMP formalisation." |
| 312 | #) |
| 313 | |
| 314 | #set(CAmkESCapDLThy OFF CACHE BOOL |
| 315 | # "Generate CapDL Isabelle specification |
| 316 | # During a CAmkES build, a textual CapDL specification of the system |
| 317 | # is generated for the purpose of initialisation. Selecting this |
| 318 | # option causes an Isabelle version of this specification to be |
| 319 | # generated as well for the purposes of reasoning about the |
| 320 | # capability distribution of a CAmkES system" |
| 321 | #) |
| 322 | |
| 323 | #set(CAmkESLabelMapping OFF CACHE BOOL |
| 324 | # "Generate policy label mapping |
| 325 | # Enable this option to generate a mapping from labels to kernel objects |
| 326 | # during compilation. A label per-CAmkES entity (component instance or |
| 327 | # connection) is generated and they are intended to form the input domain |
| 328 | # of a function mapping these to final policy labels. The final labels |
| 329 | # are then used to reason about the security properties of a system." |
| 330 | #) |
| 331 | |
| 332 | set(CAmkESVerbose OFF CACHE BOOL |
| 333 | "Enable verbose output from CAmkES. This is disabled by default as it |
| 334 | can result in a lot of output, but is useful for debugging CAmkES problems" |
| 335 | ) |
| 336 | |
Adrian Danis | ca89b10 | 2018-03-14 16:41:18 +1100 | [diff] [blame] | 337 | # Save the path to to python-capdl whilst we know it (unless it was already specified) |
| 338 | if (NOT PYTHON_CAPDL_PATH) |
Kent McLeod | f5d7fd6 | 2018-07-24 13:43:44 +1000 | [diff] [blame] | 339 | set(PYTHON_CAPDL_PATH "${CMAKE_SOURCE_DIR}/projects/capdl/python-capdl-tool") |
Adrian Danis | ca89b10 | 2018-03-14 16:41:18 +1100 | [diff] [blame] | 340 | endif() |
| 341 | if (NOT CAPDL_TOOL_SOURCE_PATH) |
Kent McLeod | f5d7fd6 | 2018-07-24 13:43:44 +1000 | [diff] [blame] | 342 | set(CAPDL_TOOL_SOURCE_PATH "${CMAKE_SOURCE_DIR}/projects/capdl/capDL-tool") |
Adrian Danis | ca89b10 | 2018-03-14 16:41:18 +1100 | [diff] [blame] | 343 | endif() |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 344 | |
| 345 | # Save the location of the camkes tool wrapper script |
| 346 | RequireFile(CAMKES_TOOL camkes.sh PATHS "${CMAKE_CURRENT_LIST_DIR}") |
| 347 | |
| 348 | # Use the camkes script to determine the location of other things |
| 349 | get_filename_component(CAMKES_TOOL_DIR "${CAMKES_TOOL}" DIRECTORY) |
| 350 | set(CAMKES_TOOL_BUILTIN_DIR "${CAMKES_TOOL_DIR}/include/builtin") |
| 351 | |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 352 | # Require the parse-capDL tool |
| 353 | ExternalProject_Add(parse_capdl_tool |
| 354 | SOURCE_DIR "${CAPDL_TOOL_SOURCE_PATH}" |
| 355 | CONFIGURE_COMMAND bash -c "cp -ra ${CAPDL_TOOL_SOURCE_PATH}/* ." |
| 356 | BUILD_ALWAYS ON |
Kent McLeod | e13a05e | 2018-08-28 11:37:19 +1000 | [diff] [blame^] | 357 | BUILD_COMMAND ${CMAKE_COMMAND} -E env make |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 358 | INSTALL_COMMAND ${CMAKE_COMMAND} -E env "PATH=$ENV{PATH}:${CMAKE_CURRENT_BINARY_DIR}/parse_capdl_tool-prefix/src/parse_capdl_tool-build" make install |
| 359 | ) |
| 360 | ExternalProject_Get_property(parse_capdl_tool BINARY_DIR) |
| 361 | set(CAPDL_TOOL_PATH "${BINARY_DIR}") |
| 362 | |
| 363 | # Search for a FMT tool for reformatting generated CAmkES C files |
| 364 | find_program(CLANG_FORMAT_TOOL clang-format) |
| 365 | if ("${CLANG_FORMAT_TOOL}" STREQUAL "CLANG_FORMAT_TOOL-NOTFOUND") |
| 366 | set(CAMKES_C_FMT_INVOCATION "") |
| 367 | else() |
| 368 | set(CAMKES_C_FMT_INVOCATION "${CLANG_FORMAT_TOOL} --style=LLVM") |
| 369 | endif() |
| 370 | |
| 371 | # Find the sponge tool, or emulate it |
| 372 | find_program(SPONGE_TOOL sponge) |
| 373 | if ("${SPONGE_TOOL}" STREQUAL "SPONGE_TOOL-NOTFOUND") |
Adrian Danis | 0fdc9d6 | 2018-06-22 15:01:49 +1000 | [diff] [blame] | 374 | set(CAMKES_SPONGE_INVOCATION "sh ${CMAKE_CURRENT_BINARY_DIR}/sponge_emul.sh") |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 375 | file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/sponge_emul.sh" "python -c 'import sys; data = sys.stdin.read(); f = open(sys.argv[1], \"w\"); f.write(data); f.close()' $@") |
| 376 | else() |
| 377 | set(CAMKES_SPONGE_INVOCATION "${SPONGE_TOOL}") |
| 378 | endif() |
| 379 | |
| 380 | # Find the Isabelle theory pre-process for formatting theory files |
Kent McLeod | f5d7fd6 | 2018-07-24 13:43:44 +1000 | [diff] [blame] | 381 | find_program(TPP_TOOL tpp PATHS ${CMAKE_CURRENT_LIST_DIR}/tools) |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 382 | if ("${TPP_TOOL}" STREQUAL "TPP_TOOL-NOTFOUND") |
| 383 | message(FATAL_ERROR "Failed to find tpp tool") |
| 384 | endif() |
| 385 | |
| 386 | # CAmkES defines its own heaps and for this to work muslcsys must not be configured to |
| 387 | # use a static morecore. We make the morecore dynamic by setting the size to 0 |
| 388 | set(LibSel4MuslcSysMorecoreBytes 0 CACHE STRING "" FORCE) |
| 389 | |
| 390 | # Function to help build the CAMKES_TOOL_ENVIRONMENT below |
| 391 | function(camkes_append_env_if) |
| 392 | # Loop through each pair of arguments and build the environment |
| 393 | set(local_env "${CAMKES_TOOL_ENVIRONMENT}") |
| 394 | math(EXPR limit "${ARGC} - 1") |
| 395 | foreach(i RANGE 0 ${limit} 2) |
| 396 | math(EXPR ip1 "${i} + 1") |
| 397 | set(check "${ARGV${i}}") |
| 398 | string(REGEX REPLACE " +" ";" check "${check}") |
| 399 | if(${check}) |
| 400 | # Add the environment |
| 401 | list(APPEND local_env "${ARGV${ip1}}=1") |
| 402 | endif() |
| 403 | endforeach() |
| 404 | set(CAMKES_TOOL_ENVIRONMENT "${local_env}" PARENT_SCOPE) |
| 405 | endfunction(camkes_append_env_if) |
| 406 | |
| 407 | function(camkes_append_flags) |
| 408 | math(EXPR limit "${ARGC} - 1") |
| 409 | set(local_flags "${CAMKES_FLAGS}") |
| 410 | foreach(i RANGE 0 ${limit}) |
| 411 | set(list "${ARGV${i}}") |
| 412 | list(GET list 0 check) |
| 413 | string(REGEX REPLACE " +" ";" check "${check}") |
| 414 | if(${check}) |
| 415 | list(GET list 1 when_true) |
| 416 | list(APPEND local_flags "${when_true}") |
| 417 | else() |
| 418 | list(LENGTH list len) |
| 419 | if (${len} GREATER 2) |
| 420 | list(GET list 2 when_false) |
| 421 | list(APPEND local_flags "${when_false}") |
| 422 | endif() |
| 423 | endif() |
| 424 | endforeach() |
| 425 | set(CAMKES_FLAGS "${local_flags}" PARENT_SCOPE) |
| 426 | endfunction(camkes_append_flags) |
| 427 | |
| 428 | # This is called from the context of a CAmkES application that has decided what the 'root' |
| 429 | # application is. This function will effectively generate a rule for building the final |
| 430 | # rootserver image |
| 431 | function(DeclareCAmkESRootserver adl) |
| 432 | cmake_parse_arguments(PARSE_ARGV 1 CAMKES_ROOT |
| 433 | "" # Option arguments |
Anna Lyons | 44adb6d | 2018-08-02 14:39:50 +1000 | [diff] [blame] | 434 | "DTS_FILE_PATH" # Single arguments |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 435 | "CPP_FLAGS;CPP_INCLUDES" # Multiple aguments |
| 436 | ) |
| 437 | # Stash this request as a global property. The main CAmkES build file will call |
| 438 | # GenerateCAmkESRootserver later once all the build scripts are processed |
| 439 | get_property(declared GLOBAL PROPERTY CAMKES_ROOT_DECLARED) |
| 440 | if (declared) |
| 441 | message(FATAL_ERROR "A CAmkES rootserver was already declared") |
| 442 | endif() |
| 443 | foreach(include IN LISTS CAMKES_ROOT_CPP_INCLUDES) |
Kent McLeod | 94369c4 | 2018-07-24 13:46:25 +1000 | [diff] [blame] | 444 | get_absolute_list_source_or_binary(include "${include}") |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 445 | list(APPEND CAMKES_ROOT_CPP_FLAGS "-I${include}") |
| 446 | endforeach() |
Kent McLeod | 94369c4 | 2018-07-24 13:46:25 +1000 | [diff] [blame] | 447 | get_absolute_list_source_or_binary(adl "${adl}") |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 448 | set_property(GLOBAL PROPERTY CAMKES_ROOT_ADL "${adl}") |
| 449 | set_property(GLOBAL PROPERTY CAMKES_ROOT_CPP_FLAGS "${CAMKES_ROOT_CPP_FLAGS}") |
| 450 | set_property(GLOBAL PROPERTY CAMKES_ROOT_DECLARED TRUE) |
Anna Lyons | 44adb6d | 2018-08-02 14:39:50 +1000 | [diff] [blame] | 451 | if(${CAmkESDTS} AND NOT "${CAMKES_ROOT_DTS_FILE}" STREQUAL "") |
| 452 | get_absolute_list_source_or_binary(CAMKES_ROOT_DTS_FILE_PATH "${CAMKES_ROOT_DTS_FILE_PATH}") |
| 453 | endif() |
| 454 | set_property(GLOBAL PROPERTY CAMKES_ROOT_DTS_FILE_PATH "${CAMKES_ROOT_DTS_FILE_PATH}") |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 455 | endfunction(DeclareCAmkESRootserver) |
| 456 | |
Adrian Danis | 84a8021 | 2018-03-23 11:35:17 +1100 | [diff] [blame] | 457 | # This takes a camkes produced dependency file (this means we can assume one dependency |
| 458 | # per line) and produces a cmake list of dependencies |
| 459 | function(MakefileDepsToList mdfile output_variable) |
| 460 | file(READ "${mdfile}" raw_file) |
| 461 | # First remove the target of the dependency list |
| 462 | string(REGEX REPLACE "^[^:]*: \\\\\r?\n" "" string_deps "${raw_file}") |
| 463 | # Now turn the list of dependencies into a cmake list. We have assumed |
| 464 | # that this makefile dep file was generated by camkes and so it has one |
| 465 | # item per line |
| 466 | string(REGEX REPLACE "\\\\\r?\n" ";" deps "${string_deps}") |
| 467 | # Strip the space from each dep |
| 468 | foreach(dep IN LISTS deps) |
| 469 | # Strip extra spacing |
| 470 | string(STRIP "${dep}" dep) |
| 471 | list(APPEND final_deps "${dep}") |
| 472 | endforeach() |
| 473 | # Write the output to the parent |
| 474 | set("${output_variable}" "${final_deps}" PARENT_SCOPE) |
| 475 | endfunction(MakefileDepsToList) |
| 476 | |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 477 | # Called to actually generate the definitions for the CAmkES rootserver. Due to its |
| 478 | # use of properties for some configuration it needs to be run after all other build |
| 479 | # scripts, typically by the main CAmkES build file |
| 480 | function(GenerateCAmkESRootserver) |
| 481 | # Retrieve properties from the declare call above |
| 482 | get_property(declared GLOBAL PROPERTY CAMKES_ROOT_DECLARED) |
| 483 | if (NOT declared) |
| 484 | message(FATAL_ERROR "No CAmkES rootserver was declared") |
| 485 | endif() |
| 486 | get_property(adl GLOBAL PROPERTY CAMKES_ROOT_ADL) |
| 487 | get_property(CAMKES_ROOT_CPP_FLAGS GLOBAL PROPERTY CAMKES_ROOT_CPP_FLAGS) |
Anna Lyons | 44adb6d | 2018-08-02 14:39:50 +1000 | [diff] [blame] | 488 | get_property(dts_file GLOBAL PROPERTY CAMKES_ROOT_DTS_FILE_PATH) |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 489 | set(CAMKES_TOOL_ENVIRONMENT "") |
| 490 | set(CAMKES_TOOL_DEPENDENCIES "") |
| 491 | # Build the environment expected by camkes, as well as the camkes.sh wrapper script |
| 492 | list(APPEND CAMKES_TOOL_ENVIRONMENT "PYTHONPATH=$ENV{PYTHONPATH}:${PYTHON_CAPDL_PATH}") |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 493 | # List of 'if condition' 'definition to add' for building the environment exports |
| 494 | camkes_append_env_if( |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 495 | "${CAmkESObjdumpMethod} STREQUAL on" CONFIG_CAMKES_USE_OBJDUMP_ON |
| 496 | "${CAmkESObjdumpMethod} STREQUAL auto" CONFIG_CAMKES_USE_OBJDUMP_AUTO |
| 497 | "${CAmkESPythonOptimisation} STREQUAL -O" CONFIG_CAMKES_PYTHON_OPTIMISE_BASIC |
| 498 | "${CAmkESPythonOptimisation} STREQUAL -OO" CONFIG_CAMKES_PYTHON_OPTIMISE_MORE |
| 499 | "${CAmkESPythonInterpreter} STREQUAL cpython" CONFIG_CAMKES_PYTHON_INTERPRETER_CPYTHON |
| 500 | "${CAmkESPythonInterpreter} STREQUAL cpython2" CONFIG_CAMKES_PYTHON_INTERPRETER_CPYTHON2 |
| 501 | "${CAmkESPythonInterpreter} STREQUAL cpython3" CONFIG_CAMKES_PYTHON_INTERPRETER_CPYTHON3 |
| 502 | "${CAmkESPythonInterpreter} STREQUAL pypy" CONFIG_CAMKES_PYTHON_INTERPRETER_PYPY |
| 503 | "${CAmkESPythonInterpreter} STREQUAL figleaf" CONFIG_CAMKES_PYTHON_INTERPRETER_FIGLEAF |
| 504 | "${CAmkESPythonInterpreter} STREQUAL coverage" CONFIG_CAMKES_PYTHON_INTERPRETER_COVERAGE |
| 505 | ) |
| 506 | # Use the path as constructed at generation time |
| 507 | list(APPEND CAMKES_TOOL_ENVIRONMENT "PATH=$ENV{PATH}") |
| 508 | get_filename_component(CAMKES_CDL_TARGET "${adl}" NAME_WE) |
| 509 | set(CAMKES_CDL_TARGET "${CMAKE_CURRENT_BINARY_DIR}/${CAMKES_CDL_TARGET}.cdl") |
| 510 | # Get an absolute reference to the ADL source |
Kent McLeod | 94369c4 | 2018-07-24 13:46:25 +1000 | [diff] [blame] | 511 | get_absolute_list_source_or_binary(CAMKES_ADL_SOURCE "${adl}") |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 512 | # Declare a common CAMKES_FLAGS that we will need to give to every invocation of camkes |
| 513 | set(CAMKES_FLAGS |
| 514 | "--import-path=${CAMKES_TOOL_BUILTIN_DIR}" |
| 515 | --platform seL4 |
| 516 | --architecture ${KernelSel4Arch} |
| 517 | --default-priority ${CAmkESDefaultPriority} |
| 518 | --default-affinity ${CAmkESDefaultAffinity} |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 519 | ) |
Anna Lyons | 44adb6d | 2018-08-02 14:39:50 +1000 | [diff] [blame] | 520 | |
| 521 | if (${CAmkESDTS}) |
| 522 | # Find the dts to use |
| 523 | if ("${dts_file}" STREQUAL "") |
| 524 | # no dts file set, try to find the default |
| 525 | FindDTS(dts_file ${PLATFORM}) |
| 526 | elseif(NOT EXISTS "${dts_file}") |
| 527 | message(FATAL_ERROR "Could not find dts file ${dts_file}") |
| 528 | endif() |
| 529 | GenDTB("${dts_file}" dtb_file) |
| 530 | list(APPEND CAMKES_FLAGS "--dtb=${dtb_file}") |
| 531 | endif() |
| 532 | |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 533 | # Build extra flags from the configuration |
| 534 | # Each of these arguments is a CONDITION FLAG_IF_CONDITION_TRUE [FLAG_IF_CONDITION_FALSE] |
| 535 | camkes_append_flags( |
| 536 | "CAmkESVerbose;--debug" |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 537 | "KernelIsMCS;--realtime" |
| 538 | "CAmkESRPCLockElision;--frpc-lock-elision;--fno-rpc-lock-elision" |
| 539 | "CAmkESSpecialiseSyscallStubs;--fspecialise-syscall-stubs;--fno-specialise-syscall-stubs" |
| 540 | "CAmkESProvideTCBCaps;--fprovide-tcb-caps;--fno-provide-tcb-caps" |
| 541 | "CAmkESSupportInit;--fsupport-init;--fno-support-init" |
| 542 | "CAmkESLargeFramePromotion;--largeframe" |
| 543 | "CAmkESDMALargeFramePromotion;--largeframe-dma" |
| 544 | "CAmkESAllowForwardReferences;--allow-forward-references" |
| 545 | "CAmkESFaultHandlers;--debug-fault-handlers" |
| 546 | "CAmkESCPP;--cpp" |
| 547 | ) |
| 548 | foreach(flag IN LISTS CAMKES_ROOT_CPP_FLAGS) |
| 549 | if(NOT CAmkESCPP) |
| 550 | message(FATAL_ERROR "Given CPP_FLAGS ${CAMKES_ROOT_CPP_FLAGS} but CAmkESCPP is disabled") |
| 551 | endif() |
| 552 | list(APPEND CAMKES_FLAGS "--cpp-flag=${flag}") |
| 553 | endforeach() |
| 554 | # Retrieve any extra import paths |
| 555 | get_property(imports GLOBAL PROPERTY CAmkESExtraImportPaths) |
| 556 | foreach(import IN LISTS imports) |
| 557 | list(APPEND CAMKES_FLAGS "--import-path=${import}") |
| 558 | endforeach() |
Anna Lyons | bf8f9c7 | 2018-08-02 14:43:35 +1000 | [diff] [blame] | 559 | # Retrieve any template paths |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 560 | get_property(templates GLOBAL PROPERTY CAmkESTemplatePaths) |
| 561 | foreach(template IN LISTS templates) |
| 562 | list(APPEND CAMKES_FLAGS --templates "${template}") |
| 563 | endforeach() |
Adrian Danis | 0f24c72 | 2018-03-23 11:30:23 +1100 | [diff] [blame] | 564 | # Need to ensure our camkes_gen folder exists as camkes will not create the directory |
| 565 | file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/camkes_gen") |
| 566 | set(deps_file "${CMAKE_CURRENT_BINARY_DIR}/camkes_gen/deps") |
Adrian Danis | 2bf14a0 | 2018-03-23 11:45:22 +1100 | [diff] [blame] | 567 | set(invoc_file "${CMAKE_CURRENT_BINARY_DIR}/camkes_gen/last_invocation") |
Adrian Danis | cf76ead | 2018-03-23 10:57:41 +1100 | [diff] [blame] | 568 | set(gen_outfile "${CMAKE_CURRENT_BINARY_DIR}/camkes-gen.cmake") |
Adrian Danis | bd2f375 | 2018-03-23 11:36:52 +1100 | [diff] [blame] | 569 | set(camkes_invocation |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 570 | ${CMAKE_COMMAND} -E env ${CAMKES_TOOL_ENVIRONMENT} "${CAMKES_TOOL}" |
| 571 | --file "${CAMKES_ADL_SOURCE}" |
| 572 | --item camkes-gen.cmake |
Adrian Danis | cf76ead | 2018-03-23 10:57:41 +1100 | [diff] [blame] | 573 | --outfile "${gen_outfile}" |
Adrian Danis | 0f24c72 | 2018-03-23 11:30:23 +1100 | [diff] [blame] | 574 | --makefile-dependencies "${deps_file}" |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 575 | ${CAMKES_FLAGS} |
Adrian Danis | bd2f375 | 2018-03-23 11:36:52 +1100 | [diff] [blame] | 576 | ) |
Adrian Danis | e2e2290 | 2018-03-23 11:41:59 +1100 | [diff] [blame] | 577 | # We need to determine if we actually need to regenerate. We start by assuming that we do |
| 578 | set(regen TRUE) |
Adrian Danis | 2bf14a0 | 2018-03-23 11:45:22 +1100 | [diff] [blame] | 579 | if((EXISTS "${invoc_file}") AND (EXISTS "${deps_file}") AND (EXISTS "${gen_outfile}")) |
| 580 | file(READ "${invoc_file}" old_contents) |
| 581 | if ("${old_contents}" STREQUAL "${camkes_invocation}") |
| 582 | MakefileDepsToList("${deps_file}" deps) |
| 583 | # At this point assume we do not need to regenerate, unless we found a newer file |
| 584 | set(regen FALSE) |
| 585 | foreach(dep IN LISTS deps) |
| 586 | if("${dep}" IS_NEWER_THAN "${gen_outfile}") |
| 587 | set(regen TRUE) |
| 588 | break() |
| 589 | endif() |
| 590 | endforeach() |
| 591 | endif() |
| 592 | endif() |
Adrian Danis | e2e2290 | 2018-03-23 11:41:59 +1100 | [diff] [blame] | 593 | if (regen) |
Adrian Danis | 2bf14a0 | 2018-03-23 11:45:22 +1100 | [diff] [blame] | 594 | message(STATUS "camkes-gen.cmake is out of date. Regenerating...") |
Adrian Danis | e2e2290 | 2018-03-23 11:41:59 +1100 | [diff] [blame] | 595 | execute_process( |
| 596 | # First delete the data structure cache directory as this is a new build |
| 597 | COMMAND |
| 598 | ${CMAKE_COMMAND} -E remove_directory "${CMAKE_CURRENT_BINARY_DIRECTOR}/camkes_pickle" |
| 599 | COMMAND ${camkes_invocation} |
| 600 | RESULT_VARIABLE camkes_gen_error |
| 601 | OUTPUT_VARIABLE camkes_output |
| 602 | ERROR_VARIABLE camkes_output |
| 603 | ) |
Adrian Danis | 2bf14a0 | 2018-03-23 11:45:22 +1100 | [diff] [blame] | 604 | file(WRITE "${invoc_file}" "${camkes_invocation}") |
Adrian Danis | e2e2290 | 2018-03-23 11:41:59 +1100 | [diff] [blame] | 605 | if (camkes_gen_error) |
Kent McLeod | 6eb834f | 2018-07-13 12:02:07 +1000 | [diff] [blame] | 606 | file(REMOVE ${gen_outfile}) |
Adrian Danis | e2e2290 | 2018-03-23 11:41:59 +1100 | [diff] [blame] | 607 | message(FATAL_ERROR "Failed to generate camkes-gen.cmake: ${camkes_output}") |
| 608 | endif() |
| 609 | # Add dependencies |
| 610 | MakefileDepsToList("${deps_file}" deps) |
| 611 | set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${deps}") |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 612 | endif() |
| 613 | # We set a property to indicate that we have done execute_process (which happens during the |
| 614 | # generation phase. This just allows us to do some debugging and detect cases where options |
| 615 | # are changed *after* this point that would have affected the execute_process |
| 616 | set_property(GLOBAL PROPERTY CAMKES_GEN_DONE TRUE) |
Adrian Danis | cf76ead | 2018-03-23 10:57:41 +1100 | [diff] [blame] | 617 | include("${gen_outfile}") |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 618 | endfunction(GenerateCAmkESRootserver) |
| 619 | |
Adrian Danis | 3291bed | 2018-03-08 13:47:17 +1100 | [diff] [blame] | 620 | # Internal helper function for setting camkes component properties |
| 621 | function(AppendCAmkESComponentTarget target_name) |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 622 | cmake_parse_arguments(PARSE_ARGV 1 CAMKES_COMPONENT |
| 623 | "" # Option arguments |
Kent McLeod | cede2f1 | 2018-07-19 18:39:48 +1000 | [diff] [blame] | 624 | "CAKEML_HEAP_SIZE;CAKEML_STACK_SIZE;LINKER_LANGUAGE" # Single arguments |
Adrian Danis | 4b2a850 | 2018-07-02 17:02:27 +1000 | [diff] [blame] | 625 | "SOURCES;CAKEML_SOURCES;INCLUDES;C_FLAGS;LD_FLAGS;LIBS" # Multiple aguments |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 626 | ) |
| 627 | # Declare a target that we will set properties on |
Adrian Danis | 3291bed | 2018-03-08 13:47:17 +1100 | [diff] [blame] | 628 | if (NOT (TARGET "${target_name}")) |
| 629 | add_custom_target("${target_name}") |
Adrian Danis | 810df60 | 2018-03-08 13:44:21 +1100 | [diff] [blame] | 630 | endif() |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 631 | # Get absolute paths for the includes and sources |
| 632 | set(includes "") |
| 633 | set(sources "") |
Adrian Danis | 4b2a850 | 2018-07-02 17:02:27 +1000 | [diff] [blame] | 634 | set(cakeml_sources "") |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 635 | foreach(inc IN LISTS CAMKES_COMPONENT_INCLUDES) |
Kent McLeod | 94369c4 | 2018-07-24 13:46:25 +1000 | [diff] [blame] | 636 | get_absolute_list_source_or_binary(inc "${inc}") |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 637 | list(APPEND includes "${inc}") |
| 638 | endforeach() |
| 639 | foreach(file IN LISTS CAMKES_COMPONENT_SOURCES) |
Kent McLeod | 94369c4 | 2018-07-24 13:46:25 +1000 | [diff] [blame] | 640 | get_absolute_list_source_or_binary(file "${file}") |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 641 | list(APPEND sources "${file}") |
| 642 | endforeach() |
Adrian Danis | 4b2a850 | 2018-07-02 17:02:27 +1000 | [diff] [blame] | 643 | foreach(file IN LISTS CAMKES_COMPONENT_CAKEML_SOURCES) |
Kent McLeod | 94369c4 | 2018-07-24 13:46:25 +1000 | [diff] [blame] | 644 | get_absolute_list_source_or_binary(file "${file}") |
Adrian Danis | 4b2a850 | 2018-07-02 17:02:27 +1000 | [diff] [blame] | 645 | list(APPEND cakeml_sources "${file}") |
| 646 | endforeach() |
Adrian Danis | 3291bed | 2018-03-08 13:47:17 +1100 | [diff] [blame] | 647 | set_property(TARGET "${target_name}" APPEND PROPERTY COMPONENT_INCLUDES "${includes}") |
| 648 | set_property(TARGET "${target_name}" APPEND PROPERTY COMPONENT_SOURCES "${sources}") |
Adrian Danis | 4b2a850 | 2018-07-02 17:02:27 +1000 | [diff] [blame] | 649 | set_property(TARGET "${target_name}" APPEND PROPERTY COMPONENT_CAKEML_SOURCES "${cakeml_sources}") |
Adrian Danis | 3291bed | 2018-03-08 13:47:17 +1100 | [diff] [blame] | 650 | set_property(TARGET "${target_name}" APPEND PROPERTY COMPONENT_C_FLAGS "${CAMKES_COMPONENT_C_FLAGS}") |
| 651 | set_property(TARGET "${target_name}" APPEND PROPERTY COMPONENT_LD_FLAGS "${CAMKES_COMPONENT_LD_FLAGS}") |
| 652 | set_property(TARGET "${target_name}" APPEND PROPERTY COMPONENT_LIBS "${CAMKES_COMPONENT_LIBS}") |
Adrian Danis | 4b2a850 | 2018-07-02 17:02:27 +1000 | [diff] [blame] | 653 | # Overwrite any previous CakeML heap or stack size |
| 654 | if (CAMKES_COMPONENT_CAKEML_HEAP_SIZE) |
| 655 | set_property(TARGET "${target_name}" PROPERTY COMPONENT_CAKEML_HEAP_SIZE "${CAMKES_COMPONENT_CAKEML_HEAP_SIZE}") |
| 656 | endif() |
| 657 | if (CAMKES_COMPONENT_CAKEML_STACK_SIZE) |
| 658 | set_property(TARGET "${target_name}" PROPERTY COMPONENT_CAKEML_STACK_SIZE "${CAMKES_COMPONENT_CAKEML_STACK_SIZE}") |
| 659 | endif() |
Kent McLeod | cede2f1 | 2018-07-19 18:39:48 +1000 | [diff] [blame] | 660 | if (CAMKES_COMPONENT_LINKER_LANGUAGE) |
| 661 | set_property(TARGET "${target_name}" APPEND PROPERTY COMPONENT_LINKER_LANGUAGE "${CAMKES_COMPONENT_LINKER_LANGUAGE}") |
| 662 | endif() |
Adrian Danis | 3291bed | 2018-03-08 13:47:17 +1100 | [diff] [blame] | 663 | endfunction(AppendCAmkESComponentTarget) |
| 664 | |
| 665 | # This is called by CAmkES components to declare information needed for the camkes-gen.cmake to |
| 666 | # actually build them. Can be called multiple times to append additional information. |
| 667 | function(DeclareCAmkESComponent name) |
| 668 | AppendCAmkESComponentTarget(CAmkESComponent_${name} ${ARGN}) |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 669 | endfunction(DeclareCAmkESComponent) |
| 670 | |
Kent McLeod | d786bc2 | 2018-05-09 10:09:05 +1000 | [diff] [blame] | 671 | # Declare built-in components that are constructed from templates and have no source files |
| 672 | DeclareCAmkESComponent(debug_server) |
| 673 | DeclareCAmkESComponent(debug_serial) |
| 674 | |
Adrian Danis | 39b2860 | 2018-03-08 14:19:08 +1100 | [diff] [blame] | 675 | # Extend a particular instantiation of a CAmkES component with additional information. This takes |
| 676 | # similar arguments to DeclareCAmkESComponent and all of the declared includes, flags etc also |
| 677 | # apply to the sources from DeclareCAmkESComponent. The includes provided here will be passed |
| 678 | # prior to the original includes allowing for overriding. This can be called multiple times for the |
| 679 | # same instance to repeatedly extend it. Similar flags will be placed after. |
| 680 | function(ExtendCAmkESComponentInstance component_name instance_name) |
| 681 | AppendCAmkESComponentTarget(CAmkESComponent_${component_name}_instance_${instance_name} ${ARGN}) |
| 682 | endfunction(ExtendCAmkESComponentInstance) |
| 683 | |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 684 | # Helper function for adding additional import paths. Largely it exists to allow list |
| 685 | # files to give relative paths and have them automatically expanded to absolute paths |
| 686 | # We add the import paths to a property, instead of a target, since we need to use |
| 687 | # it in an `execute_process` above, which cannot take generator expressions |
| 688 | function(CAmkESAddImportPath) |
| 689 | # Ensure we haven't generated the camkes-gen.cmake yet |
| 690 | get_property(is_done GLOBAL PROPERTY CAMKES_GEN_DONE) |
| 691 | if (is_done) |
| 692 | message(FATAL_ERROR "Adding import path after camkes-gen.cmake has been generated") |
| 693 | endif() |
| 694 | foreach(arg IN LISTS ARGV) |
Kent McLeod | 94369c4 | 2018-07-24 13:46:25 +1000 | [diff] [blame] | 695 | get_absolute_list_source_or_binary(arg "${arg}") |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 696 | set_property(GLOBAL APPEND PROPERTY CAmkESExtraImportPaths "${arg}") |
| 697 | endforeach() |
| 698 | endfunction(CAmkESAddImportPath) |
| 699 | function(CAmkESAddTemplatesPath) |
| 700 | # Ensure we haven't generated the camkes-gen.cmake yet |
| 701 | get_property(is_done GLOBAL PROPERTY CAMKES_GEN_DONE) |
| 702 | if (is_done) |
| 703 | message(FATAL_ERROR "Adding templates path after camkes-gen.cmake has been generated") |
| 704 | endif() |
| 705 | foreach(arg IN LISTS ARGV) |
Kent McLeod | 94369c4 | 2018-07-24 13:46:25 +1000 | [diff] [blame] | 706 | get_absolute_list_source_or_binary(arg "${arg}") |
Adrian Danis | ec8f709 | 2017-10-16 16:47:58 +1100 | [diff] [blame] | 707 | set_property(GLOBAL APPEND PROPERTY CAmkESTemplatePaths "${arg}") |
| 708 | endforeach() |
| 709 | endfunction(CAmkESAddTemplatesPath) |