Files
bizhang_-obav/cmake/nuttx/px4_impl_nuttx.cmake
Carlo Wood c6a2641507 Fix some pthread related linker stuff. (#5504)
The px4_os_add_flags defined in cmake/posix/px4_impl_posix.cmake did
add (threading) libraries to added_exe_linker_flags, which subsequently
end up in CMAKE_EXE_LINKER_FLAGS and then have no effect because those
flags are passed to the linker before any of the object files and static
libraries.

Those libraries are already added correctly in the corresponding
src/firmware/*/CMakeLists.txt files (for qurt, nuttx AND posix).

I left in the non-library linker flag '-pthread' for the bebop board,
although it seems very weird to me that this is needed (is it?).
If that is needed then it seems weird to link manually (that is,
src/firmware/*/CMakeLists.txt) with -lpthread.

For linux/g++ -pthread is added to the CXXFLAGS as it should be:
this causes the compiler to define _REENTRANT which is needed
for (the interface of) certain libraries to become thread-safe.
Offically one also can just pass -pthread to the linker, which then
causes the right libraries to be linked, but just linking with
-lpthread -lm -lrt works too.

I ran into this while adding support for libcwd, which explicitly
complains that _REENTRANT isn't defined when trying to link with
the thread-safe version of libcwd (-lcwd_r) and then tells you
to use -pthread.
2016-09-26 22:53:41 +02:00

531 lines
15 KiB
CMake

