Skip to content

Commit

Permalink
CMake: extend file server functions
Browse files Browse the repository at this point in the history
- allow custom type and instance names
- allow passing files for DefineCAmkESVMFileServer(), this avoids
  calling AddToFileServer()
- AddToFileServer() becomes just a light wrapper
- use instance specific name for archive and lib

Signed-off-by: Axel Heider <[email protected]>
  • Loading branch information
Axel Heider committed Mar 29, 2023
1 parent a8a1a63 commit a668138
Showing 1 changed file with 193 additions and 37 deletions.
230 changes: 193 additions & 37 deletions camkes_vm_helpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -63,22 +63,160 @@ function(DeclareCAmkESVM init_component)
)
endfunction(DeclareCAmkESVM)

#
# Function defines a CAmkESVMFileServer using the declared fileserver images
# and fileserver dependencies. These images are placed into a CPIO archive.
#
# Parameters:
#
# TYPE <type>
# Type of the file server CAmkES component.
# Optional, defaults to "FileServer"
#
# INSTANCE <name>
# Instance name of the file server CAmkES component.
# Optional, defaults to "fserv"
#
# FILES <item>[ <item>[...]]
# The files to be added. Each item has the form [<NAME>:]<FILE_NAME>, where
# the optional <NAME> allows using a different name for the file in the
# archive than on the disk. The build will abort if <FILE_NAME> is not found.
# Each item can either be a single file item or a CMake list of items (such a
# CMake list is basically a string with elements separated by ';'). This
# allows building lists of files in advance, which may contain different files
# for different configurations. An empty string as item is also explicitly
# allowed for convenience reasons. Thus supports cases where a an item does
# not exist in every configuration and the respective CMake variable used for
# the item is just left empty.
#
# DEPENDS <dep>[ <dep>[...]]
# Any additional dependencies for the file/image the caller is adding to the
# file server
#
#
function(DefineCAmkESVMFileServer)
# Retrieve defined kernel images, rootfs images and extraction dependencies
get_target_property(fileserver_images vm_fserver_config FILES)
get_target_property(fileserver_deps vm_fserver_config DEPS)
# Build CPIO archive given the defined kernel and rootfs images
set(CPIO_ARCHIVE "file_server_archive.o")

cmake_parse_arguments(
PARSE_ARGV
0
PARAM # variable prefix
"" # option arguments
"TYPE;INSTANCE" # optional single value arguments
"FILES;DEPENDS" # optional multi value arguments
)

