| # ############################################################################## |
| # CMakeLists.txt |
| # |
| # 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. |
| # |
| # ############################################################################## |
| |
| # ~~~ |
| # Instructions: |
| # - Run CMake from the user project directory: |
| # cmake -S <nuttx-dir> -B <build-directory> -DBOARD_CONFIG=<board> |
| # - NuttX will look for the nuttx-apps repository from its parent folder |
| # i.e., ../nuttx-apps. |
| # - A custom directory can be specified with -DNUTTX_APPS_DIR=<apps-dir>. |
| # - Build the user project with: |
| # cmake --build <build-dir> |
| # ~~~ |
| |
| # Request a version available on latest Ubuntu LTS (20.04) |
| |
| cmake_minimum_required(VERSION 3.16) |
| |
| # Handle newer CMake versions correctly by setting policies |
| |
| if(POLICY CMP0115) |
| # do not auto-guess extension in target_sources() |
| cmake_policy(SET CMP0115 NEW) |
| endif() |
| |
| # Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24: |
| |
| if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0") |
| cmake_policy(SET CMP0135 NEW) |
| endif() |
| |
| # Basic CMake configuration ################################################## |
| |
| set(CMAKE_CXX_EXTENSIONS OFF) |
| list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) |
| set(CMAKE_EXPORT_COMPILE_COMMANDS ON) |
| |
| # Setup build type (Debug Release RelWithDebInfo MinSizeRel Coverage). Default |
| # to minimum size release |
| |
| # Use nuttx optimization configuration options, workaround for cmake build type |
| # TODO Integration the build type with CMAKE |
| |
| # if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "MinSizeRel" CACHE STRING |
| # "Build type" FORCE) endif() set_property(CACHE CMAKE_BUILD_TYPE PROPERTY |
| # STRINGS "Debug;Release;RelWithDebInfo;MinSizeRel") |
| |
| # Process board config & directory locations ################################# |
| |
| set(NUTTX_DIR ${CMAKE_CURRENT_SOURCE_DIR}) |
| |
| # unceaned previous make build can cause various types of cmake error |
| if(EXISTS "${NUTTX_DIR}/.config") |
| message( |
| FATAL_ERROR "Please distclean previous make build with `make distclean`") |
| endif() |
| |
| if(NOT DEFINED BOARD_CONFIG) |
| message(FATAL_ERROR "Please define configuration with BOARD_CONFIG") |
| endif() |
| |
| find_program(KCONFIGLIB olddefconfig) |
| if(NOT KCONFIGLIB) |
| message( |
| FATAL_ERROR "Kconfig environment depends on kconfiglib, Please install: |
| $ pip install kconfiglib") |
| endif() |
| |
| # BOARD CONFIG can be set to directory path, or <board-name>[/:]<config-name> |
| # configuration pair |
| |
| if((EXISTS ${BOARD_CONFIG} AND EXISTS ${BOARD_CONFIG}/defconfig) |
| OR (EXISTS ${NUTTX_DIR}/${BOARD_CONFIG} |
| AND EXISTS ${NUTTX_DIR}/${BOARD_CONFIG}/defconfig)) |
| get_filename_component(NUTTX_BOARD_ABS_DIR ${BOARD_CONFIG} ABSOLUTE BASE_DIR |
| ${NUTTX_DIR}) |
| |
| string(REPLACE "/" ";" CONFIG_ARRAY ${NUTTX_BOARD_ABS_DIR}) |
| |
| list(LENGTH CONFIG_ARRAY CONFIG_ARRAY_LENGTH) |
| |
| if(${CONFIG_ARRAY_LENGTH} LESS 4) |
| message(FATAL_ERROR "Please define correct board config : ${BOARD_CONFIG}") |
| endif() |
| |
| math(EXPR NUTTX_CONFIG_INDEX "${CONFIG_ARRAY_LENGTH} - 1") |
| math(EXPR NUTTX_BOARD_INDEX "${CONFIG_ARRAY_LENGTH} - 3") |
| list(GET CONFIG_ARRAY ${NUTTX_BOARD_INDEX} NUTTX_BOARD) |
| list(GET CONFIG_ARRAY ${NUTTX_CONFIG_INDEX} NUTTX_CONFIG) |
| |
| string(REGEX REPLACE "(.*)/(.*)/${NUTTX_CONFIG}" "\\1" NUTTX_BOARD_DIR |
| ${NUTTX_BOARD_ABS_DIR}) |
| set(NUTTX_DEFCONFIG ${NUTTX_BOARD_ABS_DIR}/defconfig) |
| else() |
| if(BOARD_CONFIG MATCHES "/") |
| set(MATCH_REGEX "/") |
| else() |
| set(MATCH_REGEX ":") |
| endif() |
| |
| string(REPLACE ${MATCH_REGEX} ";" CONFIG_ARRAY ${BOARD_CONFIG}) |
| |
| list(LENGTH CONFIG_ARRAY CONFIG_ARRAY_LENGTH) |
| |
| if(${CONFIG_ARRAY_LENGTH} LESS 2) |
| message(FATAL_ERROR "Please define correct board config : ${BOARD_CONFIG}") |
| endif() |
| |
| list(GET CONFIG_ARRAY 0 NUTTX_BOARD) |
| list(GET CONFIG_ARRAY 1 NUTTX_CONFIG) |
| |
| file( |
| GLOB NUTTX_BOARD_DIR |
| LIST_DIRECTORIES true |
| "${NUTTX_DIR}/boards/*/*/${NUTTX_BOARD}") |
| |
| if(EXISTS ${NUTTX_BOARD_DIR}/configs/${NUTTX_CONFIG}/defconfig) |
| set(NUTTX_DEFCONFIG ${NUTTX_BOARD_DIR}/configs/${NUTTX_CONFIG}/defconfig) |
| endif() |
| endif() |
| |
| if("${NUTTX_CONFIG}" STREQUAL "") |
| message(FATAL_ERROR "Please define correct board config : ${NUTTX_CONFIG}") |
| endif() |
| |
| if(NOT EXISTS "${NUTTX_DEFCONFIG}") |
| message(FATAL_ERROR "No config file found at ${NUTTX_DEFCONFIG}") |
| endif() |
| |
| # Generate inital .config ################################################### |
| # This is needed right before any other configure step so that we can source |
| # Kconfig variables into CMake variables |
| |
| # The following commands need these variables to be passed via environment |
| |
| include(nuttx_kconfig) |
| nuttx_export_kconfig_by_value(${NUTTX_DEFCONFIG} "CONFIG_APPS_DIR") |
| |
| if(NOT CONFIG_APPS_DIR) |
| if(EXISTS "${NUTTX_DIR}/../apps") |
| set(NUTTX_APPS_DIR "${NUTTX_DIR}/../apps") |
| elseif(EXISTS "${NUTTX_DIR}/../nuttx-apps") |
| set(NUTTX_APPS_DIR "${NUTTX_DIR}/../nuttx-apps") |
| else() |
| message( |
| WARNING |
| "apps/nuttx-apps directory is not found, use dummy directory instead") |
| set(NUTTX_APPS_DIR "${NUTTX_DIR}/dummy") |
| endif() |
| else() |
| set(NUTTX_APPS_DIR ${CONFIG_APPS_DIR}) |
| set(CONFIG_APPS_DIR) |
| endif() |
| |
| if(NOT EXISTS "${NUTTX_APPS_DIR}") |
| message(FATAL_ERROR "Application directory ${NUTTX_APPS_DIR} is not found") |
| endif() |
| |
| get_filename_component(apps_dir ${NUTTX_APPS_DIR} NAME) |
| set(NUTTX_APPS_BINDIR "${CMAKE_BINARY_DIR}/${apps_dir}") |
| |
| # Support not having application directory |
| |
| if("${apps_dir}" STREQUAL "dummy") |
| file(MAKE_DIRECTORY ${NUTTX_APPS_BINDIR}) |
| file(TOUCH ${NUTTX_APPS_BINDIR}/Kconfig) |
| endif() |
| |
| set(ENV{PYTHONPYCACHEPREFIX} ${CMAKE_BINARY_DIR}) |
| set(ENV{APPSDIR} ${NUTTX_APPS_DIR}) # TODO: support not having apps/ |
| set(ENV{APPSBINDIR} ${NUTTX_APPS_BINDIR}) # TODO: support not having apps/ |
| set(ENV{BINDIR} ${CMAKE_BINARY_DIR}) # TODO: support not having apps/ |
| set(ENV{EXTERNALDIR} dummy) # TODO |
| set(ENV{DRIVERS_PLATFORM_DIR} dummy) # TODO |
| |
| set(ENV{HOST_LINUX} n) |
| set(ENV{HOST_MACOS} n) |
| set(ENV{HOST_WINDOWS} n) |
| set(ENV{HOST_OTHER} n) |
| |
| if(APPLE) |
| set(ENV{HOST_MACOS} y) |
| elseif(WIN32) |
| set(ENV{HOST_WINDOWS} y) |
| elseif(UNIX) |
| set(ENV{HOST_LINUX} y) |
| set(LINUX TRUE) |
| else() |
| set(ENV{HOST_OTHER} y) |
| set(OTHER_OS TRUE) |
| endif() |
| |
| include(nuttx_parse_function_args) |
| include(nuttx_add_subdirectory) |
| include(nuttx_create_symlink) |
| |
| # Add apps/ to the build (if present) |
| |
| if(NOT EXISTS ${NUTTX_APPS_BINDIR}/Kconfig) |
| add_subdirectory(${NUTTX_APPS_DIR} preapps) |
| endif() |
| |
| nuttx_export_kconfig(${NUTTX_DEFCONFIG}) |
| |
| if(CONFIG_ARCH_BOARD_CUSTOM) |
| get_filename_component(NUTTX_BOARD_DIR ${CONFIG_ARCH_BOARD_CUSTOM_DIR} |
| ABSOLUTE BASE_DIR ${NUTTX_DIR}) |
| endif() |
| |
| if("${NUTTX_BOARD_DIR}" STREQUAL "") |
| message(FATAL_ERROR "Please define correct board : ${NUTTX_BOARD_DIR}") |
| endif() |
| |
| if(NOT EXISTS "${NUTTX_BOARD_DIR}/CMakeLists.txt" |
| AND NOT EXISTS "${NUTTX_BOARD_DIR}/../common/CMakeLists.txt") |
| message(FATAL_ERROR "No CMakeLists.txt found at ${NUTTX_BOARD_DIR}") |
| endif() |
| |
| # Custom board ################################################### |
| |
| file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/boards/dummy) |
| if(CONFIG_ARCH_BOARD_CUSTOM) |
| get_filename_component(NUTTX_BOARD_ABS_DIR ${CONFIG_ARCH_BOARD_CUSTOM_DIR} |
| ABSOLUTE BASE_DIR ${NUTTX_DIR}) |
| else() |
| set(NUTTX_BOARD_ABS_DIR ${NUTTX_BOARD_DIR}) |
| file(TOUCH ${CMAKE_BINARY_DIR}/boards/dummy/Kconfig) |
| endif() |
| |
| if(NOT EXISTS ${CMAKE_BINARY_DIR}/boards/dummy/Kconfig) |
| if(CONFIG_ARCH_BOARD_CUSTOM AND EXISTS ${NUTTX_BOARD_ABS_DIR}/Kconfig) |
| nuttx_create_symlink(${NUTTX_BOARD_ABS_DIR}/Kconfig |
| ${CMAKE_BINARY_DIR}/boards/dummy/Kconfig) |
| else() |
| file(TOUCH ${CMAKE_BINARY_DIR}/boards/dummy/Kconfig) |
| endif() |
| endif() |
| |
| # board platfrom driver |
| |
| file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/drivers) |
| |
| if(EXISTS ${NUTTX_BOARD_ABS_DIR}/../drivers |
| AND EXISTS ${NUTTX_BOARD_ABS_DIR}/../drivers/Kconfig) |
| nuttx_create_symlink(${NUTTX_BOARD_ABS_DIR}/../drivers |
| ${CMAKE_BINARY_DIR}/drivers/platform) |
| else() |
| file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/drivers/platform) |
| file(TOUCH ${CMAKE_BINARY_DIR}/drivers/platform/Kconfig) |
| endif() |
| |
| # Custom chip ################################################### |
| |
| if(CONFIG_ARCH_CHIP_CUSTOM) |
| get_filename_component(NUTTX_CHIP_ABS_DIR ${CONFIG_ARCH_CHIP_CUSTOM_DIR} |
| ABSOLUTE BASE_DIR ${NUTTX_DIR}) |
| set(NUTTX_CHIP_ABS_DIR ${NUTTX_CHIP_ABS_DIR}) |
| else() |
| set(NUTTX_CHIP_ABS_DIR |
| "${NUTTX_DIR}/arch/${CONFIG_ARCH}/src/${CONFIG_ARCH_CHIP}") |
| endif() |
| |
| if(NOT EXISTS ${CMAKE_BINARY_DIR}/arch/dummy) |
| file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/arch/dummy) |
| endif() |
| |
| if(NOT EXISTS ${CMAKE_BINARY_DIR}/arch/dummy/Kconfig) |
| if(CONFIG_ARCH_CHIP_CUSTOM AND EXISTS ${NUTTX_CHIP_ABS_DIR}/Kconfig) |
| nuttx_create_symlink(${NUTTX_CHIP_ABS_DIR}/Kconfig |
| ${CMAKE_BINARY_DIR}/arch/dummy/Kconfig) |
| else() |
| file(TOUCH ${CMAKE_BINARY_DIR}/arch/dummy/Kconfig) |
| endif() |
| endif() |
| |
| if(NOT EXISTS ${CMAKE_BINARY_DIR}/arch/${CONFIG_ARCH}) |
| file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/arch/${CONFIG_ARCH}) |
| file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/arch/${CONFIG_ARCH}/src) |
| endif() |
| |
| if(NOT EXISTS ${CMAKE_BINARY_DIR}/arch/${CONFIG_ARCH}/src/chip) |
| nuttx_create_symlink(${NUTTX_CHIP_ABS_DIR} |
| ${CMAKE_BINARY_DIR}/arch/${CONFIG_ARCH}/src/chip) |
| endif() |
| |
| # Unsupport custom board/chips yet, workaround |
| |
| if(NOT EXISTS ${NUTTX_APPS_BINDIR}/platform/board/Kconfig) |
| file(MAKE_DIRECTORY ${NUTTX_APPS_BINDIR}/platform/board) |
| file(TOUCH ${NUTTX_APPS_BINDIR}/platform/board/Kconfig) |
| endif() |
| |
| # Copy board defconfig into main directory and expand TODO: do also for changes |
| # in board/config (by comparing stored defconfig to specified one) |
| |
| if(NOT EXISTS ${CMAKE_BINARY_DIR}/.config OR NOT "${NUTTX_DEFCONFIG}" STREQUAL |
| "${NUTTX_DEFCONFIG_SAVED}") |
| |
| message(STATUS "Initializing NuttX") |
| configure_file(${NUTTX_DEFCONFIG} defconfig COPYONLY) |
| configure_file(${NUTTX_DEFCONFIG} .config.compressed COPYONLY) |
| |
| set(ENV{KCONFIG_CONFIG} ${CMAKE_BINARY_DIR}/.config.compressed) |
| |
| # Do olddefconfig step to expand the abbreviated defconfig into normal config |
| execute_process( |
| COMMAND olddefconfig |
| ERROR_VARIABLE KCONFIG_ERROR |
| OUTPUT_VARIABLE KCONFIG_OUTPUT |
| RESULT_VARIABLE KCONFIG_STATUS |
| WORKING_DIRECTORY ${NUTTX_DIR}) |
| |
| file(RENAME ${CMAKE_BINARY_DIR}/.config.compressed |
| ${CMAKE_BINARY_DIR}/.config) |
| set(ENV{KCONFIG_CONFIG} ${CMAKE_BINARY_DIR}/.config) |
| |
| # store original expanded .config |
| configure_file(${CMAKE_BINARY_DIR}/.config ${CMAKE_BINARY_DIR}/.config.orig |
| COPYONLY) |
| |
| string(REPLACE "\n" ";" KCONFIG_ESTRING ${KCONFIG_ERROR}) |
| foreach(estring ${KCONFIG_ESTRING}) |
| string(REGEX MATCH "the 'modules' option is not supported" result |
| ${estring}) |
| if(NOT result) |
| message(WARNING "Kconfig Configuration Error: ${estring}") |
| endif() |
| endforeach() |
| |
| if(KCONFIG_STATUS AND NOT KCONFIG_STATUS EQUAL 0) |
| message( |
| FATAL_ERROR |
| "Failed to initialize Kconfig configuration: ${KCONFIG_OUTPUT}") |
| endif() |
| |
| set(NUTTX_DEFCONFIG_SAVED |
| ${NUTTX_DEFCONFIG} |
| CACHE INTERNAL "Saved defconfig path" FORCE) |
| |
| # Print configuration choices |
| |
| message(STATUS " Board: ${NUTTX_BOARD}") |
| message(STATUS " Config: ${NUTTX_CONFIG}") |
| message(STATUS " Appdir: ${NUTTX_APPS_DIR}") |
| endif() |
| |
| # Include .cmake files ####################################################### |
| |
| # this exposes all Kconfig vars to CMake |
| |
| nuttx_export_kconfig(${CMAKE_BINARY_DIR}/.config) |
| |
| include(nuttx_generate_headers) |
| include(nuttx_generate_outputs) |
| include(nuttx_add_library) |
| include(nuttx_add_application) |
| include(nuttx_add_romfs) |
| include(nuttx_add_symtab) |
| include(nuttx_add_module) |
| include(nuttx_add_dependencies) |
| include(nuttx_export_header) |
| include(nuttx_source_file_properties) |
| include(menuconfig) |
| |
| include(ExternalProject) |
| include(FetchContent) |
| |
| set(FETCHCONTENT_QUIET OFF) |
| |
| # Board common directory ##################################################### |
| |
| if(CONFIG_ARCH_BOARD_COMMON) |
| file( |
| GLOB NUTTX_COMMON_DIR |
| LIST_DIRECTORIES true |
| "${NUTTX_DIR}/boards/${CONFIG_ARCH}/${CONFIG_ARCH_CHIP}/common") |
| endif() |
| |
| # Setup toolchain ############################################################ |
| |
| # This needs to happen before project() when binaries are searched for |
| |
| list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/arch/${CONFIG_ARCH}/src/cmake) |
| set(CMAKE_TOOLCHAIN_FILE |
| "${CMAKE_SOURCE_DIR}/arch/${CONFIG_ARCH}/src/cmake/Toolchain.cmake") |
| |
| # Define project ############################################################# |
| # This triggers configuration |
| |
| project(NuttX LANGUAGES C CXX ASM) |
| if(WIN32) |
| enable_language(ASM_MASM) |
| endif() |
| |
| # Setup platform options (this needs to happen after project(), once the |
| # toolchain file has been processed) |
| |
| include(platform) |
| |
| # Setup main nuttx target #################################################### |
| |
| add_executable(nuttx) |
| if(CONFIG_BUILD_PROTECTED) |
| add_executable(nuttx_user) |
| endif() |
| |
| if(CONFIG_ALLSYMS) |
| include(nuttx_allsyms) |
| endif() |
| |
| add_dependencies(nuttx nuttx_context) |
| |
| if(WIN32) |
| set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT |
| nuttx) |
| endif() |
| |
| if(CONFIG_ARCH_SIM) |
| # Create separate sim_head OBJECT library built as part of NuttX kernel It |
| # must be separated to allow for linking against the rest of NuttX libraries |
| |
| add_library(sim_head OBJECT) |
| nuttx_add_library_internal(sim_head) |
| get_property( |
| definitions |
| TARGET nuttx |
| PROPERTY NUTTX_KERNEL_DEFINITIONS) |
| target_compile_definitions(sim_head PRIVATE ${definitions}) |
| |
| get_property( |
| options |
| TARGET nuttx |
| PROPERTY NUTTX_KERNEL_COMPILE_OPTIONS) |
| target_compile_options(sim_head PRIVATE ${options}) |
| target_compile_options(sim_head PRIVATE -fvisibility=default) |
| |
| # We need the relocatable object to be first in the list of libraries to be |
| # linked against final nuttx binary |
| |
| if(NOT WIN32) |
| target_link_libraries(nuttx PRIVATE ${CMAKE_BINARY_DIR}/nuttx.rel) |
| endif() |
| else() |
| # These flags apply to source files not part of the library. In sim build this |
| # corresponds to "host" files, so we only do this on non-sim build |
| target_compile_definitions( |
| nuttx |
| PRIVATE $<GENEX_EVAL:$<TARGET_PROPERTY:nuttx,NUTTX_COMPILE_DEFINITIONS>>) |
| target_compile_options( |
| nuttx PRIVATE $<GENEX_EVAL:$<TARGET_PROPERTY:nuttx,NUTTX_COMPILE_OPTIONS>>) |
| endif() |
| |
| # Compiler options TODO: move elsewhere |
| |
| if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") |
| if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 4.9) |
| # force color for gcc > 4.9 |
| add_compile_options(-fdiagnostics-color=always) |
| endif() |
| endif() |
| |
| if(WIN32) |
| add_compile_options( |
| -W2 |
| -wd4116 # unnamed type definition in parentheses |
| -wd4146 # unary minus operator applied to unsigned type, result still |
| # unsigned |
| -wd4244 # 'argument' : conversion from 'type1' to 'type2', possible loss of |
| # data |
| -wd4305 # 'context' : truncation from 'type1' to 'type2' |
| ) |
| else() |
| add_compile_options( |
| # system wide warnings |
| -Wall $<$<COMPILE_LANGUAGE:C>:-Wstrict-prototypes> -Wshadow -Wundef |
| # system wide options |
| $<$<COMPILE_LANGUAGE:ASM>:-D__ASSEMBLY__>) |
| endif() |
| |
| if(NOT CONFIG_LIBCXXTOOLCHAIN) |
| add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-nostdinc++>) |
| else() |
| add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-D_STDLIB_H_>) |
| endif() |
| |
| if(NOT CONFIG_CXX_EXCEPTION) |
| add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions> |
| $<$<COMPILE_LANGUAGE:CXX>:-fcheck-new>) |
| endif() |
| |
| if(CONFIG_STACK_CANARIES) |
| add_compile_options(-fstack-protector-all) |
| endif() |
| |
| if(CONFIG_NDEBUG) |
| add_compile_options(-DNDEBUG) |
| endif() |
| |
| add_definitions(-D__NuttX__) |
| |
| set_property( |
| TARGET nuttx |
| APPEND |
| PROPERTY NUTTX_KERNEL_DEFINITIONS __KERNEL__) |
| |
| # Recurse subdirectories ##################################################### |
| |
| # Each subdirectory will generate a static library |
| |
| if(CONFIG_OPENAMP) |
| include_directories(${CMAKE_SOURCE_DIR}/openamp/open-amp/lib/include) |
| endif() |
| |
| add_subdirectory(openamp) |
| add_subdirectory(arch) |
| add_subdirectory(audio) |
| add_subdirectory(binfmt) |
| add_subdirectory(crypto) |
| add_subdirectory(drivers) |
| add_subdirectory(fs) |
| add_subdirectory(graphics) |
| add_subdirectory(libs) |
| add_subdirectory(mm) |
| add_subdirectory(net) |
| add_subdirectory(sched) |
| add_subdirectory(syscall) |
| add_subdirectory(wireless) |
| |
| # This picks up the chosen board (as well as common board code) |
| |
| add_subdirectory(boards) |
| |
| # POSTBUILD -- Perform post build operations Some architectures require the use |
| # of special tools and special handling AFTER building the NuttX binary. |
| # Make.defs files for those architectures should override the following define |
| # with the correct operations for that platform |
| |
| if(TARGET nuttx_post_build) |
| add_custom_target(post_build ALL DEPENDS nuttx_post_build) |
| endif() |
| |
| # Add apps/ to the build (if present) |
| |
| if(NOT CONFIG_BUILD_KERNEL) |
| |
| if(EXISTS ${NUTTX_APPS_DIR}/CMakeLists.txt) |
| add_subdirectory(${NUTTX_APPS_DIR} apps) |
| else() |
| message( |
| STATUS "Application directory not found at ${NUTTX_APPS_DIR}, skipping") |
| endif() |
| |
| endif() |
| |
| # Link step ################################################################## |
| |
| # Get linker script to use |
| get_property(ldscript GLOBAL PROPERTY LD_SCRIPT) |
| |
| # Pre-compile linker script |
| if(DEFINED PREPROCES) |
| get_filename_component(LD_SCRIPT_NAME ${ldscript} NAME) |
| set(LD_SCRIPT_TMP "${CMAKE_BINARY_DIR}/${LD_SCRIPT_NAME}.tmp") |
| |
| add_custom_command( |
| OUTPUT ${LD_SCRIPT_TMP} |
| DEPENDS ${ldscript} |
| COMMAND ${PREPROCES} -I${CMAKE_BINARY_DIR}/include -I${NUTTX_CHIP_ABS_DIR} |
| ${ldscript} > ${LD_SCRIPT_TMP} |
| WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) |
| |
| add_custom_target(ldscript_tmp DEPENDS ${LD_SCRIPT_TMP}) |
| add_dependencies(nuttx ldscript_tmp) |
| |
| set(ldscript ${LD_SCRIPT_TMP}) |
| endif() |
| |
| # Perform link |
| |
| # Add empty source file to nuttx target since cmake requires at least one file |
| # and we will only be linking libraries |
| |
| if(CONFIG_HAVE_CXX) |
| file(TOUCH "${CMAKE_CURRENT_BINARY_DIR}/empty.cxx") |
| target_sources(nuttx PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/empty.cxx") |
| else() |
| file(TOUCH "${CMAKE_CURRENT_BINARY_DIR}/empty.c") |
| target_sources(nuttx PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/empty.c") |
| endif() |
| |
| # initialize manifest to hold all generated files |
| file(TOUCH ${CMAKE_BINARY_DIR}/nuttx.manifest) |
| |
| get_property(nuttx_kernel_libs GLOBAL PROPERTY NUTTX_KERNEL_LIBRARIES) |
| get_property(nuttx_extra_libs GLOBAL PROPERTY NUTTX_EXTRA_LIBRARIES) |
| |
| if(CONFIG_BUILD_FLAT) |
| get_property(nuttx_system_libs GLOBAL PROPERTY NUTTX_SYSTEM_LIBRARIES) |
| get_property(nuttx_apps_libs GLOBAL PROPERTY NUTTX_APPS_LIBRARIES) |
| endif() |
| |
| set(nuttx_libs ${nuttx_kernel_libs} ${nuttx_system_libs} ${nuttx_apps_libs}) |
| |
| if(NOT CONFIG_ARCH_SIM) |
| |
| # TODO: nostart/nodefault not applicable to nuttx toolchain |
| target_link_libraries( |
| nuttx |
| PRIVATE ${NUTTX_EXTRA_FLAGS} -Wl,--script=${ldscript} -Wl,--start-group |
| ${nuttx_libs} ${nuttx_extra_libs} -Wl,--end-group) |
| |
| # generate binary outputs in different formats (.bin, .hex, etc) |
| nuttx_generate_outputs(nuttx) |
| |
| if(CONFIG_UBOOT_UIMAGE) |
| add_custom_command( |
| OUTPUT uImage |
| COMMAND |
| ${MKIMAGE} -A ${CONFIG_ARCH} -O linux -C none -T kernel -a |
| ${CONFIG_UIMAGE_LOAD_ADDRESS} -e ${CONFIG_UIMAGE_ENTRY_POINT} -n nuttx |
| -d nuttx.bin uImage |
| DEPENDS nuttx) |
| add_custom_target(nuttx-uImage ALL DEPENDS uImage) |
| |
| # TODO: install? $(Q) if [ -w /tftpboot ] ; then \ cp -f uImage |
| # /tftpboot/uImage; \ fi |
| file(APPEND ${CMAKE_BINARY_DIR}/nuttx.manifest uImage) |
| endif() |
| elseif(WIN32) |
| target_link_options(nuttx PUBLIC /SAFESEH:NO) |
| math(EXPR LINK_STACKSIZE |
| "${CONFIG_SIM_STACKSIZE_ADJUSTMENT} + ${CONFIG_IDLETHREAD_STACKSIZE}" |
| OUTPUT_FORMAT DECIMAL) |
| target_link_options(nuttx PUBLIC /STACK:${LINK_STACKSIZE},${LINK_STACKSIZE}) |
| set(nuttx_libs_paths) |
| foreach(lib ${nuttx_libs}) |
| list(APPEND nuttx_libs_paths $<TARGET_FILE:${lib}>) |
| endforeach() |
| |
| add_custom_command( |
| OUTPUT ${CMAKE_BINARY_DIR}/nuttx_all.lib |
| COMMAND ${CMAKE_AR} /OUT:${CMAKE_BINARY_DIR}/nuttx_all.lib |
| ${nuttx_libs_paths} ${nuttx_extra_libs} |
| DEPENDS ${nuttx_libs} ${nuttx_extra_libs} |
| VERBATIM) |
| add_custom_target(nuttx_all-lib DEPENDS ${CMAKE_BINARY_DIR}/nuttx_all.lib) |
| add_dependencies(nuttx nuttx_all-lib) |
| target_link_libraries(nuttx PRIVATE $<TARGET_OBJECTS:sim_head> |
| ${CMAKE_BINARY_DIR}/nuttx_all.lib) |
| else() |
| # On sim platform the link step is a little different. NuttX is first built |
| # into a partially linked relocatable object nuttx.rel with no interface to |
| # host OS. Then, the names of symbols that conflict with libc symbols are |
| # renamed. The final nuttx binary is built by linking the host-specific |
| # objects with the relocatable binary. |
| |
| # C++ global objects are constructed before main get executed, but it isn't a |
| # good point for simulator because NuttX doesn't finish the kernel |
| # initialization yet. So we have to skip the standard facilities and do the |
| # construction by ourself. But how to achieve the goal? 1.Command linker |
| # generate the default script(-verbose) 2.Replace |
| # __init_array_start/__init_array_end with _sinit/_einit 3.Append |
| # __init_array_start = .; __init_array_end = .; Step 2 let nxtask_startup find |
| # objects need to construct Step 3 cheat the host there is no object to |
| # construct Note: the destructor can be fixed in the same way. |
| |
| if(NOT APPLE) |
| add_custom_command( |
| OUTPUT nuttx.ld |
| COMMAND |
| ${CMAKE_C_COMPILER} ${CMAKE_EXE_LINKER_FLAGS} |
| $<$<BOOL:${CONFIG_SIM_M32}>:-m32> -Wl,-verbose 2> /dev/null > |
| nuttx-orig.ld || true |
| COMMAND |
| cat nuttx-orig.ld | sed -e '/====/,/====/!d\;//d' -e |
| 's/__executable_start/_stext/g' -e 's/__init_array_start/_sinit/g' -e |
| 's/__init_array_end/_einit/g' -e 's/__fini_array_start/_sfini/g' -e |
| 's/__fini_array_end/_efini/g' > nuttx.ld |
| COMMAND |
| echo ARGS |
| '__init_array_start = .\; __init_array_end = .\; __fini_array_start = .\; __fini_array_end = .\;' |
| >> nuttx.ld) |
| endif() |
| |
| # conflicting symbols to rename |
| |
| include(nuttx_redefine_symbols) |
| |
| # TODO: do with single function call? |
| set(nuttx_libs_paths) |
| foreach(lib ${nuttx_libs}) |
| list(APPEND nuttx_libs_paths $<TARGET_FILE:${lib}>) |
| endforeach() |
| |
| if(APPLE) |
| add_custom_command( |
| OUTPUT nuttx.rel |
| COMMAND |
| ${CMAKE_LINKER} ARGS -r $<$<BOOL:${CONFIG_SIM_M32}>:-m32> |
| $<TARGET_OBJECTS:sim_head> $<$<NOT:$<BOOL:${APPLE}>>:-Wl,--start-group> |
| ${nuttx_libs_paths} ${nuttx_extra_libs} |
| $<$<NOT:$<BOOL:${APPLE}>>:-Wl,--end-group> -o nuttx.rel |
| DEPENDS ${nuttx_libs} ${nuttx_extra_libs} sim_head |
| COMMAND_EXPAND_LISTS) |
| else() |
| add_custom_command( |
| OUTPUT nuttx.rel |
| COMMAND |
| ${CMAKE_C_COMPILER} ARGS -r $<$<BOOL:${CONFIG_SIM_M32}>:-m32> |
| $<TARGET_OBJECTS:sim_head> $<$<NOT:$<BOOL:${APPLE}>>:-Wl,--start-group> |
| ${nuttx_libs_paths} ${nuttx_extra_libs} |
| $<$<NOT:$<BOOL:${APPLE}>>:-Wl,--end-group> -o nuttx.rel |
| COMMAND ${CMAKE_OBJCOPY} --redefine-syms=nuttx-names.dat nuttx.rel |
| DEPENDS ${nuttx_libs} ${nuttx_extra_libs} sim_head |
| COMMAND_EXPAND_LISTS) |
| endif() |
| add_custom_target(nuttx-rel DEPENDS nuttx.rel |
| $<$<NOT:$<BOOL:${APPLE}>>:nuttx.ld>) |
| |
| # link the final nuttx binary |
| add_dependencies(nuttx nuttx-rel) |
| target_link_options(nuttx PUBLIC $<$<NOT:$<BOOL:${APPLE}>>:-T nuttx.ld> |
| $<$<BOOL:${CONFIG_SIM_M32}>:-m32>) |
| endif() |
| |
| # TODO: if we use an install target a manifest may not be needed |
| if(CONFIG_ARCH_SIM) |
| file(APPEND ${CMAKE_BINARY_DIR}/nuttx.manifest "nuttx\n") |
| endif() |
| |
| # Userspace portion ########################################################## |
| |
| if(CONFIG_BUILD_PROTECTED) |
| |
| get_property(nuttx_system_libs GLOBAL PROPERTY NUTTX_SYSTEM_LIBRARIES) |
| |
| get_property(nuttx_apps_libs GLOBAL PROPERTY NUTTX_APPS_LIBRARIES) |
| |
| get_property(user_ldscript GLOBAL PROPERTY LD_SCRIPT_USER) |
| list(TRANSFORM user_ldscript PREPEND "-Wl,--script=") |
| |
| execute_process( |
| COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS} ${NUTTX_EXTRA_FLAGS} |
| --print-libgcc-file-name |
| OUTPUT_STRIP_TRAILING_WHITESPACE |
| OUTPUT_VARIABLE nuttx_user_libgcc) |
| |
| # reset link options for userspace to prevent sections from being accidentally |
| # deleted |
| set_target_properties(nuttx_user PROPERTIES LINK_OPTIONS "") |
| |
| target_link_options( |
| nuttx_user PRIVATE -nostartfiles -nodefaultlibs |
| -Wl,--entry=${CONFIG_INIT_ENTRYPOINT} |
| -Wl,--undefined=${CONFIG_INIT_ENTRYPOINT}) |
| |
| target_link_libraries( |
| nuttx_user |
| PRIVATE ${user_ldscript} |
| $<$<NOT:$<BOOL:${APPLE}>>:-Wl,--start-group> |
| ${nuttx_system_libs} |
| ${nuttx_apps_libs} |
| ${nuttx_user_libgcc} |
| $<$<BOOL:${CONFIG_HAVE_CXX}>:supc++> |
| $<$<NOT:$<BOOL:${APPLE}>>:-Wl,--end-group>) |
| |
| add_custom_command( |
| OUTPUT User.map |
| COMMAND ${CMAKE_NM} nuttx_user > User.map |
| DEPENDS nuttx_user) |
| add_custom_target(usermap ALL DEPENDS User.map) |
| |
| # generate binary outputs in different formats (.bin, .hex, etc) |
| nuttx_generate_outputs(nuttx_user) |
| |
| # create merged .hex file ready to be flashed TODO: does not seem to be |
| # generating a functional hex file |
| if(CONFIG_INTELHEX_BINARY AND SREC_CAT) |
| add_custom_command( |
| OUTPUT nuttx_combined.hex |
| COMMAND ${SREC_CAT} nuttx.hex -intel nuttx_user.hex -intel -o |
| nuttx_combined.hex -intel |
| DEPENDS nuttx_user nuttx) |
| add_custom_target(nuttx-combined ALL DEPENDS nuttx_combined.hex) |
| endif() |
| |
| # TODO: could also merge elf binaries |
| endif() |
| |
| if(CONFIG_BUILD_KERNEL) |
| # TODO: generate nuttx-export-xxx.tar.gz for userland development |
| |
| endif() |