# ############################################################################## # cmake/nuttx_add_application.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. # # ############################################################################## include(nuttx_parse_function_args) define_property( GLOBAL PROPERTY NUTTX_APPS_LIBRARIES BRIEF_DOCS "NuttX application libs" FULL_DOCS "List of all NuttX application libraries") # ~~~ # nuttx_add_application # # Description: # Declares a NuttX application as a static library. The corresponding target # will be named apps_. The first entry into the source list is assumed # to be the one containing main() and will thus receive a -Dmain=app_main # definition during build. # # Usage: # nuttx_add_application( NAME [ PRIORITY ] # [ STACKSIZE ] [ COMPILE_FLAGS ] # [ INCLUDE_DIRECTORIES ] [ DEPENDS ] # [ DEFINITIONS ] [ MODULE ] [ SRCS ] ) # # Parameters: # NAME : unique name of application # PRIORITY : priority # STACKSIZE : stack size # COMPILE_FLAGS : compile flags # INCLUDE_DIRECTORIES : include directories # DEPENDS : targets which this module depends on # DEFINITIONS : optional compile definitions # MODULE : if "m", build module (designed to received # CONFIG_ value) # SRCS : source files # NO_MAIN_ALIAS : do not add a main=_main alias(*) # # (*) This is only really needed in convoluted cases where a single .c file # contains differently named _main() entries for different . This # situation should really be changed into a separate main file per actual app # using a shared user library. # # Example: # nuttx_add_application( # NAME test # SRCS file.cpp # STACKSIZE 1024 # DEPENDS nshlib # MODULE ${CONFIG_EXAMPLES_TEST}) # ~~~ function(nuttx_add_application) # parse arguments into variables nuttx_parse_function_args( FUNC nuttx_add_application ONE_VALUE NAME PRIORITY STACKSIZE MODULE MULTI_VALUE COMPILE_FLAGS INCLUDE_DIRECTORIES SRCS DEPENDS DEFINITIONS OPTIONS NO_MAIN_ALIAS REQUIRED NAME ARGN ${ARGN}) # create target if(SRCS) if(MODULE AND ("${MODULE}" STREQUAL "m") OR CONFIG_BUILD_KERNEL) # create as standalone executable (loadable application or "module") set(TARGET "${NAME}") # Use ELF capable toolchain, by building manually and overwriting the # non-elf output if(NOT CMAKE_C_ELF_COMPILER) add_library(${TARGET} ${SRCS}) add_custom_command( TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_C_COMPILER} $> $ -o ${TARGET} COMMAND_EXPAND_LISTS) else() add_executable(${TARGET} ${SRCS}) target_link_options( ${TARGET} PRIVATE $>) endif() # easy access to final ELF, regardless of how it was created set_property(TARGET ${TARGET} PROPERTY ELF_BINARY ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}) nuttx_add_library_internal(${TARGET}) install(TARGETS ${TARGET}) set_property( TARGET nuttx APPEND PROPERTY NUTTX_LOADABLE_APPS ${TARGET}) else() # create as library to be archived into libapps.a set(TARGET "apps_${NAME}") add_library(${TARGET} ${SRCS}) nuttx_add_library_internal(${TARGET}) # add to list of application libraries set_property(GLOBAL APPEND PROPERTY NUTTX_APPS_LIBRARIES ${TARGET}) if(NOT NO_MAIN_ALIAS) # provide main() alias list(GET SRCS 0 MAIN_SRC) set_property( SOURCE ${MAIN_SRC} APPEND PROPERTY COMPILE_DEFINITIONS main=${NAME}_main) endif() endif() # loadable build requires applying ELF flags to all applications if(CONFIG_BUILD_LOADABLE) target_compile_options( ${TARGET} PRIVATE $>) endif() else() set(TARGET "apps_${NAME}") add_custom_target(${TARGET}) set_property(GLOBAL APPEND PROPERTY NUTTX_APPS_ONLY_REGISTER ${TARGET}) endif() # apps applications need to depends on apps_context by default add_dependencies(${TARGET} apps_context) # store parameters into properties (used during builtin list generation) set_target_properties(${TARGET} PROPERTIES APP_MAIN ${NAME}_main) set_target_properties(${TARGET} PROPERTIES APP_NAME ${NAME}) if(PRIORITY) set_target_properties(${TARGET} PROPERTIES APP_PRIORITY ${PRIORITY}) else() set_target_properties(${TARGET} PROPERTIES APP_PRIORITY SCHED_PRIORITY_DEFAULT) endif() if(STACKSIZE) set_target_properties(${TARGET} PROPERTIES APP_STACK ${STACKSIZE}) else() set_target_properties(${TARGET} PROPERTIES APP_STACK ${CONFIG_DEFAULT_TASK_STACKSIZE}) endif() # compile options if(COMPILE_FLAGS) target_compile_options(${TARGET} PRIVATE ${COMPILE_FLAGS}) endif() # compile definitions if(DEFINITIONS) target_compile_definitions(${TARGET} PRIVATE ${DEFINITIONS}) endif() if(INCLUDE_DIRECTORIES) foreach(inc ${INCLUDE_DIRECTORIES}) target_include_directories(${TARGET} PRIVATE ${inc}) endforeach() endif() # add supplied dependencies if(DEPENDS) # using target_link_libraries for dependencies provides linking as well as # interface include and libraries foreach(dep ${DEPENDS}) nuttx_add_dependencies(TARGET ${TARGET} DEPENDS ${dep}) if(TARGET ${dep}) get_target_property(dep_type ${dep} TYPE) if(${dep_type} STREQUAL "STATIC_LIBRARY") target_link_libraries(${TARGET} PRIVATE ${dep}) endif() endif() endforeach() endif() endfunction()