############################################################################
#
# Copyright (c) 2015 PX4 Development Team. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name PX4 nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
#=============================================================================
#
# Defined functions in this file
#
# OS Specific Functions
#
# * px4_nuttx_add_firmware
# * px4_nuttx_generate_builtin_commands
# * px4_nuttx_add_export
# * px4_nuttx_add_romfs
#
# Required OS Inteface Functions
#
# * px4_os_add_flags
# * px4_os_prebuild_targets
#
include(common/px4_base)
#=============================================================================
#
# px4_nuttx_add_firmware
#
# This function adds a nuttx firmware target.
#
# Usage:
# px4_nuttx_add_firmware(OUT <out-target> EXE <in-executable>
# PARAM_XML <param_xml> AIRFRAMES_XML <airframes_xml>)
#
# Input:
# EXE : the executable to generate the firmware from
# BOARD : the board
# PARAM_XML : param xml file (optional)
# AIRFRAMES_XML : airframes xml file (optional)
#
# Output:
# OUT : the generated firmware target
#
# Example:
# px4_nuttx_add_firmware(TARGET fw_test EXE test)
#
function(px4_nuttx_add_firmware)
px4_parse_function_args(
NAME px4_nuttx_add_firmware
ONE_VALUE BOARD OUT EXE PARAM_XML AIRFRAMES_XML
REQUIRED OUT EXE BOARD
ARGN ${ARGN})
set(extra_args)
if (PARAM_XML)
list(APPEND extra_args
--parameter_xml ${PARAM_XML}
)
endif()
if (AIRFRAMES_XML)
list(APPEND extra_args
--airframe_xml ${AIRFRAMES_XML}
)
endif()
add_custom_command(OUTPUT ${OUT}
COMMAND ${OBJCOPY} -O binary ${EXE} ${EXE}.bin
COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/Tools/px_mkfw.py
--prototype ${PX4_SOURCE_DIR}/Images/${BOARD}.prototype
--git_identity ${PX4_SOURCE_DIR}
${extra_args}
--image ${EXE}.bin > ${OUT}
DEPENDS ${EXE}
)
add_custom_target(build_firmware_${BOARD} ALL DEPENDS ${OUT})
endfunction()
#=============================================================================
#
# px4_nuttx_generate_builtin_commands
#
# This function generates the builtin_commands.c src for nuttx
#
# Usage:
# px4_nuttx_generate_builtin_commands(
# MODULE_LIST <in-list>
# OUT <file>)
#
# Input:
# MODULE_LIST : list of modules
#
# Output:
# OUT : generated builtin_commands.c src
#
# Example:
# px4_nuttx_generate_builtin_commands(
# OUT <generated-src> MODULE_LIST px4_simple_app)
#
function(px4_nuttx_generate_builtin_commands)
px4_parse_function_args(
NAME px4_nuttx_generate_builtin_commands
ONE_VALUE OUT
MULTI_VALUE MODULE_LIST
REQUIRED MODULE_LIST OUT
ARGN ${ARGN})
set(builtin_apps_string)
set(builtin_apps_decl_string)
set(command_count 0)
foreach(module ${MODULE_LIST})
foreach(property MAIN STACK_MAIN PRIORITY)
get_target_property(${property} ${module} ${property})
endforeach()
if (MAIN)
set(builtin_apps_string
"${builtin_apps_string}\t{\"${MAIN}\", ${PRIORITY}, ${STACK_MAIN}, ${MAIN}_main},\n")
set(builtin_apps_decl_string
"${builtin_apps_decl_string}extern int ${MAIN}_main(int argc, char *argv[]);\n")
math(EXPR command_count "${command_count}+1")
endif()
endforeach()
configure_file(${PX4_SOURCE_DIR}/cmake/nuttx/builtin_commands.c.in
${OUT})
endfunction()
#=============================================================================
#
# px4_nuttx_add_export
#
# This function generates a nuttx export.
#
# Usage:
# px4_nuttx_add_export(
# OUT <out-target>
# CONFIG <in-string>
# DEPENDS <in-list>)
#
# Input:
# CONFIG : the board to generate the export for
# DEPENDS : dependencies
#
# Output:
# OUT : the export target
#
# Example:
# px4_nuttx_add_export(OUT nuttx_export CONFIG px4fmu-v2)
#
function(px4_nuttx_add_export)
px4_parse_function_args(
NAME px4_nuttx_add_export
ONE_VALUE OUT CONFIG THREADS
MULTI_VALUE DEPENDS
REQUIRED OUT CONFIG THREADS
ARGN ${ARGN})
set(nuttx_src ${PX4_BINARY_DIR}/${CONFIG}/NuttX)
# patch
add_custom_target(__nuttx_patch_${CONFIG})
file(GLOB nuttx_patches RELATIVE ${PX4_SOURCE_DIR}
${PX4_SOURCE_DIR}/nuttx-patches/*.patch)
foreach(patch ${nuttx_patches})
string(REPLACE "/" "_" patch_name "${patch}-${CONFIG}")
message(STATUS "nuttx-patch: ${patch}")
add_custom_command(OUTPUT nuttx_patch_${patch_name}.stamp
COMMAND ${PATCH} -p0 -N < ${PX4_SOURCE_DIR}/${patch}
COMMAND ${TOUCH} nuttx_patch_${patch_name}.stamp
DEPENDS ${DEPENDS}
)
add_custom_target(nuttx_patch_${patch_name}
DEPENDS nuttx_patch_${patch_name}.stamp)
add_dependencies(nuttx_patch nuttx_patch_${patch_name})
endforeach()
# Read defconfig to see if CONFIG_ARMV7M_STACKCHECK is yes
# note: CONFIG will be BOARD in the future evaluation of ${hw_stack_check_${CONFIG}
file(STRINGS "${PX4_SOURCE_DIR}/nuttx-configs/${CONFIG}/nsh/defconfig"
hw_stack_check_${CONFIG}
REGEX "CONFIG_ARMV7M_STACKCHECK=y"
)
if ("${hw_stack_check_${CONFIG}}" STREQUAL "CONFIG_ARMV7M_STACKCHECK=y")
set(config_nuttx_hw_stack_check_${CONFIG} y CACHE INTERNAL "")
endif()
# copy and export
file(RELATIVE_PATH nuttx_cp_src ${PX4_BINARY_DIR} ${PX4_SOURCE_DIR}/NuttX)
file(GLOB_RECURSE config_files ${PX4_SOURCE_DIR}/nuttx-configs/${CONFIG}/*)
add_custom_command(OUTPUT ${PX4_BINARY_DIR}/${CONFIG}.export
COMMAND ${MKDIR} -p ${nuttx_src}
COMMAND rsync -a --delete --exclude=.git ${nuttx_cp_src}/ ${CONFIG}/NuttX/
#COMMAND ${ECHO} Configuring NuttX for ${CONFIG}
COMMAND ${MAKE} --no-print-directory -C${nuttx_src}/nuttx -r --quiet distclean
COMMAND ${CP} -r ${PX4_SOURCE_DIR}/nuttx-configs/PX4_Warnings.mk ${nuttx_src}/nuttx/
COMMAND ${CP} -r ${PX4_SOURCE_DIR}/nuttx-configs/${CONFIG} ${nuttx_src}/nuttx/configs
COMMAND cd ${nuttx_src}/nuttx/tools && ./configure.sh ${CONFIG}/nsh && cd ..
#COMMAND ${ECHO} Exporting NuttX for ${CONFIG}
COMMAND ${MAKE} --no-print-directory --quiet -C ${nuttx_src}/nuttx -j${THREADS} -r CONFIG_ARCH_BOARD=${CONFIG} export > nuttx_build.log
COMMAND ${CP} -r ${nuttx_src}/nuttx/nuttx-export.zip ${PX4_BINARY_DIR}/${CONFIG}.export
DEPENDS ${config_files} "${PX4_SOURCE_DIR}/nuttx-configs/${CONFIG}/nsh/defconfig" ${DEPENDS}
WORKING_DIRECTORY ${PX4_BINARY_DIR}
COMMENT "Building NuttX for ${CONFIG}")
# extract
add_custom_command(OUTPUT nuttx_export_${CONFIG}.stamp
COMMAND ${RM} -rf ${nuttx_src}/nuttx-export
COMMAND ${UNZIP} -q ${PX4_BINARY_DIR}/${CONFIG}.export -d ${nuttx_src}
COMMAND ${TOUCH} nuttx_export_${CONFIG}.stamp
DEPENDS ${DEPENDS} ${PX4_BINARY_DIR}/${CONFIG}.export)
add_custom_target(${OUT}
DEPENDS nuttx_export_${CONFIG}.stamp)
endfunction()
#=============================================================================
#
# px4_nuttx_create_bin
#
# The functions generates a bin image for nuttx.
#
# Usage:
# px4_nuttx_create_bin(BIN <out-file> EXE <in-file>)
#
# Input:
# EXE : the exe file
#
# Output:
# OUT : the binary output file
#
# Example:
# px4_nuttx_create_bin(OUT my_exe.bin EXE my_exe)
#
function(px4_nuttx_create_bin)
px4_parse_function_args(
NAME px4_nuttx_create_bin
ONE_VALUE EXE OUT
REQUIRED EXE OUT
ARGN ${ARGN})
add_custom_command(OUTPUT ${OUT}
COMMAND ${OBJCOPY} -O binary ${EXE} ${EXE}.bin
DEPENDS ${EXE})
set(${OUT} ${${OUT}} PARENT_SCOPE)
endfunction()
#=============================================================================
#
# px4_nuttx_add_romfs
#
# The functions creates a ROMFS filesystem for nuttx.
#
# Usage:
# px4_nuttx_add_romfs(
# OUT <out-target>
# ROOT <in-directory>
# EXTRAS <in-list>)
#
# Input:
# ROOT : the root of the ROMFS
# EXTRAS : list of extra files
#
# Output:
# OUT : the ROMFS library target
#
# Example:
# px4_nuttx_add_romfs(OUT my_romfs ROOT "ROMFS/my_board")
#
function(px4_nuttx_add_romfs)
px4_parse_function_args(
NAME px4_nuttx_add_romfs
ONE_VALUE OUT ROOT
MULTI_VALUE EXTRAS
REQUIRED OUT ROOT
ARGN ${ARGN})
set(romfs_temp_dir ${PX4_BINARY_DIR}/tmp/${ROOT})
set(romfs_src_dir ${PX4_SOURCE_DIR}/${ROOT})
set(romfs_autostart ${PX4_SOURCE_DIR}/Tools/px_process_airframes.py)
set(romfs_pruner ${PX4_SOURCE_DIR}/Tools/px_romfs_pruner.py)
set(bin_to_obj ${PX4_SOURCE_DIR}/cmake/nuttx/bin_to_obj.py)
set(extras_dir ${CMAKE_CURRENT_BINARY_DIR}/extras)
file(GLOB_RECURSE romfs_src_files ${romfs_src_dir} ${romfs_src_dir}/*)
set(cmake_test ${PX4_SOURCE_DIR}/cmake/test/cmake_tester.py)
set(extras)
foreach(extra ${EXTRAS})
get_filename_component(file_name ${extra} NAME)
set(file_dest ${extras_dir}/${file_name})
add_custom_command(OUTPUT ${file_dest}
COMMAND cmake -E copy ${extra} ${file_dest}
DEPENDS ${extra}
)
list(APPEND extras ${file_dest})
endforeach()
add_custom_target(collect_extras DEPENDS ${extras})
add_custom_command(OUTPUT romfs.o
COMMAND cmake -E remove_directory ${romfs_temp_dir}
COMMAND cmake -E copy_directory ${romfs_src_dir} ${romfs_temp_dir}
COMMAND cmake -E copy_directory ${extras_dir} ${romfs_temp_dir}/extras
COMMAND ${PYTHON_EXECUTABLE} ${romfs_autostart}
-a ${romfs_temp_dir}/init.d
-s ${romfs_temp_dir}/init.d/rc.autostart
COMMAND ${PYTHON_EXECUTABLE} ${romfs_pruner}
--folder ${romfs_temp_dir}
COMMAND ${GENROMFS} -f ${CMAKE_CURRENT_BINARY_DIR}/romfs.bin
-d ${romfs_temp_dir} -V "NSHInitVol"
#COMMAND cmake -E remove_directory ${romfs_temp_dir}
COMMAND ${PYTHON_EXECUTABLE} ${bin_to_obj}
--ld ${LD} --c_flags ${CMAKE_C_FLAGS}
--include_path "${PX4_SOURCE_DIR}/src/include"
--c_compiler ${CMAKE_C_COMPILER}
--nm ${NM} --objcopy ${OBJCOPY}
--obj romfs.o
--var romfs_img
--bin romfs.bin
DEPENDS ${romfs_src_files} ${extras}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
add_library(${OUT} STATIC romfs.o)
set_target_properties(${OUT} PROPERTIES LINKER_LANGUAGE C)
set(${OUT} ${${OUT}} PARENT_SCOPE)
endfunction()
#=============================================================================
#
# px4_os_add_flags
#
# Set the nuttx build flags.
#
# Usage:
# px4_os_add_flags(
# C_FLAGS <inout-variable>
# CXX_FLAGS <inout-variable>
# OPTIMIZATION_FLAGS <inout-variable>
# EXE_LINKER_FLAGS <inout-variable>
# INCLUDE_DIRS <inout-variable>
# LINK_DIRS <inout-variable>
# DEFINITIONS <inout-variable>)
#
# Input:
# BOARD : flags depend on board/nuttx config
#
# Input/Output: (appends to existing variable)
# C_FLAGS : c compile flags variable
# CXX_FLAGS : c++ compile flags variable
# OPTIMIZATION_FLAGS : optimization compile flags variable
# EXE_LINKER_FLAGS : executable linker flags variable
# INCLUDE_DIRS : include directories
# LINK_DIRS : link directories
# DEFINITIONS : definitions
#
# Note that EXE_LINKER_FLAGS is not suitable for adding libraries because
# these flags are added before any of the object files and static libraries.
# Add libraries in src/firmware/nuttx/CMakeLists.txt.
#
# Example:
# px4_os_add_flags(
# C_FLAGS CMAKE_C_FLAGS
# CXX_FLAGS CMAKE_CXX_FLAGS
# OPTIMIZATION_FLAGS optimization_flags
# EXE_LINKER_FLAG CMAKE_EXE_LINKER_FLAGS
# INCLUDES <list>)
#
function(px4_os_add_flags)
set(inout_vars
C_FLAGS CXX_FLAGS OPTIMIZATION_FLAGS EXE_LINKER_FLAGS INCLUDE_DIRS LINK_DIRS DEFINITIONS)
px4_parse_function_args(
NAME px4_os_add_flags
ONE_VALUE ${inout_vars} BOARD
REQUIRED ${inout_vars} BOARD
ARGN ${ARGN})
px4_add_common_flags(
BOARD ${BOARD}
C_FLAGS ${C_FLAGS}
CXX_FLAGS ${CXX_FLAGS}
OPTIMIZATION_FLAGS ${OPTIMIZATION_FLAGS}
EXE_LINKER_FLAGS ${EXE_LINKER_FLAGS}
INCLUDE_DIRS ${INCLUDE_DIRS}
LINK_DIRS ${LINK_DIRS}
DEFINITIONS ${DEFINITIONS})
set(nuttx_export_dir ${PX4_BINARY_DIR}/${BOARD}/NuttX/nuttx-export)
set(added_include_dirs
${nuttx_export_dir}/include
${nuttx_export_dir}/include/cxx
${nuttx_export_dir}/arch/chip
${nuttx_export_dir}/arch/common
)
set(added_link_dirs
${nuttx_export_dir}/libs
)
set(added_definitions
-D__PX4_NUTTX
-D__DF_NUTTX
)
set(added_c_flags
-nodefaultlibs
-nostdlib
)
set(added_cxx_flags
-nodefaultlibs
-nostdlib
)
set(added_exe_linker_flags) # none currently
set(instrument_flags)
if ("${config_nuttx_hw_stack_check_${BOARD}}" STREQUAL "y")
set(instrument_flags
-finstrument-functions
-ffixed-r10
)
list(APPEND c_flags ${instrument_flags})
list(APPEND cxx_flags ${instrument_flags})
endif()
set(cpu_flags)
# Handle non-F4 boards specifically here
if (${BOARD} STREQUAL "px4io-v1")
set(cpu_flags
-mcpu=cortex-m3
-mthumb
-march=armv7-m
)
elseif (${BOARD} STREQUAL "px4io-v2")
set(cpu_flags
-mcpu=cortex-m3
-mthumb
-march=armv7-m
)
else ()
set(cpu_flags
-mcpu=cortex-m4
-mthumb
-march=armv7e-m
-mfpu=fpv4-sp-d16
-mfloat-abi=hard
)
endif()
list(APPEND c_flags ${cpu_flags})
list(APPEND cxx_flags ${cpu_flags})
# output
foreach(var ${inout_vars})
string(TOLOWER ${var} lower_var)
set(${${var}} ${${${var}}} ${added_${lower_var}} PARENT_SCOPE)
#message(STATUS "nuttx: set(${${var}} ${${${var}}} ${added_${lower_var}} PARENT_SCOPE)")
endforeach()
endfunction()
#=============================================================================
#
# px4_os_prebuild_targets
#
# This function generates os dependent targets
# Usage:
# px4_os_prebuild_targets(
# OUT <out-list_of_targets>
# BOARD <in-string>
# )
#
# Input:
# BOARD : board
# THREADS : number of threads for building
#
# Output:
# OUT : the target list
#
# Example:
# px4_os_prebuild_targets(OUT target_list BOARD px4fmu-v2)
#
function(px4_os_prebuild_targets)
px4_parse_function_args(
NAME px4_os_prebuild_targets
ONE_VALUE OUT BOARD THREADS
REQUIRED OUT BOARD
ARGN ${ARGN})
px4_nuttx_add_export(OUT nuttx_export_${BOARD}
CONFIG ${BOARD}
THREADS ${THREADS}
DEPENDS git_nuttx)
add_custom_target(${OUT} DEPENDS nuttx_export_${BOARD})
endfunction()
# vim: set noet fenc=utf-8 ff=unix nowrap: