# ##############################################################################
# cmake/nuttx_syscall_utils.cmake
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
# license agreements. See the NOTICE file distributed with this work for
# additional information regarding copyright ownership. The ASF licenses this
# file to you under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
#
# ##############################################################################
# The parse_syscall_csv function parses a list of CSV files that contain all the
# system calls prototypes. it returns a list of expected file names with `.c` as
# the suffix. Usage: parse_syscall_csv(OUTPUT syscall1.csv syscall2.csv ...)
function(parse_syscall_csv OUTPUT_VAR)
# Initialize empty result list
set(RESULT_LIST)
# Process each input CSV file
foreach(CSV_FILE ${ARGN})
# Read CSV file and store each line as a list item
file(STRINGS ${CSV_FILE} SYSCALLS)
# Extract first column (before comma) from each line
list(TRANSFORM SYSCALLS REPLACE "^\"([^,]+)\",.+" "\\1")
# Append .c to each item
list(TRANSFORM SYSCALLS APPEND ".c")
# Append to our result list
list(APPEND RESULT_LIST ${SYSCALLS})
endforeach()
# Remove any potential duplicates
list(REMOVE_DUPLICATES RESULT_LIST)
# Store the result in the output variable
set(${OUTPUT_VAR}
${RESULT_LIST}
PARENT_SCOPE)
endfunction()
# This function parses will generate the system call files for the given
# syscalls parsed from the CSV files.
#
# MODE can be either STUB, PROXY or WRAP.
#
# OUTPATH is the output directory.
#
# ALL_SYSCALLS is a list of all the system calls to generate. They are suffixed
# by ".c"
#
# CSV_FILES is a list of all the CSV files that will feed to the mksyscall tool.
#
# Usage: generate_syscall_files(OUTPUT_VAR GENERATED_PROXIES MODE PROXY OUTPATH
# "${CMAKE_CURRENT_BINARY_DIR}" ALL_SYSCALLS ${SYSCALLS} CSV_FILES
# ${CMAKE_CURRENT_LIST_DIR}/../syscall.csv)
function(generate_syscall_files)
# Parse function arguments
set(OPTIONS)
set(ONEVALUEARG OUTPUT_VAR OUTPATH MODE)
set(MULTIVALUEARGS ALL_SYSCALLS CSV_FILES)
cmake_parse_arguments(ARG "${OPTIONS}" "${ONEVALUEARG}" "${MULTIVALUEARGS}"
${ARGN})
# Validate arguments
if(NOT ARG_OUTPUT_VAR)
message(FATAL_ERROR "OUTPUT_VAR argument is required")
endif()
if(NOT ARG_OUTPATH)
set(ARG_OUTPATH "${CMAKE_CURRENT_BINARY_DIR}")
endif()
if(NOT ARG_MODE MATCHES "^(STUB|PROXY|WRAP)$")
message(FATAL_ERROR "MODE must be either STUB, PROXY or WRAP")
endif()
if(NOT ARG_CSV_FILES)
message(FATAL_ERROR "At least one CSV file must be specified")
endif()
if(NOT ARG_ALL_SYSCALLS)
message(FATAL_ERROR "At least one syscall must be specified")
endif()
if(ARG_MODE STREQUAL "STUB")
list(TRANSFORM ARG_ALL_SYSCALLS PREPEND "${ARG_OUTPATH}/STUB_")
set(MKSYSCALL_MODE "-s")
elseif(ARG_MODE STREQUAL "PROXY")
list(TRANSFORM ARG_ALL_SYSCALLS PREPEND "${ARG_OUTPATH}/PROXY_")
set(MKSYSCALL_MODE "-p")
else()
list(TRANSFORM ARG_ALL_SYSCALLS PREPEND "${ARG_OUTPATH}/WRAP_")
set(MKSYSCALL_MODE "-w")
endif()
# Generate the custom command for all files
add_custom_command(
OUTPUT ${ARG_ALL_SYSCALLS}
COMMAND ${CMAKE_BINARY_DIR}/bin_host/mksyscall ${MKSYSCALL_MODE}
${ARG_CSV_FILES} ${ARG_TYPE_REFERENCES}
WORKING_DIRECTORY ${ARG_OUTPATH}
DEPENDS mksyscall
COMMENT "Generating system call ${ARG_MODE}s")
# Set output variable
set(${ARG_OUTPUT_VAR}
${ARG_ALL_SYSCALLS}
PARENT_SCOPE)
endfunction()