New cmakelists (#1977)

This commit is contained in:
Jonas Vautherin
2023-05-04 01:44:41 +02:00
committed by GitHub
parent fdef5cc0fc
commit ce00667f1e
23 changed files with 326 additions and 2176 deletions
+24
View File
@@ -52,6 +52,30 @@ jobs:
run: |
./scripts/test.sh py
build-cmake-c-example:
name: Build cmake C example
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- name: Install dependencies
run: |
sudo apt update
sudo apt install -y python3 python3-pip
- name: Install pip dependencies
run: |
python3 -m pip install -r pymavlink/requirements.txt
- name: Install MAVLink headers
run: |
cmake -Bbuild -H. -DCMAKE_INSTALL_PREFIX=install
cmake --build build --target install
- name: Build example
run: |
cd examples/c
cmake -Bbuild -H. -DCMAKE_PREFIX_PATH=$(pwd)/../../install
cmake --build build
node-tests:
name: Node ${{ matrix.node-version }} test
runs-on: ubuntu-20.04
+1
View File
@@ -5,6 +5,7 @@ doc/messages
doc/*.log
.DS_Store
build*
install*
.nfs*
share/
__pycache__
+55 -229
View File
@@ -1,248 +1,74 @@
project (mavlink)
cmake_minimum_required(VERSION 3.13)
if (NOT DEFINED MAVLINK_SOURCE_DIR)
set(MAVLINK_SOURCE_DIR ${PROJECT_SOURCE_DIR})
endif ()
project(mavlink)
# settings
cmake_minimum_required (VERSION 2.8.2)
set(PROJECT_VERSION_MAJOR "1")
set(PROJECT_VERSION_MINOR "0")
set(PROJECT_VERSION_PATCH "9")
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
set(PROJECT_CONTACT_EMAIL http://groups.google.com/group/mavlink)
set(PROJECT_CONTACT_VENDOR mavlink)
set(LIBRARY_VERSION ${PROJECT_VERSION})
set(LIBRARY_SOVERSION "0.0.0")
find_package(Python COMPONENTS Interpreter REQUIRED)
# third party
# none required
# options
option(USE_SYSTEM_PYMAVLINK "Generate mavlink files with system-wide installed mavgen" OFF)
option(WITH_TESTS "Build test programs." OFF)
option(WITH_BUILD_DEPS "Build dependencies." OFF) # no deps currently to build
option(WITH_BUILD_STATIC "Build preferring static linking." ON)
option(INSTALL_PYMAVLINK "Install pymavlink." ON)
# variables
set(ROOT_THREAD TRUE CACHE INTERNAL "Is this the top level of the recursion?")
# modules
list(APPEND CMAKE_MODULE_PATH ${MAVLINK_SOURCE_DIR}/cmake ${MAVLINK_SOURCE_DIR}/cmake/arkcmake)
include(DefineCMakeDefaults)
include(CheckIncludeFiles)
include(CheckFunctionExists)
include(CheckSymbolExists)
include(CheckLibraryExists)
#include(CheckTypeSize)
#include(CheckPrototypeExists)
#include(CheckCXXSourceCompiles)
#include(CheckCSourceCompiles)
include(ExternalProjectWithFilename)
if (UNIX)
include(GNUInstallDirs)
set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "Installation path for libraries")
endif ()
# spawn new cmake to build deps
if (WITH_BUILD_DEPS AND ROOT_THREAD)
execute_process(COMMAND ${CMAKE_COMMAND} "${MAVLINK_SOURCE_DIR}"
"-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}"
"-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}"
"-DWITH_BUILD_DEPS=${WITH_BUILD_DEPS}"
"-DWITH_BUILD_STATIC=${WITH_BUILD_STATIC}"
"-DWITH_TESTS=${WITH_TESTS}"
"-DROOT_THREAD=FALSE"
RESULT_VARIABLE ERROR)
if (ERROR)
message(FATAL_ERROR "error, recursing loop returned error code: ${ERROR}")
endif()
message("** Making dependencies")
execute_process(COMMAND ${CMAKE_MAKE_PROGRAM} "-j4" "-f${CMAKE_BINARY_DIR}/Makefile")
message("** Configuring ${PROJECT_NAME}")
if (NOT MAVLINK_DIALECT)
set(MAVLINK_DIALECT common)
endif()
message(STATUS "MAVLink dialect: ${MAVLINK_DIALECT}")
# external projects find path
if(NOT EP_BASE_DIR)
set(EP_BASE_DIR "${CMAKE_BINARY_DIR}/CMakeExternals")
if (NOT MAVLINK_VERSION)
set(MAVLINK_VERSION 2.0)
endif()
set_property(DIRECTORY PROPERTY EP_BASE ${EP_BASE_DIR})
set(EP_INSTALL_DIR "${EP_BASE_DIR}/Install")
list(APPEND CMAKE_FIND_ROOT_PATH ${EP_BASE_DIR})
message(STATUS "MAVLink version: ${MAVLINK_VERSION}")
# prefer static packages if building static library
message("** Finding libraries")
if (WITH_BUILD_STATIC)
# prefer static libs
if(WIN32)
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
else()
set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
endif()
endif()
set(EXAMPLE_HEADER ${CMAKE_CURRENT_BINARY_DIR}/include/mavlink/${MAVLINK_DIALECT}/mavlink.h)
# find libraries with cmake modules
if(${CMAKE_VERSION} VERSION_LESS 3.12)
option(USE_PYTHON3 "Use python3 to build MAVLink" OFF)
else()
option(USE_PYTHON3 "Use python3 to build MAVLink" ON)
endif()
add_custom_command(OUTPUT ${EXAMPLE_HEADER}
COMMAND Python::Interpreter
-m pymavlink.tools.mavgen
--lang=C
--wire-protocol=${MAVLINK_VERSION}
--output ${CMAKE_CURRENT_BINARY_DIR}/include/mavlink/
message_definitions/v1.0/${MAVLINK_DIALECT}.xml
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS message_definitions/v1.0/${MAVLINK_DIALECT}.xml
COMMENT "Generating C headers")
if(USE_PYTHON3)
find_package(Python3 COMPONENTS Interpreter Development REQUIRED)
set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE})
set(PYTHON_SITELIB ${Python3_SITELIB})
else()
find_package(PythonInterp)
set(PYTHON_SITELIB ${CMAKE_INSTALL_LIBDIR}/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages)
endif()
# enable languages
if (WITH_TESTS)
enable_language(C)
enable_language(CXX)
include(DefineCompilerFlags)
endif()
# Unfortunately, the dependencies don't work for INTERFACE libraries.
# The only way I could make it work is to add ALL which means it
# will do the file generation every time even when nothing has changed.
add_custom_target(generate_c_headers
ALL
DEPENDS ${EXAMPLE_HEADER})
# build dependencies
if (WITH_BUILD_DEPS AND (NOT ROOT_THREAD) )
message("** Configuring dependencies")
add_library(mavlink INTERFACE)
# add external projects
add_dependencies(mavlink generate_c_headers)
# none required currently
include(GNUInstallDirs)
set(CMAKE_DEFAULT_ARGS
-DEP_BASE_DIR=${EP_BASE_DIR}
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
)
target_include_directories(mavlink
INTERFACE
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
# terminate non root cmake thread
return()
endif()
install(TARGETS mavlink
EXPORT MAVLinkTargets
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
# configure
#check_include_files(string.h HAVE_STRING_H)
#check_function_exists(memcopy HAVE_MEMCOPY)
#check_symbol_exists(LC_MESSAGES "locale.h" HAVE_LC_MESSAGES)
#check_library_exists(pthread attachNode "" HAVE_PTHREAD)
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include/mavlink"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
FILES_MATCHING PATTERN "*.h"
)
# config files
configure_file(config.h.in config.h)
install(FILES ${CMAKE_BINARY_DIR}/config.h DESTINATION include/${PROJECT_NAME} COMPONENT Dev)
install(EXPORT MAVLinkTargets
FILE MAVLinkTargets.cmake
NAMESPACE MAVLink::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MAVLink
)
# mavgen location for mavlink generation
set(mavgen_EXECUTABLE_WITH_PYTHON_INVOCATION ${CMAKE_COMMAND} -E env "PYTHONPATH=$ENV{PYTHONPATH}:${CMAKE_CURRENT_SOURCE_DIR}" ${PYTHON_EXECUTABLE} -m pymavlink.tools.mavgen)
if(USE_SYSTEM_PYMAVLINK)
find_program (
mavgen_EXECUTABLE
NAMES mavgen mavgen.py
)
# For the build tree
configure_file(MAVLinkConfig.cmake.in
"${PROJECT_BINARY_DIR}/MAVLinkConfig.cmake" @ONLY)
# For the install tree
configure_file(MAVLinkConfig.cmake.in
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/MAVLinkConfig.cmake" @ONLY)
# Fallback to Python invocation, if not found.
if (mavgen_EXECUTABLE-NOTFOUND)
set(mavgen_EXECUTABLE ${mavgen_EXECUTABLE_WITH_PYTHON_INVOCATION})
endif()
else()
set(mavgen_EXECUTABLE ${mavgen_EXECUTABLE_WITH_PYTHON_INVOCATION})
endif()
message(STATUS "mavgen_EXECUTABLE: ${mavgen_EXECUTABLE}")
macro(generateMavlink version definitions)
foreach(definition ${definitions})
set(targetName ${definition}-v${version})
set(definitionAbsPath ${MAVLINK_SOURCE_DIR}/message_definitions/v1.0/${definition})
message(STATUS "processing: ${definitionAbsPath}")
add_custom_command(
OUTPUT ${targetName}-stamp
COMMAND ${mavgen_EXECUTABLE} --lang=C
--wire-protocol=${version}
--output=include/v${version}
${definitionAbsPath}
COMMAND touch ${targetName}-stamp
)
add_custom_target(${targetName} ALL DEPENDS ${targetName}-stamp)
endforeach()
endmacro()
# build
set(v1.0Definitions
ASLUAV.xml
ardupilotmega.xml
common.xml
matrixpilot.xml
minimal.xml
paparazzi.xml
python_array_test.xml
test.xml
ualberta.xml
)
generateMavlink("1.0" "${v1.0Definitions}")
generateMavlink("2.0" "${v1.0Definitions}")
# testing
if (BUILD_TEST)
if (UNIX)
include_directories(${CMAKE_BINARY_DIR}/include/v1.0/common)
# TODO fix udp example
#add_executable(mavlink_udp examples/linux/mavlink_udp.c)
endif()
endif()
# install files
install(DIRECTORY ${CMAKE_BINARY_DIR}/include/ DESTINATION include/${PROJECT_NAME} COMPONENT Dev FILES_MATCHING PATTERN "*.h*")
install(DIRECTORY ${CMAKE_BINARY_DIR}/src/ DESTINATION share/${PROJECT_NAME} COMPONENT Dev FILES_MATCHING PATTERN "*.c*")
install(DIRECTORY ${MAVLINK_SOURCE_DIR}/share/${PROJECT_NAME} DESTINATION share COMPONENT Dev FILES_MATCHING PATTERN "*.c*")
if (INSTALL_PYMAVLINK)
if (UNIX)
install(DIRECTORY ${MAVLINK_SOURCE_DIR}/pymavlink DESTINATION ${PYTHON_SITELIB} COMPONENT Dev)
else ()
install(DIRECTORY ${MAVLINK_SOURCE_DIR}/pymavlink DESTINATION "share/pyshared" COMPONENT Dev)
endif ()
endif()
configure_file(pc.in ${PROJECT_NAME}.pc)
install(FILES
${PROJECT_BINARY_DIR}/${PROJECT_NAME}.pc
DESTINATION lib${LIB_SUFFIX}/pkgconfig COMPONENT Dev
)
### packaging
# apple bundle icon
if (APPLE)
# set how it shows up in Info.plist
set(MACOSX_BUNDLE_ICON_FILE mavlink.icns)
# set where in the bundle to put the icns file
set_source_files_properties(cmake/mavlink.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
# include the icns file in the target
#list(APPEND MAVLINKGUI_SRCS cmake/mavlink.icns)
endif()
# set NSIS image
if (WIN32)
set(CPACK_PACKAGE_ICON "${MAVLINK_SOURCE_DIR}/cmake/mavlink.bmp")
endif()
# add file extensions and set resource files
configure_file("COPYING" "COPYING.txt" COPYONLY)
configure_file("README.md" "README.md" COPYONLY)
set(CPACK_RESOURCE_FILE_LICENSE "${MAVLINK_SOURCE_DIR}/COPYING")
set(CPACK_RESOURCE_FILE_README "${MAVLINK_SOURCE_DIR}/README.md")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CPACK_RESOURCE_FILE_README}")
set(CPACK_RESOURCE_FILE_WELCOME "${MAVLINK_SOURCE_DIR}/cmake/WELCOME.txt")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "mavlink message marshalling library")
set(CPACK_PACKAGE_VENDOR ${PROJECT_CONTACT_VENDOR})
set(CPACK_PACKAGE_CONTACT "${PROJECT_CONTACT_EMAIL}")
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
set(CPACK_SET_DESTDIR TRUE)
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}")
set(CPACK_COMPONENTS_GROUPING "ALL_COMPONENTS_IN_ONE")
include(CPack)
# vim:sw=4:ts=4:expandtab
"${PROJECT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/MAVLinkConfig.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MAVLink
)
+3
View File
@@ -0,0 +1,3 @@
get_filename_component(MAVLINK_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
include("${MAVLINK_CMAKE_DIR}/MAVLinkTargets.cmake")
+39 -6
View File
@@ -1,6 +1,6 @@
[![Build Status](https://github.com/mavlink/mavlink/workflows/Test%20and%20deploy/badge.svg)](https://github.com/mavlink/mavlink/actions?query=branch%3Amaster)
## MAVLink
# MAVLink
MAVLink -- Micro Air Vehicle Message Marshalling Library.
@@ -9,21 +9,21 @@ MAVLink is a very lightweight, header-only message library for communication bet
> **Tip** MAVLink is very well suited for applications with very limited communication bandwidth. Its reference implementation in C is highly optimized for resource-constrained systems with limited RAM and flash memory. It is field-proven and deployed in many products where it serves as interoperability interface between components of different manufacturers.
### QuickStart
## Quick start
### Generate C headers
To install the minimal MAVLink environment on Ubuntu LTS 20.04 or 22.04, enter the following on a terminal:
```bash
# Dependencies
sudo apt install python3-pip
sudo apt install python3-lxml libxml2-utils
# Clone mavlink into the directory of your choice
git clone https://github.com/mavlink/mavlink.git --recursive
cd mavlink
# Set the PYTHONPATH environment variable to the path of the root of the cloned mavlink repository
PYTHONPATH=$PWD
python3 -m pip install pymavlink/requirements.txt
```
You can then build the MAVLink2 C-library for `message_definitions/v1.0/common.xml` from the `/mavlink` directory as shown:
@@ -32,14 +32,47 @@ You can then build the MAVLink2 C-library for `message_definitions/v1.0/common.x
python3 -m pymavlink.tools.mavgen --lang=C --wire-protocol=2.0 --output=generated/include/mavlink/v2.0 message_definitions/v1.0/common.xml
```
### Use from cmake
To include the headers in cmake, install them locally, e.g. into the directory `install`:
```
cmake -Bbuild -H. -DCMAKE_INSTALL_PREFIX=install -DMAVLINK_DIALECT=common -DMAVLINK_VERSION=2.0
cmake --build build --target install
```
Then use `find_package` to get the dependency in `CMakeLists.txt`:
```
find_package(MAVLink REQUIRED)
add_executable(my_program my_program.c)
target_link_libraries(my_program PRIVATE MAVLink::mavlink)
```
And pass the local install directory to cmake (adapt to your directory structure):
```
cd ../my_program
cmake -Bbuild -H. -DCMAKE_PREFIX_PATH=../mavlink/install
```
For a full example, check [examples/c](examples/c).
*Note: even though we use `target_link_libraries` in cmake, it doesn't actually "link" to MAVLink as it's just a header-only library.*
### Other instructions
Instructions for using the C libraries are then covered in [Using C MAVLink Libraries (mavgen)](https://mavlink.io/en/mavgen_c/).
> **Note:** [Installing the MAVLink Toolchain](https://mavlink.io/en/getting_started/installation.html) explains how to install MAVLink on other Ubuntu platforms and Windows, while [Generating MAVLink Libraries](https://mavlink.io/en/getting_started/generate_libraries.html) explains how to build MAVLink for the other programming languages [supported by the project](https://mavlink.io/en/#supported_languages).
> The sub-topics of [Using MAVLink Libraries](https://mavlink.io/en/getting_started/use_libraries.html) explain how to use the generated libraries.
## Key Links
* [Documentation/Website](https://mavlink.io/en/) (mavlink.io/en/)
* [Discussion/Support](https://mavlink.io/en/#support) (Slack)
* [Discussion/Support](https://mavlink.io/en/#support)
* [Contributing](https://mavlink.io/en/contributing/contributing.html)
* [License](https://mavlink.io/en/#license)
-8
View File
@@ -1,8 +0,0 @@
# only keep relevant arkcmake files
arkcmake/*
!arkcmake/updateArkcmake.py
!arkcmake/DefineCMakeDefaults.cmake
!arkcmake/DefineCompilerFlags.cmake
!arkcmake/MacroCheckCCompilerFlagSSP.cmake
!arkcmake/MacroEnsureOutOfSourceBuild.cmake
!arkcmake/ExternalProjectWithFilename.cmake
-1
View File
@@ -1 +0,0 @@
Welcome to installation. This program will guide you through the installation of this software.
-32
View File
@@ -1,32 +0,0 @@
# Always include srcdir and builddir in include path
# This saves typing ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY} in
# about every subdir
# since cmake 2.4.0
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Put the include dirs which are in the source or build tree
# before all other include dirs, so the headers in the sources
# are prefered over the already installed ones
# since cmake 2.4.1
set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON)
# Use colored output
# since cmake 2.4.0
set(CMAKE_COLOR_MAKEFILE ON)
# Define the generic version of the libraries here
set(GENERIC_LIB_VERSION "0.1.0")
set(GENERIC_LIB_SOVERSION "0")
# Set the default build type to release with debug info
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE RelWithDebInfo
CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
)
endif (NOT CMAKE_BUILD_TYPE)
# disallow in-source build
include(MacroEnsureOutOfSourceBuild)
macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source build.
Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there.")
-90
View File
@@ -1,90 +0,0 @@
# define system dependent compiler flags
include(CheckCCompilerFlag)
include(MacroCheckCCompilerFlagSSP)
#
# Define GNUCC compiler flags
#
if (${CMAKE_C_COMPILER_ID} MATCHES GNU)
# add -Wconversion ?
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -pedantic -pedantic-errors")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wshadow -Wmissing-prototypes -Wdeclaration-after-statement")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused -Wfloat-equal -Wpointer-arith -Wwrite-strings -Wformat-security")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-format-attribute")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -pedantic-errors")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wshadow")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunused -Wfloat-equal -Wpointer-arith -Wwrite-strings -Wformat-security")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wmissing-format-attribute")
if (UNIX AND NOT WIN32)
# with -fPIC
check_c_compiler_flag("-fPIC" WITH_FPIC)
if (WITH_FPIC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
endif (WITH_FPIC)
endif(UNIX AND NOT WIN32)
check_c_compiler_flag_ssp("-fstack-protector" WITH_STACK_PROTECTOR)
if (WITH_STACK_PROTECTOR)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fstack-protector")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKDER_FLAGS} -fstack-protector")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKDER_FLAGS} -fstack-protector")
endif (WITH_STACK_PROTECTOR)
check_c_compiler_flag("-D_FORTIFY_SOURCE=2" WITH_FORTIFY_SOURCE)
if (WITH_FORTIFY_SOURCE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_FORTIFY_SOURCE=2")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORTIFY_SOURCE=2")
endif (WITH_FORTIFY_SOURCE)
endif (${CMAKE_C_COMPILER_ID} MATCHES GNU)
if (UNIX AND NOT WIN32)
#
# Check for large filesystem support
#
if (CMAKE_SIZEOF_VOID_P MATCHES "8")
# with large file support
execute_process(
COMMAND
getconf LFS64_CFLAGS
OUTPUT_VARIABLE
_lfs_CFLAGS
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
else (CMAKE_SIZEOF_VOID_P MATCHES "8")
# with large file support
execute_process(
COMMAND
getconf LFS_CFLAGS
OUTPUT_VARIABLE
_lfs_CFLAGS
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif (CMAKE_SIZEOF_VOID_P MATCHES "8")
if (_lfs_CFLAGS)
string(REGEX REPLACE "[\r\n]" " " "${_lfs_CFLAGS}" "${${_lfs_CFLAGS}}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_lfs_CFLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_lfs_CFLAGS}")
endif (_lfs_CFLAGS)
endif (UNIX AND NOT WIN32)
if (MSVC)
# Use secure functions by defaualt and suppress warnings about
#"deprecated" functions
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS}")
endif (MSVC)
File diff suppressed because it is too large Load Diff
@@ -1,26 +0,0 @@
# - Check whether the C compiler supports a given flag in the
# context of a stack checking compiler option.
# CHECK_C_COMPILER_FLAG_SSP(FLAG VARIABLE)
#
# FLAG - the compiler flag
# VARIABLE - variable to store the result
#
# This actually calls the check_c_source_compiles macro.
# See help for CheckCSourceCompiles for a listing of variables
# that can modify the build.
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
INCLUDE(CheckCSourceCompiles)
MACRO (CHECK_C_COMPILER_FLAG_SSP _FLAG _RESULT)
SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
SET(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}")
CHECK_C_SOURCE_COMPILES("int main(int argc, char **argv) { char buffer[256]; return buffer[argc]=0;}" ${_RESULT})
SET (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
ENDMACRO (CHECK_C_COMPILER_FLAG_SSP)
@@ -1,19 +0,0 @@
# - MACRO_ENSURE_OUT_OF_SOURCE_BUILD(<errorMessage>)
# MACRO_ENSURE_OUT_OF_SOURCE_BUILD(<errorMessage>)
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
macro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD _errorMessage)
string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" _insource)
if (_insource)
file(REMOVE [CMakeCache.txt CMakeFiles])
message(FATAL_ERROR "${_errorMessage}")
endif (_insource)
endmacro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD)
# vim:ts=4:sw=4:expandtab
-19
View File
@@ -1,19 +0,0 @@
#!/usr/bin/python
# Author: Lenna X. Peterson (github.com/lennax)
# Based on bash script by James Goppert (github.com/jgoppert)
#
# script used to update cmake modules from git repo, can't make this
# a submodule otherwise it won't know how to interpret the CMakeLists.txt
# # # # # # subprocess# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
import os # for os.path
import subprocess # for check_call()
clone_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
print(clone_path)
os.chdir(clone_path)
subprocess.check_call(["git", "clone", "git://github.com/arktools/arkcmake.git","arkcmake_tmp"])
subprocess.check_call(["rm", "-rf", "arkcmake_tmp/.git"])
if os.path.isdir("arkcmake"):
subprocess.check_call(["rm", "-rf", "arkcmake"])
subprocess.check_call(["mv", "arkcmake_tmp", "arkcmake"])
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

-1
View File
@@ -1 +0,0 @@
#define MAVLINK_VERSION "${PROJECT_VERSION}"
+11
View File
@@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.13)
project(udp_example C)
set(CMAKE_C_STANDARD 11)
find_package(MAVLink REQUIRED)
add_executable(udp_example udp_example.c)
target_link_libraries(udp_example PRIVATE MAVLink::mavlink)
+22
View File
@@ -0,0 +1,22 @@
# Simple C example
Simple example receiving and sending MAVLink v2 over UDP based on POSIX APIs (e.g. Linux, BSD, macOS).
## Install MAVLink
In top level directory, build and install the MAVLink headers locally into the install folder:
```
cmake -Bbuild -H. -DCMAKE_INSTALL_PREFIX=install
cmake --build build --target install
```
## Build example
In the example directory, build the example while passing the local install directory:
```
cd examples/c
cmake -Bbuild -H. -DCMAKE_PREFIX_PATH=$(pwd)/../../install
cmake --build build
```
+171
View File
@@ -0,0 +1,171 @@
// Simple example receiving and sending MAVLink v2 over UDP
// based on POSIX APIs (e.g. Linux, BSD, macOS).
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <time.h>
#include <mavlink/common/mavlink.h>
void receive_some(int socket_fd, struct sockaddr_in* src_addr, socklen_t* src_addr_len, bool* src_addr_set);
void handle_heartbeat(const mavlink_message_t* message);
void send_some(int socket_fd, const struct sockaddr_in* src_addr, socklen_t src_addr_len);
void send_heartbeat(int socket_fd, const struct sockaddr_in* src_addr, socklen_t src_addr_len);
int main(int argc, char* argv[])
{
// Open UDP socket
const int socket_fd = socket(PF_INET, SOCK_DGRAM, 0);
if (socket_fd < 0) {
printf("socket error: %s\n", strerror(errno));
return -1;
}
// Bind to port
struct sockaddr_in addr = {};
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
inet_pton(AF_INET, "0.0.0.0", &(addr.sin_addr)); // listen on all network interfaces
addr.sin_port = htons(14550); // default port on the ground
if (bind(socket_fd, (struct sockaddr*)(&addr), sizeof(addr)) != 0) {
printf("bind error: %s\n", strerror(errno));
return -2;
}
// We set a timeout at 100ms to prevent being stuck in recvfrom for too
// long and missing our chance to send some stuff.
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 100000;
if (setsockopt(socket_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
printf("setsockopt error: %s\n", strerror(errno));
return -3;
}
struct sockaddr_in src_addr = {};
socklen_t src_addr_len = sizeof(src_addr);
bool src_addr_set = false;
while (true) {
// For illustration purposes we don't bother with threads or async here
// and just interleave receiving and sending.
// This only works if receive_some returns every now and then.
receive_some(socket_fd, &src_addr, &src_addr_len, &src_addr_set);
if (src_addr_set) {
send_some(socket_fd, &src_addr, src_addr_len);
}
}
return 0;
}
void receive_some(int socket_fd, struct sockaddr_in* src_addr, socklen_t* src_addr_len, bool* src_addr_set)
{
// We just receive one UDP datagram and then return again.
char buffer[2048]; // enough for MTU 1500 bytes
const int ret = recvfrom(
socket_fd, buffer, sizeof(buffer), 0, (struct sockaddr*)(src_addr), src_addr_len);
if (ret < 0) {
printf("recvfrom error: %s\n", strerror(errno));
} else if (ret == 0) {
// peer has done an orderly shutdown
return;
}
*src_addr_set = true;
mavlink_message_t message;
mavlink_status_t status;
for (int i = 0; i < ret; ++i) {
if (mavlink_parse_char(MAVLINK_COMM_0, buffer[i], &message, &status) == 1) {
// printf(
// "Received message %d from %d/%d\n",
// message.msgid, message.sysid, message.compid);
switch (message.msgid) {
case MAVLINK_MSG_ID_HEARTBEAT:
handle_heartbeat(&message);
break;
}
}
}
}
void handle_heartbeat(const mavlink_message_t* message)
{
mavlink_heartbeat_t heartbeat;
mavlink_msg_heartbeat_decode(message, &heartbeat);
printf("Got heartbeat from ");
switch (heartbeat.autopilot) {
case MAV_AUTOPILOT_GENERIC:
printf("generic");
break;
case MAV_AUTOPILOT_ARDUPILOTMEGA:
printf("ArduPilot");
break;
case MAV_AUTOPILOT_PX4:
printf("PX4");
break;
default:
printf("other");
break;
}
printf(" autopilot\n");
}
void send_some(int socket_fd, const struct sockaddr_in* src_addr, socklen_t src_addr_len)
{
// Whenever a second has passed, we send a heartbeat.
static time_t last_time = 0;
time_t current_time = time(NULL);
if (current_time - last_time >= 1) {
send_heartbeat(socket_fd, src_addr, src_addr_len);
last_time = current_time;
}
}
void send_heartbeat(int socket_fd, const struct sockaddr_in* src_addr, socklen_t src_addr_len)
{
mavlink_message_t message;
const uint8_t system_id = 42;
const uint8_t base_mode = 0;
const uint8_t custom_mode = 0;
mavlink_msg_heartbeat_pack_chan(
system_id,
MAV_COMP_ID_PERIPHERAL,
MAVLINK_COMM_0,
&message,
MAV_TYPE_GENERIC,
MAV_AUTOPILOT_GENERIC,
base_mode,
custom_mode,
MAV_STATE_STANDBY);
uint8_t buffer[MAVLINK_MAX_PACKET_LEN];
const int len = mavlink_msg_to_send_buffer(buffer, &message);
int ret = sendto(socket_fd, buffer, len, 0, (const struct sockaddr*)src_addr, src_addr_len);
if (ret != len) {
printf("sendto error: %s\n", strerror(errno));
} else {
printf("Sent heartbeat\n");
}
}
-1
View File
@@ -1 +0,0 @@
mavlink_udp
-21
View File
@@ -1,21 +0,0 @@
# MAVLink UDP Quickstart Instructions
MAVLink UDP Example for *nix system (Linux, MacOS, BSD, etc.)
To compile with GCC, just enter:
```
gcc -std=c99 -I ../../include/common -o mavlink_udp mavlink_udp.c
```
The MAVLink header directory must be added to the include path, as shown above.
Be sure to use version 2.0 of the MAVLink headers for this example
as the example uses MAVLink 2 extension fields.
To run, type:
```
./mavlink_udp
```
If you run *QGroundControl* on the same machine, checkout received message in MAVLink Inspector widget.
-219
View File
@@ -1,219 +0,0 @@
/*******************************************************************************
Copyright (C) 2010 Bryan Godbolt godbolt ( a t ) ualberta.ca
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
/*
This program sends some data to qgroundcontrol using the mavlink protocol. The sent packets
cause qgroundcontrol to respond with heartbeats. Any settings or custom commands sent from
qgroundcontrol are printed by this program along with the heartbeats.
I compiled this program successfully on Ubuntu 10.04 with the following command
gcc -I ../../pixhawk/mavlink/include -o udp-server udp-server-test.c
the rt library is needed for the clock_gettime on linux
*/
/* These headers are for QNX, but should all be standard on unix/linux */
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <time.h>
#if (defined __QNX__) | (defined __QNXNTO__)
/* QNX specific headers */
#include <unix.h>
#else
/* Linux / MacOS POSIX timer headers */
#include <sys/time.h>
#include <time.h>
#include <arpa/inet.h>
#include <stdbool.h> /* required for the definition of bool in C99 */
#endif
/* This assumes you have the mavlink headers on your include path
or in the same folder as this source file */
#include <mavlink.h>
#define BUFFER_LENGTH 2041 // minimum buffer size that can be used with qnx (I don't know why)
uint64_t microsSinceEpoch();
int main(int argc, char* argv[])
{
char help[] = "--help";
char target_ip[100];
float position[6] = {};
int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
struct sockaddr_in gcAddr;
struct sockaddr_in locAddr;
//struct sockaddr_in fromAddr;
uint8_t buf[BUFFER_LENGTH];
ssize_t recsize;
socklen_t fromlen = sizeof(gcAddr);
int bytes_sent;
mavlink_message_t msg;
uint16_t len;
int i = 0;
//int success = 0;
unsigned int temp = 0;
// Check if --help flag was used
if ((argc == 2) && (strcmp(argv[1], help) == 0))
{
printf("\n");
printf("\tUsage:\n\n");
printf("\t");
printf("%s", argv[0]);
printf(" <ip address of QGroundControl>\n");
printf("\tDefault for localhost: udp-server 127.0.0.1\n\n");
exit(EXIT_FAILURE);
}
// Change the target ip if parameter was given
strcpy(target_ip, "127.0.0.1");
if (argc == 2)
{
strcpy(target_ip, argv[1]);
}
memset(&locAddr, 0, sizeof(locAddr));
locAddr.sin_family = AF_INET;
locAddr.sin_addr.s_addr = INADDR_ANY;
locAddr.sin_port = htons(14551);
/* Bind the socket to port 14551 - necessary to receive packets from qgroundcontrol */
if (-1 == bind(sock,(struct sockaddr *)&locAddr, sizeof(struct sockaddr)))
{
perror("error bind failed");
close(sock);
exit(EXIT_FAILURE);
}
/* Attempt to make it non blocking */
#if (defined __QNX__) | (defined __QNXNTO__)
if (fcntl(sock, F_SETFL, O_NONBLOCK | FASYNC) < 0)
#else
if (fcntl(sock, F_SETFL, O_NONBLOCK | O_ASYNC) < 0)
#endif
{
fprintf(stderr, "error setting nonblocking: %s\n", strerror(errno));
close(sock);
exit(EXIT_FAILURE);
}
memset(&gcAddr, 0, sizeof(gcAddr));
gcAddr.sin_family = AF_INET;
gcAddr.sin_addr.s_addr = inet_addr(target_ip);
gcAddr.sin_port = htons(14550);
for (;;)
{
/*Send Heartbeat */
mavlink_msg_heartbeat_pack(1, 200, &msg, MAV_TYPE_HELICOPTER, MAV_AUTOPILOT_GENERIC, MAV_MODE_GUIDED_ARMED, 0, MAV_STATE_ACTIVE);
len = mavlink_msg_to_send_buffer(buf, &msg);
bytes_sent = sendto(sock, buf, len, 0, (struct sockaddr*)&gcAddr, sizeof(struct sockaddr_in));
/* Send Status */
mavlink_msg_sys_status_pack(1, 200, &msg, 0, 0, 0, 500, 11000, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
len = mavlink_msg_to_send_buffer(buf, &msg);
bytes_sent = sendto(sock, buf, len, 0, (struct sockaddr*)&gcAddr, sizeof (struct sockaddr_in));
/* Send Local Position */
mavlink_msg_local_position_ned_pack(1, 200, &msg, microsSinceEpoch(),
position[0], position[1], position[2],
position[3], position[4], position[5]);
len = mavlink_msg_to_send_buffer(buf, &msg);
bytes_sent = sendto(sock, buf, len, 0, (struct sockaddr*)&gcAddr, sizeof(struct sockaddr_in));
/* Send attitude */
mavlink_msg_attitude_pack(1, 200, &msg, microsSinceEpoch(), 1.2, 1.7, 3.14, 0.01, 0.02, 0.03);
len = mavlink_msg_to_send_buffer(buf, &msg);
bytes_sent = sendto(sock, buf, len, 0, (struct sockaddr*)&gcAddr, sizeof(struct sockaddr_in));
memset(buf, 0, BUFFER_LENGTH);
recsize = recvfrom(sock, (void *)buf, BUFFER_LENGTH, 0, (struct sockaddr *)&gcAddr, &fromlen);
if (recsize > 0)
{
// Something received - print out all bytes and parse packet
mavlink_message_t msg;
mavlink_status_t status;
printf("Bytes Received: %d\nDatagram: ", (int)recsize);
for (i = 0; i < recsize; ++i)
{
temp = buf[i];
printf("%02x ", (unsigned char)temp);
if (mavlink_parse_char(MAVLINK_COMM_0, buf[i], &msg, &status))
{
// Packet received
printf("\nReceived packet: SYS: %d, COMP: %d, LEN: %d, MSG ID: %d\n", msg.sysid, msg.compid, msg.len, msg.msgid);
}
}
printf("\n");
}
memset(buf, 0, BUFFER_LENGTH);
sleep(1); // Sleep one second
}
}
/* QNX timer version */
#if (defined __QNX__) | (defined __QNXNTO__)
uint64_t microsSinceEpoch()
{
struct timespec time;
uint64_t micros = 0;
clock_gettime(CLOCK_REALTIME, &time);
micros = (uint64_t)time.tv_sec * 1000000 + time.tv_nsec/1000;
return micros;
}
#else
uint64_t microsSinceEpoch()
{
struct timeval tv;
uint64_t micros = 0;
gettimeofday(&tv, NULL);
micros = ((uint64_t)tv.tv_sec) * 1000000 + tv.tv_usec;
return micros;
}
#endif
-7
View File
@@ -1,7 +0,0 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@CMAKE_INSTALL_PREFIX@
Name: @PROJECT_NAME@
Description: MAVLink micro air vehicle marshalling / communication library
Version: @PROJECT_VERSION@
Cflags: -I@CMAKE_INSTALL_PREFIX@/include/@PROJECT_NAME@