1# 2# Copyright 2017, 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 13cmake_minimum_required(VERSION 3.5.1) 14 15project(rumprun NONE) 16 17if(KernelArchX86) 18 if(Kernel64) 19 set(rumprun_arch "x86_64") 20 set(rumprun_sel4_arch "${rumprun_arch}") 21 set(rumprun_tuple "x86_64-rumprun-netbsd") 22 list(APPEND RUMPKERNEL_FLAGS -F ACLFLAGS=-m64) 23 else() 24 set(rumprun_arch "i486") 25 set(rumprun_sel4_arch "i386") 26 set(rumprun_tuple "i486-rumprun-netbsdelf") 27 list( 28 APPEND 29 RUMPKERNEL_FLAGS 30 -F 31 ACLFLAGS=-m32 32 -F 33 ACLFLAGS=-fno-pic 34 ) 35 endif() 36 set(rumprun_tool_prefix "${rumprun_sel4_arch}--netbsd") 37elseif(KernelArchARM) 38 if(Kernel32) 39 set(rumprun_arch "arm") 40 set(rumprun_sel4_arch "aarch32") 41 set(rumprun_tuple "arm-rumprun-netbsdelf-eabi") 42 set(rumprun_tool_prefix "arm--netbsdelf-eabi") 43 # Suppress warnings that would otherwise stop the compilation 44 list(APPEND RUMPKERNEL_FLAGS -F CWARNFLAGS=-w) 45 endif() 46 # Append -march flag to ensure Rump is built properly for the specific CPU arch 47 list(APPEND RUMPKERNEL_FLAGS -F ACFLAGS='-march=${KernelArmArmV}') 48else() 49 # Stop processing this file the target platform isn't supported. 50 return() 51endif() 52 53# Build for release (Without debug symbols) 54if("${CMAKE_BUILD_TYPE}" IN_LIST "Release;MinSizeRel") 55 list(APPEND RUMPKERNEL_FLAGS -r) 56endif() 57 58# Ignore errors that cause compile to fail for GCC 8 59if(NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS 8.0) 60 list( 61 APPEND 62 RUMPKERNEL_FLAGS 63 -F 64 CFLAGS='-Wno-cast-function-type 65 -Wno-packed-not-aligned 66 -Wno-tautological-compare' 67 ) 68endif() 69 70set(configure_string "") 71config_string(RumprunTMPFSNumMiB RUMPRUN_TMPFS_NUM_MiB "Set this to the size of memory \ 72 you want to back the tmpfs at /tmp." DEFAULT 1 UNQUOTE) 73 74config_string(RumprunCookfsDir RUMPRUN_COOKFS_DIR "cookfs directory" DEFAULT " ") 75 76config_option( 77 UseLargePages 78 USE_LARGE_PAGES 79 "Use large pages for rumprun backing memory. This reduces the amount of book keeping required \ 80 to track the pages created and also reduces initialisation time. However, mprotect depends on \ 81 4k pages in order to remap the pages with new permissions. Thus, enabling large pages results in \ 82 disabling the stack guard page functionality. Use at own risk." 83 DEFAULT 84 OFF 85) 86 87add_config_library(rumprun "${configure_string}") 88 89# Only set FULLDIRPATH if the COOKFS dir is set to something proper 90if(NOT ${RumprunCookfsDir} STREQUAL " ") 91 set(FULLDIRPATH ${CMAKE_SOURCE_DIR}/${RumprunCookfsDir}) 92 file(GLOB_RECURSE FULLDIR_DEPS ${FULLDIRPATH}/*) 93 94endif() 95 96file(GLOB_RECURSE ROOTFS_DEPS lib/librumprunfs_base/rootfs/*) 97 98add_custom_command( 99 OUTPUT build-temp/.librumrunfs.stamp 100 COMMAND 101 mkdir -p ${rumprun_sel4_arch}/sel4-obj/rootfs/ && rsync -av ${FULLDIRPATH} 102 ${CMAKE_CURRENT_SOURCE_DIR}/lib/librumprunfs_base/rootfs/ 103 ${rumprun_sel4_arch}/sel4-obj//rootfs/ 104 --delete 105 COMMAND touch ${CMAKE_CURRENT_BINARY_DIR}/build-temp/.librumrunfs.stamp 106 VERBATIM 107 DEPENDS ${ROOTFS_DEPS} ${FULLDIR_DEPS} 108 COMMENT "[Copying files to rootfs: ${FULLDIRPATH}]" 109) 110 111file(RELATIVE_PATH BUILD_DIRECTORY_RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) 112 113set( 114 RR_ENV_VARS 115 PATH=$ENV{PATH} 116 SEL4_ARCH=${rumprun_sel4_arch} 117 RUMPRUN_BASE_DIR=${CMAKE_CURRENT_SOURCE_DIR} 118 RUMP_BUILD_DIR=${CMAKE_CURRENT_BINARY_DIR} 119 CC=${CMAKE_C_COMPILER} 120 CXX=${CMAKE_CXX_COMPILER} 121) 122 123set( 124 RUMPRUN_SEL4LIBS 125 sel4 126 sel4runtime 127 sel4muslcsys 128 sel4allocman 129 platsupport 130 sel4platsupport 131 platsupport 132 sel4serialserver 133 sel4sync 134 sel4utils 135 sel4vspace 136 sel4vka 137 sel4simple-default 138 sel4simple 139 sel4debug 140 utils 141 cpio 142 elf 143) 144 145set(LDFLAGS_SEL4 "") 146set(CFLAGS_SEL4 "") 147foreach(RUMPRUN_SEL4LIB IN LISTS RUMPRUN_SEL4LIBS) 148 string( 149 APPEND CFLAGS_SEL4 150 " -I$<JOIN:$<TARGET_PROPERTY:${RUMPRUN_SEL4LIB},INTERFACE_INCLUDE_DIRECTORIES>, -I>" 151 ) 152 string(APPEND LDFLAGS_SEL4 " -L$<TARGET_FILE_DIR:${RUMPRUN_SEL4LIB}> -l${RUMPRUN_SEL4LIB}") 153endforeach() 154string(APPEND LDFLAGS_SEL4 " $<TARGET_PROPERTY:muslc_imported,IMPORTED_LOCATION>") 155string(APPEND CFLAGS_SEL4 " -I${CMAKE_CURRENT_SOURCE_DIR}/platform/sel4/include/sel4") 156 157string( 158 APPEND CFLAGS_SEL4 159 " -I$<JOIN:$<TARGET_PROPERTY:sel4_autoconf,INTERFACE_INCLUDE_DIRECTORIES>, -I>" 160) 161string( 162 APPEND CFLAGS_SEL4 163 " -I$<JOIN:$<TARGET_PROPERTY:rumprun_Config,INTERFACE_INCLUDE_DIRECTORIES>, -I>" 164) 165 166# Create a custom target that invokes a rumprun build command from ./build-rr.sh 167# command_name is the name of the command to run 168# command_description is the command description printed out by ninja 169# There are optional arguments: 170# PHONY will cause the target to always be stale so that it will always rerun the command 171# TARGET_NAME overrides the target name. Otherwise the command_name is used as the target name 172# RUMP_TARGETS are 173# FILE_DEPS are files that get passed to DEPENDS of the internal custom_command definition 174# ENV_VARS are extra environment variables that get set when build-rr.sh is called 175function(CreateRumprunBuildCommand command_name command_description) 176 cmake_parse_arguments( 177 PARSE_ARGV 178 2 179 RUMP_BUILD 180 "PHONY" 181 "TARGET_NAME" 182 "RUMP_TARGETS;FILE_DEPS;ENV_VARS;OUTPUT_FILES" 183 ) 184 if(NOT "${RUMP_BUILD_UNPARSED_ARGUMENTS}" STREQUAL "") 185 message(FATAL_ERROR "Unknown arguments to CreateRumprunBuildCommand") 186 endif() 187 188 # Suppress rump build output 189 # TODO find a way to disable this when the verbose flag is passed to ninja 190 set(QUIET -q -q) 191 192 # Create command line that will be invoked 193 set( 194 BUILD_RR_CMD_LINE 195 ${CMAKE_COMMAND} 196 -E 197 env 198 ${RR_ENV_VARS} 199 ${RUMP_BUILD_ENV_VARS} 200 ./build-rr.sh 201 ${QUIET} 202 -d 203 ${BUILD_DIRECTORY_RELATIVE}/${rumprun_sel4_arch}/rumprun 204 -o 205 ${BUILD_DIRECTORY_RELATIVE}/${rumprun_sel4_arch}/sel4-obj 206 sel4 207 ${command_name} 208 -- 209 ${RUMPKERNEL_FLAGS} 210 ) 211 212 # Add stampfiles from other rump targets to rump_deps list to be used in custom_command depends field 213 foreach(RUMP_TARGET IN LISTS RUMP_BUILD_RUMP_TARGETS) 214 get_target_property(stamp ${RUMP_TARGET} STAMP_FILE) 215 list(APPEND rump_deps ${stamp}) 216 endforeach() 217 218 # We support overriding the target name if neccessary 219 set(STAMP build-temp/${command_name}.stamp) 220 Set(TARGET_NAME ${command_name}) 221 if(NOT "${RUMP_BUILD_TARGET_NAME}" STREQUAL "") 222 set(TARGET_NAME ${RUMP_BUILD_TARGET_NAME}) 223 set(STAMP build-temp/${RUMP_BUILD_TARGET_NAME}.stamp) 224 endif() 225 226 # custom_command doesn't have a BUILD_ALWAYS option, so we emulate it by creating a phony dependency 227 # That is then deleted at the end of each build. This is used when we cannot correctly track dependencies 228 if(RUMP_BUILD_PHONY) 229 set(STAMP_PHONY ${CMAKE_CURRENT_BINARY_DIR}/build-temp/${TARGET_NAME}.phony.stamp) 230 set(TOUCHSTAMP_PHONY ${CMAKE_COMMAND} -E remove ${STAMP_PHONY}) 231 add_custom_command( 232 OUTPUT ${STAMP_PHONY} 233 COMMAND 234 ${CMAKE_COMMAND} -E touch ${STAMP_PHONY} 235 COMMENT "[Calling phony rule]" 236 ) 237 endif() 238 239 # Create custom command. It deletes the PHONY stampfile if one exists, runs the rump command and then touches the output ${STAMP} file 240 add_custom_command( 241 OUTPUT ${STAMP} ${RUMP_BUILD_OUTPUT_FILES} 242 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 243 COMMAND ${TOUCHSTAMP_PHONY} 244 COMMAND ${BUILD_RR_CMD_LINE} 245 COMMAND 246 ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${STAMP} 247 DEPENDS 248 ${RUMP_BUILD_RUMP_TARGETS} 249 ${rump_deps} 250 ${RUMP_BUILD_FILE_DEPS} 251 ${STAMP_PHONY} 252 COMMENT "[Calling ./build-rr.sh - ${command_description}]" 253 ) 254 255 # Add Target for custom_command. 256 add_custom_target( 257 ${TARGET_NAME} 258 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${STAMP} ${RUMP_BUILD_RUMP_TARGETS} 259 ) 260 261 # Set STAMP_FILE property on custom target so that other RUMP_TARGETS can depend on it 262 set_target_properties(${TARGET_NAME} PROPERTIES STAMP_FILE ${CMAKE_CURRENT_BINARY_DIR}/${STAMP}) 263 264endfunction() 265 266# Glob all of the different files in the rumprun sources 267# We use a glob as it isn't practical to keep a full list of files up to date 268file(GLOB APP_TOOLS_FILES app-tools/*) 269file(GLOB_RECURSE SEL4_PLATFORM_FILES platform/sel4/*) 270 271set( 272 RUMPRUN_GLOB_NETBSD_SOURCES OFF 273 CACHE BOOL "This flag causes CMake to add lots of source files to its dependency lists 274 which noticeably slows down its configuration times (up to 4 times slower). 275 When not making changes in the rumprun directory, it is likely not necessary 276 to have this enabled." 277) 278if(RUMPRUN_GLOB_NETBSD_SOURCES) 279 file(GLOB_RECURSE RUMPRUN_LIB_FILES lib/*) 280 file(GLOB_RECURSE RUMPRUN_INCLUDE_FILES include/*) 281 file(GLOB_RECURSE SRC_NETBSD_FILES src-netbsd/*) 282 file(GLOB_RECURSE BUILD_RR_FILES buildrump.sh/*) 283endif() 284 285# Create rumprun build targets 286CreateRumprunBuildCommand(tools "Rump kernel tools" FILE_DEPS ${BUILD_RR_FILES} ${SRC_NETBSD_FILES}) 287 288CreateRumprunBuildCommand(toolsconfig "Extra Rumprun tools configuration" RUMP_TARGETS tools) 289 290CreateRumprunBuildCommand(rumplibs "Rump kernel modules" RUMP_TARGETS toolsconfig) 291 292CreateRumprunBuildCommand( 293 apptools 294 "Rumprun app toolchains" 295 RUMP_TARGETS 296 rumplibs 297 FILE_DEPS 298 ${APP_TOOLS_FILES} 299) 300 301CreateRumprunBuildCommand(userspace "Rumprun userspace libraries" RUMP_TARGETS rumplibs) 302 303CreateRumprunBuildCommand( 304 platformtoplevel 305 "platform toplevel" 306 RUMP_TARGETS 307 userspace 308 toolsconfig 309 FILE_DEPS 310 ${RUMPRUN_LIB_FILES} 311 ${CMAKE_CURRENT_SOURCE_DIR}/platform/makepseudolinkstubs.sh 312) 313 314CreateRumprunBuildCommand( 315 platformheaders 316 "Platform headers" 317 RUMP_TARGETS 318 toolsconfig 319 FILE_DEPS 320 ${SEL4_PLATFORM_FILES} 321 ${RUMPRUN_LIB_FILES} 322 ${RUMPRUN_INCLUDE_FILES} 323) 324 325CreateRumprunBuildCommand( 326 platformlibs 327 "Rumprun platform libraries" 328 RUMP_TARGETS 329 platformheaders 330 rumplibs 331 userspace 332 platformtoplevel 333 FILE_DEPS 334 ${CMAKE_CURRENT_BINARY_DIR}/build-temp/.librumrunfs.stamp 335 ${RUMPRUN_LIB_FILES} 336 ${RUMPRUN_INCLUDE_FILES} 337) 338 339# platformobj, rump_pci, and extralibs targets all depend on seL4 header files that we can't easily track 340# therefore these rules need to be marked as PHONY and rerun everytime 341CreateRumprunBuildCommand( 342 platformobj 343 "Platform object files" 344 PHONY 345 ENV_VARS 346 "LDFLAGS_SEL4=${LDFLAGS_SEL4}" 347 "CRTOBJFILES_SEL4=${CRTObjFiles}" 348 "FINOBJFILES_SEL4=${FinObjFiles}" 349 "CFLAGS_SEL4=${CFLAGS_SEL4}" 350 RUMP_TARGETS 351 userspace 352 platformheaders 353 rumplibs 354 FILE_DEPS 355 ${SEL4_PLATFORM_FILES} 356 ${RUMPRUN_LIB_FILES} 357 ${RUMPRUN_INCLUDE_FILES} 358 ${RUMPRUN_SEL4LIBS} 359 muslc 360 OUTPUT_FILES 361 ${CMAKE_CURRENT_BINARY_DIR}/${rumprun_sel4_arch}/sel4-obj/rumprun-intermediate.o 362) 363 364CreateRumprunBuildCommand( 365 extralibs 366 "extra rump kernel modules" 367 PHONY 368 ENV_VARS 369 "CFLAGS_SEL4=${CFLAGS_SEL4}" 370 RUMP_TARGETS 371 platformheaders 372 rumplibs 373 FILE_DEPS 374 ${SEL4_PLATFORM_FILES} 375 ${RUMPRUN_LIB_FILES} 376 ${RUMPRUN_INCLUDE_FILES} 377 ${SRC_NETBSD_FILES} 378 ${RUMPRUN_SEL4LIBS} 379 muslc 380) 381 382CreateRumprunBuildCommand( 383 platforminstall 384 "Install Platform files" 385 RUMP_TARGETS 386 platformlibs 387 platformobj 388 extralibs 389) 390 391CreateRumprunBuildCommand( 392 pci 393 "PCI rump kernel modules" 394 PHONY 395 TARGET_NAME 396 rump_pci 397 ENV_VARS 398 "CFLAGS_SEL4=${CFLAGS_SEL4}" 399 RUMP_TARGETS 400 platformheaders 401 rumplibs 402 FILE_DEPS 403 ${SEL4_PLATFORM_FILES} 404 ${RUMPRUN_LIB_FILES} 405 ${RUMPRUN_INCLUDE_FILES} 406 ${SRC_NETBSD_FILES} 407 ${RUMPRUN_SEL4LIBS} 408 muslc 409) 410 411# Install commands install artifacts to the rumprun install directory. Top level is everything required to build rumprun applications 412# bottom level is everything required to link a rumprun app with the bottom level platform libraries and basefiles. 413CreateRumprunBuildCommand( 414 install 415 "install toplevel" 416 RUMP_TARGETS 417 userspace 418 apptools 419 platformtoplevel 420 TARGET_NAME 421 rumprun_install_toplevel 422) 423CreateRumprunBuildCommand( 424 install 425 "install bottomlevel" 426 PHONY 427 RUMP_TARGETS 428 platforminstall 429 rump_pci 430 rumplibs 431 rumprun_install_toplevel 432 TARGET_NAME 433 rumprun_install_bottomlevel 434) 435 436# Add toplevel and bottomlevel libraries. The IMPORTED_LOCATION property is important because it forces the downstream dependencies 437# to be rebuilt if any of the rumprun commands have been run. This is also why these are libraries and not custom targets. 438add_library(rumprun_toplevel_support STATIC IMPORTED GLOBAL) 439add_dependencies(rumprun_toplevel_support rumprun_install_toplevel) 440get_target_property(stamp rumprun_install_toplevel STAMP_FILE) 441set_property(TARGET rumprun_toplevel_support PROPERTY IMPORTED_LOCATION "${stamp}") 442 443add_library(rumprun_bottomlevel_support STATIC IMPORTED GLOBAL) 444add_dependencies(rumprun_bottomlevel_support rumprun_install_bottomlevel rumprun_toplevel_support) 445get_target_property(stamp rumprun_install_bottomlevel STAMP_FILE) 446set_property(TARGET rumprun_bottomlevel_support PROPERTY IMPORTED_LOCATION "${stamp}") 447 448# Add interface library to make seL4 rumprun headers available to loader apps 449add_library(rumprun INTERFACE) 450add_dependencies(rumprun rumprun_bottomlevel_support) 451target_include_directories(rumprun INTERFACE "platform/sel4/include/sel4") 452 453# TODO: Figure out way to better handle target properties for install locations. We currently hard code them as it would be too 454# convoluted to pull them out of the generated config files and use in generator expressions. 455set_property( 456 TARGET rumprun_toplevel_support 457 PROPERTY RUMPRUN_TOOLCHAIN_PATH "${CMAKE_CURRENT_BINARY_DIR}/${rumprun_sel4_arch}/rumprun/bin" 458) 459set_property( 460 TARGET rumprun_toplevel_support 461 PROPERTY 462 RUMPRUN_TOOLCHAIN_CMAKE 463 "${CMAKE_CURRENT_BINARY_DIR}/${rumprun_sel4_arch}/rumprun/rumprun-${rumprun_arch}/share/${rumprun_tuple}-toolchain.cmake" 464) 465set_property(TARGET rumprun_toplevel_support PROPERTY RUMPRUN_TOOLCHAIN_TUPLE "${rumprun_tuple}") 466set_property( 467 TARGET rumprun_bottomlevel_support 468 PROPERTY RUMPRUN_BASEDIR "${CMAKE_CURRENT_BINARY_DIR}/${rumprun_sel4_arch}/sel4-obj" 469) 470 471set( 472 RUMPRUN_TOOLS_DIR "${CMAKE_CURRENT_BINARY_DIR}/${rumprun_sel4_arch}/sel4-obj/rumptools/bin" 473 CACHE INTERNAL "" 474 FORCE 475) 476set( 477 RUMPRUN_BASEDIR "${CMAKE_CURRENT_BINARY_DIR}/${rumprun_sel4_arch}/sel4-obj" 478 CACHE INTERNAL "" 479 FORCE 480) 481set(RUMPRUN_TOOLS_PREFIX "${rumprun_tool_prefix}" CACHE INTERNAL "" FORCE) 482set( 483 RUMPRUN_TOOLCHAIN_PATH "${CMAKE_CURRENT_BINARY_DIR}/${rumprun_sel4_arch}/rumprun/bin" 484 CACHE INTERNAL "" 485 FORCE 486) 487 488add_library(rumprun_intermediate_file STATIC IMPORTED GLOBAL) 489target_link_libraries( 490 rumprun_intermediate_file 491 INTERFACE 492 rumprun 493 ${RUMPRUN_SEL4LIBS} 494 rumprun_Config 495 sel4_autoconf 496) 497set_property( 498 TARGET rumprun_intermediate_file 499 PROPERTY 500 IMPORTED_LOCATION 501 "${CMAKE_CURRENT_BINARY_DIR}/${rumprun_sel4_arch}/sel4-obj/rumprun-intermediate.o" 502) 503add_dependencies(rumprun_intermediate_file platformobj) 504