diff --git a/.github/workflows/test_and_deploy.yml b/.github/workflows/test_and_deploy.yml index 44a448e8..358d1238 100644 --- a/.github/workflows/test_and_deploy.yml +++ b/.github/workflows/test_and_deploy.yml @@ -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 diff --git a/.gitignore b/.gitignore index 80269487..21f992e7 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ doc/messages doc/*.log .DS_Store build* +install* .nfs* share/ __pycache__ diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a77f381..92ed5676 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 + $ +) - # 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 +) diff --git a/MAVLinkConfig.cmake.in b/MAVLinkConfig.cmake.in new file mode 100644 index 00000000..d6f37a3f --- /dev/null +++ b/MAVLinkConfig.cmake.in @@ -0,0 +1,3 @@ +get_filename_component(MAVLINK_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) +include("${MAVLINK_CMAKE_DIR}/MAVLinkTargets.cmake") + diff --git a/README.md b/README.md index dd1140d1..0d6deeb9 100644 --- a/README.md +++ b/README.md @@ -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) diff --git a/cmake/.gitignore b/cmake/.gitignore deleted file mode 100644 index dd0a0cd8..00000000 --- a/cmake/.gitignore +++ /dev/null @@ -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 diff --git a/cmake/WELCOME.txt b/cmake/WELCOME.txt deleted file mode 100644 index 5330087b..00000000 --- a/cmake/WELCOME.txt +++ /dev/null @@ -1 +0,0 @@ -Welcome to installation. This program will guide you through the installation of this software. diff --git a/cmake/arkcmake/DefineCMakeDefaults.cmake b/cmake/arkcmake/DefineCMakeDefaults.cmake deleted file mode 100644 index 1ea2fd8f..00000000 --- a/cmake/arkcmake/DefineCMakeDefaults.cmake +++ /dev/null @@ -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.") diff --git a/cmake/arkcmake/DefineCompilerFlags.cmake b/cmake/arkcmake/DefineCompilerFlags.cmake deleted file mode 100644 index 0926328b..00000000 --- a/cmake/arkcmake/DefineCompilerFlags.cmake +++ /dev/null @@ -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) diff --git a/cmake/arkcmake/ExternalProjectWithFilename.cmake b/cmake/arkcmake/ExternalProjectWithFilename.cmake deleted file mode 100644 index b4ca674f..00000000 --- a/cmake/arkcmake/ExternalProjectWithFilename.cmake +++ /dev/null @@ -1,1497 +0,0 @@ -# - Create custom targets to build projects in external trees -# The 'ExternalProjectWithFilename_Add' function creates a custom target to drive -# download, update/patch, configure, build, install and test steps of an -# external project: -# ExternalProjectWithFilename_Add( # Name for custom target -# [DEPENDS projects...] # Targets on which the project depends -# [PREFIX dir] # Root dir for entire project -# [LIST_SEPARATOR sep] # Sep to be replaced by ; in cmd lines -# [TMP_DIR dir] # Directory to store temporary files -# [STAMP_DIR dir] # Directory to store step timestamps -# #--Download step-------------- -# [FILENAME filename] # Set the download filename -# [DOWNLOAD_DIR dir] # Directory to store downloaded files -# [DOWNLOAD_COMMAND cmd...] # Command to download source tree -# [CVS_REPOSITORY cvsroot] # CVSROOT of CVS repository -# [CVS_MODULE mod] # Module to checkout from CVS repo -# [CVS_TAG tag] # Tag to checkout from CVS repo -# [SVN_REPOSITORY url] # URL of Subversion repo -# [SVN_REVISION rev] # Revision to checkout from Subversion repo -# [SVN_USERNAME john ] # Username for Subversion checkout and update -# [SVN_PASSWORD doe ] # Password for Subversion checkout and update -# [SVN_TRUST_CERT 1 ] # Trust the Subversion server site certificate -# [GIT_REPOSITORY url] # URL of git repo -# [GIT_TAG tag] # Git branch name, commit id or tag -# [URL /.../src.tgz] # Full path or URL of source -# [URL_MD5 md5] # MD5 checksum of file at URL -# [TIMEOUT seconds] # Time allowed for file download operations -# #--Update/Patch step---------- -# [UPDATE_COMMAND cmd...] # Source work-tree update command -# [PATCH_COMMAND cmd...] # Command to patch downloaded source -# #--Configure step------------- -# [SOURCE_DIR dir] # Source dir to be used for build -# [CONFIGURE_COMMAND cmd...] # Build tree configuration command -# [CMAKE_COMMAND /.../cmake] # Specify alternative cmake executable -# [CMAKE_GENERATOR gen] # Specify generator for native build -# [CMAKE_ARGS args...] # Arguments to CMake command line -# [CMAKE_CACHE_ARGS args...] # Initial cache arguments, of the form -Dvar:string=on -# #--Build step----------------- -# [BINARY_DIR dir] # Specify build dir location -# [BUILD_COMMAND cmd...] # Command to drive the native build -# [BUILD_IN_SOURCE 1] # Use source dir for build dir -# #--Install step--------------- -# [INSTALL_DIR dir] # Installation prefix -# [INSTALL_COMMAND cmd...] # Command to drive install after build -# #--Test step------------------ -# [TEST_BEFORE_INSTALL 1] # Add test step executed before install step -# [TEST_AFTER_INSTALL 1] # Add test step executed after install step -# [TEST_COMMAND cmd...] # Command to drive test -# #--Output logging------------- -# [LOG_DOWNLOAD 1] # Wrap download in script to log output -# [LOG_UPDATE 1] # Wrap update in script to log output -# [LOG_CONFIGURE 1] # Wrap configure in script to log output -# [LOG_BUILD 1] # Wrap build in script to log output -# [LOG_TEST 1] # Wrap test in script to log output -# [LOG_INSTALL 1] # Wrap install in script to log output -# #--Custom targets------------- -# [STEP_TARGETS st1 st2 ...] # Generate custom targets for these steps -# ) -# The *_DIR options specify directories for the project, with default -# directories computed as follows. -# If the PREFIX option is given to ExternalProjectWithFilename_Add() or the EP_PREFIX -# directory property is set, then an external project is built and installed -# under the specified prefix: -# TMP_DIR = /tmp -# STAMP_DIR = /src/-stamp -# DOWNLOAD_DIR = /src -# SOURCE_DIR = /src/ -# BINARY_DIR = /src/-build -# INSTALL_DIR = -# Otherwise, if the EP_BASE directory property is set then components -# of an external project are stored under the specified base: -# TMP_DIR = /tmp/ -# STAMP_DIR = /Stamp/ -# DOWNLOAD_DIR = /Download/ -# SOURCE_DIR = /Source/ -# BINARY_DIR = /Build/ -# INSTALL_DIR = /Install/ -# If no PREFIX, EP_PREFIX, or EP_BASE is specified then the default -# is to set PREFIX to "-prefix". -# Relative paths are interpreted with respect to the build directory -# corresponding to the source directory in which ExternalProjectWithFilename_Add is -# invoked. -# -# If SOURCE_DIR is explicitly set to an existing directory the project -# will be built from it. -# Otherwise a download step must be specified using one of the -# DOWNLOAD_COMMAND, CVS_*, SVN_*, or URL options. -# The URL option may refer locally to a directory or source tarball, -# or refer to a remote tarball (e.g. http://.../src.tgz). -# -# The 'ExternalProjectWithFilename_Add_Step' function adds a custom step to an external -# project: -# ExternalProjectWithFilename_Add_Step( # Names of project and custom step -# [COMMAND cmd...] # Command line invoked by this step -# [COMMENT "text..."] # Text printed when step executes -# [DEPENDEES steps...] # Steps on which this step depends -# [DEPENDERS steps...] # Steps that depend on this step -# [DEPENDS files...] # Files on which this step depends -# [ALWAYS 1] # No stamp file, step always runs -# [WORKING_DIRECTORY dir] # Working directory for command -# [LOG 1] # Wrap step in script to log output -# ) -# The command line, comment, and working directory of every standard -# and custom step is processed to replace tokens -# , -# , -# , -# and -# with corresponding property values. -# -# The 'ExternalProjectWithFilename_Get_Property' function retrieves external project -# target properties: -# ExternalProjectWithFilename_Get_Property( [prop1 [prop2 [...]]]) -# It stores property values in variables of the same name. -# Property names correspond to the keyword argument names of -# 'ExternalProjectWithFilename_Add'. -# -# The 'ExternalProjectWithFilename_Add_StepTargets' function generates custom targets for -# the steps listed: -# ExternalProjectWithFilename_Add_StepTargets( [step1 [step2 [...]]]) -# -# If STEP_TARGETS is set then ExternalProjectWithFilename_Add_StepTargets is automatically -# called at the end of matching calls to ExternalProjectWithFilename_Add_Step. Pass -# STEP_TARGETS explicitly to individual ExternalProjectWithFilename_Add calls, or -# implicitly to all ExternalProjectWithFilename_Add calls by setting the directory property -# EP_STEP_TARGETS. -# -# If STEP_TARGETS is not set, clients may still manually call -# ExternalProjectWithFilename_Add_StepTargets after calling ExternalProjectWithFilename_Add or -# ExternalProjectWithFilename_Add_Step. -# -# This functionality is provided to make it easy to drive the steps -# independently of each other by specifying targets on build command lines. -# For example, you may be submitting to a sub-project based dashboard, where -# you want to drive the configure portion of the build, then submit to the -# dashboard, followed by the build portion, followed by tests. If you invoke -# a custom target that depends on a step halfway through the step dependency -# chain, then all the previous steps will also run to ensure everything is -# up to date. -# -# For example, to drive configure, build and test steps independently for each -# ExternalProjectWithFilename_Add call in your project, write the following line prior to -# any ExternalProjectWithFilename_Add calls in your CMakeLists file: -# -# set_property(DIRECTORY PROPERTY EP_STEP_TARGETS configure build test) - -#============================================================================= -# Copyright 2008-2009 Kitware, Inc. -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of CMake, substitute the full -# License text for the above reference.) - -# Pre-compute a regex to match documented keywords for each command. -math(EXPR _ep_documentation_line_count "${CMAKE_CURRENT_LIST_LINE} - 16") -file(STRINGS "${CMAKE_CURRENT_LIST_FILE}" lines - LIMIT_COUNT ${_ep_documentation_line_count} - REGEX "^# ( \\[[A-Z0-9_]+ [^]]*\\] +#.*$|[A-Za-z0-9_]+\\()") -foreach(line IN LISTS lines) - if("${line}" MATCHES "^# [A-Za-z0-9_]+\\(") - if(_ep_func) - set(_ep_keywords_${_ep_func} "${_ep_keywords_${_ep_func}})$") - endif() - string(REGEX REPLACE "^# ([A-Za-z0-9_]+)\\(.*" "\\1" _ep_func "${line}") - #message("function [${_ep_func}]") - set(_ep_keywords_${_ep_func} "^(") - set(_ep_keyword_sep) - else() - string(REGEX REPLACE "^# \\[([A-Z0-9_]+) .*" "\\1" _ep_key "${line}") - #message(" keyword [${_ep_key}]") - set(_ep_keywords_${_ep_func} - "${_ep_keywords_${_ep_func}}${_ep_keyword_sep}${_ep_key}") - set(_ep_keyword_sep "|") - endif() -endforeach() -if(_ep_func) - set(_ep_keywords_${_ep_func} "${_ep_keywords_${_ep_func}})$") -endif() - - -function(_ep_parse_arguments f name ns args) - # Transfer the arguments to this function into target properties for the - # new custom target we just added so that we can set up all the build steps - # correctly based on target properties. - # - # We loop through ARGN and consider the namespace starting with an - # upper-case letter followed by at least two more upper-case letters, - # numbers or underscores to be keywords. - set(key) - - foreach(arg IN LISTS args) - set(is_value 1) - - if(arg MATCHES "^[A-Z][A-Z0-9_][A-Z0-9_]+$" AND - NOT ((arg STREQUAL "${key}") AND (key STREQUAL "COMMAND")) AND - NOT arg MATCHES "^(TRUE|FALSE)$") - if(_ep_keywords_${f} AND arg MATCHES "${_ep_keywords_${f}}") - set(is_value 0) - endif() - endif() - - if(is_value) - if(key) - # Value - if(NOT arg STREQUAL "") - set_property(TARGET ${name} APPEND PROPERTY ${ns}${key} "${arg}") - else() - get_property(have_key TARGET ${name} PROPERTY ${ns}${key} SET) - if(have_key) - get_property(value TARGET ${name} PROPERTY ${ns}${key}) - set_property(TARGET ${name} PROPERTY ${ns}${key} "${value};${arg}") - else() - set_property(TARGET ${name} PROPERTY ${ns}${key} "${arg}") - endif() - endif() - else() - # Missing Keyword - message(AUTHOR_WARNING "value '${arg}' with no previous keyword in ${f}") - endif() - else() - set(key "${arg}") - endif() - endforeach() -endfunction(_ep_parse_arguments) - - -define_property(DIRECTORY PROPERTY "EP_BASE" INHERITED - BRIEF_DOCS "Base directory for External Project storage." - FULL_DOCS - "See documentation of the ExternalProjectWithFilename_Add() function in the " - "ExternalProjectWithFilename module." - ) - -define_property(DIRECTORY PROPERTY "EP_PREFIX" INHERITED - BRIEF_DOCS "Top prefix for External Project storage." - FULL_DOCS - "See documentation of the ExternalProjectWithFilename_Add() function in the " - "ExternalProjectWithFilename module." - ) - -define_property(DIRECTORY PROPERTY "EP_STEP_TARGETS" INHERITED - BRIEF_DOCS - "List of ExternalProjectWithFilename steps that automatically get corresponding targets" - FULL_DOCS - "See documentation of the ExternalProjectWithFilename_Add_StepTargets() function in the " - "ExternalProjectWithFilename module." - ) - - -function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git_repository git_tag src_name work_dir) - file(WRITE ${script_filename} -"if(\"${git_tag}\" STREQUAL \"\") - message(FATAL_ERROR \"Tag for git checkout should not be empty.\") -endif() - -execute_process( - COMMAND \${CMAKE_COMMAND} -E remove_directory \"${source_dir}\" - RESULT_VARIABLE error_code - ) -if(error_code) - message(FATAL_ERROR \"Failed to remove directory: '${source_dir}'\") -endif() - -execute_process( - COMMAND \"${git_EXECUTABLE}\" clone \"${git_repository}\" \"${src_name}\" - WORKING_DIRECTORY \"${work_dir}\" - RESULT_VARIABLE error_code - ) -if(error_code) - message(FATAL_ERROR \"Failed to clone repository: '${git_repository}'\") -endif() - -execute_process( - COMMAND \"${git_EXECUTABLE}\" checkout ${git_tag} - WORKING_DIRECTORY \"${work_dir}/${src_name}\" - RESULT_VARIABLE error_code - ) -if(error_code) - message(FATAL_ERROR \"Failed to checkout tag: '${git_tag}'\") -endif() - -execute_process( - COMMAND \"${git_EXECUTABLE}\" submodule init - WORKING_DIRECTORY \"${work_dir}/${src_name}\" - RESULT_VARIABLE error_code - ) -if(error_code) - message(FATAL_ERROR \"Failed to init submodules in: '${work_dir}/${src_name}'\") -endif() - -execute_process( - COMMAND \"${git_EXECUTABLE}\" submodule update --recursive - WORKING_DIRECTORY \"${work_dir}/${src_name}\" - RESULT_VARIABLE error_code - ) -if(error_code) - message(FATAL_ERROR \"Failed to update submodules in: '${work_dir}/${src_name}'\") -endif() - -" -) - -endfunction(_ep_write_gitclone_script) - - -function(_ep_write_downloadfile_script script_filename remote local timeout md5) - if(timeout) - set(timeout_args TIMEOUT ${timeout}) - set(timeout_msg "${timeout} seconds") - else() - set(timeout_args "# no TIMEOUT") - set(timeout_msg "none") - endif() - - if(md5) - set(md5_args EXPECTED_MD5 ${md5}) - else() - set(md5_args "# no EXPECTED_MD5") - endif() - - file(WRITE ${script_filename} -"message(STATUS \"downloading... - src='${remote}' - dst='${local}' - timeout='${timeout_msg}'\") - -file(DOWNLOAD - \"${remote}\" - \"${local}\" - SHOW_PROGRESS - ${md5_args} - ${timeout_args} - STATUS status - LOG log) - -list(GET status 0 status_code) -list(GET status 1 status_string) - -if(NOT status_code EQUAL 0) - message(FATAL_ERROR \"error: downloading '${remote}' failed - status_code: \${status_code} - status_string: \${status_string} - log: \${log} -\") -endif() - -message(STATUS \"downloading... done\") -" -) - -endfunction(_ep_write_downloadfile_script) - - -function(_ep_write_verifyfile_script script_filename local md5) - file(WRITE ${script_filename} -"message(STATUS \"verifying file... - file='${local}'\") - -set(verified 0) - -# If an expected md5 checksum exists, compare against it: -# -if(NOT \"${md5}\" STREQUAL \"\") - execute_process(COMMAND \${CMAKE_COMMAND} -E md5sum \"${local}\" - OUTPUT_VARIABLE ov - OUTPUT_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE rv) - - if(NOT rv EQUAL 0) - message(FATAL_ERROR \"error: computing md5sum of '${local}' failed\") - endif() - - string(REGEX MATCH \"^([0-9A-Fa-f]+)\" md5_actual \"\${ov}\") - - string(TOLOWER \"\${md5_actual}\" md5_actual) - string(TOLOWER \"${md5}\" md5) - - if(NOT \"\${md5}\" STREQUAL \"\${md5_actual}\") - message(FATAL_ERROR \"error: md5sum of '${local}' does not match expected value - md5_expected: \${md5} - md5_actual: \${md5_actual} -\") - endif() - - set(verified 1) -endif() - -if(verified) - message(STATUS \"verifying file... done\") -else() - message(STATUS \"verifying file... warning: did not verify file - no URL_MD5 checksum argument? corrupt file?\") -endif() -" -) - -endfunction(_ep_write_verifyfile_script) - - -function(_ep_write_extractfile_script script_filename name filename directory) - set(args "") - - if(filename MATCHES "(\\.|=)(bz2|tar\\.gz|tgz|zip)$") - set(args xfz) - endif() - - if(filename MATCHES "(\\.|=)tar$") - set(args xf) - endif() - - if(args STREQUAL "") - message(SEND_ERROR "error: do not know how to extract '${filename}' -- known types are .bz2, .tar, .tar.gz, .tgz and .zip") - return() - endif() - - file(WRITE ${script_filename} -"# Make file names absolute: -# -get_filename_component(filename \"${filename}\" ABSOLUTE) -get_filename_component(directory \"${directory}\" ABSOLUTE) - -message(STATUS \"extracting... - src='\${filename}' - dst='\${directory}'\") - -if(NOT EXISTS \"\${filename}\") - message(FATAL_ERROR \"error: file to extract does not exist: '\${filename}'\") -endif() - -# Prepare a space for extracting: -# -set(i 1234) -while(EXISTS \"\${directory}/../ex-${name}\${i}\") - math(EXPR i \"\${i} + 1\") -endwhile() -set(ut_dir \"\${directory}/../ex-${name}\${i}\") -file(MAKE_DIRECTORY \"\${ut_dir}\") - -# Extract it: -# -message(STATUS \"extracting... [tar ${args}]\") -execute_process(COMMAND \${CMAKE_COMMAND} -E tar ${args} \${filename} - WORKING_DIRECTORY \${ut_dir} - RESULT_VARIABLE rv) - -if(NOT rv EQUAL 0) - message(STATUS \"extracting... [error clean up]\") - file(REMOVE_RECURSE \"\${ut_dir}\") - message(FATAL_ERROR \"error: extract of '\${filename}' failed\") -endif() - -# Analyze what came out of the tar file: -# -message(STATUS \"extracting... [analysis]\") -file(GLOB contents \"\${ut_dir}/*\") -list(LENGTH contents n) -if(NOT n EQUAL 1 OR NOT IS_DIRECTORY \"\${contents}\") - set(contents \"\${ut_dir}\") -endif() - -# Move \"the one\" directory to the final directory: -# -message(STATUS \"extracting... [rename]\") -file(REMOVE_RECURSE \${directory}) -get_filename_component(contents \${contents} ABSOLUTE) -file(RENAME \${contents} \${directory}) - -# Clean up: -# -message(STATUS \"extracting... [clean up]\") -file(REMOVE_RECURSE \"\${ut_dir}\") - -message(STATUS \"extracting... done\") -" -) - -endfunction(_ep_write_extractfile_script) - - -function(_ep_set_directories name) - get_property(prefix TARGET ${name} PROPERTY _EP_PREFIX) - if(NOT prefix) - get_property(prefix DIRECTORY PROPERTY EP_PREFIX) - if(NOT prefix) - get_property(base DIRECTORY PROPERTY EP_BASE) - if(NOT base) - set(prefix "${name}-prefix") - endif() - endif() - endif() - if(prefix) - set(tmp_default "${prefix}/tmp") - set(download_default "${prefix}/src") - set(source_default "${prefix}/src/${name}") - set(binary_default "${prefix}/src/${name}-build") - set(stamp_default "${prefix}/src/${name}-stamp") - set(install_default "${prefix}") - else() # assert(base) - set(tmp_default "${base}/tmp/${name}") - set(download_default "${base}/Download/${name}") - set(source_default "${base}/Source/${name}") - set(binary_default "${base}/Build/${name}") - set(stamp_default "${base}/Stamp/${name}") - set(install_default "${base}/Install/${name}") - endif() - get_property(build_in_source TARGET ${name} PROPERTY _EP_BUILD_IN_SOURCE) - if(build_in_source) - get_property(have_binary_dir TARGET ${name} PROPERTY _EP_BINARY_DIR SET) - if(have_binary_dir) - message(FATAL_ERROR - "External project ${name} has both BINARY_DIR and BUILD_IN_SOURCE!") - endif() - endif() - set(top "${CMAKE_CURRENT_BINARY_DIR}") - set(places stamp download source binary install tmp) - foreach(var ${places}) - string(TOUPPER "${var}" VAR) - get_property(${var}_dir TARGET ${name} PROPERTY _EP_${VAR}_DIR) - if(NOT ${var}_dir) - set(${var}_dir "${${var}_default}") - endif() - if(NOT IS_ABSOLUTE "${${var}_dir}") - get_filename_component(${var}_dir "${top}/${${var}_dir}" ABSOLUTE) - endif() - set_property(TARGET ${name} PROPERTY _EP_${VAR}_DIR "${${var}_dir}") - endforeach() - if(build_in_source) - get_property(source_dir TARGET ${name} PROPERTY _EP_SOURCE_DIR) - set_property(TARGET ${name} PROPERTY _EP_BINARY_DIR "${source_dir}") - endif() - - # Make the directories at CMake configure time *and* add a custom command - # to make them at build time. They need to exist at makefile generation - # time for Borland make and wmake so that CMake may generate makefiles - # with "cd C:\short\paths\with\no\spaces" commands in them. - # - # Additionally, the add_custom_command is still used in case somebody - # removes one of the necessary directories and tries to rebuild without - # re-running cmake. - foreach(var ${places}) - string(TOUPPER "${var}" VAR) - get_property(dir TARGET ${name} PROPERTY _EP_${VAR}_DIR) - file(MAKE_DIRECTORY "${dir}") - if(NOT EXISTS "${dir}") - message(FATAL_ERROR "dir '${dir}' does not exist after file(MAKE_DIRECTORY)") - endif() - endforeach() -endfunction(_ep_set_directories) - - -# IMPORTANT: this MUST be a macro and not a function because of the -# in-place replacements that occur in each ${var} -# -macro(_ep_replace_location_tags target_name) - set(vars ${ARGN}) - foreach(var ${vars}) - if(${var}) - foreach(dir SOURCE_DIR BINARY_DIR INSTALL_DIR TMP_DIR) - get_property(val TARGET ${target_name} PROPERTY _EP_${dir}) - string(REPLACE "<${dir}>" "${val}" ${var} "${${var}}") - endforeach() - endif() - endforeach() -endmacro() - - -function(_ep_write_initial_cache target_name script_filename args) - # Write out values into an initial cache, that will be passed to CMake with -C - set(script_initial_cache "") - set(regex "^([^:]+):([^=]+)=(.*)$") - set(setArg "") - foreach(line ${args}) - if("${line}" MATCHES "^-D") - if(setArg) - # This is required to build up lists in variables, or complete an entry - set(setArg "${setArg}${accumulator}\" CACHE ${type} \"Initial cache\" FORCE)") - set(script_initial_cache "${script_initial_cache}\n${setArg}") - set(accumulator "") - set(setArg "") - endif() - string(REGEX REPLACE "^-D" "" line ${line}) - if("${line}" MATCHES "${regex}") - string(REGEX MATCH "${regex}" match "${line}") - set(name "${CMAKE_MATCH_1}") - set(type "${CMAKE_MATCH_2}") - set(value "${CMAKE_MATCH_3}") - set(setArg "set(${name} \"${value}") - else() - message(WARNING "Line '${line}' does not match regex. Ignoring.") - endif() - else() - # Assume this is a list to append to the last var - set(accumulator "${accumulator};${line}") - endif() - endforeach() - # Catch the final line of the args - if(setArg) - set(setArg "${setArg}${accumulator}\" CACHE ${type} \"Initial cache\" FORCE)") - set(script_initial_cache "${script_initial_cache}\n${setArg}") - endif() - # Replace location tags. - _ep_replace_location_tags(${target_name} script_initial_cache) - # Write out the initial cache file to the location specified. - if(NOT EXISTS "${script_filename}.in") - file(WRITE "${script_filename}.in" "\@script_initial_cache\@\n") - endif() - configure_file("${script_filename}.in" "${script_filename}") -endfunction(_ep_write_initial_cache) - - -function(ExternalProjectWithFilename_Get_Property name) - foreach(var ${ARGN}) - string(TOUPPER "${var}" VAR) - get_property(${var} TARGET ${name} PROPERTY _EP_${VAR}) - if(NOT ${var}) - message(FATAL_ERROR "External project \"${name}\" has no ${var}") - endif() - set(${var} "${${var}}" PARENT_SCOPE) - endforeach() -endfunction(ExternalProjectWithFilename_Get_Property) - - -function(_ep_get_configure_command_id name cfg_cmd_id_var) - get_target_property(cmd ${name} _EP_CONFIGURE_COMMAND) - - if(cmd STREQUAL "") - # Explicit empty string means no configure step for this project - set(${cfg_cmd_id_var} "none" PARENT_SCOPE) - else() - if(NOT cmd) - # Default is "use cmake": - set(${cfg_cmd_id_var} "cmake" PARENT_SCOPE) - else() - # Otherwise we have to analyze the value: - if(cmd MATCHES "^[^;]*/configure") - set(${cfg_cmd_id_var} "configure" PARENT_SCOPE) - elseif(cmd MATCHES "^[^;]*/cmake" AND NOT cmd MATCHES ";-[PE];") - set(${cfg_cmd_id_var} "cmake" PARENT_SCOPE) - elseif(cmd MATCHES "config") - set(${cfg_cmd_id_var} "configure" PARENT_SCOPE) - else() - set(${cfg_cmd_id_var} "unknown:${cmd}" PARENT_SCOPE) - endif() - endif() - endif() -endfunction(_ep_get_configure_command_id) - - -function(_ep_get_build_command name step cmd_var) - set(cmd "${${cmd_var}}") - if(NOT cmd) - set(args) - _ep_get_configure_command_id(${name} cfg_cmd_id) - if(cfg_cmd_id STREQUAL "cmake") - # CMake project. Select build command based on generator. - get_target_property(cmake_generator ${name} _EP_CMAKE_GENERATOR) - if("${CMAKE_GENERATOR}" MATCHES "Make" AND - ("${cmake_generator}" MATCHES "Make" OR NOT cmake_generator)) - # The project uses the same Makefile generator. Use recursive make. - set(cmd "$(MAKE)") - if(step STREQUAL "INSTALL") - set(args install) - endif() - if(step STREQUAL "TEST") - set(args test) - endif() - else() - # Drive the project with "cmake --build". - get_target_property(cmake_command ${name} _EP_CMAKE_COMMAND) - if(cmake_command) - set(cmd "${cmake_command}") - else() - set(cmd "${CMAKE_COMMAND}") - endif() - set(args --build ${binary_dir} --config ${CMAKE_CFG_INTDIR}) - if(step STREQUAL "INSTALL") - list(APPEND args --target install) - endif() - # But for "TEST" drive the project with corresponding "ctest". - if(step STREQUAL "TEST") - string(REGEX REPLACE "^(.*/)cmake([^/]*)$" "\\1ctest\\2" cmd "${cmd}") - set(args "") - endif() - endif() - else() # if(cfg_cmd_id STREQUAL "configure") - # Non-CMake project. Guess "make" and "make install" and "make test". - # But use "$(MAKE)" to get recursive parallel make. - set(cmd "$(MAKE)") - if(step STREQUAL "INSTALL") - set(args install) - endif() - if(step STREQUAL "TEST") - set(args test) - endif() - endif() - - # Use user-specified arguments instead of default arguments, if any. - get_property(have_args TARGET ${name} PROPERTY _EP_${step}_ARGS SET) - if(have_args) - get_target_property(args ${name} _EP_${step}_ARGS) - endif() - - list(APPEND cmd ${args}) - endif() - - set(${cmd_var} "${cmd}" PARENT_SCOPE) -endfunction(_ep_get_build_command) - -function(_ep_write_log_script name step cmd_var) - ExternalProjectWithFilename_Get_Property(${name} stamp_dir) - set(command "${${cmd_var}}") - - set(make "") - set(code_cygpath_make "") - if("${command}" MATCHES "^\\$\\(MAKE\\)") - # GNU make recognizes the string "$(MAKE)" as recursive make, so - # ensure that it appears directly in the makefile. - string(REGEX REPLACE "^\\$\\(MAKE\\)" "\${make}" command "${command}") - set(make "-Dmake=$(MAKE)") - - if(WIN32 AND NOT CYGWIN) - set(code_cygpath_make " -if(\${make} MATCHES \"^/\") - execute_process( - COMMAND cygpath -w \${make} - OUTPUT_VARIABLE cygpath_make - ERROR_VARIABLE cygpath_make - RESULT_VARIABLE cygpath_error - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - if(NOT cygpath_error) - set(make \${cygpath_make}) - endif() -endif() -") - endif() - endif() - - set(config "") - if("${CMAKE_CFG_INTDIR}" MATCHES "^\\$") - string(REPLACE "${CMAKE_CFG_INTDIR}" "\${config}" command "${command}") - set(config "-Dconfig=${CMAKE_CFG_INTDIR}") - endif() - - # Wrap multiple 'COMMAND' lines up into a second-level wrapper - # script so all output can be sent to one log file. - if("${command}" MATCHES ";COMMAND;") - set(code_execute_process " -${code_cygpath_make} -execute_process(COMMAND \${command} RESULT_VARIABLE result) -if(result) - set(msg \"Command failed (\${result}):\\n\") - foreach(arg IN LISTS command) - set(msg \"\${msg} '\${arg}'\") - endforeach(arg) - message(FATAL_ERROR \"\${msg}\") -endif() -") - set(code "") - set(cmd "") - set(sep "") - foreach(arg IN LISTS command) - if("x${arg}" STREQUAL "xCOMMAND") - set(code "${code}set(command \"${cmd}\")${code_execute_process}") - set(cmd "") - set(sep "") - else() - set(cmd "${cmd}${sep}${arg}") - set(sep ";") - endif() - endforeach() - set(code "set(ENV{VS_UNICODE_OUTPUT} \"\")\n${code}set(command \"${cmd}\")${code_execute_process}") - file(WRITE ${stamp_dir}/${name}-${step}-impl.cmake "${code}") - set(command ${CMAKE_COMMAND} "-Dmake=\${make}" "-Dconfig=\${config}" -P ${stamp_dir}/${name}-${step}-impl.cmake) - endif() - - # Wrap the command in a script to log output to files. - set(script ${stamp_dir}/${name}-${step}.cmake) - set(logbase ${stamp_dir}/${name}-${step}) - file(WRITE ${script} " -${code_cygpath_make} -set(ENV{VS_UNICODE_OUTPUT} \"\") -set(command \"${command}\") -execute_process( - COMMAND \${command} - RESULT_VARIABLE result - OUTPUT_FILE \"${logbase}-out.log\" - ERROR_FILE \"${logbase}-err.log\" - ) -if(result) - set(msg \"Command failed: \${result}\\n\") - foreach(arg IN LISTS command) - set(msg \"\${msg} '\${arg}'\") - endforeach(arg) - set(msg \"\${msg}\\nSee also\\n ${logbase}-*.log\\n\") - message(FATAL_ERROR \"\${msg}\") -else() - set(msg \"${name} ${step} command succeeded. See also ${logbase}-*.log\\n\") - message(STATUS \"\${msg}\") -endif() -") - set(command ${CMAKE_COMMAND} ${make} ${config} -P ${script}) - set(${cmd_var} "${command}" PARENT_SCOPE) -endfunction(_ep_write_log_script) - -# This module used to use "/${CMAKE_CFG_INTDIR}" directly and produced -# makefiles with "/./" in paths for custom command dependencies. Which -# resulted in problems with parallel make -j invocations. -# -# This function was added so that the suffix (search below for ${cfgdir}) is -# only set to "/${CMAKE_CFG_INTDIR}" when ${CMAKE_CFG_INTDIR} is not going to -# be "." (multi-configuration build systems like Visual Studio and Xcode...) -# -function(_ep_get_configuration_subdir_suffix suffix_var) - set(suffix "") - if(CMAKE_CONFIGURATION_TYPES) - set(suffix "/${CMAKE_CFG_INTDIR}") - endif() - set(${suffix_var} "${suffix}" PARENT_SCOPE) -endfunction(_ep_get_configuration_subdir_suffix) - - -function(ExternalProjectWithFilename_Add_StepTargets name) - set(steps ${ARGN}) - - _ep_get_configuration_subdir_suffix(cfgdir) - ExternalProjectWithFilename_Get_Property(${name} stamp_dir) - - foreach(step ${steps}) - add_custom_target(${name}-${step} - DEPENDS ${stamp_dir}${cfgdir}/${name}-${step}) - endforeach() -endfunction(ExternalProjectWithFilename_Add_StepTargets) - - -function(ExternalProjectWithFilename_Add_Step name step) - set(cmf_dir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles) - ExternalProjectWithFilename_Get_Property(${name} stamp_dir) - - _ep_get_configuration_subdir_suffix(cfgdir) - - add_custom_command(APPEND - OUTPUT ${cmf_dir}${cfgdir}/${name}-complete - DEPENDS ${stamp_dir}${cfgdir}/${name}-${step} - ) - _ep_parse_arguments(ExternalProjectWithFilename_Add_Step - ${name} _EP_${step}_ "${ARGN}") - - # Steps depending on this step. - get_property(dependers TARGET ${name} PROPERTY _EP_${step}_DEPENDERS) - foreach(depender IN LISTS dependers) - add_custom_command(APPEND - OUTPUT ${stamp_dir}${cfgdir}/${name}-${depender} - DEPENDS ${stamp_dir}${cfgdir}/${name}-${step} - ) - endforeach() - - # Dependencies on files. - get_property(depends TARGET ${name} PROPERTY _EP_${step}_DEPENDS) - - # Dependencies on steps. - get_property(dependees TARGET ${name} PROPERTY _EP_${step}_DEPENDEES) - foreach(dependee IN LISTS dependees) - list(APPEND depends ${stamp_dir}${cfgdir}/${name}-${dependee}) - endforeach() - - # The command to run. - get_property(command TARGET ${name} PROPERTY _EP_${step}_COMMAND) - if(command) - set(comment "Performing ${step} step for '${name}'") - else() - set(comment "No ${step} step for '${name}'") - endif() - get_property(work_dir TARGET ${name} PROPERTY _EP_${step}_WORKING_DIRECTORY) - - # Replace list separators. - get_property(sep TARGET ${name} PROPERTY _EP_LIST_SEPARATOR) - if(sep AND command) - string(REPLACE "${sep}" "\\;" command "${command}") - endif() - - # Replace location tags. - _ep_replace_location_tags(${name} comment command work_dir) - - # Custom comment? - get_property(comment_set TARGET ${name} PROPERTY _EP_${step}_COMMENT SET) - if(comment_set) - get_property(comment TARGET ${name} PROPERTY _EP_${step}_COMMENT) - endif() - - # Run every time? - get_property(always TARGET ${name} PROPERTY _EP_${step}_ALWAYS) - if(always) - set_property(SOURCE ${stamp_dir}${cfgdir}/${name}-${step} PROPERTY SYMBOLIC 1) - set(touch) - else() - set(touch ${CMAKE_COMMAND} -E touch ${stamp_dir}${cfgdir}/${name}-${step}) - endif() - - # Wrap with log script? - get_property(log TARGET ${name} PROPERTY _EP_${step}_LOG) - if(command AND log) - _ep_write_log_script(${name} ${step} command) - endif() - - add_custom_command( - OUTPUT ${stamp_dir}${cfgdir}/${name}-${step} - COMMENT ${comment} - COMMAND ${command} - COMMAND ${touch} - DEPENDS ${depends} - WORKING_DIRECTORY ${work_dir} - VERBATIM - ) - - # Add custom "step target"? - get_property(step_targets TARGET ${name} PROPERTY _EP_STEP_TARGETS) - if(NOT step_targets) - get_property(step_targets DIRECTORY PROPERTY EP_STEP_TARGETS) - endif() - foreach(st ${step_targets}) - if("${st}" STREQUAL "${step}") - ExternalProjectWithFilename_Add_StepTargets(${name} ${step}) - break() - endif() - endforeach() -endfunction(ExternalProjectWithFilename_Add_Step) - - -function(_ep_add_mkdir_command name) - ExternalProjectWithFilename_Get_Property(${name} - source_dir binary_dir install_dir stamp_dir download_dir tmp_dir) - - _ep_get_configuration_subdir_suffix(cfgdir) - - ExternalProjectWithFilename_Add_Step(${name} mkdir - COMMENT "Creating directories for '${name}'" - COMMAND ${CMAKE_COMMAND} -E make_directory ${source_dir} - COMMAND ${CMAKE_COMMAND} -E make_directory ${binary_dir} - COMMAND ${CMAKE_COMMAND} -E make_directory ${install_dir} - COMMAND ${CMAKE_COMMAND} -E make_directory ${tmp_dir} - COMMAND ${CMAKE_COMMAND} -E make_directory ${stamp_dir}${cfgdir} - COMMAND ${CMAKE_COMMAND} -E make_directory ${download_dir} - ) -endfunction(_ep_add_mkdir_command) - - -function(_ep_get_git_version git_EXECUTABLE git_version_var) - if(git_EXECUTABLE) - execute_process( - COMMAND "${git_EXECUTABLE}" --version - OUTPUT_VARIABLE ov - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - string(REGEX REPLACE "^git version (.+)$" "\\1" version "${ov}") - set(${git_version_var} "${version}" PARENT_SCOPE) - endif() -endfunction() - - -function(_ep_is_dir_empty dir empty_var) - file(GLOB gr "${dir}/*") - if("${gr}" STREQUAL "") - set(${empty_var} 1 PARENT_SCOPE) - else() - set(${empty_var} 0 PARENT_SCOPE) - endif() -endfunction() - - -function(_ep_add_download_command name) - ExternalProjectWithFilename_Get_Property(${name} source_dir stamp_dir download_dir tmp_dir) - - get_property(cmd_set TARGET ${name} PROPERTY _EP_DOWNLOAD_COMMAND SET) - get_property(cmd TARGET ${name} PROPERTY _EP_DOWNLOAD_COMMAND) - get_property(cvs_repository TARGET ${name} PROPERTY _EP_CVS_REPOSITORY) - get_property(svn_repository TARGET ${name} PROPERTY _EP_SVN_REPOSITORY) - get_property(git_repository TARGET ${name} PROPERTY _EP_GIT_REPOSITORY) - get_property(url TARGET ${name} PROPERTY _EP_URL) - get_property(fname TARGET ${name} PROPERTY _EP_FILENAME) - - # TODO: Perhaps file:// should be copied to download dir before extraction. - string(REGEX REPLACE "^file://" "" url "${url}") - - set(depends) - set(comment) - set(work_dir) - - if(cmd_set) - set(work_dir ${download_dir}) - elseif(cvs_repository) - find_package(CVS) - if(NOT CVS_EXECUTABLE) - message(FATAL_ERROR "error: could not find cvs for checkout of ${name}") - endif() - - get_target_property(cvs_module ${name} _EP_CVS_MODULE) - if(NOT cvs_module) - message(FATAL_ERROR "error: no CVS_MODULE") - endif() - - get_property(cvs_tag TARGET ${name} PROPERTY _EP_CVS_TAG) - - set(repository ${cvs_repository}) - set(module ${cvs_module}) - set(tag ${cvs_tag}) - configure_file( - "${CMAKE_ROOT}/Modules/RepositoryInfo.txt.in" - "${stamp_dir}/${name}-cvsinfo.txt" - @ONLY - ) - - get_filename_component(src_name "${source_dir}" NAME) - get_filename_component(work_dir "${source_dir}" PATH) - set(comment "Performing download step (CVS checkout) for '${name}'") - set(cmd ${CVS_EXECUTABLE} -d ${cvs_repository} -q co ${cvs_tag} -d ${src_name} ${cvs_module}) - list(APPEND depends ${stamp_dir}/${name}-cvsinfo.txt) - elseif(svn_repository) - find_package(Subversion) - if(NOT Subversion_SVN_EXECUTABLE) - message(FATAL_ERROR "error: could not find svn for checkout of ${name}") - endif() - - get_property(svn_revision TARGET ${name} PROPERTY _EP_SVN_REVISION) - get_property(svn_username TARGET ${name} PROPERTY _EP_SVN_USERNAME) - get_property(svn_password TARGET ${name} PROPERTY _EP_SVN_PASSWORD) - get_property(svn_trust_cert TARGET ${name} PROPERTY _EP_SVN_TRUST_CERT) - - set(repository "${svn_repository} user=${svn_username} password=${svn_password}") - set(module) - set(tag ${svn_revision}) - configure_file( - "${CMAKE_ROOT}/Modules/RepositoryInfo.txt.in" - "${stamp_dir}/${name}-svninfo.txt" - @ONLY - ) - - get_filename_component(src_name "${source_dir}" NAME) - get_filename_component(work_dir "${source_dir}" PATH) - set(comment "Performing download step (SVN checkout) for '${name}'") - set(svn_user_pw_args "") - if(svn_username) - set(svn_user_pw_args ${svn_user_pw_args} "--username=${svn_username}") - endif() - if(svn_password) - set(svn_user_pw_args ${svn_user_pw_args} "--password=${svn_password}") - endif() - if(svn_trust_cert) - set(svn_trust_cert_args --trust-server-cert) - endif() - set(cmd ${Subversion_SVN_EXECUTABLE} co ${svn_repository} ${svn_revision} - --non-interactive ${svn_trust_cert_args} ${svn_user_pw_args} ${src_name}) - list(APPEND depends ${stamp_dir}/${name}-svninfo.txt) - elseif(git_repository) - find_package(Git) - if(NOT GIT_EXECUTABLE) - message(FATAL_ERROR "error: could not find git for clone of ${name}") - endif() - - # The git submodule update '--recursive' flag requires git >= v1.6.5 - # - _ep_get_git_version("${GIT_EXECUTABLE}" git_version) - if(git_version VERSION_LESS 1.6.5) - message(FATAL_ERROR "error: git version 1.6.5 or later required for 'git submodule update --recursive': git_version='${git_version}'") - endif() - - get_property(git_tag TARGET ${name} PROPERTY _EP_GIT_TAG) - if(NOT git_tag) - set(git_tag "master") - endif() - - set(repository ${git_repository}) - set(module) - set(tag ${git_tag}) - configure_file( - "${CMAKE_ROOT}/Modules/RepositoryInfo.txt.in" - "${stamp_dir}/${name}-gitinfo.txt" - @ONLY - ) - - get_filename_component(src_name "${source_dir}" NAME) - get_filename_component(work_dir "${source_dir}" PATH) - - # Since git clone doesn't succeed if the non-empty source_dir exists, - # create a cmake script to invoke as download command. - # The script will delete the source directory and then call git clone. - # - _ep_write_gitclone_script(${tmp_dir}/${name}-gitclone.cmake ${source_dir} - ${GIT_EXECUTABLE} ${git_repository} ${git_tag} ${src_name} ${work_dir} - ) - set(comment "Performing download step (git clone) for '${name}'") - set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-gitclone.cmake) - list(APPEND depends ${stamp_dir}/${name}-gitinfo.txt) - elseif(url) - get_filename_component(work_dir "${source_dir}" PATH) - get_property(md5 TARGET ${name} PROPERTY _EP_URL_MD5) - set(repository "external project URL") - set(module "${url}") - set(tag "${md5}") - configure_file( - "${CMAKE_ROOT}/Modules/RepositoryInfo.txt.in" - "${stamp_dir}/${name}-urlinfo.txt" - @ONLY - ) - list(APPEND depends ${stamp_dir}/${name}-urlinfo.txt) - if(IS_DIRECTORY "${url}") - get_filename_component(abs_dir "${url}" ABSOLUTE) - set(comment "Performing download step (DIR copy) for '${name}'") - set(cmd ${CMAKE_COMMAND} -E remove_directory ${source_dir} - COMMAND ${CMAKE_COMMAND} -E copy_directory ${abs_dir} ${source_dir}) - else() - if("${url}" MATCHES "^[a-z]+://") - # TODO: Should download and extraction be different steps? - - # MODIFICATION HERE: allows setting filename for urls - # where filename is not embedded, such as github - if ("${fname}" STREQUAL "") - string(REGEX MATCH "[^/\\?]*$" fname "${url}") - endif() - # this is set by filename now - if(NOT "${fname}" MATCHES "(\\.|=)(bz2|tar|tgz|tar\\.gz|zip)$") - string(REGEX MATCH "([^/\\?]+(\\.|=)(bz2|tar|tgz|tar\\.gz|zip))/.*$" match_result "${url}") - set(fname "${CMAKE_MATCH_1}") - endif() - if(NOT "${fname}" MATCHES "(\\.|=)(bz2|tar|tgz|tar\\.gz|zip)$") - message(FATAL_ERROR "Could not extract tarball filename from url:\n ${url}") - endif() - string(REPLACE ";" "-" fname "${fname}") - set(file ${download_dir}/${fname}) - get_property(timeout TARGET ${name} PROPERTY _EP_TIMEOUT) - _ep_write_downloadfile_script("${stamp_dir}/download-${name}.cmake" "${url}" "${file}" "${timeout}" "${md5}") - set(cmd ${CMAKE_COMMAND} -P ${stamp_dir}/download-${name}.cmake - COMMAND) - set(comment "Performing download step (download, verify and extract) for '${name}'") - else() - set(file "${url}") - set(comment "Performing download step (verify and extract) for '${name}'") - endif() - _ep_write_verifyfile_script("${stamp_dir}/verify-${name}.cmake" "${file}" "${md5}") - list(APPEND cmd ${CMAKE_COMMAND} -P ${stamp_dir}/verify-${name}.cmake) - _ep_write_extractfile_script("${stamp_dir}/extract-${name}.cmake" "${name}" "${file}" "${source_dir}") - list(APPEND cmd ${CMAKE_COMMAND} -P ${stamp_dir}/extract-${name}.cmake) - endif() - else() - _ep_is_dir_empty("${source_dir}" empty) - if(${empty}) - message(SEND_ERROR "error: no download info for '${name}' -- please specify existing/non-empty SOURCE_DIR or one of URL, CVS_REPOSITORY and CVS_MODULE, SVN_REPOSITORY, GIT_REPOSITORY or DOWNLOAD_COMMAND") - endif() - endif() - - get_property(log TARGET ${name} PROPERTY _EP_LOG_DOWNLOAD) - if(log) - set(log LOG 1) - else() - set(log "") - endif() - - ExternalProjectWithFilename_Add_Step(${name} download - COMMENT ${comment} - COMMAND ${cmd} - WORKING_DIRECTORY ${work_dir} - DEPENDS ${depends} - DEPENDEES mkdir - ${log} - ) -endfunction(_ep_add_download_command) - - -function(_ep_add_update_command name) - ExternalProjectWithFilename_Get_Property(${name} source_dir) - - get_property(cmd_set TARGET ${name} PROPERTY _EP_UPDATE_COMMAND SET) - get_property(cmd TARGET ${name} PROPERTY _EP_UPDATE_COMMAND) - get_property(cvs_repository TARGET ${name} PROPERTY _EP_CVS_REPOSITORY) - get_property(svn_repository TARGET ${name} PROPERTY _EP_SVN_REPOSITORY) - get_property(git_repository TARGET ${name} PROPERTY _EP_GIT_REPOSITORY) - - set(work_dir) - set(comment) - set(always) - - if(cmd_set) - set(work_dir ${source_dir}) - elseif(cvs_repository) - if(NOT CVS_EXECUTABLE) - message(FATAL_ERROR "error: could not find cvs for update of ${name}") - endif() - set(work_dir ${source_dir}) - set(comment "Performing update step (CVS update) for '${name}'") - get_property(cvs_tag TARGET ${name} PROPERTY _EP_CVS_TAG) - set(cmd ${CVS_EXECUTABLE} -d ${cvs_repository} -q up -dP ${cvs_tag}) - set(always 1) - elseif(svn_repository) - if(NOT Subversion_SVN_EXECUTABLE) - message(FATAL_ERROR "error: could not find svn for update of ${name}") - endif() - set(work_dir ${source_dir}) - set(comment "Performing update step (SVN update) for '${name}'") - get_property(svn_revision TARGET ${name} PROPERTY _EP_SVN_REVISION) - get_property(svn_username TARGET ${name} PROPERTY _EP_SVN_USERNAME) - get_property(svn_password TARGET ${name} PROPERTY _EP_SVN_PASSWORD) - get_property(svn_trust_cert TARGET ${name} PROPERTY _EP_SVN_TRUST_CERT) - set(svn_user_pw_args "") - if(svn_username) - set(svn_user_pw_args ${svn_user_pw_args} "--username=${svn_username}") - endif() - if(svn_password) - set(svn_user_pw_args ${svn_user_pw_args} "--password=${svn_password}") - endif() - if(svn_trust_cert) - set(svn_trust_cert_args --trust-server-cert) - endif() - set(cmd ${Subversion_SVN_EXECUTABLE} up ${svn_revision} - --non-interactive ${svn_trust_cert_args} ${svn_user_pw_args}) - set(always 1) - elseif(git_repository) - if(NOT GIT_EXECUTABLE) - message(FATAL_ERROR "error: could not find git for fetch of ${name}") - endif() - set(work_dir ${source_dir}) - set(comment "Performing update step (git fetch) for '${name}'") - get_property(git_tag TARGET ${name} PROPERTY _EP_GIT_TAG) - if(NOT git_tag) - set(git_tag "master") - endif() - set(cmd ${GIT_EXECUTABLE} fetch - COMMAND ${GIT_EXECUTABLE} checkout ${git_tag} - COMMAND ${GIT_EXECUTABLE} submodule update --recursive - ) - set(always 1) - endif() - - get_property(log TARGET ${name} PROPERTY _EP_LOG_UPDATE) - if(log) - set(log LOG 1) - else() - set(log "") - endif() - - ExternalProjectWithFilename_Add_Step(${name} update - COMMENT ${comment} - COMMAND ${cmd} - ALWAYS ${always} - WORKING_DIRECTORY ${work_dir} - DEPENDEES download - ${log} - ) -endfunction(_ep_add_update_command) - - -function(_ep_add_patch_command name) - ExternalProjectWithFilename_Get_Property(${name} source_dir) - - get_property(cmd_set TARGET ${name} PROPERTY _EP_PATCH_COMMAND SET) - get_property(cmd TARGET ${name} PROPERTY _EP_PATCH_COMMAND) - - set(work_dir) - - if(cmd_set) - set(work_dir ${source_dir}) - endif() - - ExternalProjectWithFilename_Add_Step(${name} patch - COMMAND ${cmd} - WORKING_DIRECTORY ${work_dir} - DEPENDEES download - ) -endfunction(_ep_add_patch_command) - - -# TODO: Make sure external projects use the proper compiler -function(_ep_add_configure_command name) - ExternalProjectWithFilename_Get_Property(${name} source_dir binary_dir tmp_dir) - - _ep_get_configuration_subdir_suffix(cfgdir) - - # Depend on other external projects (file-level). - set(file_deps) - get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS) - foreach(dep IN LISTS deps) - get_property(dep_stamp_dir TARGET ${dep} PROPERTY _EP_STAMP_DIR) - list(APPEND file_deps ${dep_stamp_dir}${cfgdir}/${dep}-done) - endforeach() - - get_property(cmd_set TARGET ${name} PROPERTY _EP_CONFIGURE_COMMAND SET) - if(cmd_set) - get_property(cmd TARGET ${name} PROPERTY _EP_CONFIGURE_COMMAND) - else() - get_target_property(cmake_command ${name} _EP_CMAKE_COMMAND) - if(cmake_command) - set(cmd "${cmake_command}") - else() - set(cmd "${CMAKE_COMMAND}") - endif() - - get_property(cmake_args TARGET ${name} PROPERTY _EP_CMAKE_ARGS) - list(APPEND cmd ${cmake_args}) - - # If there are any CMAKE_CACHE_ARGS, write an initial cache and use it - get_property(cmake_cache_args TARGET ${name} PROPERTY _EP_CMAKE_CACHE_ARGS) - if(cmake_cache_args) - set(_ep_cache_args_script "${tmp_dir}/${name}-cache.cmake") - _ep_write_initial_cache(${name} "${_ep_cache_args_script}" "${cmake_cache_args}") - list(APPEND cmd "-C${_ep_cache_args_script}") - endif() - - get_target_property(cmake_generator ${name} _EP_CMAKE_GENERATOR) - if(cmake_generator) - list(APPEND cmd "-G${cmake_generator}" "${source_dir}") - else() - if(CMAKE_EXTRA_GENERATOR) - list(APPEND cmd "-G${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}" - "${source_dir}") - else() - list(APPEND cmd "-G${CMAKE_GENERATOR}" "${source_dir}") - endif() - endif() - endif() - - # If anything about the configure command changes, (command itself, cmake - # used, cmake args or cmake generator) then re-run the configure step. - # Fixes issue http://public.kitware.com/Bug/view.php?id=10258 - # - if(NOT EXISTS ${tmp_dir}/${name}-cfgcmd.txt.in) - file(WRITE ${tmp_dir}/${name}-cfgcmd.txt.in "cmd='\@cmd\@'\n") - endif() - configure_file(${tmp_dir}/${name}-cfgcmd.txt.in ${tmp_dir}/${name}-cfgcmd.txt) - list(APPEND file_deps ${tmp_dir}/${name}-cfgcmd.txt) - list(APPEND file_deps ${_ep_cache_args_script}) - - get_property(log TARGET ${name} PROPERTY _EP_LOG_CONFIGURE) - if(log) - set(log LOG 1) - else() - set(log "") - endif() - - ExternalProjectWithFilename_Add_Step(${name} configure - COMMAND ${cmd} - WORKING_DIRECTORY ${binary_dir} - DEPENDEES update patch - DEPENDS ${file_deps} - ${log} - ) -endfunction(_ep_add_configure_command) - - -function(_ep_add_build_command name) - ExternalProjectWithFilename_Get_Property(${name} binary_dir) - - get_property(cmd_set TARGET ${name} PROPERTY _EP_BUILD_COMMAND SET) - if(cmd_set) - get_property(cmd TARGET ${name} PROPERTY _EP_BUILD_COMMAND) - else() - _ep_get_build_command(${name} BUILD cmd) - endif() - - get_property(log TARGET ${name} PROPERTY _EP_LOG_BUILD) - if(log) - set(log LOG 1) - else() - set(log "") - endif() - - ExternalProjectWithFilename_Add_Step(${name} build - COMMAND ${cmd} - WORKING_DIRECTORY ${binary_dir} - DEPENDEES configure - ${log} - ) -endfunction(_ep_add_build_command) - - -function(_ep_add_install_command name) - ExternalProjectWithFilename_Get_Property(${name} binary_dir) - - get_property(cmd_set TARGET ${name} PROPERTY _EP_INSTALL_COMMAND SET) - if(cmd_set) - get_property(cmd TARGET ${name} PROPERTY _EP_INSTALL_COMMAND) - else() - _ep_get_build_command(${name} INSTALL cmd) - endif() - - get_property(log TARGET ${name} PROPERTY _EP_LOG_INSTALL) - if(log) - set(log LOG 1) - else() - set(log "") - endif() - - ExternalProjectWithFilename_Add_Step(${name} install - COMMAND ${cmd} - WORKING_DIRECTORY ${binary_dir} - DEPENDEES build - ${log} - ) -endfunction(_ep_add_install_command) - - -function(_ep_add_test_command name) - ExternalProjectWithFilename_Get_Property(${name} binary_dir) - - get_property(before TARGET ${name} PROPERTY _EP_TEST_BEFORE_INSTALL) - get_property(after TARGET ${name} PROPERTY _EP_TEST_AFTER_INSTALL) - get_property(cmd_set TARGET ${name} PROPERTY _EP_TEST_COMMAND SET) - - # Only actually add the test step if one of the test related properties is - # explicitly set. (i.e. the test step is omitted unless requested...) - # - if(cmd_set OR before OR after) - if(cmd_set) - get_property(cmd TARGET ${name} PROPERTY _EP_TEST_COMMAND) - else() - _ep_get_build_command(${name} TEST cmd) - endif() - - if(before) - set(dep_args DEPENDEES build DEPENDERS install) - else() - set(dep_args DEPENDEES install) - endif() - - get_property(log TARGET ${name} PROPERTY _EP_LOG_TEST) - if(log) - set(log LOG 1) - else() - set(log "") - endif() - - ExternalProjectWithFilename_Add_Step(${name} test - COMMAND ${cmd} - WORKING_DIRECTORY ${binary_dir} - ${dep_args} - ${log} - ) - endif() -endfunction(_ep_add_test_command) - - -function(ExternalProjectWithFilename_Add name) - _ep_get_configuration_subdir_suffix(cfgdir) - - # Add a custom target for the external project. - set(cmf_dir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles) - add_custom_target(${name} ALL DEPENDS ${cmf_dir}${cfgdir}/${name}-complete) - set_property(TARGET ${name} PROPERTY _EP_IS_EXTERNAL_PROJECT 1) - _ep_parse_arguments(ExternalProjectWithFilename_Add ${name} _EP_ "${ARGN}") - _ep_set_directories(${name}) - ExternalProjectWithFilename_Get_Property(${name} stamp_dir) - - # The 'complete' step depends on all other steps and creates a - # 'done' mark. A dependent external project's 'configure' step - # depends on the 'done' mark so that it rebuilds when this project - # rebuilds. It is important that 'done' is not the output of any - # custom command so that CMake does not propagate build rules to - # other external project targets. - add_custom_command( - OUTPUT ${cmf_dir}${cfgdir}/${name}-complete - COMMENT "Completed '${name}'" - COMMAND ${CMAKE_COMMAND} -E make_directory ${cmf_dir}${cfgdir} - COMMAND ${CMAKE_COMMAND} -E touch ${cmf_dir}${cfgdir}/${name}-complete - COMMAND ${CMAKE_COMMAND} -E touch ${stamp_dir}${cfgdir}/${name}-done - DEPENDS ${stamp_dir}${cfgdir}/${name}-install - VERBATIM - ) - - - # Depend on other external projects (target-level). - get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS) - foreach(arg IN LISTS deps) - add_dependencies(${name} ${arg}) - endforeach() - - # Set up custom build steps based on the target properties. - # Each step depends on the previous one. - # - # The target depends on the output of the final step. - # (Already set up above in the DEPENDS of the add_custom_target command.) - # - _ep_add_mkdir_command(${name}) - _ep_add_download_command(${name}) - _ep_add_update_command(${name}) - _ep_add_patch_command(${name}) - _ep_add_configure_command(${name}) - _ep_add_build_command(${name}) - _ep_add_install_command(${name}) - - # Test is special in that it might depend on build, or it might depend - # on install. - # - _ep_add_test_command(${name}) -endfunction(ExternalProjectWithFilename_Add) diff --git a/cmake/arkcmake/MacroCheckCCompilerFlagSSP.cmake b/cmake/arkcmake/MacroCheckCCompilerFlagSSP.cmake deleted file mode 100644 index b64fb453..00000000 --- a/cmake/arkcmake/MacroCheckCCompilerFlagSSP.cmake +++ /dev/null @@ -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, -# -# 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) - diff --git a/cmake/arkcmake/MacroEnsureOutOfSourceBuild.cmake b/cmake/arkcmake/MacroEnsureOutOfSourceBuild.cmake deleted file mode 100644 index 3ff891b5..00000000 --- a/cmake/arkcmake/MacroEnsureOutOfSourceBuild.cmake +++ /dev/null @@ -1,19 +0,0 @@ -# - MACRO_ENSURE_OUT_OF_SOURCE_BUILD() -# MACRO_ENSURE_OUT_OF_SOURCE_BUILD() - -# Copyright (c) 2006, Alexander Neundorf, -# -# 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 diff --git a/cmake/arkcmake/updateArkcmake.py b/cmake/arkcmake/updateArkcmake.py deleted file mode 100755 index 246b69d0..00000000 --- a/cmake/arkcmake/updateArkcmake.py +++ /dev/null @@ -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"]) diff --git a/cmake/mavlink.bmp b/cmake/mavlink.bmp deleted file mode 100644 index 57b01168..00000000 Binary files a/cmake/mavlink.bmp and /dev/null differ diff --git a/cmake/mavlink.png b/cmake/mavlink.png deleted file mode 100644 index 1f665fee..00000000 Binary files a/cmake/mavlink.png and /dev/null differ diff --git a/config.h.in b/config.h.in deleted file mode 100644 index 6b10f6c3..00000000 --- a/config.h.in +++ /dev/null @@ -1 +0,0 @@ -#define MAVLINK_VERSION "${PROJECT_VERSION}" diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt new file mode 100644 index 00000000..2fc9a2af --- /dev/null +++ b/examples/c/CMakeLists.txt @@ -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) diff --git a/examples/c/README.md b/examples/c/README.md new file mode 100644 index 00000000..e9043efd --- /dev/null +++ b/examples/c/README.md @@ -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 +``` diff --git a/examples/c/udp_example.c b/examples/c/udp_example.c new file mode 100644 index 00000000..a1478ebe --- /dev/null +++ b/examples/c/udp_example.c @@ -0,0 +1,171 @@ +// Simple example receiving and sending MAVLink v2 over UDP +// based on POSIX APIs (e.g. Linux, BSD, macOS). + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + + +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"); + } +} diff --git a/examples/linux/.gitignore b/examples/linux/.gitignore deleted file mode 100644 index ce4f5db0..00000000 --- a/examples/linux/.gitignore +++ /dev/null @@ -1 +0,0 @@ -mavlink_udp diff --git a/examples/linux/README.md b/examples/linux/README.md deleted file mode 100644 index cdf48b29..00000000 --- a/examples/linux/README.md +++ /dev/null @@ -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. diff --git a/examples/linux/mavlink_udp.c b/examples/linux/mavlink_udp.c deleted file mode 100644 index 3d474943..00000000 --- a/examples/linux/mavlink_udp.c +++ /dev/null @@ -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 . - - ****************************************************************************/ -/* - 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if (defined __QNX__) | (defined __QNXNTO__) -/* QNX specific headers */ -#include -#else -/* Linux / MacOS POSIX timer headers */ -#include -#include -#include -#include /* 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 - - -#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(" \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 diff --git a/pc.in b/pc.in deleted file mode 100644 index e02ba17a..00000000 --- a/pc.in +++ /dev/null @@ -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@