if(PARAM_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Unknown arguments: ${PARAM_UNPARSED_ARGUMENTS}")
endif()

if(NOT PARAM_TYPE)
set(PARAM_TYPE "FileServer")
endif()

if(NOT PARAM_INSTANCE)
set(PARAM_INSTANCE "fserv")
endif()

if(PARAM_DEPENDS)
set_property(
TARGET vm_fserver_config
APPEND
PROPERTY DEPS_${PARAM_INSTANCE} ${PARAM_DEPENDS}
)
endif()

foreach(element IN LISTS PARAM_FILES)
foreach(item IN LISTS element) # [<CPIO_NAME>:]<FILENAME>
if(NOT item)
continue()
endif()
string(
REGEX
MATCH
"^([^:]+)(:([^:]+))?$"
cpio_item
"${item}"
)
if(NOT cpio_item)
message(FATAL_ERROR "invalid paramete format: '${item}'")
endif()
if(CMAKE_MATCH_3)
set(CPIO_NAME "${CMAKE_MATCH_1}")
set(FILE_NAME "${CMAKE_MATCH_3}")
else()
set(FILE_NAME "${CMAKE_MATCH_1}")
get_filename_component(CPIO_NAME "${FILE_NAME}" NAME)
endif()
# For legacy reasons, we still call AddToFileServer() here. It will
# simplify things a lot, if this function is removed completely. It
# is no longer needed, because we accept lists of files now., which
# the caller is supposed to build then. For now, AddToFileServer()
# is just a light wrapper that build such a list. Thus, there is no
# need to pass dependencies from PARAM_DEPENDS here, have added them
# above already.
AddToFileServer("${CPIO_NAME}" "${FILE_NAME}" INSTANCE "${PARAM_INSTANCE}")
endforeach()
endforeach()

# now process the file/deps list
get_target_property(files vm_fserver_config FILES_${PARAM_INSTANCE})
if(NOT files) # this also catches "files-NOTFOUND" if property is not set
set(files "")
endif()
get_target_property(deps vm_fserver_config DEPS_${PARAM_INSTANCE})
if(NOT deps) # this also catches "deps-NOTFOUND" if property is not set
set(deps "")
endif()

set(INST_BIN_DIR "${CMAKE_CURRENT_BINARY_DIR}/${PARAM_INSTANCE}")

set(CPIO_FILES "")
foreach(item IN LISTS files) # <CPIO_NAME>:<FILENAME>
string(
REGEX
MATCH
"^([^:]+):([^:]+)$"
cpio_item
"${item}"
)
if(NOT cpio_item)
message(FATAL_ERROR "invalid CPIO file format: '${item}'")
endif()
set(CPIO_NAME "${CMAKE_MATCH_1}")
set(FILE_NAME "${CMAKE_MATCH_2}")
set(CPIO_FILE "${INST_BIN_DIR}/files/${CPIO_NAME}")
add_custom_command(
OUTPUT "${CPIO_FILE}"
COMMENT "copy: ${FILE_NAME} -> ${CPIO_FILE}"
COMMAND
${CMAKE_COMMAND} -E copy "${FILE_NAME}" "${CPIO_FILE}"
VERBATIM
DEPENDS ${FILE_NAME} ${deps}
)
# There is no need to create an explicit target for the command above,
# the archive creation depends on all files in CPIO_FILES, where the
# command above is the creation rule for each one.
list(APPEND CPIO_FILES "${CPIO_FILE}")
endforeach()

# Build CPIO archive. It implicitly depends on all files in CPIO_FILES,
# which have their own dependencies each from above. So we don't have any
# additional explicit dependencies here.
# Unfortunately MakeCPIO() support plain file names only and does not
# support paths. Thus, the archive will be created in the built output root
# folder, where using INST_BIN_DIR would be a bit cleaner actually.
set(CPIO_ARCHIVE "${PARAM_INSTANCE}_cpio_archive.o")
include(cpio)
MakeCPIO("${CPIO_ARCHIVE}" "${fileserver_images}" DEPENDS "${fileserver_deps}")
# Build a library from the CPIO archive
set(FILESERVER_LIB "fileserver_cpio")
MakeCPIO("${CPIO_ARCHIVE}" "${CPIO_FILES}")

# Build a library from the CPIO archive. Ensure the lib has a unique name
# within the project, as there could be more than one file server.
set(FILESERVER_LIB "${PARAM_INSTANCE}_file_archive_cpio")
add_library("${FILESERVER_LIB}" STATIC EXCLUDE_FROM_ALL "${CPIO_ARCHIVE}")
set_property(TARGET "${FILESERVER_LIB}" PROPERTY LINKER_LANGUAGE C)
# Add the CPIO-library to the FileServer component
ExtendCAmkESComponentInstance(FileServer fserv LIBS "${FILESERVER_LIB}")
ExtendCAmkESComponentInstance("${PARAM_TYPE}" "${PARAM_INSTANCE}" LIBS "${FILESERVER_LIB}")

endfunction(DefineCAmkESVMFileServer)

# Function for declaring the CAmkESVM root server. Taking the camkes application
Expand All @@ -105,40 +243,58 @@ function(DeclareCAmkESVMRootServer camkes_config)
endfunction(DeclareCAmkESVMRootServer)

# Function for adding a file/image to the vm file server.
# filename_pref: The name the caller wishes to use to reference the file in the CPIO archive. This
# corresponds with the name set in the 'kernel_image' camkes variable for a given instance vm.
# file_dest: The location of the file/image the caller is adding to the file server
# DEPENDS: Any additional dependencies for the file/image the caller is adding to the
# file server
#
# Parameters:
#
# <filename_pref>
# The name the caller wishes to use to reference the file in the CPIO archive.
# This corresponds with the name set in the 'kernel_image' camkes variable for
# a given instance vm.
#
# <file_dest>
# The location of the file/image the caller is adding to the file server
#
# INSTANCE <name>
# Instance name of the file server CAmkES component.
# Optional, defaults to "fserv"
#
# DEPENDS <dep>[ <dep>[...]]
# Any additional dependencies for the file/image the caller is adding to the
# file server
#
function(AddToFileServer filename_pref file_dest)
# Get any existing dependencies when adding the image into the file server archive
cmake_parse_arguments(PARSE_ARGV 2 CAMKES_FILESERVER "" "" "DEPENDS")
if(NOT "${CAMKES_FILESERVER_UNPARSED_ARGUMENTS}" STREQUAL "")
message(FATAL_ERROR "Unknown arguments to AddToFileServer")
endif()
# Create a copy of the file in the binary directory to the callers
# preferred name
add_custom_command(
OUTPUT file_server/${filename_pref}
COMMAND
${CMAKE_COMMAND} -E copy "${file_dest}"
"${CMAKE_CURRENT_BINARY_DIR}/file_server/${filename_pref}"
VERBATIM
DEPENDS ${file_dest} ${CAMKES_FILESERVER_DEPENDS}
)
#Create custom target for copy command
add_custom_target(
copy_${filename_pref}
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/file_server/${filename_pref}"

cmake_parse_arguments(
PARSE_ARGV
2
PARAM # variable prefix
"" # option arguments
"INSTANCE" # optional single value arguments
"DEPENDS" # optional multi value arguments
)
# Store the rootfs file location. Used when building the CPIO at a later stage

if(PARAM_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Unknown arguments: ${PARAM_UNPARSED_ARGUMENTS}")
endif()

if(NOT PARAM_INSTANCE)
set(PARAM_INSTANCE "fserv")
endif()

set_property(
TARGET vm_fserver_config
APPEND
PROPERTY FILES "${CMAKE_CURRENT_BINARY_DIR}/file_server/${filename_pref}"
PROPERTY FILES_${PARAM_INSTANCE} "${filename_pref}:${file_dest}"
)
# Append soft link dependency
set_property(TARGET vm_fserver_config APPEND PROPERTY DEPS "copy_${filename_pref}")

if(PARAM_DEPENDS)
set_property(
TARGET vm_fserver_config
APPEND
PROPERTY DEPS_${PARAM_INSTANCE} ${PARAM_DEPENDS}
)
endif()

endfunction(AddToFileServer)

# Function for decompressing/extracting a vmlinux file from a given kernel image
Expand Down

0 comments on commit a668138

Please sign in to comment.