incubator-nuttx/cmake/nuttx_add_library.cmake

235 lines
8.3 KiB
CMake

# ##############################################################################
# cmake/nuttx_add_library.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.
#
# ##############################################################################
# Internal utility function
#
# Used by functions below, not to be used directly
function(nuttx_add_library_internal target)
# ensure nuttx_context is created before this
add_dependencies(${target} nuttx_context)
# add specified search directories for CXX targets
target_include_directories(
${target}
PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:$<GENEX_EVAL:$<TARGET_PROPERTY:nuttx,NUTTX_CXX_INCLUDE_DIRECTORIES>>>
)
# add main include directories
target_include_directories(
${target} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/include
${CMAKE_BINARY_DIR}/include)
# Set global compile options & definitions We use the "nuttx" target to hold
# these properties so that libraries added after this property is set can read
# the final value at build time. The GENEX_EVAL allows the property to hold
# generator expression itself
target_compile_options(
${target}
PRIVATE $<GENEX_EVAL:$<TARGET_PROPERTY:nuttx,NUTTX_COMPILE_OPTIONS>>)
target_compile_definitions(
${target} PRIVATE $<GENEX_EVAL:$<TARGET_PROPERTY:nuttx,NUTTX_DEFINITIONS>>)
target_include_directories(
${target}
PRIVATE $<GENEX_EVAL:$<TARGET_PROPERTY:nuttx,NUTTX_INCLUDE_DIRECTORIES>>)
# Set install config for all library
install(TARGETS ${target})
endfunction()
# Auxiliary libraries
#
# The whole purpose of this is to overcome the limitation of CMake 3.16 to set
# source file properties from directories different from the one defining the
# target where the source file is used. This auxiliary library acts as an
# intermediate target that is usually linked to the system/kernel library
# defined at a higher level.
function(nuttx_add_aux_library target)
# declare target
add_library(${target} OBJECT ${ARGN})
nuttx_add_library_internal(${target} ${ARGN})
endfunction()
# User (application) libraries
#
# An user library is a target which is defined as a collection of object files
# which is ultimately archived into the apps library
function(nuttx_add_user_library target)
# declare target
add_library(${target} OBJECT ${ARGN})
add_dependencies(${target} apps_context)
nuttx_add_library_internal(${target} ${ARGN})
# link to final libapps
target_link_libraries(apps PRIVATE ${target})
# add apps/include to include path
target_include_directories(${target} PRIVATE ${NUTTX_APPS_DIR}/include)
endfunction()
# System Libraries
#
# A system library is a library which is built into the OS but does not receive
# kernel-level flags (such as __KERNEL__). This is will be part of the userspace
# blob in kernel builds
function(nuttx_add_system_library target)
# declare target
add_library(${target} ${ARGN})
# add library to build
nuttx_add_library_internal(${target} ${ARGN})
# add to list of libraries to link to final nuttx binary
set_property(GLOBAL APPEND PROPERTY NUTTX_SYSTEM_LIBRARIES ${target})
endfunction()
# Kernel Libraries
#
# nuttx_add_kernel_library(target [SPLIT] [SAME_SOURCES] [sources ...])
#
# For non-kernel builds, this defines an OS library which will receive
# kernel-level flags (such as __KERNEL__) and will be linked into nuttx binary
# For kernel builds, the same happens unless SPLIT is specified. In this case
# both a <target> and a k<target> library will be defined, but only the latter
# having the kernel-level flags. In this case, both libraries will receive the
# same set of sources (the original <target> should be used by the user to add
# sources).
function(nuttx_add_kernel_library target)
cmake_parse_arguments(ARGS SPLIT "" "" ${ARGN})
set(SRCS ${ARGS_UNPARSED_ARGUMENTS})
if(ARGS_SPLIT AND NOT CONFIG_BUILD_FLAT)
set(kernel_target k${target})
# add non-kernel (system) library
nuttx_add_system_library(${target} ${SRCS})
else()
set(kernel_target ${target})
endif()
# add kernel library
add_library(${kernel_target} ${SRCS})
nuttx_add_library_internal(${kernel_target} ${SRCS})
set_property(GLOBAL APPEND PROPERTY NUTTX_KERNEL_LIBRARIES ${kernel_target})
# Add kernel options & definitions See note above in
# nuttx_add_library_internal() on syntax and nuttx target use
if(NOT ARGS_SPLIT OR NOT "${target}" STREQUAL "${kernel_target}")
target_compile_options(
${kernel_target}
PRIVATE
$<GENEX_EVAL:$<TARGET_PROPERTY:nuttx,NUTTX_KERNEL_COMPILE_OPTIONS>>)
target_compile_definitions(
${kernel_target}
PRIVATE $<GENEX_EVAL:$<TARGET_PROPERTY:nuttx,NUTTX_KERNEL_DEFINITIONS>>)
target_include_directories(
${kernel_target}
PRIVATE
$<GENEX_EVAL:$<TARGET_PROPERTY:nuttx,NUTTX_KERNEL_INCLUDE_DIRECTORIES>>)
endif()
if(NOT "${target}" STREQUAL "${kernel_target}")
# The k${target} lib will have the same sources added to that ${target} lib.
# This allows to do target_sources(${target} ..) easily
target_sources(${kernel_target}
PRIVATE $<TARGET_PROPERTY:${target},SOURCES>)
# same for include directories
target_include_directories(
${kernel_target} PRIVATE $<TARGET_PROPERTY:${target},INCLUDE_DIRECTORIES>)
endif()
endfunction()
include(nuttx_parse_function_args)
define_property(
GLOBAL
PROPERTY NUTTX_LIBRARIES
BRIEF_DOCS "NuttX libs"
FULL_DOCS "List of all NuttX libraries")
# =============================================================================
#
# nuttx_add_library
#
# Wrapper of cmake add_library but with nuttx platform dependencies
#
function(nuttx_add_library target)
add_library(${target} ${ARGN})
add_dependencies(${target} apps_context)
set_property(GLOBAL APPEND PROPERTY NUTTX_SYSTEM_LIBRARIES ${target})
nuttx_add_library_internal(${target})
endfunction()
# =============================================================================
#
# nuttx_add_extra_library
#
# Add extra library to extra attribute, extra library will be treated as an
# import target and have a complete full path this will be used to avoid adding
# the -l prefix to the link target between different cmake versions and
# platformss
#
function(nuttx_add_extra_library)
foreach(extra_lib ${ARGN})
# define the target name of the extra library
string(REGEX REPLACE "[^a-zA-Z0-9]" "_" extra_target "${extra_lib}")
# set the absolute path of the library for the import target
nuttx_library_import(${extra_target} ${extra_lib})
set_property(GLOBAL APPEND PROPERTY NUTTX_EXTRA_LIBRARIES ${extra_target})
endforeach()
endfunction()
# Import static library
#
function(nuttx_library_import library_name library_path)
add_library(${library_name} STATIC IMPORTED GLOBAL)
set_target_properties(${library_name} PROPERTIES IMPORTED_LOCATION
${library_path})
endfunction()
# nuttx_add_external_library
#
# the target library of add_library has been called in external CMakeLists.txt
# so that they can be added to the final link
#
# Usually used with Nuttx to include an external system that already supports
# CMake compilation
function(nuttx_add_external_library target)
cmake_parse_arguments(ARGS "" MODE "" ${ARGN})
if(NOT ARGS_MODE)
set_property(GLOBAL APPEND PROPERTY NUTTX_SYSTEM_LIBRARIES ${target})
elseif("${ARGS_MODE}" STREQUAL "APPS")
set_property(GLOBAL APPEND PROPERTY NUTTX_APPS_LIBRARIES ${target})
elseif("${ARGS_MODE}" STREQUAL "KERNEL")
set_property(GLOBAL APPEND PROPERTY NUTTX_KERNEL_LIBRARIES ${target})
endif()
nuttx_add_library_internal(${target})
endfunction()