diff --git a/.editorconfig b/.editorconfig index 74b1663..0611f52 100644 --- a/.editorconfig +++ b/.editorconfig @@ -37,3 +37,7 @@ indent_size = 4 [.ycm_extra_conf.py] indent_style = space indent_size = 2 + +[extern/mbed-os/**] +trim_trailing_whitespace = false +insert_final_newline = false diff --git a/.gitignore b/.gitignore index 5ca7f17..3493aec 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,9 @@ extern/mbed-os _build* _coverage* +cmake_build cmake/config/ +.mbedbuild .cache .clangd *.ioc.csv diff --git a/CMakeLists.txt b/CMakeLists.txt index fe5f382..d42e5ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,6 @@ # Copyright 2020 Ladislas de Toldi (ladislas [at] detoldi.me) # SPDX-License-Identifier: Apache-2.0 -# mbed-cmake requires at least CMake 3.18 cmake_minimum_required(VERSION 3.19) # Activate ccache @@ -12,38 +11,42 @@ if(CCACHE) set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE}) endif() -# Before all, set ROOT_DIR, MBED_OS_DIR -set(ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) -set(MBED_OS_DIR ${ROOT_DIR}/extern/mbed-os) +# Set ROOT_DIR, MBED_PATH, MBED_CONFIG_PATH +set(ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(MBED_PATH ${ROOT_DIR}/extern/mbed-os CACHE INTERNAL "") +set(MBED_CONFIG_PATH ${ROOT_DIR}/.mbedbuild CACHE INTERNAL "") -# And include mbed-cmake.cmake -include(./mbed-cmake.cmake) - -# Then configure name of the project -project("Mbed CMake Template" LANGUAGES C CXX ASM) +# For convenience, define useful variables +set(LIBS_DIR ${ROOT_DIR}/libs) +set(SPIKES_DIR ${ROOT_DIR}/spikes) +set(TARGETS_DIR ${ROOT_DIR}/targets) # Generate compile commands database set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "") -# For convenience you can define useful variables -set(LIBS_DIR ${ROOT_DIR}/libs) -set(SPIKES_DIR ${ROOT_DIR}/spikes) -set(TARGETS_DIR ${ROOT_DIR}/targets) +# Include mbed os cmake logic +include(${MBED_PATH}/tools/cmake/app.cmake) -# Add custom target subdirectory -set(AVAILABLE_CUSTOM_TARGETS DISCO_ORIGINAL LEKA_V1_0_DEV LEKA_V1_1_DEV LEKA_V1_2_DEV) -if (${TARGET_BOARD} IN_LIST AVAILABLE_CUSTOM_TARGETS) - add_subdirectory(${TARGETS_DIR}/TARGET_${TARGET_BOARD}) -endif() +# Colored output when compiling +add_compile_options(-fdiagnostics-color) + +# 💡 Set project name and languages +project("Mbed CMake Template" LANGUAGES C CXX ASM) + +# Add mbed-os +add_subdirectory(${MBED_PATH}) +include(${ROOT_DIR}/cmake/mbed_create_distro.cmake) +mbed_create_distro(mbed_for_my_app mbed-os) # Add libraries add_subdirectory(${LIBS_DIR}/HelloWorld) -# If you use spikes to test features, you can add them here -add_subdirectory(${SPIKES_DIR}/blinky) - -# Add the main source files of the project from ./src +# Add executable targets main & blinky (as spike) +# 💡 You can uncomment both lines to make it fail add_subdirectory(${ROOT_DIR}/src) +add_subdirectory(${SPIKES_DIR}/blinky) -# Finally print the mbed-cmake build report -mbed_cmake_print_build_report() +option(VERBOSE_BUILD "Have a verbose build process") +if(VERBOSE_BUILD) + set(CMAKE_VERBOSE_MAKEFILE ON) +endif() diff --git a/Makefile b/Makefile index 7a40cec..54282a9 100644 --- a/Makefile +++ b/Makefile @@ -77,13 +77,13 @@ clean_config: config_target: mkdir_config @echo "" - @echo "🏃 Running configuration script for target $(TARGET_BOARD) 📝" - python3 $(CMAKE_DIR)/scripts/configure_cmake_for_target.py $(TARGET_BOARD) -p $(PROJECT_BUILD_DIR)/cmake_config/$(TARGET_BOARD) -a $(ROOT_DIR)/mbed_app.json + @echo "🏃 Running target configuration script 📝" + mbed-tools configure -t GCC_ARM -m $(TARGET_BOARD) --mbed-os-path=./extern/mbed-os config_cmake: mkdir_build @echo "" @echo "🏃 Running cmake configuration script for target $(TARGET_BOARD) 📝" - @cmake -S . -B $(TARGET_BUILD_DIR) -GNinja -DTARGET_BOARD="$(TARGET_BOARD)" -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DENABLE_CODE_ANALYSIS=$(CODE_ANALYSIS) + @cmake -S . -B $(TARGET_BUILD_DIR) -GNinja -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) # # MARK: - Tests targets @@ -176,7 +176,6 @@ mbed_clone: @echo "🧬 Cloning Mbed OS 📦" @rm -rf $(MBED_OS_DIR) git clone --depth=1 --branch=$(BRANCH) https://github.com/ARMmbed/mbed-os $(MBED_OS_DIR) - @$(MAKE) mbed_symlink_files mbed_curl: @echo "" @@ -186,7 +185,6 @@ mbed_curl: curl -O -L https://github.com/ARMmbed/mbed-os/archive/$(VERSION).tar.gz tar -xzf $(VERSION).tar.gz --strip-components=1 -C extern/mbed-os rm -rf $(VERSION).tar.gz - @$(MAKE) mbed_symlink_files mbed_symlink_files: @echo "" diff --git a/README.md b/README.md index 010c8d4..01453ed 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,39 @@ # Mbed CMake Template +## 🚧 WIP - From USCRPL/mbed-cmake to Mbed OS first-party CMake + +> ⚠️⚠️⚠️ + +This branch is a WIP to move from USCRPL/mbed-cmake to Mbed OS first-party CMake. + +### Instructions + +```shell +# Clone repository & switch branch +git clone https://github.com/ladislas/mbed-cmake-template +cd mbed-cmake-template +git checkout feature/move-to-vanilla-cmake + +# Clone mbed-os in `./extern/mbed-os` +# You can select the branch or tag you want +git clone --depth=10 --branch=master https://github.com/ARMmbed/mbed-os ./extern/mbed-os + +# Config CMake +make config + +# Build the project +make +``` + +Please note: + +- there is no need to run `mbed-tools configure... `, `.mbedbuild` is included in the repository for `DISCO_F769NI` +- `make config` runs `make clean` before configuring CMake +- To chekcout a different branch in `mbed-os`, `cd ./extern/mbed-os` and then `git checkout` or `gh pr checkout {pr_number}` +- To test two `add_executable` targets, you can uncomment line 29-30 from the main `CMakeLists.txt` + +> ⚠️⚠️⚠️ + **Version: 1.0.0** ## Introduction diff --git a/cmake/MbedUnitTests.cmake b/cmake/MbedUnitTests.cmake deleted file mode 100644 index 6c1f948..0000000 --- a/cmake/MbedUnitTests.cmake +++ /dev/null @@ -1,71 +0,0 @@ -# This file is called by mbed-src/CMakeLists.txt when unit tests are active -# and we only want to build a stub that contains all the headers. - -project(mbed-os) - - -# Unit test stub include dirs (list adapted from mbed-src/UNITTESTS/CMakeLists.txt) -set(unittest-includes-base - "UNITTESTS/target_h" - "UNITTESTS/target_h/events" - "UNITTESTS/target_h/events/equeue" - "UNITTESTS/target_h/platform" - "UNITTESTS/target_h/platform/cxxsupport" - "UNITTESTS/target_h/drivers" - "UNITTESTS/stubs" - "UNITTESTS/.." - "UNITTESTS/../features" - "UNITTESTS/../features/netsocket" - "UNITTESTS/../platform" - "UNITTESTS/../drivers" - "UNITTESTS/../hal" - "UNITTESTS/../events" - "UNITTESTS/../events/source" - "UNITTESTS/../events/internal" - "UNITTESTS/../rtos" - "UNITTESTS/../rtos/TARGET_CORTEX" - "UNITTESTS/../rtos/TARGET_CORTEX/rtx5/Include" - "UNITTESTS/../cmsis" - "UNITTESTS/../features/frameworks" - "UNITTESTS/../features/frameworks/mbed-trace" - "UNITTESTS/../features/frameworks/nanostack-libservice" - "UNITTESTS/../features/frameworks/nanostack-libservice/mbed-client-libservice" - "UNITTESTS/../features/filesystem/fat" - "UNITTESTS/../features/filesystem/fat/ChaN" - "UNITTESTS/../features/filesystem/bd" - "UNITTESTS/../features/filesystem/" - "UNITTESTS/../features/filesystem/littlefs" - "UNITTESTS/../features/filesystem/littlefs/littlefs" - "UNITTESTS/../features/cellular/framework/API" - "UNITTESTS/../features/cellular/framework/AT" - "UNITTESTS/../features/cellular/framework/device" - "UNITTESTS/../features/cellular/framework" - "UNITTESTS/../features/cellular/framework/common" - "UNITTESTS/../features/lorawan" - "UNITTESTS/../features/lorawan/lorastack" - "UNITTESTS/../features/lorawan/lorastack/mac" - "UNITTESTS/../features/lorawan/lorastack/phy" - "UNITTESTS/../features/lorawan/system" - "UNITTESTS/../features/mbedtls" - "UNITTESTS/../features/mbedtls/inc" - "UNITTESTS/../features/storage/kvstore/conf" - "UNITTESTS/../features/storage/blockdevice" - ) - -# create final library target which refers to MBed OS stubs -add_library(mbed-os INTERFACE) -target_compile_options(mbed-os INTERFACE -include ${MBED_CMAKE_SOURCE_DIR}/mbed-conf-unittests.h) -target_include_directories(mbed-os INTERFACE ${unittest-includes-base}) - -# fix error with missing types when building for MinGW -set(CMAKE_EXTRA_INCLUDE_FILES "sys/types.h") -check_all_types(uid_t gid_t nlink_t) -if(NOT HAVE_UID_T) - target_compile_definitions(mbed-os INTERFACE uid_t=int) -endif() -if(NOT HAVE_GID_T) - target_compile_definitions(mbed-os INTERFACE gid_t=int) -endif() -if(NOT HAVE_NLINK_T) - target_compile_definitions(mbed-os INTERFACE nlink_t=int) -endif() \ No newline at end of file diff --git a/cmake/ToolchainArmClangBuild.cmake b/cmake/ToolchainArmClangBuild.cmake deleted file mode 100644 index c0f79b8..0000000 --- a/cmake/ToolchainArmClangBuild.cmake +++ /dev/null @@ -1,88 +0,0 @@ -# This file is called by mbed-src/CMakeLists.txt when the ArmClang compiler is used. - -project(mbed-os) - -get_filename_component(LINKER_SCRIPT_FILENAME "${MBED_LINKER_SCRIPT}" NAME_WE) -get_filename_component(LINKER_SCRIPT_DIR ${MBED_LINKER_SCRIPT} DIRECTORY) -get_filename_component(LINKER_SCRIPT_EXT ${MBED_LINKER_SCRIPT} LAST_EXT) - -set(PREPROCESSED_LINKER_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/${LINKER_SCRIPT_FILENAME}_fixed${LINKER_SCRIPT_EXT}) - -# for Arm Compiler, all we need to do is replace the shebang at the top with the correct command line -set(PREPROCESS_ARGS ${MCU_COMPILE_OPTIONS} ${ARMCLANG_CPU_OPTION} -E -x c) - -# build the shebang command following the logic in arm.py -list_to_space_separated(SHEBANG_COMMAND ${PREPROCESS_ARGS}) -set(SHEBANG_COMMAND "#! \"${CMAKE_C_COMPILER}\" ${SHEBANG_COMMAND} -I\"${CMAKE_CURRENT_SOURCE_DIR}/${LINKER_SCRIPT_DIR}\"") - -# now replace it into the file -file(READ ${MBED_LINKER_SCRIPT} LINKER_SCRIPT_CONTENTS) -string(REGEX REPLACE "^#![^\n]+(.*)$" "${SHEBANG_COMMAND}\\1" PREPROC_LINKER_SCRIPT_CONTENTS "${LINKER_SCRIPT_CONTENTS}") -file(GENERATE OUTPUT ${PREPROCESSED_LINKER_SCRIPT} CONTENT "${PREPROC_LINKER_SCRIPT_CONTENTS}") - -# force all compilations to include the compile definitions files -# note: SHELL prefixes are a workaround for an annoying CMake issue: https://gitlab.kitware.com/cmake/cmake/issues/15826 -set(MBED_COMPILE_OPTIONS "SHELL:-include \"${MBED_CMAKE_CONFIG_HEADERS_PATH}/mbed_config.h\"" "SHELL:-include \"${MBED_CMAKE_CONFIG_HEADERS_PATH}/mbed_target_config.h\"") - -# convert include args for passing to preprocessor manually -set(PREPROCESSOR_INCLUDE_ARGS - -include ${MBED_CMAKE_CONFIG_HEADERS_PATH}/mbed_config.h - -include ${MBED_CMAKE_CONFIG_HEADERS_PATH}/mbed_target_config.h) - -foreach(INCLUDE_DIR ${MBED_INCLUDE_DIRS}) - list(APPEND PREPROCESSOR_INCLUDE_ARGS "-I${INCLUDE_DIR}") -endforeach() - -# Annoyingly, the ARMC6 assembler does not do preprocessing. So we have to give it a little help. -# This finds all assembler files (.S) in the source list, and adds a custom command to preprocess them. -# Also, the assembler files need to be linked as objects into the final version (something with the provided linker scripts???), -# they can't be in a .a file, so we have to build them separately. -set(OLD_MBED_SOURCE_FILES ${MBED_SOURCE_FILES}) -set(MBED_SOURCE_FILES "") -set(ASM_SOURCE_FILES "") -foreach(SOURCE_FILE ${OLD_MBED_SOURCE_FILES}) - get_filename_component(SOURCE_EXT ${SOURCE_FILE} LAST_EXT) - - if("${SOURCE_EXT}" STREQUAL ".S") - - # ASM file -- time to go DIY - get_filename_component(SOURCE_FILENAME ${SOURCE_FILE} NAME_WE) - get_filename_component(SOURCE_DIR ${SOURCE_FILE} DIRECTORY) - - set(PREPROCESSED_SOURCE_FILE_DIR ${CMAKE_CURRENT_BINARY_DIR}/${SOURCE_DIR}) - file(MAKE_DIRECTORY ${PREPROCESSED_SOURCE_FILE_DIR}) - set(PREPROCESSED_SOURCE_FILE ${PREPROCESSED_SOURCE_FILE_DIR}/${SOURCE_FILENAME}_preproc.S) - - add_custom_command( - OUTPUT ${PREPROCESSED_SOURCE_FILE} - MAIN_DEPENDENCY ${SOURCE_FILE} - COMMAND ${CMAKE_C_COMPILER} ${PREPROCESS_ARGS} ${PREPROCESSOR_INCLUDE_ARGS} ${CMAKE_CURRENT_SOURCE_DIR}/${SOURCE_FILE} -o ${PREPROCESSED_SOURCE_FILE} - COMMENT "Preprocessing ${SOURCE_FILE}" - VERBATIM) - - list(APPEND ASM_SOURCE_FILES ${PREPROCESSED_SOURCE_FILE}) - - else() - # not ASM file, keep - list(APPEND MBED_SOURCE_FILES ${SOURCE_FILE}) - endif() -endforeach() - -# Let's just say that Arm Compiler is not a big fan of .a libraries, at least when they contain things like -# weak symbols and code that calls ASM. -# I tried using a static library at first, and that just sent things into a massive bootloop that poured a -# deluge of crash reports through my terminal. -# Soooo... let's NOT do that. - -add_library(mbed-os-obj OBJECT ${ASM_SOURCE_FILES} ${MBED_SOURCE_FILES}) -target_compile_options(mbed-os-obj PUBLIC ${MBED_COMPILE_OPTIONS}) -target_include_directories(mbed-os-obj PUBLIC ${MBED_INCLUDE_DIRS}) - -# create final library target (interface which contains objects, link options, and compile flags) -add_library(mbed-os INTERFACE) -target_link_libraries(mbed-os INTERFACE - --scatter ${PREPROCESSED_LINKER_SCRIPT} - ${MBED_LINK_OPTIONS}) -target_sources(mbed-os INTERFACE $) -target_compile_options(mbed-os INTERFACE ${MBED_COMPILE_OPTIONS}) -target_include_directories(mbed-os INTERFACE ${MBED_INCLUDE_DIRS}) \ No newline at end of file diff --git a/cmake/ToolchainArmClangDefine.cmake b/cmake/ToolchainArmClangDefine.cmake deleted file mode 100644 index c16a708..0000000 --- a/cmake/ToolchainArmClangDefine.cmake +++ /dev/null @@ -1,76 +0,0 @@ -# CMake toolchain file to set compiler for the ArmClang toolchain - -SET(CMAKE_SYSTEM_NAME Generic) -SET(CMAKE_SYSTEM_VERSION 1) - -# specify the cross compiler -set(CMAKE_C_COMPILER armclang) -set(CMAKE_CXX_COMPILER armclang) - -set(CMAKE_C_COMPILER_ID ARMClang) -set(CMAKE_CXX_COMPILER_ID ARMClang) - -set(OLD_MCU_COMPILE_OPTIONS ${MCU_COMPILE_OPTIONS}) -set(MCU_COMPILE_OPTIONS "") -foreach(OPTION ${OLD_MCU_COMPILE_OPTIONS}) - - # remove some Mbed flags that shouldn't be in build commands (CMake auto adds these) - if(("${OPTION}" STREQUAL "-c") OR - ("${OPTION}" STREQUAL "-MMD")) - # don't add - elseif("${OPTION}" MATCHES "--target=(.*)") - - # parse out CPU target and tell CMake about it - set(CMAKE_C_COMPILER_TARGET ${CMAKE_MATCH_1}) - set(CMAKE_CXX_COMPILER_TARGET ${CMAKE_MATCH_1}) - set(CMAKE_ASM_COMPILER_TARGET ${CMAKE_MATCH_1}) - - list(APPEND MCU_COMPILE_OPTIONS ${OPTION}) - - set(ARMCLANG_TARGET_OPTION ${OPTION}) - - elseif("${OPTION}" MATCHES "-mcpu=(.*)") - - # parse out CPU name and set CMAKE_SYSTEM_PROCESSOR to it to prevent CMake error - set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_MATCH_1}) - set(ARMCLANG_CPU_OPTION ${OPTION}) # used for the preprocessor command - - else() - - # no special handling for this arg - list(APPEND MCU_COMPILE_OPTIONS ${OPTION}) - endif() -endforeach() - -# convert list to space-separated for CMAKE_C_FLAGS etc. -list_to_space_separated(CHIP_FLAGS ${MCU_COMPILE_OPTIONS}) - -set(CHIP_LINKER_FLAGS "") - -# certain flags will only work if linking with Mbed OS, not for regular executables, so we need to strip those out so CMake can configure -set(MBED_LINK_OPTIONS "") - -foreach(FLAG ${MCU_LINK_OPTIONS}) - if("${FLAG}" IN_LIST MCU_COMPILE_FLAGS) - # duplicate flag, do nothing - else() - string(APPEND CHIP_LINKER_FLAGS " ${FLAG}") - endif() -endforeach() - -# also add config-specific link flags (these go with mbed-os since they need generator expressions) -foreach(BUILD_TYPE ${CMAKE_CONFIGURATION_TYPES}) - string(TOUPPER "${BUILD_TYPE}" BUILD_TYPE_UCASE) - foreach(OPTION ${MCU_LINK_OPTIONS_${BUILD_TYPE_UCASE}}) - if(NOT "${OPTION}" STREQUAL "") - list(APPEND MBED_LINK_OPTIONS $<$:${OPTION}>) - endif() - endforeach() -endforeach() - -#note: these initialize the cache variables on first configure -set(CMAKE_C_FLAGS_INIT "${CHIP_FLAGS} ") -set(CMAKE_CXX_FLAGS_INIT "${CHIP_FLAGS} ") -set(CMAKE_ASM_FLAGS_INIT "${CHIP_FLAGS} -x assembler -masm=auto -Wno-unused-command-line-argument ") - -set(CMAKE_EXE_LINKER_FLAGS_INIT "${CHIP_LINKER_FLAGS}") diff --git a/cmake/ToolchainGCCArmBuild.cmake b/cmake/ToolchainGCCArmBuild.cmake deleted file mode 100644 index 57a0e5f..0000000 --- a/cmake/ToolchainGCCArmBuild.cmake +++ /dev/null @@ -1,63 +0,0 @@ -# This file is called by mbed-src/CMakeLists.txt when the GCC Arm compiler is used. - -project(mbed-os) - -# add command to preprocess linker script -get_filename_component(LINKER_SCRIPT_FILENAME "${MBED_LINKER_SCRIPT}" NAME_WE) -get_filename_component(LINKER_SCRIPT_DIR ${MBED_LINKER_SCRIPT} DIRECTORY) -get_filename_component(LINKER_SCRIPT_EXT ${MBED_LINKER_SCRIPT} LAST_EXT) - -set(PREPROCESSED_LINKER_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/${LINKER_SCRIPT_FILENAME}_preprocessed${LINKER_SCRIPT_EXT}) - -# NOTE: clearly the linker script is not assembly! We give -x assembler-with-cpp to force GCC to try and compile the file -# as if it was assembly. It only gets to the preprocessor stage because of -E, and everything works fine. -set(PREPROCESS_ONLY_FLAGS -x assembler-with-cpp -E -Wp,-P ${CMAKE_EXE_LINKER_FLAGS}) - -# This is kind of a hack, but without it we would have to have a seperate facility for finding the preprocessor executable. -# We also needed to pass the linker flags because they can include defines needed in the linker script -add_custom_command( - OUTPUT ${PREPROCESSED_LINKER_SCRIPT} - COMMAND ${CMAKE_CXX_COMPILER} ${PREPROCESS_ONLY_FLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/${MBED_LINKER_SCRIPT} -o ${PREPROCESSED_LINKER_SCRIPT} - MAIN_DEPENDENCY ${MBED_LINKER_SCRIPT} - COMMENT "Preprocessing linker script ${MBED_LINKER_SCRIPT} -> ${PREPROCESSED_LINKER_SCRIPT}" - VERBATIM) - -# add target so we can force this command to be run before mbed is compiled -add_custom_target( - mbed-linker-script - DEPENDS ${PREPROCESSED_LINKER_SCRIPT}) - -# force all compilations to include the compile definitions files -# note: SHELL prefixes are a workaround for an annoying CMake issue: https://gitlab.kitware.com/cmake/cmake/issues/15826 -set(MBED_COMPILE_OPTIONS "SHELL:-include \"${MBED_CMAKE_CONFIG_HEADERS_PATH}/mbed_config.h\"" "SHELL:-include \"${MBED_CMAKE_CONFIG_HEADERS_PATH}/mbed_target_config.h\"") - -# create the static library for the rest of the source files -add_library(mbed-os-static STATIC ${MBED_SOURCE_FILES}) -target_compile_options(mbed-os-static PUBLIC ${MBED_COMPILE_OPTIONS}) -target_include_directories(mbed-os-static PUBLIC ${MBED_INCLUDE_DIRS}) - -# make sure linker script gets built before anything trying to use mbed-os -add_dependencies(mbed-os-static mbed-linker-script) - -# disable some annoying warnings during the Mbed build -target_compile_options(mbed-os-static PRIVATE - $<$:-Wno-reorder> - -Wno-unused-function - -Wno-unused-variable - -Wno-enum-compare - -Wno-attributes) - -# create final library target (wraps actual library target in -Wl,--whole-archive [which is needed for weak symbols to work]) -add_library(mbed-os INTERFACE) - -target_include_directories(mbed-os - INTERFACE - ${MBED_OS_DIR} -) - -target_link_libraries(mbed-os INTERFACE - -Wl,--whole-archive - mbed-os-static - -Wl,--no-whole-archive - -T\"${PREPROCESSED_LINKER_SCRIPT}\" - ${MBED_LINK_OPTIONS}) diff --git a/cmake/ToolchainGCCArmDefine.cmake b/cmake/ToolchainGCCArmDefine.cmake deleted file mode 100644 index c60c409..0000000 --- a/cmake/ToolchainGCCArmDefine.cmake +++ /dev/null @@ -1,47 +0,0 @@ -# CMake toolchain file to set compiler for the gcc-arm toolchain - -SET(CMAKE_SYSTEM_NAME Generic) -SET(CMAKE_SYSTEM_VERSION 1) -set(CMAKE_EXECUTABLE_SUFFIX elf) - -# specify the cross compiler -set(CMAKE_C_COMPILER arm-none-eabi-gcc) -set(CMAKE_CXX_COMPILER arm-none-eabi-g++) - -# remove some Mbed flags that shouldn't be in build commands (CMake will handle these) -list(REMOVE_ITEM MCU_COMPILE_OPTIONS -c -MMD) - -# convert list to space-separated for CMAKE_C_FLAGS etc. -list_to_space_separated(CHIP_FLAGS ${MCU_COMPILE_OPTIONS}) - -set(CHIP_LINKER_FLAGS "") - -# certain flags will only work if linking with Mbed OS, not for regular executables, so we need to strip those out so CMake can configure -set(MBED_LINK_OPTIONS "") - -foreach(FLAG ${MCU_LINK_OPTIONS}) - if("${FLAG}" MATCHES "--wrap") - list(APPEND MBED_LINK_OPTIONS "${FLAG}") - elseif("${FLAG}" IN_LIST MCU_COMPILE_FLAGS) - # duplicate flag, do nothing - else() - string(APPEND CHIP_LINKER_FLAGS " ${FLAG}") - endif() -endforeach() - -# also add config-specific link flags (these go with mbed-os since they need generator expressions) -foreach(BUILD_TYPE ${CMAKE_CONFIGURATION_TYPES}) - string(TOUPPER "${BUILD_TYPE}" BUILD_TYPE_UCASE) - foreach(OPTION ${MCU_LINK_OPTIONS_${BUILD_TYPE_UCASE}}) - if(NOT "${OPTION}" STREQUAL "") - list(APPEND MBED_LINK_OPTIONS $<$:${OPTION}>) - endif() - endforeach() -endforeach() - -#note: these initialize the cache variables on first configure -set(CMAKE_C_FLAGS_INIT "${CHIP_FLAGS}") -set(CMAKE_CXX_FLAGS_INIT "${CHIP_FLAGS} -Wvla -fno-exceptions -fno-rtti") -set(CMAKE_ASM_FLAGS_INIT "${CHIP_FLAGS}") - -set(CMAKE_EXE_LINKER_FLAGS_INIT "${CHIP_LINKER_FLAGS} --specs=nosys.specs -Wl,--start-group -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys -Wl,--end-group") diff --git a/cmake/mbed_create_distro.cmake b/cmake/mbed_create_distro.cmake new file mode 100644 index 0000000..5397754 --- /dev/null +++ b/cmake/mbed_create_distro.cmake @@ -0,0 +1,117 @@ +# Patched version of the mbed function. +# (replaced "target_link_options(mbed-core INTERFACE" with "target_link_options(${target} PRIVATE") +# Can be removed once #14199 is merged +function(mbed_generate_options_for_linker_patched target definitions_file) + set(_compile_definitions + "$" + ) + + # Remove macro definitions that contain spaces as the lack of escape sequences and quotation marks + # in the macro when retrieved using generator expressions causes linker errors. + # This includes string macros, array macros, and macros with operations. + # TODO CMake: Add escape sequences and quotation marks where necessary instead of removing these macros. + set(_compile_definitions + "$" + ) + + # Append -D to all macros as we pass these as response file to cxx compiler + set(_compile_definitions + "$<$:-D$>" + ) + file(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/${target}.txt" CONTENT "${_compile_definitions}\n") + set(${definitions_file} @${CMAKE_BINARY_DIR}/${target}.txt PARENT_SCOPE) +endfunction() + +# Patched version of the mbed function. +# (replaced "target_link_options(mbed-core INTERFACE" with "target_link_options(${target} PRIVATE") +# Can be removed once #14199 is merged +function(mbed_set_mbed_target_linker_script_patched target) + get_property(mbed_target_linker_script GLOBAL PROPERTY MBED_TARGET_LINKER_FILE) + mbed_generate_options_for_linker_patched(${target} _linker_preprocess_definitions) + if(MBED_TOOLCHAIN STREQUAL "GCC_ARM") + set(CMAKE_PRE_BUILD_COMMAND + COMMAND "arm-none-eabi-cpp" ${_linker_preprocess_definitions} -x assembler-with-cpp -E -Wp,-P + ${mbed_target_linker_script} -o ${CMAKE_BINARY_DIR}/${target}.link_script.ld + + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + BYPRODUCTS "${CMAKE_BINARY_DIR}/${target}.link_script.ld" + ) + target_link_options(${target} + PRIVATE + "-T" "${CMAKE_BINARY_DIR}/${target}.link_script.ld" + "-Wl,-Map=${CMAKE_BINARY_DIR}/${target}${CMAKE_EXECUTABLE_SUFFIX}.map" + ) + elseif(MBED_TOOLCHAIN STREQUAL "ARM") + set(CMAKE_PRE_BUILD_COMMAND COMMAND "") + target_link_options(target + PRIVATE + "--scatter=${mbed_target_linker_script}" + "--predefine=${_linker_preprocess_definitions}" + "--map" + ) + endif() + add_custom_command( + TARGET + ${target} + PRE_LINK + ${CMAKE_PRE_BUILD_COMMAND} + COMMENT + "Link line:" + VERBATIM + ) +endfunction() + +# Append the value of PROPERTY from SOURCE to the value of PROPERTY on DESTINATION +function(copy_append_property PROPERTY SOURCE DESTINATION) + get_property(PROP_IS_DEFINED TARGET ${SOURCE} PROPERTY ${PROPERTY} SET) + if(PROP_IS_DEFINED) + get_property(PROP_VALUE TARGET ${SOURCE} PROPERTY ${PROPERTY}) + #message("Copying ${PROPERTY} from ${SOURCE} -> ${DESTINATION}: ${PROP_VALUE} ") + set_property(TARGET ${DESTINATION} APPEND PROPERTY ${PROPERTY} "${PROP_VALUE}") + endif() +endfunction(copy_append_property) + +# Create a "distribution" of Mbed OS containing the base Mbed and certain modules. +# This distribution only needs to be compiled once and can be referenced in an arbitrary amount of targets +function(mbed_create_distro NAME) # ARGN: modules... + add_library(${NAME} OBJECT) + mbed_configure_app_target(${NAME}) + + # First link as private dependencies + target_link_libraries(${NAME} PRIVATE ${ARGN}) + + # Now copy include dirs, compile defs, and compile options (but NOT interface source files) over + # to the distribution target so they will be passed into things that link to it. + # To do this, we need to recursively traverse the tree of dependencies. + set(REMAINING_MODULES ${ARGN}) + set(COMPLETED_MODULES ${ARGN}) + while(NOT "${REMAINING_MODULES}" STREQUAL "") + + list(GET REMAINING_MODULES 0 CURR_MODULE) + + #message("Processing ${CURR_MODULE}") + + copy_append_property(INTERFACE_COMPILE_DEFINITIONS ${CURR_MODULE} ${NAME}) + copy_append_property(INTERFACE_COMPILE_OPTIONS ${CURR_MODULE} ${NAME}) + copy_append_property(INTERFACE_INCLUDE_DIRECTORIES ${CURR_MODULE} ${NAME}) + copy_append_property(INTERFACE_LINK_OPTIONS ${CURR_MODULE} ${NAME}) + + list(REMOVE_AT REMAINING_MODULES 0) + list(APPEND COMPLETED_MODULES ${CURR_MODULE}) + + # find sub-modules of this module + get_property(SUBMODULES TARGET ${CURR_MODULE} PROPERTY INTERFACE_LINK_LIBRARIES) + #message("Deps of ${CURR_MODULE}: ${SUBMODULES}") + foreach(SUBMODULE ${SUBMODULES}) + if(NOT "${SUBMODULE}" MATCHES "::@") # remove CMake internal CMAKE_DIRECTORY_ID_SEP markers + if(NOT ${SUBMODULE} IN_LIST COMPLETED_MODULES) + list(APPEND REMAINING_MODULES ${SUBMODULE}) + endif() + endif() + endforeach() + + #message("REMAINING_MODULES: ${REMAINING_MODULES}") + + endwhile() + +endfunction(mbed_create_distro) diff --git a/cmake/scripts/check_python_package.py b/cmake/scripts/check_python_package.py deleted file mode 100644 index 47434dc..0000000 --- a/cmake/scripts/check_python_package.py +++ /dev/null @@ -1,10 +0,0 @@ -#file which is invoked by the cmake build system to check if all necessary python packages are installed. - -import sys - -try: - __import__(sys.argv[1]) -except ImportError: - exit(1) - -exit(0) \ No newline at end of file diff --git a/cmake/scripts/configure_cmake_for_target.py b/cmake/scripts/configure_cmake_for_target.py deleted file mode 100644 index 180ae4d..0000000 --- a/cmake/scripts/configure_cmake_for_target.py +++ /dev/null @@ -1,306 +0,0 @@ -import sys -import os -import argparse -import traceback -import re -import json -import pathlib - -from pathlib import Path - -# import Mbed's built-in tools library -project_root_dir = Path(os.path.dirname(__file__)).parent.parent -mbed_os_dir = os.path.join(project_root_dir, "extern/mbed-os") -custom_targets_dir = os.path.join(project_root_dir, "targets") - -sys.path.append(mbed_os_dir) - -try: - from tools import build_api, options - from tools.resources import Resources, FileType - from tools.notifier.term import TerminalNotifier - from tools.config import Config - from tools.targets import Target -except ImportError: - - print("Failed to import the Mbed OS Python configuration system!") - print("Be sure that you have installed all required python modules, see ",mbed_os_dir,"/requirements.txt") - traceback.print_exc() - exit(1) - - - -def write_target_header(target_header_path:str, symbol_list:list): - """ Write the target header to the given path using the given symbol defines""" - - target_header = open(target_header_path, "w") - target_header.write( - """/* - Mbed OS Target Define Header. - This contains all of the #defines specific to your target and device. - It is prepended to every source file using the -include compiler option. - AUTOGENERATED by configure_for_target.py. DO NOT EDIT! - */ - -""") - - with_value_re = re.compile(r"^([^=]+)=(.*)$") - - for definition in sorted(symbol_list): - - # convert defines in command-line format (VAR=value) to header format (#define VAR value) - with_value_match = with_value_re.fullmatch(definition) - if with_value_match is not None: - target_header.write("#define " + with_value_match.group(1) + " " + with_value_match.group(2) + "\n") - else: - # no value given, so follow GCC command line semantics and define it to 1 - target_header.write("#define " + definition + " 1\n") - - target_header.close() - -def build_cmake_list(list_name:str, contents:list): - """ Get a string containing CMake code for a list with the given name. """ - - list_string = f"set({list_name}" - for string in contents: - - # items containing spaces need to be quoted - if " " in string: - list_string += "\n \"" + string + "\"" - else: - list_string += "\n " + string - - list_string += ")\n\n" - - return list_string - -def build_cmake_path_list(list_name:str, paths:list): - """ Build a CMake list of file paths. Does extra conversion to prepare file paths for CMake.""" - - converted_paths = [] - for path in paths: - - # paths should be relative to the mbed-src directory - relative_path = os.path.relpath(path, mbed_os_dir) - - # CMake always uses forward slashes, even on Windows - converted_paths.append(relative_path.replace(os.path.sep, "/")) - - return build_cmake_list(list_name, converted_paths) - -def write_cmake_config(cmake_config_path:str, mcu_compile_flags:list, mcu_link_flags:list, - linker_script:str, include_dirs:list, source_files:list, target_name:str, toolchain_name:str, profile_flags:list, - profile_link_flags:list, profile_names:list): - - """ Write the configuration file for CMake using info extracted from the Python scripts""" - - cmake_config = open(cmake_config_path, "w") - cmake_config.write( - """# Mbed OS CMake configuration file. -# This contains all of the information needed for CMake to compile and use Mbed OS. -# It was extracted from the Mbed configuration files when you originally configured this project. -# AUTOGENERATED by configure_for_target.py. DO NOT EDIT! - -""") - - cmake_config.write(build_cmake_list("MBED_TARGET_NAME", [target_name])) - cmake_config.write(build_cmake_list("MBED_TOOLCHAIN_NAME", [toolchain_name])) - - # note: CMake convention is that variables called "FLAGS" are strings while variables called "OPTIONS" are lists. - cmake_config.write(build_cmake_list("MCU_COMPILE_OPTIONS", mcu_compile_flags)) - cmake_config.write(build_cmake_list("MCU_LINK_OPTIONS", mcu_link_flags)) - cmake_config.write(build_cmake_path_list("MBED_LINKER_SCRIPT", [linker_script])) - cmake_config.write(build_cmake_path_list("MBED_INCLUDE_DIRS", include_dirs)) - cmake_config.write(build_cmake_path_list("MBED_SOURCE_FILES", source_files)) - - for profile_idx in range(0, len(profile_names)): - cmake_config.write(build_cmake_list("MCU_COMPILE_OPTIONS_" + profile_names[profile_idx], profile_flags[profile_idx])) - - for profile_idx in range(0, len(profile_names)): - cmake_config.write(build_cmake_list("MCU_LINK_OPTIONS_" + profile_names[profile_idx], profile_link_flags[profile_idx])) - - cmake_config.close() - -# Function to print all known configuration variables. -# Based on tools/get_config.py -def print_config(print_descriptions:bool, toolchain): - - params, macros = toolchain.config.get_config_data() - features = toolchain.config.get_features() - - if not params and not macros: - print("No configuration data available.") - sys.exit(0) - if params: - print("Configuration parameters") - print("------------------------") - for p in sorted(list(params.keys())): - if print_descriptions: - print(params[p].get_verbose_description()) - else: - print(str(params[p])) - print("") - - print("Macros") - print("------") - for m in Config.config_macros_to_macros(macros): - print(m) - -# Parse args -# ------------------------------------------------------------------------- -GENERATED_DEFAULT_PATH = "../mbed-cmake-config/" - -parser = argparse.ArgumentParser(description="Configure mbed-cmake for a processor target.") - -parser.add_argument('target', type=str, help="Mbed target name to configure the build system for.") - -parser.add_argument('-l', '--list-config', action="store_true", help="List all the config options that Mbed OS supports for your target") -parser.add_argument('-c', '--print-config', action="store_true", help="Print all the config options that Mbed OS supports for your target, with descriptions") -parser.add_argument('-p', '--generated-path', default=GENERATED_DEFAULT_PATH, - help="The relative path to the directory which will store the generated files") -parser.add_argument('-t', '--toolchain', default="GCC_ARM", - choices=["ARMC6", "GCC_ARM"], - help="Toolchain that you will be compiling with.") -parser.add_argument('-a', '--app-config', default=None, - help="Path to mbed_app.json") -parser.add_argument('-x', '--custom-target', action="store_true", - help="Tell the config script that the target is a custom target") -args = parser.parse_args() - -target_name = args.target -toolchain_name = args.toolchain -get_config = args.list_config or args.print_config -verbose_config = args.print_config -generated_rpath = args.generated_path -generated_path = os.path.join(project_root_dir, generated_rpath) -app_config_path = args.app_config -is_custom_target = args.custom_target - -pathlib.Path(generated_path).mkdir(parents=True, exist_ok=True) -with open(os.path.join(generated_path, "do-not-modify.txt"), 'w') as do_not_modify: - do_not_modify.write("Files in this folder were generated by configure_for_target.py") - - -# Perform the scan of the Mbed OS dirs & custom targets -# ------------------------------------------------------------------------- - -# Add custom targets -if is_custom_target: - Target.add_extra_targets(custom_targets_dir) - -# profile constants -# list of all profile JSONs -profile_jsons = [os.path.join(mbed_os_dir, "tools/profiles/develop.json"), - os.path.join(mbed_os_dir, "tools/profiles/debug.json"), - os.path.join(mbed_os_dir, "tools/profiles/release.json")] -# CMake build type matching each Mbed profile -profile_cmake_names = ["RELWITHDEBINFO", - "DEBUG", - "RELEASE"] - -print("Configuring build system for target " + target_name) - -# Can NOT be the current directory, or it screws up some internal regexes inside mbed tools. -# That was a fun hour to debug... - -config_header_dir = os.path.join(generated_path, "config-headers") -pathlib.Path(config_header_dir).mkdir(parents=True, exist_ok=True) # create dir if not exists - -notifier = TerminalNotifier(True, False) - -# create a different toolchain for each profile so that we can detect the flags needed in each configuration -profile_toolchains = [] -for profile_json_path in profile_jsons: - with open(profile_json_path) as profile_file: - - print(">> Collecting data for config " + profile_json_path) - profile_data = json.load(profile_file) - profile_toolchain = build_api.prepare_toolchain(src_paths=[mbed_os_dir], build_dir=config_header_dir, target=target_name, toolchain_name=toolchain_name, build_profile=[profile_data], app_config=app_config_path) - # each toolchain must then scan the mbed dir to pick up more configs - resources = Resources(notifier).scan_with_toolchain(src_paths=[mbed_os_dir], toolchain=profile_toolchain, exclude=True) - profile_toolchain.RESPONSE_FILES=False - - - profile_toolchains.append(profile_toolchain) - - -# Add custom targets -if is_custom_target: - target_dir = "TARGET_" + target_name - resources.add_directory(os.path.join(custom_targets_dir, target_dir)) - -# Profiles seem to only set flags, so for the remaining operations we can use any toolchain -toolchain = profile_toolchains[0] -print("Generated config header: " + toolchain.get_config_header()) - - -print("Using settings from these JSON files:\n " + "\n ".join(resources.get_file_paths(FileType.JSON))) - - -# Write target header -# ------------------------------------------------------------------------- - -target_header_path = os.path.join(config_header_dir, "mbed_target_config.h") -write_target_header(target_header_path, toolchain.get_symbols()) -print("Generated target config header: " + target_header_path) - -# Write CMake config file -# ------------------------------------------------------------------------- - -cmake_config_dir = os.path.join(generated_path, "cmake", ) -pathlib.Path(cmake_config_dir).mkdir(parents=True, exist_ok=True) # create dir if not exists - -cmake_config_path = os.path.join(cmake_config_dir, "MbedOSConfig.cmake") - -# create include paths -inc_paths = resources.get_file_paths(FileType.INC_DIR) -inc_paths = set(inc_paths) # De-duplicate include paths -inc_paths = sorted(set(inc_paths)) # Sort include paths for consistency - -# Get sources -sources = ( - resources.get_file_paths(FileType.ASM_SRC) + - resources.get_file_paths(FileType.C_SRC) + - resources.get_file_paths(FileType.CPP_SRC) - ) - -# common flags are the intersection of flags from all configurations -common_flags = set(toolchain.flags['common']) -common_link_flags = set(toolchain.flags['ld']) - -for profile_idx in range(1, len(profile_toolchains)): - - common_flags = common_flags & set(profile_toolchains[profile_idx].flags['common']) - common_link_flags = common_link_flags & set(profile_toolchains[profile_idx].flags['ld']) - -# profile flags are the flags in one profile that are not in common flags. -profile_flags = [] -profile_link_flags = [] -for profile_idx in range(0, len(profile_toolchains)): - profile_flags.append(set(profile_toolchains[profile_idx].flags['common']) - common_flags) - profile_link_flags.append(set(profile_toolchains[profile_idx].flags['ld']) - common_link_flags) - -write_cmake_config(cmake_config_path, - mcu_compile_flags=toolchain.flags['common'], - mcu_link_flags=toolchain.flags['ld'], - linker_script=resources.get_file_paths(FileType.LD_SCRIPT)[0], - include_dirs = inc_paths, - source_files = sources, - target_name = target_name, - toolchain_name=toolchain_name, - profile_flags = profile_flags, - profile_link_flags = profile_link_flags, - profile_names = profile_cmake_names) - -print("Generated CMake configuration file: " + cmake_config_path) - -if get_config: - print("") - print_config(verbose_config, toolchain) - -print("-----------------------------------------------") -print(" mbed-cmake configuration complete.") -print("") -print(" MAKE SURE TO DELETE ANY OLD CMAKE") -print(" BUILD DIRS BEFORE RUNNING CMAKE AGAIN") -print("-----------------------------------------------") diff --git a/cmake/scripts/nxpprog.py b/cmake/scripts/nxpprog.py deleted file mode 100644 index f4f61dc..0000000 --- a/cmake/scripts/nxpprog.py +++ /dev/null @@ -1,1399 +0,0 @@ -#!/usr/bin/python3 -# -# Copyright (c) 2009 Brian Murphy -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# -# A simple programmer which works with the ISP protocol on NXP LPC arm -# processors. - -import binascii -import os -import sys -import struct -import getopt -import serial -import socket -import time - -# debugging config - -# If true, echo from the chip will be turned on and checked against the sent string. -ENABLE_ECHO = False - -# If true, print all transmitted and received serial messages to the console -PRINT_SERIAL = True - -CMD_SUCCESS = 0 -INVALID_COMMAND = 1 -SRC_ADDR_ERROR = 2 -DST_ADDR_ERROR = 3 -SRC_ADDR_NOT_MAPPED = 4 -DST_ADDR_NOT_MAPPED = 5 -COUNT_ERROR = 6 -INVALID_SECTOR = 7 -SECTOR_NOT_BLANK = 8 -SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION = 9 -COMPARE_ERROR = 10 -BUSY = 11 -PARAM_ERROR = 12 -ADDR_ERROR = 13 -ADDR_NOT_MAPPED = 14 -CMD_LOCKED = 15 -INVALID_CODE = 16 -INVALID_BAUD_RATE = 17 -INVALID_STOP_BIT = 18 -CODE_READ_PROTECTION_ENABLED = 19 - -# flash sector sizes for lpc23xx/lpc24xx/lpc214x processors -flash_sector_lpc23xx = ( - 4, 4, 4, 4, 4, 4, 4, 4, - 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, - 4, 4, 4, 4, 4, 4 - ) - -# flash sector sizes for 64k lpc21xx processors (without bootsector) -flash_sector_lpc21xx_64 = ( - 8, 8, 8, 8, 8, 8, 8, 8 - ) - -# flash sector sizes for 128k lpc21xx processors (without bootsector) -flash_sector_lpc21xx_128 = ( - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8 - ) - -# flash sector sizes for 256k lpc21xx processors (without bootsector) -flash_sector_lpc21xx_256 = ( - 8, 8, 8, 8, 8, 8, 8, 8, - 64, 64, - 8, 8, 8, 8, 8, 8, 8, - ) - -# flash sector sizes for lpc17xx processors -flash_sector_lpc17xx = ( - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, - ) - -# flash sector sizes for lpc11xx processors -flash_sector_lpc11xx = ( - 4, 4, 4, 4, 4, 4, 4, 4, - ) - -# flash sector sizes for lpc18xx processors -flash_sector_lpc18xx = ( - 8, 8, 8, 8, 8, 8, 8, 8, - 64, 64, 64, 64, 64, 64, 64, - ) - - -flash_prog_buffer_base_default = 0x40001000 -flash_prog_buffer_size_default = 4096 - -# cpu parameter table -cpu_parms = { - # 128k flash - "lpc2364" : { - "flash_sector" : flash_sector_lpc23xx, - "flash_sector_count": 11, - "devid": 369162498 - }, - # 256k flash - "lpc2365" : { - "flash_sector" : flash_sector_lpc23xx, - "flash_sector_count": 15, - "devid": 369158179 - }, - "lpc2366" : { - "flash_sector" : flash_sector_lpc23xx, - "flash_sector_count": 15, - "devid": 369162531 - }, - # 512k flash - "lpc2367" : { - "flash_sector" : flash_sector_lpc23xx, - "devid": 369158181 - }, - "lpc2368" : { - "flash_sector" : flash_sector_lpc23xx, - "devid": 369162533 - }, - "lpc2377" : { - "flash_sector" : flash_sector_lpc23xx, - "devid": 385935397 - }, - "lpc2378" : { - "flash_sector" : flash_sector_lpc23xx, - "devid": 385940773 - }, - "lpc2387" : { - "flash_sector" : flash_sector_lpc23xx, - "devid": 402716981 - - }, - "lpc2388" : { - "flash_sector" : flash_sector_lpc23xx, - "devid": 402718517 - }, - # lpc21xx - # some incomplete info here need at least sector count - "lpc2141": { - "devid": 196353, - "flash_sector": flash_sector_lpc23xx, - "flash_sector_count": 8, - }, - "lpc2142": { - "flash_sector": flash_sector_lpc23xx, - "flash_sector_count": 9, - "devid": 196369, - }, - "lpc2144": { - "flash_sector": flash_sector_lpc23xx, - "flash_sector_count": 11, - "devid": 196370, - }, - "lpc2146": { - "flash_sector": flash_sector_lpc23xx, - "flash_sector_count": 15, - "devid": 196387, - }, - "lpc2148": { - "flash_sector": flash_sector_lpc23xx, - "flash_sector_count": 27, - "devid": 196389, - }, - "lpc2109" : { - "flash_sector": flash_sector_lpc21xx_64, - "devid": 33685249 - }, - "lpc2119" : { - "flash_sector": flash_sector_lpc21xx_128, - "devid": 33685266 - }, - "lpc2129" : { - "flash_sector": flash_sector_lpc21xx_256, - "devid": 33685267 - }, - "lpc2114" : { - "flash_sector" : flash_sector_lpc21xx_128, - "devid": 16908050 - }, - "lpc2124" : { - "flash_sector" : flash_sector_lpc21xx_256, - "devid": 16908051 - }, - "lpc2194" : { - "flash_sector" : flash_sector_lpc21xx_256, - "devid": 50462483 - }, - "lpc2292" : { - "flash_sector" : flash_sector_lpc21xx_256, - "devid": 67239699 - }, - "lpc2294" : { - "flash_sector" : flash_sector_lpc21xx_256, - "devid": 84016915 - }, - # lpc22xx - "lpc2212" : { - "flash_sector" : flash_sector_lpc21xx_128 - }, - "lpc2214" : { - "flash_sector" : flash_sector_lpc21xx_256 - }, - # lpc24xx - "lpc2458" : { - "flash_sector" : flash_sector_lpc23xx, - "devid": 352386869, - }, - "lpc2468" : { - "flash_sector" : flash_sector_lpc23xx, - "devid": 369164085, - }, - "lpc2478" : { - "flash_sector" : flash_sector_lpc23xx, - "devid": 386006837, - }, - # lpc17xx - "lpc1769" : { - "flash_sector" : flash_sector_lpc17xx, - "flash_prog_buffer_base" : 0x10000200, - "csum_vec": 7, - "devid": 0x26113f37, - "cpu_type": "thumb", - }, - "lpc1768" : { - "flash_sector" : flash_sector_lpc17xx, - "flash_prog_buffer_base" : 0x10001000, - "csum_vec": 7, - "devid": 0x26013f37, - "cpu_type": "thumb", - }, - "lpc1767" : { - "flash_sector" : flash_sector_lpc17xx, - "flash_prog_buffer_base" : 0x10001000, - "csum_vec": 7, - "devid": 0x26012837, - "cpu_type": "thumb", - }, - "lpc1766" : { - "flash_sector" : flash_sector_lpc17xx, - "flash_prog_buffer_base" : 0x10001000, - "csum_vec": 7, - "devid": 0x26013f33, - "cpu_type": "thumb", - }, - "lpc1765" : { - "flash_sector" : flash_sector_lpc17xx, - "flash_prog_buffer_base" : 0x10001000, - "csum_vec": 7, - "devid": 0x26013733, - "cpu_type": "thumb", - }, - "lpc1764" : { - "flash_sector" : flash_sector_lpc17xx, - "flash_prog_buffer_base" : 0x10001000, - "csum_vec": 7, - "devid": 0x26011922, - "cpu_type": "thumb", - }, - "lpc1763" : { - "flash_sector" : flash_sector_lpc17xx, - "flash_prog_buffer_base" : 0x10001000, - "csum_vec": 7, - "devid": 0x26012033, - "cpu_type": "thumb", - }, - "lpc1759" : { - "flash_sector" : flash_sector_lpc17xx, - "flash_prog_buffer_base" : 0x10001000, - "csum_vec": 7, - "devid": 0x25113737, - "cpu_type": "thumb", - }, - "lpc1758" : { - "flash_sector" : flash_sector_lpc17xx, - "flash_prog_buffer_base" : 0x10001000, - "csum_vec": 7, - "devid": 0x25013f37, - "cpu_type": "thumb", - }, - "lpc1756" : { - "flash_sector" : flash_sector_lpc17xx, - "flash_prog_buffer_base" : 0x10001000, - "csum_vec": 7, - "devid": 0x25011723, - "cpu_type": "thumb", - }, - "lpc1754" : { - "flash_sector" : flash_sector_lpc17xx, - "flash_prog_buffer_base" : 0x10001000, - "csum_vec": 7, - "devid": 0x25011722, - "cpu_type": "thumb", - }, - "lpc1752" : { - "flash_sector" : flash_sector_lpc17xx, - "flash_prog_buffer_base" : 0x10001000, - "csum_vec": 7, - "devid": 0x25001121, - "cpu_type": "thumb", - }, - "lpc1751" : { - "flash_sector" : flash_sector_lpc17xx, - "flash_prog_buffer_base" : 0x10001000, - "csum_vec": 7, - "devid": 0x25001110, - "cpu_type": "thumb", - }, - "lpc1114" : { - "flash_sector" : flash_sector_lpc11xx, - "flash_prog_buffer_base" : 0x10000400, - "devid": 0x0444102B, - "flash_prog_buffer_size" : 1024 - }, - # lpc18xx - "lpc1817" : { - "flash_sector" : flash_sector_lpc18xx, - "flash_bank_addr": (0x1a000000, 0x1b000000), - "flash_prog_buffer_base" : 0x10081000, - "devid": (0xF001DB3F, 0), - "devid_word1_mask": 0xff, - "csum_vec": 7, - "cpu_type": "thumb", - }, - "lpc1832" : { - "flash_sector" : flash_sector_lpc18xx, - "flash_bank_addr": (0x1a000000), - "flash_prog_buffer_base" : 0x10081000, - "csum_vec": 7, - "cpu_type": "thumb", - }, - "lpc1833" : { - "flash_sector" : flash_sector_lpc18xx, - "flash_sector_count": 11, - "flash_bank_addr": (0x1a000000, 0x1b000000), - "flash_prog_buffer_base" : 0x10081000, - "devid": (0xf001da30, 0x44), - "csum_vec": 7, - "cpu_type": "thumb", - }, - "lpc1837" : { - "flash_sector" : flash_sector_lpc18xx, - "flash_bank_addr": (0x1a000000, 0x1b000000), - "flash_prog_buffer_base" : 0x10081000, - "devid": (0xf001da30, 0), - "csum_vec": 7, - "cpu_type": "thumb", - }, - "lpc1853" : { - "flash_sector" : flash_sector_lpc18xx, - "flash_sector_count": 11, - "flash_bank_addr": (0x1a000000, 0x1b000000), - "flash_prog_buffer_base" : 0x10081000, - "devid": (0xf001d830, 0), - "csum_vec": 7, - "cpu_type": "thumb", - }, - "lpc1857" : { - "flash_sector" : flash_sector_lpc18xx, - "flash_bank_addr": (0x1a000000, 0x1b000000), - "flash_prog_buffer_base" : 0x10081000, - "devid": (0xf001d830, 0x44), - "csum_vec": 7, - "cpu_type": "thumb", - }, -} - - -def log(str): - sys.stdout.write("%s\n" % str) - sys.stdout.flush() - - -def dump(name, str): - sys.stderr.write("%s:\n" % name) - ct = 0 - for i in str: - sys.stderr.write("%x, " % ord(i)) - ct += 1 - if ct == 4: - ct = 0 - sys.stderr.write("\n") - sys.stderr.write("\n") - - -def panic(str): - log("PANIC: " + str) - sys.exit(1) - - -def syntax(): - panic( -"""\ -{0} : program image file to processor. -{0} --udp : program processor using Ethernet. -{0} --start= : start the device at . -{0} --read= --addr=
--len= : - read length bytes from address and dump them to a file. -{0} --serialnumber : get the device serial number -{0} --list : list supported processors. -options: - --cpu= : set the cpu type. - --oscfreq= : set the oscillator frequency. - --baud= : set the baud rate. - --xonxoff : enable xonxoff flow control. - --control : use RTS and DTR to control reset and int0. - --addr= : set the base address for the image. - --verify : read the device after programming. - --verifyonly : don't program, just verify. - --eraseonly : don't program, just erase. Implies --eraseall. - --eraseall : erase all flash not just the area written to. - --blankcheck : don't program, just check that the flash is blank. - --bank=[0|1] : select bank for devices with flash banks. - --port= : UDP port number to use (default 41825). - --mac= : MAC address to associate IP address with.\ -""".format(os.path.basename(sys.argv[0]))) - -class SerialDevice(object): - def __init__(self, device, baud, xonxoff=False, control=False): - # Create the Serial object without port to avoid automatic opening - self._serial = serial.Serial(port=None, baudrate=baud, stopbits=serial.STOPBITS_ONE) - - # Disable RTS and DRT to avoid automatic reset to ISP mode (use --control for explicit reset) - self._serial.setRTS(1) - self._serial.setDTR(1) - - # Select and open the port after RTS and DTR are set to zero - print("Opening device...") - self._serial.setPort(device) - self._serial.open() - - # set a timeout just in case there is nothing connected - # or the device is in the wrong mode. - # This timeout is too short for slow baud rates but who wants to - # use them? - self._serial.timeout = .2 - # device wants Xon Xoff flow control - if xonxoff: - self._serial.xonxoff = True - - # reset pin is controlled by DTR implying int0 is controlled by RTS - self.reset_pin = "dtr" - - if control: - print("Resetting chip...") - self.isp_mode() - print("Reset complete.") - - time.sleep(.1) - - self._serial.flushInput() - - # put the chip in isp mode by resetting it using RTS and DTR signals - # this is of course only possible if the signals are connected in - # this way - def isp_mode(self): - self.reset(0) - time.sleep(.1) - self.int0(1) - self.reset(1) - time.sleep(.5) - self.reset(0) - time.sleep(.1) - self.int0(0) - - def reset(self, level): - if self.reset_pin == "rts": - self._serial.setRTS(level) - else: - self._serial.setDTR(level) - - def int0(self, level): - # if reset pin is rts int0 pin is dtr - if self.reset_pin == "rts": - self._serial.setDTR(level) - else: - self._serial.setRTS(level) - - def write(self, data): - self._serial.write(data) - - def readline(self, timeout_allowed:bool=False): - - line = b'' - while True: - c = self._serial.read(1) - if not c: - - if not timeout_allowed: - print("Timeout after receiving %d characters" % len(line)) - print("Line so far: %s" % line.hex()) - - break - if c == b'\r': - if not line: - continue - else: - break - if c == b'\n': - if not line: - continue - else: - break - line += c - - #print("Line (%d chars): %s" % (len(line), line.hex())) - - return line.decode("ASCII", "ignore") - -class UdpDevice(object): - def __init__(self, address): - self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self._sock.settimeout(5) - self._inet_addr = address[0] - self._udp_port = address[1] - self._eth_addr = address[2] - - if self._eth_addr: - import subprocess - # Try add host to ARP table - obj = subprocess.Popen(['arp', '-s', self._inet_addr, self._eth_addr], - stdout=subprocess.PIPE, stderr=subprocess.PIPE, - shell=True) - res = obj.communicate() - stdout_text = res[0].decode('ascii', 'ignore') if res[0] else "" - stderr_text = res[1].decode('ascii', 'ignore') if res[1] else "" - if obj.returncode or stderr_text: - panic("Failed to register IP address " + - "(Administrative privileges may be required)\r\n" + - stderr_text.replace('\r', '').replace('\n', '')) - - self._sock.bind(('', self._udp_port)) - - def write(self, data): - self._sock.sendto(data, (self._inet_addr, self._udp_port)) - - def readline(self, timeout=None): - if timeout: - ot = self._sock.gettimeout() - self._sock.settimeout(timeout) - - try: - line, addr = self._sock.recvfrom(1024) - except Exception as e: - line = b"" - - if timeout: - self._sock.settimeout(ot) - - return line.decode("UTF-8", "ignore").replace('\r','').replace('\n','') - -class nxpprog: - def __init__(self, cpu, device, baud, osc_freq, xonxoff=False, control=False, address=None, verify=False): - self.echo_on = True - self.verify = verify - self.OK = 'OK' - self.RESEND = 'RESEND' - self.sync_str = 'Synchronized' - - # for calculations in 32 bit modulo arithmetic - self.U32_MOD = (2 ** 32) - - # uuencoded line length - self.uu_line_size = 45 - # uuencoded block length - self.uu_block_size = self.uu_line_size * 20 - - if address: - self.device = UdpDevice(address) - else: - self.device = SerialDevice(device, baud, xonxoff, control) - - self.cpu = cpu - - self.connection_init(osc_freq) - - self.banks = self.get_cpu_parm("flash_bank_addr", 0) - - if self.banks == 0: - self.sector_commands_need_bank = False - else: - self.sector_commands_need_bank = True - - def connection_init(self, osc_freq:int): - self.sync(osc_freq) - - if self.cpu == "autodetect": - devid = self.get_devid() - for dcpu in cpu_parms.keys(): - cpu_devid = cpu_parms[dcpu].get("devid") - if not cpu_devid: - continue - - # mask devid word1 - devid_word1_mask = cpu_parms[dcpu].get("devid_word1_mask") - if devid_word1_mask and isinstance(devid, tuple) and devid[0] == cpu_devid[0] and (devid[1] & devid_word1_mask) == (cpu_devid[1] & devid_word1_mask): - log("Detected %s" % dcpu) - self.cpu = dcpu - break - - if devid == cpu_devid: - log("Detected %s" % dcpu) - self.cpu = dcpu - break - if self.cpu == "autodetect": - panic("Cannot autodetect from device id %d(0x%x), set cpu name manually" % - (devid, devid)) - - # unlock write commands - self.isp_command("U 23130") - - - # this version takes a bytes argument, - # and does not send a newline - def dev_write(self, data): - - if PRINT_SERIAL: - print('<- ' + data.decode("utf-8")) - - self.device.write(data) - - # this version takes a str argument, and - # appends a newline. - def dev_writeln(self, data): - data_bytes = data.encode('UTF-8') + b'\r\n' - - if PRINT_SERIAL: - print('<- ' + data) - - self.device.write(data_bytes) - - def dev_readline(self, timeout_allowed:bool = False): - data = self.device.readline(timeout_allowed) - - if PRINT_SERIAL: - print('-> ' + data) - - return data - - def errexit(self, str, status): - if not status: - panic("%s: timeout" % str) - err = int(status) - if err != 0: - error_desc = [ - 'CMD_SUCCESS: Command is executed successfully', - 'INVALID_COMMAND: Invalid command', - 'SRC_ADDR_ERROR: Source address is not on word boundary', - 'DST_ADDR_ERROR: Destination address is not on word or 256 byte boundary', - 'SRC_ADDR_NOT_MAPPED: Source address is not mapped in the memory map', - 'DST_ADDR_NOT_MAPPED: Destination address is not mapped in the memory map', - 'COUNT_ERROR: Byte count is not multiple of 4 or is not a permitted value', - 'INVALID_SECTOR: Sector number is invalid or end sector number is greater than start sector number', - 'SECTOR_NOT_BLANK: Sector is not blank', - 'SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION: Command to prepare sector for write operation was not executed', - 'COMPARE_ERROR: Source and destination data not equal', - 'BUSY: Flash programming hardware interface is busy', - 'PARAM_ERROR: Insufficient number of parameters or invalid parameter', - 'ADDR_ERROR: Address not on word boundary', - 'ADDR_NOT_MAPPED: Address is not mapped in the memory map', - 'CMD_LOCKED: Command is locked', - 'INVALID_CODE: Unlock code is invalid', - 'INVALID_BAUD_RATE: Invalid baud rate setting', - 'INVALID_STOP_BIT: Invalid stop bit setting', - 'CODE_READ_PROTECTION_ENABLED: Code read protection enabled' - ] - str = str.replace('\r','').replace('\n','') - errstr = error_desc[err] if err < len(error_desc) else "" - panic("%s: %d - %s" % (str, err, errstr)) - - - # Send a command string (without a newline) to the chip. - # If an error code is returned, the command is retried, - # except if the error code is in allowed_error_codes - def isp_command(self, cmd, allowed_error_codes=()): - - # turn the codes into strings - allowed_result_strings = set() - - for code in allowed_error_codes: - allowed_result_strings.add(str(code)) - - retry = 5 - status = None - while retry > 0: - retry -= 1 - self.dev_writeln(cmd) - - # throw away echo data - if self.echo_on: - echo = self.dev_readline() - if self.verify and echo != cmd: - log('Invalid echo -- retrying command') - self.dev_readline() # remove status code - continue - - status = self.dev_readline() - if status == "0" or status in allowed_result_strings: - return status - - self.errexit("'%s' error" % cmd, status) - - return status - - - def sync(self, osc): - - self.device._serial.flushInput() - - #self.device._serial.baudrate = 750000 - - self.dev_write(b'?') - self.dev_readline() - - self.dev_writeln(self.sync_str) - s = self.dev_readline() - self.dev_readline() - - # detect echo state - if s == self.sync_str: - self.echo_on = True - elif s == self.OK: - self.echo_on = False - else: - panic("No sync string") - - # set the oscillator frequency - self.dev_writeln('%d' % osc) - if self.echo_on: - s = self.dev_readline() - if not ('%d' % osc) in s: - panic('Invalid echo') - - s = self.dev_readline() - if s != self.OK: - if s == str(INVALID_COMMAND): - pass - else: - self.errexit(("'%d' osc not ok" % osc), None) - panic("Osc not ok") - - if not ENABLE_ECHO: - # disable echo - self.dev_writeln('A 0') - if self.echo_on: - s = self.dev_readline() - if s != 'A 0': - panic('Invalid echo') - - s = self.dev_readline() - if s == str(CMD_SUCCESS): - self.echo_on = False - elif s == str(INVALID_COMMAND): - pass - else: - self.errexit("'A 0' echo disable failed", s) - panic("Echo disable failed") - - - def sum(self, data): - s = 0 - if isinstance(data, str): - for ch in data: - s += ord(ch) - else: - for i in data: - s += i - return s - - - def write_ram_block(self, addr, data): - data_len = len(data) - - for i in range(0, data_len, self.uu_line_size): - c_line_size = data_len - i - if c_line_size > self.uu_line_size: - c_line_size = self.uu_line_size - block = data[i:i+c_line_size] - bstr = binascii.b2a_uu(block).decode("UTF-8")[0:-1] - self.dev_writeln(bstr) - - if self.echo_on: - echo = self.dev_readline() - if echo != bstr: - log("Invalid echo from RAM block") - - # sometimes the echo could be invalid because a newline was erroneously inserted. - # In this case, clear out any remaining lines in the buffer to fix things. - self.device._serial.flushInput() - - retry = 3 - - status = None - - while retry > 0: - retry -= 1 - - checksum_str = '%s' % self.sum(data) - self.dev_writeln(checksum_str) - - if self.echo_on: - echo = self.dev_readline() - if echo != checksum_str: - log("Invalid echo from RAM block checksum") - continue - - status = self.dev_readline() - if status == self.OK or status == self.RESEND: - break - - if not status: - return "timeout" - if status == self.RESEND: - return "resend" - if status == self.OK: - return "" - - # unknown status result - panic("Unknown status from writing RAM block: " + status) - - def uudecode(self, line): - # uu encoded data has an encoded length first - linelen = ord(line[0]) - 32 - - uu_linelen = (linelen + 3 - 1) // 3 * 4 - - if uu_linelen + 1 != len(line): - panic("Error in line length") - - # pure python implementation - if this was C we would - # use bitshift operations here - decoded = "" - for i in range(1, len(line), 4): - c = 0 - for j in line[i: i + 4]: - ch = ord(j) - 32 - ch %= 64 - c = c * 64 + ch - s = [] - for j in range(0, 3): - s.append(c % 256) - c = c // 256 - for j in reversed(s): - decoded = decoded + chr(j) - - # only return real data - return decoded[0:linelen] - - - def read_block(self, addr, data_len, fd=None): - self.isp_command("R %d %d" % ( addr, data_len )) - - expected_lines = (data_len + self.uu_line_size - 1) // self.uu_line_size - - data = "" - for i in range(0, expected_lines, 20): - lines = expected_lines - i - if lines > 20: - lines = 20 - cdata = "" - for i in range(0, lines): - line = self.dev_readline() - - decoded = self.uudecode(line) - - cdata += decoded - - s = self.dev_readline() - - if int(s) != self.sum(cdata): - panic("Checksum mismatch on read got 0x%x expected 0x%x" % (int(s), self.sum(data))) - else: - self.dev_writeln(self.OK) - - if fd: - fd.write(cdata) - else: - data += cdata - - if fd: - return None - else: - return data - - def write_ram_data(self, addr, data): - image_len = len(data) - for i in range(0, image_len, self.uu_block_size): - - a_block_size = image_len - i - if a_block_size > self.uu_block_size: - a_block_size = self.uu_block_size - - self.isp_command("W %d %d" % ( addr, a_block_size )) - - retry = 10 - while retry >= 0: - retry -= 1 - err = self.write_ram_block(addr, data[i : i + a_block_size]) - if not err: - break - elif err != "resend": - panic("Write error: %s" % err) - else: - log("Resending -- %d Attempts Left" % retry) - - addr += a_block_size - - - def find_flash_sector(self, addr): - table = self.get_cpu_parm("flash_sector") - flash_base_addr = self.get_cpu_parm("flash_bank_addr", 0) - if flash_base_addr == 0: - faddr = 0 - else: - faddr = flash_base_addr[0] # fix to have a current flash bank - for i in range(0, len(table)): - n_faddr = faddr + table[i] * 1024 - if addr >= faddr and addr < n_faddr: - return i - faddr = n_faddr - return -1 - - - def bytestr(self, ch, count): - data = b'' - for i in range(0, count): - data += bytes([ch]) - return data - - - def insert_csum(self, orig_image): - # make this a valid image by inserting a checksum in the correct place - intvecs = struct.unpack("<8I", orig_image[0:32]) - - # default vector is 5: 0x14, new cortex cpus use 7: 0x1c - valid_image_csum_vec = self.get_cpu_parm("csum_vec", 5) - # calculate the checksum over the interrupt vectors - csum = 0 - intvecs_list = [] - for vec in range(0, len(intvecs)): - intvecs_list.append(intvecs[vec]) - if valid_image_csum_vec == 5 or vec <= valid_image_csum_vec: - csum = csum + intvecs[vec] - # remove the value at the checksum location - csum -= intvecs[valid_image_csum_vec] - - csum %= self.U32_MOD - csum = self.U32_MOD - csum - - log("Inserting intvec checksum 0x%08x in image at offset %d" % - (csum, valid_image_csum_vec)) - - intvecs_list[valid_image_csum_vec] = csum - - image = b'' - for vecval in intvecs_list: - image += struct.pack(" ram_block: - a_ram_block = ram_block - - flash_addr_start = image_index + flash_addr_base - flash_addr_end = flash_addr_start + a_ram_block - 1 - - log("Writing %d bytes to 0x%x" % (a_ram_block, flash_addr_start)) - - self.write_ram_data(ram_addr, - image[image_index: image_index + a_ram_block]) - - s_flash_sector = self.find_flash_sector(flash_addr_start) - - e_flash_sector = self.find_flash_sector(flash_addr_end) - - self.prepare_flash_sectors(s_flash_sector, e_flash_sector) - - # copy ram to flash - self.isp_command("C %d %d %d" % - (flash_addr_start, ram_addr, a_ram_block)) - - # optionally compare ram and flash - if verify: - old_panic = panic - panic = log - result = self.isp_command("M %d %d %d" % - (flash_addr_start, ram_addr, a_ram_block), (COMPARE_ERROR,)) - panic = old_panic - if result == str(CMD_SUCCESS): - pass - elif result == str(COMPARE_ERROR): - offset = self.dev_readline() # offset - print("Compare error between RAM and flash! Offset of first difference in sector: %s" % (offset, )) - success = False - else: - self.errexit("Error during verify", result) - - return success - - - def verify_image(self, flash_addr_base, image): - success = True - - image_length = len(image) - start_addr = flash_addr_base - end_addr = flash_addr_base + image_length - - start_sector = self.find_flash_sector(start_addr) - end_sector = self.find_flash_sector(end_addr) - - table = self.get_cpu_parm("flash_sector") - flash_base_addr = self.get_cpu_parm("flash_bank_addr", 0) - if flash_base_addr == 0: - faddr = 0 - else: - faddr = flash_base_addr[0] # fix to have a current flash bank - - index = 0 - sector = start_sector - while sector <= end_sector: - start_of_sector = faddr + 1024 * sum(table[:sector]) - end_of_sector = faddr + 1024 * sum(table[:sector+1]) - - start = start_addr if start_of_sector < start_addr else start_of_sector - end = end_addr if end_of_sector > end_addr else end_of_sector - length = 4 * ((end - start) // 4) - - log("Verify sector %i: Reading %d bytes from 0x%x" % (sector, length, start)) - data = self.read_block(start, length) - if isinstance(image[0], int): - data = [ord(x) for x in data] - - if len(data) != length: - panic("Verify failed! lengths differ") - - for (i, (x, y)) in enumerate(zip(data, image[index:index+(end-start)])): - if x != y: - log("Verify failed! content differ at location 0x%x. Expected: 0x%x, got: 0x%x" % (faddr + i, y, x)) - success = False - - index = index + length - sector = sector + 1 - - return success - - - def start(self, addr=0): - mode = self.get_cpu_parm("cpu_type", "arm") - # start image at address 0 - if mode == "arm": - m = "A" - elif mode == "thumb": - m = "T" - else: - panic("Invalid mode to start") - - self.isp_command("G %d %s" % (addr, m)) - - - def select_bank(self, bank): - status = self.isp_command("S %d" % bank) - - if status == self.OK: - return 1 - - return 0 - - - def get_devid(self): - self.isp_command("J") - id1 = self.dev_readline() - - # FIXME find a way of doing this without a timeout - id2 = self.dev_readline(True) - if id2: - ret = (int(id1), int(id2)) - else: - ret = int(id1) - return ret - - - def get_serial_number(self): - self.isp_command("N") - id1 = self.dev_readline() - id2 = self.dev_readline() - id3 = self.dev_readline() - id4 = self.dev_readline() - return ' '.join([id1, id2, id3, id4]) - - -def main(argv=None): - if argv is None: - argv = sys.argv - - # defaults - osc_freq = 16000 # kHz - baud = 115200 - cpu = "autodetect" - flash_addr_base = 0 - erase_all = False - erase_only = False - verify = False - verify_only = False - blank_check = False - xonxoff = False - start = False - control = False - select_bank = False - read = False - readlen = 0 - get_serial_number = False - udp = False - port = -1 - mac = "" # "0C-1D-12-E0-1F-10" - - optlist, args = getopt.getopt(argv[1:], '', - ['cpu=', 'oscfreq=', 'baud=', 'addr=', 'start=', - 'filetype=', 'bank=', 'read=', 'len=', 'serialnumber', - 'udp', 'port=', 'mac=', 'verify', 'verifyonly', 'blankcheck', - 'xonxoff', 'eraseall', 'eraseonly', 'list', 'control']) - - for o, a in optlist: - if o == "--list": - log("Supported cpus:") - for val in sorted(cpu_parms.keys()): - log(" %s" % val) - sys.exit(0) - if o == "--cpu": - cpu = a - elif o == "--xonxoff": - xonxoff = True - elif o == "--oscfreq": - osc_freq = int(a) - elif o == "--addr": - flash_addr_base = int(a, 0) - elif o == "--baud": - baud = int(a) - elif o == "--eraseall": - erase_all = True - elif o == "--eraseonly": - erase_only = True - elif o == "--verify": - verify = True - elif o == "--verifyonly": - verify = True - verify_only = True - elif o == "--blankcheck": - verify = True - blank_check = True - elif o == "--control": - control = True - elif o == "--start": - start = True - if a: - startaddr = int(a, 0) - else: - startaddr = 0 - elif o == "--bank": - select_bank = True - bank = int(a) - elif o == "--read": - read = True - readfile = a - elif o == "--serialnumber": - get_serial_number = True - elif o == "--len": - readlen = int(a) - elif o == "--udp": - udp = True - elif o == "--port": - port = int(a) - elif o == "--mac": - mac = a - else: - panic("Unhandled option: %s" % o) - - if cpu != "autodetect" and not cpu in cpu_parms: - panic("Unsupported cpu %s" % cpu) - - if len(args) == 0: - syntax() - - device = args[0] - - if udp: - if '.' in device: - if ':' in device: - device, port = tuple(device.split(':')) - port = int(port) - if port<0 or port>65535: - panic("Bad port number: %d" % port) - parts = [int(x) for x in device.split('.')] - if len(parts)!=4 or min(parts)<0 or max(parts)>255: - panic("Bad IPv4-address: %s" % device) - device = '.'.join([str(x) for x in parts]) - elif ':' in device: - # panic("Bad IPv6-address: %s" % device) - pass - else: - panic("Bad IP-address: %s" % device) - if port < 0: - port = 41825 - if mac: - parts = [int(x, 16) for x in mac.split('-')] - if len(parts)!=6 or min(parts)<0 or max(parts)>255: - panic("Bad MAC-address: %s" % mac) - mac = '-'.join(['%02x'%x for x in parts]) - log("cpu=%s ip=%s:%d mac=%s" % (cpu, device, port, mac)) - else: - log("cpu=%s ip=%s:%d" % (cpu, device, port)) - else: - log("cpu=%s oscfreq=%d device=%s baud=%d" % (cpu, osc_freq, device, baud)) - - prog = nxpprog(cpu, device, baud, osc_freq, xonxoff, control, (device, port, mac) if udp else None, verify) - - if erase_only: - prog.erase_all(verify) - elif blank_check: - prog.blank_check_all() - elif start: - prog.start(startaddr) - elif select_bank: - prog.select_bank(bank) - elif get_serial_number: - sn = prog.get_serial_number() - sys.stdout.write(sn) - elif read: - if not readlen: - panic("Read length is 0") - fd = open(readfile, "w") - prog.read_block(flash_addr_base, readlen, fd) - fd.close() - else: - if len(args) != 2: - syntax() - - filename = args[1] - - image = open(filename, "rb").read() - - if not verify_only: - start = time.time() - success = prog.prog_image(image, flash_addr_base, erase_all, verify) - stop = time.time() - elapsed = stop - start - log("Programmed %s in %.1f seconds" % ("successfully" if success else "with errors", elapsed)) - - if verify: - start = time.time() - success = prog.verify_image(flash_addr_base, image) - stop = time.time() - elapsed = stop - start - log("Verified %s in %.1f seconds" % ("successfully" if success else "with errors", elapsed)) - - if not verify_only: - prog.start(flash_addr_base) - - -if __name__ == '__main__': - sys.exit(main()) - -# EOF diff --git a/cmake/templates/Template_MbedOS_CMakelists.txt b/cmake/templates/Template_MbedOS_CMakelists.txt deleted file mode 100644 index 359e8db..0000000 --- a/cmake/templates/Template_MbedOS_CMakelists.txt +++ /dev/null @@ -1,9 +0,0 @@ - -# include correct mbed-cmake buildfile based on toolchain -if(MBED_UNITTESTS) - include(MbedUnitTests) -elseif("${MBED_TOOLCHAIN_NAME}" STREQUAL "ARMC6") - include(ToolchainArmClangBuild) -elseif("${MBED_TOOLCHAIN_NAME}" STREQUAL "GCC_ARM") - include(ToolchainGCCArmBuild) -endif() diff --git a/cmake/templates/Template_MbedOS_mbedignore.txt b/cmake/templates/Template_MbedOS_mbedignore.txt deleted file mode 100644 index 8473874..0000000 --- a/cmake/templates/Template_MbedOS_mbedignore.txt +++ /dev/null @@ -1,17 +0,0 @@ -connectivity/celluar/* -connectivity/libraries/mbed-coap/* -connectivity/libraries/ppp/* -connectivity/lowaran/* -connectivity/lwipstack/* -connectivity/nanostack/* -connectivity/nfc/* -connectivity/drivers/802.15.4_RF/* -connectivity/drivers/cellular/* -connectivity/drivers/emac/* -connectivity/drivers/lora/* -connectivity/drivers/mbedtls/* -connectivity/drivers/nfc/* - -features/* -storage/kvstore/* -drivers/device_key/* diff --git a/cmake/utils/AddMbedExecutable.cmake b/cmake/utils/AddMbedExecutable.cmake deleted file mode 100644 index 4446ef6..0000000 --- a/cmake/utils/AddMbedExecutable.cmake +++ /dev/null @@ -1,111 +0,0 @@ - -# Note: some code originally from here: https://os.mbed.com/cookbook/mbed-cmake - -# needed for memory map script -check_python_package(intelhex HAVE_INTELHEX) -check_python_package(prettytable HAVE_PRETTYTABLE) - -set(CAN_RUN_MEMAP TRUE) -if(NOT (HAVE_INTELHEX AND HAVE_PRETTYTABLE)) - message(WARNING "Unable to run the memory mapper due to missing Python dependencies.") - set(CAN_RUN_MEMAP FALSE) -endif() - -# Why doesn't memap use the same toolchain names as the rest of the Mbed build system? -# Don't ask me! -if("${MBED_TOOLCHAIN_NAME}" STREQUAL "ARMC6") - set(MEMAP_TOOLCHAIN_NAME "ARM_STD") -else() - set(MEMAP_TOOLCHAIN_NAME ${MBED_TOOLCHAIN_NAME}) -endif() - -# figure out objcopy command -get_filename_component(TOOLCHAIN_BIN_DIR ${CMAKE_C_COMPILER} DIRECTORY) - -if("${MBED_TOOLCHAIN_NAME}" STREQUAL "ARMC6") - set(OBJCOPY_NAME fromelf) -elseif("${MBED_TOOLCHAIN_NAME}" STREQUAL "GCC_ARM") - set(OBJCOPY_NAME arm-none-eabi-objcopy) -endif() - -find_program( - OBJCOPY_EXECUTABLE - NAMES ${OBJCOPY_NAME} - HINTS ${TOOLCHAIN_BIN_DIR} - DOC "Path to objcopy executable") - -if(NOT EXISTS ${OBJCOPY_EXECUTABLE}) - message(FATAL_ERROR "Failed to find objcopy executable! Please set OBJCOPY_EXECUTABLE to the path to ${OBJCOPY_NAME}") -endif() - -#custom function to add a mbed executable and generate mbed source files -function(add_mbed_executable EXECUTABLE) - - add_executable(${EXECUTABLE} ${ARGN}) - - target_link_libraries(${EXECUTABLE} mbed-os) - - set(BIN_FILE ${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE}.bin) - set(HEX_FILE ${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE}.hex) - - if("${MBED_TOOLCHAIN_NAME}" STREQUAL "ARMC6") - # the ArmClang CMake platform files automatically generate a memory map - target_link_libraries(${EXECUTABLE} --info=totals --map) - set(MAP_FILE ${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE}${CMAKE_EXECUTABLE_SUFFIX}.map) - - set(OBJCOPY_ELF_TO_BIN_COMMAND ${OBJCOPY_EXECUTABLE} --bin -o ${BIN_FILE} $) - set(OBJCOPY_ELF_TO_HEX_COMMAND ${OBJCOPY_EXECUTABLE} --i32 -o ${HEX_FILE} $) - - elseif("${MBED_TOOLCHAIN_NAME}" STREQUAL "GCC_ARM") - - set(MAP_FILE ${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE}.map) - - # add link options to generate memory map - target_link_libraries(${EXECUTABLE} -Wl,\"-Map=${MAP_FILE}\",--cref) - - set(OBJCOPY_ELF_TO_BIN_COMMAND ${OBJCOPY_EXECUTABLE} -O binary $ ${BIN_FILE}) - set(OBJCOPY_ELF_TO_HEX_COMMAND ${OBJCOPY_EXECUTABLE} -O ihex $ ${HEX_FILE}) - - endif() - - # generate .bin firmware file - add_custom_command( - TARGET ${EXECUTABLE} POST_BUILD - COMMAND ${OBJCOPY_ELF_TO_BIN_COMMAND} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Objcopying ${EXECUTABLE} to mbed firmware ${BIN_FILE}") - - # generate .hex firmware file - add_custom_command( - TARGET ${EXECUTABLE} POST_BUILD - COMMAND ${OBJCOPY_ELF_TO_HEX_COMMAND} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Objcopying ${EXECUTABLE} to mbed firmware ${HEX_FILE}") - - set_property(DIRECTORY PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${BIN_FILE} ${MAP_FILE} ${HEX_FILE}) - - if(CAN_RUN_MEMAP) - add_custom_command( - TARGET ${EXECUTABLE} POST_BUILD - COMMAND ${Python3_EXECUTABLE} ${MBED_OS_DIR}/tools/memap.py -t ${MEMAP_TOOLCHAIN_NAME} ${MAP_FILE} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Displaying memory map for ${EXECUTABLE}") - endif() - - # add upload target - # gen_upload_target(${EXECUTABLE} ${BIN_FILE}) - -endfunction(add_mbed_executable) - -# When in not unit testing mode, we want buildfiles to still process OK. -# However, unit tests can't build for the MBed itself. -# So, add_mbed_unit_test is a no-op. -function(add_mbed_unit_test EXECUTABLE) - - # unit tests active -- create a dummy target that only exists so setting properties on it doesn't fail. - add_executable(${EXECUTABLE} ${MBED_CMAKE_SOURCE_DIR}/cmake/dummy.cpp) - - # prevent this target from being built during normal make commands - set_property(TARGET ${EXECUTABLE} PROPERTY EXCLUDE_FROM_ALL TRUE) - -endfunction(add_mbed_unit_test) diff --git a/cmake/utils/AddMbedUnitTestsExecutable.cmake b/cmake/utils/AddMbedUnitTestsExecutable.cmake deleted file mode 100644 index 7881b20..0000000 --- a/cmake/utils/AddMbedUnitTestsExecutable.cmake +++ /dev/null @@ -1,25 +0,0 @@ - - -# When in unit testing mode, we want buildfiles to still process OK. -# However, executables can't link correctly because mbed-os is stubbed out as headers. -# So, while libraries build normally, add_mbed_executable is a no-op. -function(add_mbed_executable EXECUTABLE) - - # unit tests active -- create a dummy target that only exists so setting properties on it doesn't fail. - add_executable(${EXECUTABLE} ${MBED_CMAKE_SOURCE_DIR}/cmake/dummy.cpp) - - # prevent this target from being built during normal make commands - set_property(TARGET ${EXECUTABLE} PROPERTY EXCLUDE_FROM_ALL TRUE) - -endfunction(add_mbed_executable) - - -# Convenience function to add an executable containing GTest unit tests. -# CTest will be used to run the tests. -# When unit test mode is disabled, this becomes a no-op. -function(add_mbed_unit_test EXECUTABLE) - add_executable(${EXECUTABLE} ${ARGN}) - target_link_libraries(${EXECUTABLE} GMock::Main) - - gtest_discover_tests(${EXECUTABLE}) -endfunction(add_mbed_unit_test) \ No newline at end of file diff --git a/cmake/utils/CheckPythonPackage.cmake b/cmake/utils/CheckPythonPackage.cmake deleted file mode 100644 index cbd430b..0000000 --- a/cmake/utils/CheckPythonPackage.cmake +++ /dev/null @@ -1,62 +0,0 @@ -# CMake functions for checking for Python packages -# Requires PYTHON_EXECUTABLE to be defined. Call FindPythonInterp first! - -# NOTE: if moving this file, be sure to also move python_packagecheck.py - -# must evaluate this now since CMAKE_CURRENT_LIST_DIR doesn't work in function scope -set(PYTHON_PACKAGECHECK_SCRIPT ${MBED_CMAKE_SCRIPTS_DIR}/check_python_package.py) - -# set OUTPUT_VAR to whether PACKAGENAME was found -function(check_python_package PACKAGENAME OUTPUT_VAR) - - # can't have Python packages without Python! - if(NOT Python3_FOUND) - set(${OUTPUT_VAR} FALSE PARENT_SCOPE) - return() - endif() - - set(NEED_TO_RUN_CHECK TRUE) - - if(DEFINED ${OUTPUT_VAR}) - if(${OUTPUT_VAR}) - - # if the python interpreter changed, we need to recheck - if("${PY_INTERP_FOR_${OUTPUT_VAR}}" STREQUAL "${Python3_EXECUTABLE}") - set(NEED_TO_RUN_CHECK FALSE) - endif() - - endif() - endif() - - if(NEED_TO_RUN_CHECK) - set(PY_INTERP_FOR_${OUTPUT_VAR} ${Python3_EXECUTABLE} CACHE INTERNAL "The python interpreter used to run the ${OUTPUT_VAR} check" FORCE) - - execute_process(COMMAND ${Python3_EXECUTABLE} ${PYTHON_PACKAGECHECK_SCRIPT} ${PACKAGENAME} - RESULT_VARIABLE PACKAGECHECK_RESULT) - - test(HAVE_PACKAGE ${PACKAGECHECK_RESULT} EQUAL 0) - - if(HAVE_PACKAGE) - message(STATUS "Checking for Python package ${PACKAGENAME} -- found") - else() - message(STATUS "Checking for Python package ${PACKAGENAME} -- not found") - endif() - - set(${OUTPUT_VAR} ${HAVE_PACKAGE} CACHE BOOL "Whether the Python package ${PACKAGENAME} was found" FORCE) - mark_as_advanced(${OUTPUT_VAR}) - - endif() -endfunction(check_python_package) - -# check that PACKAGENAME can be imported, and print an error if not -function(verify_python_package PACKAGENAME) - - # we can just generate our own variable name - string(TOUPPER "HAVE_${PACKAGENAME}" HAVE_VAR_NAME) - - check_python_package(${PACKAGENAME} ${HAVE_VAR_NAME}) - - if(NOT ${HAVE_VAR_NAME}) - message(FATAL_ERROR "The required Python package ${PACKAGENAME} was not found in ${Python3_EXECUTABLE}. Please install it.") - endif() -endfunction(verify_python_package) diff --git a/cmake/utils/CopyBinToMbedBoard.cmake b/cmake/utils/CopyBinToMbedBoard.cmake deleted file mode 100644 index ecb677d..0000000 --- a/cmake/utils/CopyBinToMbedBoard.cmake +++ /dev/null @@ -1,26 +0,0 @@ - -# CMake script which is invoked at install time to copy a bin file onto the mbed - -# arguments: -# BIN_FILE bin file to install -# MBED_PATH path to Mbed virtual thumb drive on the computer - -if(NOT (IS_DIRECTORY "${MBED_PATH}" AND EXISTS "${MBED_PATH}")) - message(FATAL_ERROR "No mbed detected at MBED_PATH \"${MBED_PATH}\" \ -Did you set MBED_PATH in CMake? -Did you try turning it on and off again? -Is it plugged in?") - return() -endif() - -# remove all other bin files on the device -file(GLOB OLD_BIN_FILES "${MBED_PATH}/*.bin") - -foreach(FILE ${OLD_BIN_FILES}) - file(REMOVE "${FILE}") - message(STATUS "Removed old bin file: ${FILE}") -endforeach() - -# now copy the new bin file in place -message(STATUS "Installing to mbed: ${BIN_FILE}") -file(COPY ${BIN_FILE} DESTINATION ${MBED_PATH}) diff --git a/cmake/utils/FindJLINK.cmake b/cmake/utils/FindJLINK.cmake deleted file mode 100644 index 802a828..0000000 --- a/cmake/utils/FindJLINK.cmake +++ /dev/null @@ -1,40 +0,0 @@ -# ---------------------------------------------- -# CMake finder for SEGGER's J-Link upload tools -# -# -# This module defines: -# JLINK - full path to jlink flash executable -# JLINK_GDBSERVER - full path to JLink command line GDB server -# JLINK_FOUND - whether or not the JLink executable was found - -set(JLINK_EXE_NAME JLinkExe) -set(JLINK_PATH "") -set(GDBSERVER_EXE_NAME JLinkGDBServer) - -# try to figure out where JLink may be installed. -if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows") - - # on Windows, the default install location is in Program Files, under a folder called SEGGER then another folder with JLink then the version number. - file(GLOB JLINK_PATH "C:/Program Files*/SEGGER/Jlink*") - - # if we found multiple paths, check the one with the highest version number first - list(SORT JLINK_PATH) - list(REVERSE JLINK_PATH) - - # on Windows, it's jlink.exe - set(JLINK_EXE_NAME JLink) - - # on Windows, they add a CL suffix to differentiate against the GUI version - set(GDBSERVER_EXE_NAME JLinkGDBServerCL) -elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") - - # symlinks are supposed to get created here - set(JLINK_PATH /usr/local/bin) -endif() - -find_program(JLINK NAMES ${JLINK_EXE_NAME} PATHS ${JLINK_PATH} DOC "Path to the JLink flash executable") -find_program(JLINK_GDBSERVER NAMES ${GDBSERVER_EXE_NAME} PATHS ${JLINK_PATH} DOC "Path to the JLink GDB server") - -find_package_handle_standard_args(JLINK FOUND_VAR JLINK_FOUND REQUIRED_VARS JLINK JLINK_GDBSERVER) - - diff --git a/cmake/utils/FindOpenOCD.cmake b/cmake/utils/FindOpenOCD.cmake deleted file mode 100644 index b134f85..0000000 --- a/cmake/utils/FindOpenOCD.cmake +++ /dev/null @@ -1,50 +0,0 @@ -# ---------------------------------------------- -# CMake finder for OpenOCD -# -# -# This module defines: -# OpenOCD - full path to OpenOCD executable -# OpenOCD_SCRIPT_DIR - Path containing OpenOCD scripts -# OpenOCD_FOUND - whether or not the OpenOCD executable was found - -set(OpenOCD_PATHS "") - -# try to figure out where JLink may be installed. -if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows") - - # on Windows, assume that the user extracted the binaries to Program Files - - # if the host is 64 bit, there will be a Program Files (x86) folder - if(EXISTS "C:/Program Files (x86)") - file(GLOB OpenOCD_PATHS "C:/Program Files*/openocd-*/bin-x64") - else() - file(GLOB OpenOCD_PATHS "C:/Program Files/openocd-*/bin") - endif() - - # if we found multiple paths, check the one with the highest version number first - list(SORT OpenOCD_PATHS) - list(REVERSE OpenOCD_PATHS) - -endif() - -find_program(OpenOCD NAMES openocd PATHS ${OpenOCD_PATHS} DOC "Path to the openocd executable") - -# guess a script dir for each path found -set(OpenOCD_SCRIPT_DIR_HINTS "") -if(NOT "${OpenOCD_PATHS}" STREQUAL "") - list(APPEND OpenOCD_SCRIPT_DIR_HINTS HINTS) - foreach(PATH ${OpenOCD_PATHS}) - # location relative to executable in Windows package - list(APPEND OpenOCD_SCRIPT_DIR_HINTS ${PATH}/../scripts) - endforeach() -endif() - -find_path(OpenOCD_SCRIPT_DIR - NAMES interface/cmsis-dap.cfg - ${OpenOCD_SCRIPT_DIR_HINTS} - PATHS /usr/share/openocd/scripts/ - DOC "Path to OpenOCD scripts folder. Should contain interface/cmsis-dap.cfg.") - -find_package_handle_standard_args(OpenOCD FOUND_VAR OpenOCD_FOUND REQUIRED_VARS OpenOCD OpenOCD_SCRIPT_DIR) - - diff --git a/cmake/utils/FindPython3_Backported.cmake b/cmake/utils/FindPython3_Backported.cmake deleted file mode 100644 index 9ce7467..0000000 --- a/cmake/utils/FindPython3_Backported.cmake +++ /dev/null @@ -1,203 +0,0 @@ -# HAMSTER: backport of FindPython3 for earlier CMake verisons - -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPython3 ------------ - -Find Python 3 interpreter, compiler and development environment (include -directories and libraries). - -Three components are supported: - -* ``Interpreter``: search for Python 3 interpreter -* ``Compiler``: search for Python 3 compiler. Only offered by IronPython. -* ``Development``: search for development artifacts (include directories and - libraries) -* ``NumPy``: search for NumPy include directories. - -If no ``COMPONENTS`` is specified, ``Interpreter`` is assumed. - -To ensure consistent versions between components ``Interpreter``, ``Compiler``, -``Development`` and ``NumPy``, specify all components at the same time:: - - find_package (Python3 COMPONENTS Interpreter Development) - -This module looks only for version 3 of Python. This module can be used -concurrently with :module:`FindPython2` module to use both Python versions. - -The :module:`FindPython` module can be used if Python version does not matter -for you. - -.. note:: - - If components ``Interpreter`` and ``Development`` are both specified, this - module search only for interpreter with same platform architecture as the one - defined by ``CMake`` configuration. This contraint does not apply if only - ``Interpreter`` component is specified. - -Imported Targets -^^^^^^^^^^^^^^^^ - -This module defines the following :ref:`Imported Targets ` -(when :prop_gbl:`CMAKE_ROLE` is ``PROJECT``): - -``Python3::Interpreter`` - Python 3 interpreter. Target defined if component ``Interpreter`` is found. -``Python3::Compiler`` - Python 3 compiler. Target defined if component ``Compiler`` is found. -``Python3::Python`` - Python 3 library. Target defined if component ``Development`` is found. -``Python3::NumPy`` - NumPy library for Python 3. Target defined if component ``NumPy`` is found. - -Result Variables -^^^^^^^^^^^^^^^^ - -This module will set the following variables in your project -(see :ref:`Standard Variable Names `): - -``Python3_FOUND`` - System has the Python 3 requested components. -``Python3_Interpreter_FOUND`` - System has the Python 3 interpreter. -``Python3_EXECUTABLE`` - Path to the Python 3 interpreter. -``Python3_INTERPRETER_ID`` - A short string unique to the interpreter. Possible values include: - * Python - * ActivePython - * Anaconda - * Canopy - * IronPython -``Python3_STDLIB`` - Standard platform independent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``. -``Python3_STDARCH`` - Standard platform dependent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``. -``Python3_SITELIB`` - Third-party platform independent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``. -``Python3_SITEARCH`` - Third-party platform dependent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``. -``Python3_Compiler_FOUND`` - System has the Python 3 compiler. -``Python3_COMPILER`` - Path to the Python 3 compiler. Only offered by IronPython. -``Python3_COMPILER_ID`` - A short string unique to the compiler. Possible values include: - * IronPython -``Python3_Development_FOUND`` - System has the Python 3 development artifacts. -``Python3_INCLUDE_DIRS`` - The Python 3 include directories. -``Python3_LIBRARIES`` - The Python 3 libraries. -``Python3_LIBRARY_DIRS`` - The Python 3 library directories. -``Python3_RUNTIME_LIBRARY_DIRS`` - The Python 3 runtime library directories. -``Python3_VERSION`` - Python 3 version. -``Python3_VERSION_MAJOR`` - Python 3 major version. -``Python3_VERSION_MINOR`` - Python 3 minor version. -``Python3_VERSION_PATCH`` - Python 3 patch version. -``Python3_NumPy_FOUND`` - System has the NumPy. -``Python3_NumPy_INCLUDE_DIRS`` - The NumPy include directries. -``Python3_NumPy_VERSION`` - The NumPy version. - -Hints -^^^^^ - -``Python3_ROOT_DIR`` - Define the root directory of a Python 3 installation. - -``Python3_USE_STATIC_LIBS`` - * If not defined, search for shared libraries and static libraries in that - order. - * If set to TRUE, search **only** for static libraries. - * If set to FALSE, search **only** for shared libraries. - -``Python3_FIND_REGISTRY`` - On Windows the ``Python3_FIND_REGISTRY`` variable determine the order - of preference between registry and environment variables. - The ``Python3_FIND_REGISTRY`` variable can be set to empty or one of the - following: - - * ``FIRST``: Try to use registry before environment variables. - This is the default. - * ``LAST``: Try to use registry after environment variables. - * ``NEVER``: Never try to use registry. - -``CMAKE_FIND_FRAMEWORK`` - On macOS the :variable:`CMAKE_FIND_FRAMEWORK` variable determine the order of - preference between Apple-style and unix-style package components. - - .. note:: - - Value ``ONLY`` is not supported so ``FIRST`` will be used instead. - -``Python3_FIND_VIRTUALENV`` - This variable defines the handling of virtual environments. It is meaningfull - only when a virtual environment is active (i.e. the ``activate`` script has - been evaluated). In this case, it takes precedence over - ``Python3_FIND_REGISTRY`` and ``CMAKE_FIND_FRAMEWORK`` variables. - The ``Python3_FIND_VIRTUALENV`` variable can be set to empty or one of the - following: - - * ``FIRST``: The virtual environment is used before any other standard - paths to look-up for the interpreter. This is the default. - * ``ONLY``: Only the virtual environment is used to look-up for the - interpreter. - * ``STANDARD``: The virtual environment is not used to look-up for the - interpreter. In this case, variable ``Python3_FIND_REGISTRY`` (Windows) - or ``CMAKE_FIND_FRAMEWORK`` (macOS) can be set with value ``LAST`` or - ``NEVER`` to select preferably the interpreter from the virtual - environment. - -Commands -^^^^^^^^ - -This module defines the command ``Python3_add_library`` (when -:prop_gbl:`CMAKE_ROLE` is ``PROJECT``), which has the same semantics as -:command:`add_library`, but takes care of Python module naming rules -(only applied if library is of type ``MODULE``), and adds a dependency to target -``Python3::Python``:: - - Python3_add_library (my_module MODULE src1.cpp) - -If library type is not specified, ``MODULE`` is assumed. -#]=======================================================================] - - -set(_PYTHON_PREFIX Python3) - -set(_Python3_REQUIRED_VERSION_MAJOR 3) - -include(${CMAKE_CURRENT_LIST_DIR}/FindPythonSupport.cmake) - -if (COMMAND __Python3_add_library) - macro (Python3_add_library) - __Python3_add_library (Python3 ${ARGV}) - endmacro() -endif() - -unset(_PYTHON_PREFIX) \ No newline at end of file diff --git a/cmake/utils/FindPythonSupport.cmake b/cmake/utils/FindPythonSupport.cmake deleted file mode 100644 index 078f98d..0000000 --- a/cmake/utils/FindPythonSupport.cmake +++ /dev/null @@ -1,1372 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -# -# This file is a "template" file used by various FindPython modules. -# - -cmake_policy (VERSION 3.7) - -# -# Initial configuration -# -if (NOT DEFINED _PYTHON_PREFIX) - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() -if (NOT DEFINED _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() -if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 3) - set(_${_PYTHON_PREFIX}_VERSIONS 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0) -elseif (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 2) - set(_${_PYTHON_PREFIX}_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0) -else() - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() - -get_property(_${_PYTHON_PREFIX}_CMAKE_ROLE GLOBAL PROPERTY CMAKE_ROLE) - - -# -# helper commands -# -macro (_PYTHON_DISPLAY_FAILURE _PYTHON_MSG) - if (${_PYTHON_PREFIX}_FIND_REQUIRED) - message (FATAL_ERROR "${_PYTHON_MSG}") - else() - if (NOT ${_PYTHON_PREFIX}_FIND_QUIETLY) - message(STATUS "${_PYTHON_MSG}") - endif () - endif() - - set (${_PYTHON_PREFIX}_FOUND FALSE) - string (TOUPPER "${_PYTHON_PREFIX}" _${_PYTHON_PREFIX}_UPPER_PREFIX) - set (${_PYTHON_UPPER_PREFIX}_FOUND FALSE) - return() -endmacro() - - -macro (_PYTHON_FIND_FRAMEWORKS) - set (${_PYTHON_PREFIX}_FRAMEWORKS) - if (APPLE) - set (_pff_frameworks ${CMAKE_FRAMEWORK_PATH} - $ENV{CMAKE_FRAMEWORK_PATH} - ~/Library/Frameworks - /usr/local/Frameworks - ${CMAKE_SYSTEM_FRAMEWORK_PATH}) - list (REMOVE_DUPLICATES _pff_frameworks) - foreach (_pff_framework IN LISTS _pff_frameworks) - if (EXISTS ${_pff_framework}/Python.framework) - list (APPEND ${_PYTHON_PREFIX}_FRAMEWORKS ${_pff_framework}/Python.framework) - endif() - endforeach() - unset (_pff_frameworks) - unset (_pff_framework) - endif() -endmacro() - -function (_PYTHON_GET_FRAMEWORKS _PYTHON_PGF_FRAMEWORK_PATHS _PYTHON_VERSION) - set (_PYTHON_FRAMEWORK_PATHS) - foreach (_PYTHON_FRAMEWORK IN LISTS ${_PYTHON_PREFIX}_FRAMEWORKS) - list (APPEND _PYTHON_FRAMEWORK_PATHS - "${_PYTHON_FRAMEWORK}/Versions/${_PYTHON_VERSION}") - endforeach() - set (${_PYTHON_PGF_FRAMEWORK_PATHS} ${_PYTHON_FRAMEWORK_PATHS} PARENT_SCOPE) -endfunction() - - -function (_PYTHON_VALIDATE_INTERPRETER) - if (NOT ${_PYTHON_PREFIX}_EXECUTABLE) - return() - endif() - - if (ARGC EQUAL 1) - set (expected_version ${ARGV0}) - else() - unset (expected_version) - endif() - - get_filename_component (python_name "${${_PYTHON_PREFIX}_EXECUTABLE}" NAME) - - if (expected_version AND NOT python_name STREQUAL "python${expected_version}${CMAKE_EXECUTABLE_SUFFIX}") - # executable found must have a specific version - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT version EQUAL expected_version) - # interpreter not usable or has wrong major version - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - return() - endif() - else() - if (NOT python_name STREQUAL "python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}${CMAKE_EXECUTABLE_SUFFIX}") - # executable found do not have version in name - # ensure major version is OK - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write(str(sys.version_info[0]))" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - # interpreter not usable or has wrong major version - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - return() - endif() - endif() - endif() - - if (CMAKE_SIZEOF_VOID_P AND "Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND NOT CMAKE_CROSSCOMPILING) - # In this case, interpreter must have same architecture as environment - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys, struct; sys.stdout.write(str(struct.calcsize(\"P\")))" - RESULT_VARIABLE result - OUTPUT_VARIABLE size - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT size EQUAL CMAKE_SIZEOF_VOID_P) - # interpreter not usable or has wrong architecture - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - return() - endif() - endif() -endfunction() - - -function (_PYTHON_VALIDATE_COMPILER expected_version) - if (NOT ${_PYTHON_PREFIX}_COMPILER) - return() - endif() - - # retrieve python environment version from compiler - set (working_dir "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir") - file (WRITE "${working_dir}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))\n") - execute_process (COMMAND "${${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${working_dir}/version.py" - WORKING_DIRECTORY "${working_dir}" - OUTPUT_QUIET - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process (COMMAND "${working_dir}/version" - WORKING_DIRECTORY "${working_dir}" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET) - file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}") - - if (result OR NOT version EQUAL expected_version) - # Compiler not usable or has wrong major version - set (${_PYTHON_PREFIX}_COMPILER ${_PYTHON_PREFIX}_COMPILER-NOTFOUND CACHE INTERNAL "" FORCE) - endif() -endfunction() - - -function (_PYTHON_FIND_RUNTIME_LIBRARY _PYTHON_LIB) - string (REPLACE "_RUNTIME" "" _PYTHON_LIB "${_PYTHON_LIB}") - # look at runtime part on systems supporting it - if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR - (CMAKE_SYSTEM_NAME MATCHES "MSYS|CYGWIN" - AND ${_PYTHON_LIB} MATCHES "${CMAKE_IMPORT_LIBRARY_SUFFIX}$")) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX}) - # MSYS has a special syntax for runtime libraries - if (CMAKE_SYSTEM_NAME MATCHES "MSYS") - list (APPEND CMAKE_FIND_LIBRARY_PREFIXES "msys-") - endif() - find_library (${ARGV}) - endif() -endfunction() - - -function (_PYTHON_SET_LIBRARY_DIRS _PYTHON_SLD_RESULT) - unset (_PYTHON_DIRS) - set (_PYTHON_LIBS ${ARGV}) - list (REMOVE_AT _PYTHON_LIBS 0) - foreach (_PYTHON_LIB IN LISTS _PYTHON_LIBS) - if (${_PYTHON_LIB}) - get_filename_component (_PYTHON_DIR "${${_PYTHON_LIB}}" DIRECTORY) - list (APPEND _PYTHON_DIRS "${_PYTHON_DIR}") - endif() - endforeach() - if (_PYTHON_DIRS) - list (REMOVE_DUPLICATES _PYTHON_DIRS) - endif() - set (${_PYTHON_SLD_RESULT} ${_PYTHON_DIRS} PARENT_SCOPE) -endfunction() - - -# If major version is specified, it must be the same as internal major version -if (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR - AND NOT ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Wrong major version specified is \"${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}\", but expected major version is \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") -endif() - - -# handle components -if (NOT ${_PYTHON_PREFIX}_FIND_COMPONENTS) - set (${_PYTHON_PREFIX}_FIND_COMPONENTS Interpreter) - set (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter TRUE) -endif() -if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Interpreter" "Development") - list (REMOVE_DUPLICATES ${_PYTHON_PREFIX}_FIND_COMPONENTS) -endif() -foreach (_${_PYTHON_PREFIX}_COMPONENT IN LISTS ${_PYTHON_PREFIX}_FIND_COMPONENTS) - set (${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_FOUND FALSE) -endforeach() -unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) - -# Set versions to search -## default: search any version -set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSIONS}) - -if (${_PYTHON_PREFIX}_FIND_VERSION_COUNT GREATER 1) - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR}) - else() - unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) - # add all compatible versions - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_VERSIONS) - if (_${_PYTHON_PREFIX}_VERSION VERSION_GREATER_EQUAL ${_PYTHON_PREFIX}_FIND_VERSION) - list (APPEND _${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSION}) - endif() - endforeach() - endif() -endif() - -# Python and Anaconda distributions: define which architectures can be used -if (CMAKE_SIZEOF_VOID_P) - # In this case, search only for 64bit or 32bit - math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8") - set (_${_PYTHON_PREFIX}_ARCH2 ${_${_PYTHON_PREFIX}_ARCH}) -else() - # architecture unknown, search for both 64bit and 32bit - set (_${_PYTHON_PREFIX}_ARCH 64) - set (_${_PYTHON_PREFIX}_ARCH2 32) -endif() - -# IronPython support -if (CMAKE_SIZEOF_VOID_P) - # In this case, search only for 64bit or 32bit - math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8") - set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy${_${_PYTHON_PREFIX}_ARCH} ipy) -else() - # architecture unknown, search for natural interpreter - set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy) -endif() -set (_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES net45 net40) - -# Apple frameworks handling -_python_find_frameworks () - -# Save CMAKE_FIND_APPBUNDLE -if (DEFINED CMAKE_FIND_APPBUNDLE) - set (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE ${CMAKE_FIND_APPBUNDLE}) -else() - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) -endif() -# To avoid app bundle lookup -set (CMAKE_FIND_APPBUNDLE "NEVER") - -# Save CMAKE_FIND_FRAMEWORK -if (DEFINED CMAKE_FIND_FRAMEWORK) - set (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) - if (CMAKE_FIND_FRAMEWORK STREQUAL "ONLY") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: CMAKE_FIND_FRAMEWORK: 'ONLY' value is not supported. 'FIRST' will be used instead.") - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK "FIRST") - else() - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) - endif() -else() - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK "FIRST") -endif() -# To avoid framework lookup -set (CMAKE_FIND_FRAMEWORK "NEVER") - -# Windows Registry handling -if (DEFINED ${_PYTHON_PREFIX}_FIND_REGISTRY) - if (NOT ${_PYTHON_PREFIX}_FIND_REGISTRY MATCHES "^(FIRST|LAST|NEVER)$") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_REGISTRY}: invalid value for '${_PYTHON_PREFIX}_FIND_REGISTRY'. 'FIRST', 'LAST' or 'NEVER' expected.") - set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST") - else() - set (_${_PYTHON_PREFIX}_FIND_REGISTRY ${${_PYTHON_PREFIX}_FIND_REGISTRY}) - endif() -else() - set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST") -endif() - -# virtual environments handling -if (DEFINED ENV{VIRTUAL_ENV}) - if (DEFINED ${_PYTHON_PREFIX}_FIND_VIRTUALENV) - if (NOT ${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY|STANDARD)$") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_VIRTUALENV}: invalid value for '${_PYTHON_PREFIX}_FIND_VIRTUALENV'. 'FIRST', 'ONLY' or 'IGNORE' expected.") - set (_${_PYTHON_PREFIX}_FIND_VIRTUALENV "FIRST") - else() - set (_${_PYTHON_PREFIX}_FIND_VIRTUALENV ${${_PYTHON_PREFIX}_FIND_VIRTUALENV}) - endif() - else() - set (_${_PYTHON_PREFIX}_FIND_VIRTUALENV FIRST) - endif() -else() - set (_${_PYTHON_PREFIX}_FIND_VIRTUALENV STANDARD) -endif() - - -unset (_${_PYTHON_PREFIX}_REQUIRED_VARS) -unset (_${_PYTHON_PREFIX}_CACHED_VARS) - - -# first step, search for the interpreter -if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) - endif() - - set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - # look-up for various versions and locations - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) - - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - - # Virtual environments handling - if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ENV VIRTUAL_ENV - PATH_SUFFIXES bin Scripts - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION}) - if (${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "ONLY") - continue() - endif() - endif() - - # Apple frameworks handling - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # Windows registry - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # try using HINTS - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - # try using standard paths. - if (WIN32) - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR) - else() - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - NAMES_PER_DIR) - endif() - - # Apple frameworks handling - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_DEFAULT_PATH) - endif() - - # Windows registry - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_DEFAULT_PATH) - endif() - - _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION}) - if (${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - endforeach() - - if (NOT ${_PYTHON_PREFIX}_EXECUTABLE AND - NOT _${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "ONLY") - # No specific version found. Retry with generic names - # try using HINTS - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - # try using standard paths. - # NAMES_PER_DIR is not defined on purpose to have a chance to find - # expected version. - # For example, typical systems have 'python' for version 2.* and 'python3' - # for version 3.*. So looking for names per dir will find, potentially, - # systematically 'python' (i.e. version 2) even if version 3 is searched. - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) - - _python_validate_interpreter () - endif() - - # retrieve exact version of executable found - if (${_PYTHON_PREFIX}_EXECUTABLE) - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_VERSION - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 ${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 ${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 ${_PYTHON_PREFIX}_VERSION_PATCH) - else() - # Interpreter is not usable - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - unset (${_PYTHON_PREFIX}_VERSION) - endif() - endif() - - if (${_PYTHON_PREFIX}_EXECUTABLE - AND ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Interpreter_FOUND TRUE) - # Use interpreter version for future searches to ensure consistency - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - endif() - - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - if (NOT CMAKE_SIZEOF_VOID_P) - # determine interpreter architecture - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; print(sys.maxsize > 2**32)" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_IS64BIT - ERROR_VARIABLE ${_PYTHON_PREFIX}_IS64BIT) - if (NOT _${_PYTHON_PREFIX}_RESULT) - if (${_PYTHON_PREFIX}_IS64BIT) - set (_${_PYTHON_PREFIX}_ARCH 64) - set (_${_PYTHON_PREFIX}_ARCH2 64) - else() - set (_${_PYTHON_PREFIX}_ARCH 32) - set (_${_PYTHON_PREFIX}_ARCH2 32) - endif() - endif() - endif() - - # retrieve interpreter identity - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -V - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID - ERROR_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID) - if (NOT _${_PYTHON_PREFIX}_RESULT) - if (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Anaconda") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "Anaconda") - elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Enthought") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "Canopy") - else() - string (REGEX REPLACE "^([^ ]+).*" "\\1" ${_PYTHON_PREFIX}_INTERPRETER_ID "${${_PYTHON_PREFIX}_INTERPRETER_ID}") - if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "Python") - # try to get a more precise ID - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; print(sys.copyright)" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_COPYRIGHT - ERROR_QUIET) - if (${_PYTHON_PREFIX}_COPYRIGHT MATCHES "ActiveState") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "ActivePython") - endif() - endif() - endif() - else() - set (${_PYTHON_PREFIX}_INTERPRETER_ID Python) - endif() - else() - unset (${_PYTHON_PREFIX}_INTERPRETER_ID) - endif() - - # retrieve various package installation directories - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))" - - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_LIBPATHS - ERROR_QUIET) - if (NOT _${_PYTHON_PREFIX}_RESULT) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 0 ${_PYTHON_PREFIX}_STDLIB) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 1 ${_PYTHON_PREFIX}_STDARCH) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 2 ${_PYTHON_PREFIX}_SITELIB) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 3 ${_PYTHON_PREFIX}_SITEARCH) - else() - unset (${_PYTHON_PREFIX}_STDLIB) - unset (${_PYTHON_PREFIX}_STDARCH) - unset (${_PYTHON_PREFIX}_SITELIB) - unset (${_PYTHON_PREFIX}_SITEARCH) - endif() - - mark_as_advanced (${_PYTHON_PREFIX}_EXECUTABLE) -endif() - - -# second step, search for compiler (IronPython) -if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Compiler) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_COMPILER) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_COMPILER) - endif() - - # IronPython specific artifacts - # If IronPython interpreter is found, use its path - unset (_${_PYTHON_PREFIX}_IRON_ROOT) - if (${_PYTHON_PREFIX}_Interpreter_FOUND AND ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") - get_filename_component (_${_PYTHON_PREFIX}_IRON_ROOT "${${_PYTHON_PREFIX}_EXECUTABLE}" DIRECTORY) - endif() - - # try using root dir and registry - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_DEFAULT_PATH) - endif() - - _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION}) - if (${_PYTHON_PREFIX}_COMPILER) - break() - endif() - endforeach() - - # no specific version found, re-try in standard paths - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}) - - if (${_PYTHON_PREFIX}_COMPILER) - # retrieve python environment version from compiler - set (_${_PYTHON_PREFIX}_VERSION_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir") - file (WRITE "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))\n") - execute_process (COMMAND "${${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" - WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}" - OUTPUT_QUIET - ERROR_QUIET) - execute_process (COMMAND "${_${_PYTHON_PREFIX}_VERSION_DIR}/version" - WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_VERSION - ERROR_QUIET) - if (NOT _${_PYTHON_PREFIX}_RESULT) - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH) - - if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND) - # set public version information - set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION}) - set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR}) - set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH}) - endif() - else() - # compiler not usable - set (${_PYTHON_PREFIX}_COMPILER ${_PYTHON_PREFIX}_COMPILER-NOTFOUND CACHE INTERNAL "" FORCE) - endif() - file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}") - endif() - - if (${_PYTHON_PREFIX}_COMPILER) - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - # Compiler must be compatible with interpreter - if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE) - endif() - elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE) - # Use compiler version for future searches to ensure consistency - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - endif() - endif() - - if (${_PYTHON_PREFIX}_Compiler_FOUND) - set (${_PYTHON_PREFIX}_COMPILER_ID IronPython) - else() - unset (${_PYTHON_PREFIX}_COMPILER_ID) - endif() - - mark_as_advanced (${_PYTHON_PREFIX}_COMPILER) -endif() - - -# third step, search for the development artifacts -## Development environment is not compatible with IronPython interpreter -if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARY - ${_PYTHON_PREFIX}_INCLUDE_DIR) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_LIBRARY - ${_PYTHON_PREFIX}_LIBRARY_RELEASE - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - ${_PYTHON_PREFIX}_LIBRARY_DEBUG - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - ${_PYTHON_PREFIX}_INCLUDE_DIR) - endif() - - # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES) - if (DEFINED ${_PYTHON_PREFIX}_USE_STATIC_LIBS AND NOT WIN32) - set(_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) - if(${_PYTHON_PREFIX}_USE_STATIC_LIBS) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) - else() - list (REMOVE_ITEM CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) - endif() - else() - endif() - - # if python interpreter is found, use its location and version to ensure consistency - # between interpreter and development environment - unset (_${_PYTHON_PREFIX}_PREFIX) - unset (_${_PYTHON_PREFIX}_EXEC_PREFIX) - unset (_${_PYTHON_PREFIX}_BASE_EXEC_PREFIX) - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.EXEC_PREFIX)" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_EXEC_PREFIX - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - unset (_${_PYTHON_PREFIX}_EXEC_PREFIX) - endif() - - if (NOT ${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "STANDARD") - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.BASE_EXEC_PREFIX)" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_BASE_EXEC_PREFIX - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - unset (_${_PYTHON_PREFIX}_BASE_EXEC_PREFIX) - endif() - endif() - endif() - set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_EXEC_PREFIX}" "${_${_PYTHON_PREFIX}_BASE_EXEC_PREFIX}" "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) - - # try to use pythonX.Y-config tool - set (_${_PYTHON_PREFIX}_CONFIG_NAMES) - if (DEFINED CMAKE_LIBRARY_ARCHITECTURE) - set (_${_PYTHON_PREFIX}_CONFIG_NAMES "${CMAKE_LIBRARY_ARCHITECTURE}-python${_${_PYTHON_PREFIX}_VERSION}-config") - endif() - list (APPEND _${_PYTHON_PREFIX}_CONFIG_NAMES "python${_${_PYTHON_PREFIX}_VERSION}-config") - find_program (_${_PYTHON_PREFIX}_CONFIG - NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - unset (_${_PYTHON_PREFIX}_CONFIG_NAMES) - - if (NOT _${_PYTHON_PREFIX}_CONFIG) - continue() - endif() - if (DEFINED CMAKE_LIBRARY_ARCHITECTURE) - # check that config tool match library architecture - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --configdir - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_CONFIGDIR - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - continue() - endif() - string(FIND "${_${_PYTHON_PREFIX}_CONFIGDIR}" "${CMAKE_LIBRARY_ARCHITECTURE}" _${_PYTHON_PREFIX}_RESULT) - if (_${_PYTHON_PREFIX}_RESULT EQUAL -1) - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - continue() - endif() - endif() - - # retrieve root install directory - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --prefix - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PREFIX - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - # python-config is not usable - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - continue() - endif() - set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}" "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - # retrieve library - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - # retrieve library directory - string (REGEX MATCHALL "-L[^ ]+" _${_PYTHON_PREFIX}_LIB_DIRS "${_${_PYTHON_PREFIX}_FLAGS}") - string (REPLACE "-L" "" _${_PYTHON_PREFIX}_LIB_DIRS "${_${_PYTHON_PREFIX}_LIB_DIRS}") - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_LIB_DIRS) - # retrieve library name - string (REGEX MATCHALL "-lpython[^ ]+" _${_PYTHON_PREFIX}_LIB_NAMES "${_${_PYTHON_PREFIX}_FLAGS}") - string (REPLACE "-l" "" _${_PYTHON_PREFIX}_LIB_NAMES "${_${_PYTHON_PREFIX}_LIB_NAMES}") - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_LIB_NAMES) - - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} ${_${_PYTHON_PREFIX}_LIB_DIRS} - PATH_SUFFIXES lib - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - # retrieve runtime library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_PATH} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - endif() - - # retrieve include directory - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --includes - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - # retrieve include directory - string (REGEX MATCHALL "-I[^ ]+" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_FLAGS}") - string (REPLACE "-I" "" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIRS}") - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_DIRS) - - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_DIRS} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_INCLUDE_DIR) - break() - endif() - endforeach() - - # Rely on HINTS and standard paths if config tool failed to locate artifacts - if (NOT (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) OR NOT ${_PYTHON_PREFIX}_INCLUDE_DIR) - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) - - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - - set (_${_PYTHON_PREFIX}_REGISTRY_PATHS - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # search in HINTS locations - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) - endif() - - # search in all default paths - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config) - # retrieve runtime library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - endif() - - if (WIN32) - # search for debug library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - # use library location as a hint - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - NO_DEFAULT_PATH) - else() - # search first in known locations - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib libs - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - # search in all default paths - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib libs) - endif() - if (${_PYTHON_PREFIX}_LIBRARY_DEBUG) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - endif() - endif() - - # Don't search for include dir until library location is known - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS) - - if (${_PYTHON_PREFIX}_EXECUTABLE) - # pick up include directory from configuration - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; import sysconfig; sys.stdout.write(sysconfig.get_path('include'))" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PATH - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - file (TO_CMAKE_PATH "${_${_PYTHON_PREFIX}_PATH}" _${_PYTHON_PREFIX}_PATH) - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PATH}") - endif() - endif() - - foreach (_${_PYTHON_PREFIX}_LIB IN ITEMS ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - if (${_${_PYTHON_PREFIX}_LIB}) - # Use the library's install prefix as a hint - if (${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - elseif (${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - elseif (DEFINED CMAKE_LIBRARY_ARCHITECTURE AND ${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+)/lib/${CMAKE_LIBRARY_ARCHITECTURE}") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - else() - # assume library is in a directory under root - get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${${_${_PYTHON_PREFIX}_LIB}}" DIRECTORY) - get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY) - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}") - endif() - endif() - endforeach() - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_HINTS) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu - include/python${_${_PYTHON_PREFIX}_VERSION}m - include/python${_${_PYTHON_PREFIX}_VERSION}u - include/python${_${_PYTHON_PREFIX}_VERSION} - include - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu - include/python${_${_PYTHON_PREFIX}_VERSION}m - include/python${_${_PYTHON_PREFIX}_VERSION}u - include/python${_${_PYTHON_PREFIX}_VERSION} - include - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu - include/python${_${_PYTHON_PREFIX}_VERSION}m - include/python${_${_PYTHON_PREFIX}_VERSION}u - include/python${_${_PYTHON_PREFIX}_VERSION} - include - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) AND ${_PYTHON_PREFIX}_INCLUDE_DIR) - break() - endif() - endforeach() - - # search header file in standard locations - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h) - endif() - - if (${_PYTHON_PREFIX}_INCLUDE_DIR) - # retrieve version from header file - file (STRINGS "${${_PYTHON_PREFIX}_INCLUDE_DIR}/patchlevel.h" _${_PYTHON_PREFIX}_VERSION - REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"") - string (REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1" - _${_PYTHON_PREFIX}_VERSION "${_${_PYTHON_PREFIX}_VERSION}") - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH) - - if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT ${_PYTHON_PREFIX}_Compiler_FOUND) - # set public version information - set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION}) - set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR}) - set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH}) - endif() - endif() - - # define public variables - include (${CMAKE_CURRENT_LIST_DIR}/../SelectLibraryConfigurations.cmake) - select_library_configurations (${_PYTHON_PREFIX}) - if (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") - elseif (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}") - else() - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "$${_PYTHON_PREFIX}_RUNTIME_LIBRARY-NOTFOUND") - endif() - - _python_set_library_dirs (${_PYTHON_PREFIX}_LIBRARY_DIRS - ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - if (UNIX) - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$") - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS ${${_PYTHON_PREFIX}_LIBRARY_DIRS}) - endif() - else() - _python_set_library_dirs (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - endif() - - set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${${_PYTHON_PREFIX}_INCLUDE_DIR}") - - mark_as_advanced (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - ${_PYTHON_PREFIX}_INCLUDE_DIR) - - if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - AND ${_PYTHON_PREFIX}_INCLUDE_DIR) - if (${_PYTHON_PREFIX}_Interpreter_FOUND OR ${_PYTHON_PREFIX}_Compiler_FOUND) - # development environment must be compatible with interpreter/compiler - if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_Development_FOUND TRUE) - endif() - elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Development_FOUND TRUE) - endif() - endif() - - # Restore the original find library ordering - if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES}) - endif() -endif() - -if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Interpreter_FOUND) - if (${_PYTHON_PREFIX}_FIND_REQUIRED_NumPy) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR) - endif() - execute_process( - COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "from __future__ import print_function\ntry: import numpy; print(numpy.get_include(), end='')\nexcept:pass\n" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_NumPy_PATH - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - find_path(${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR - NAMES "numpy/arrayobject.h" "numpy/numpyconfig.h" - HINTS "${_${_PYTHON_PREFIX}_NumPy_PATH}" - NO_DEFAULT_PATH) - endif() - if(${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR) - set(${_PYTHON_PREFIX}_NumPy_INCLUDE_DIRS "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}") - set(${_PYTHON_PREFIX}_NumPy_FOUND TRUE) - endif() - if(${_PYTHON_PREFIX}_NumPy_FOUND) - execute_process( - COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "from __future__ import print_function\ntry: import numpy; print(numpy.__version__, end='')\nexcept:pass\n" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_NumPy_VERSION) - if (NOT _${_PYTHON_PREFIX}_RESULT) - set(${_PYTHON_PREFIX}_NumPy_VERSION "${_${_PYTHON_PREFIX}_NumPy_VERSION}") - endif() - endif() -endif() - -# final validation -if (${_PYTHON_PREFIX}_VERSION_MAJOR AND - NOT ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Found unsuitable major version \"${${_PYTHON_PREFIX}_VERSION_MAJOR}\", but required major version is exact version \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") -endif() - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args (${_PYTHON_PREFIX} - REQUIRED_VARS ${_${_PYTHON_PREFIX}_REQUIRED_VARS} - VERSION_VAR ${_PYTHON_PREFIX}_VERSION - HANDLE_COMPONENTS) - -# Create imported targets and helper functions -if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") - if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Interpreter_FOUND - AND NOT TARGET ${_PYTHON_PREFIX}::Interpreter) - add_executable (${_PYTHON_PREFIX}::Interpreter IMPORTED) - set_property (TARGET ${_PYTHON_PREFIX}::Interpreter - PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_EXECUTABLE}") - endif() - - if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Compiler_FOUND - AND NOT TARGET ${_PYTHON_PREFIX}::Compiler) - add_executable (${_PYTHON_PREFIX}::Compiler IMPORTED) - set_property (TARGET ${_PYTHON_PREFIX}::Compiler - PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_COMPILER}") - endif() - - if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Development_FOUND AND NOT TARGET ${_PYTHON_PREFIX}::Python) - - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - set (_${_PYTHON_PREFIX}_LIBRARY_TYPE SHARED) - else() - set (_${_PYTHON_PREFIX}_LIBRARY_TYPE STATIC) - endif() - - add_library (${_PYTHON_PREFIX}::Python ${_${_PYTHON_PREFIX}_LIBRARY_TYPE} IMPORTED) - - set_property (TARGET ${_PYTHON_PREFIX}::Python - PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIR}") - - if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) - OR (${_PYTHON_PREFIX}_LIBRARY_DEBUG AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)) - # System manage shared libraries in two parts: import and runtime - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" - IMPORTED_IMPLIB_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" - IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" - IMPORTED_IMPLIB_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" - IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}") - else() - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_IMPLIB "${${_PYTHON_PREFIX}_LIBRARY}" - IMPORTED_LOCATION "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY}") - endif() - else() - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" - IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}") - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" - IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}") - else() - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_LOCATION "${${_PYTHON_PREFIX}_LIBRARY}") - endif() - endif() - - if (_${_PYTHON_PREFIX}_CONFIG AND _${_PYTHON_PREFIX}_LIBRARY_TYPE STREQUAL "STATIC") - # extend link information with dependent libraries - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - string (REGEX MATCHALL "-[Ll][^ ]+" _${_PYTHON_PREFIX}_LINK_LIBRARIES "${_${_PYTHON_PREFIX}_FLAGS}") - # remove elements relative to python library itself - list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-lpython") - foreach (_${_PYTHON_PREFIX}_DIR IN LISTS ${_PYTHON_PREFIX}_LIBRARY_DIRS) - list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-L${${_PYTHON_PREFIX}_DIR}") - endforeach() - set_property (TARGET ${_PYTHON_PREFIX}::Python - PROPERTY INTERFACE_LINK_LIBRARIES ${_${_PYTHON_PREFIX}_LINK_LIBRARIES}) - endif() - endif() - - # - # PYTHON_ADD_LIBRARY ( [STATIC|SHARED|MODULE] src1 src2 ... srcN) - # It is used to build modules for python. - # - function (__${_PYTHON_PREFIX}_ADD_LIBRARY prefix name) - cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY - "STATIC;SHARED;MODULE" "" "") - - unset (type) - if (NOT (PYTHON_ADD_LIBRARY_STATIC - OR PYTHON_ADD_LIBRARY_SHARED - OR PYTHON_ADD_LIBRARY_MODULE)) - set (type MODULE) - endif() - add_library (${name} ${type} ${ARGN}) - target_link_libraries (${name} PRIVATE ${prefix}::Python) - - # customize library name to follow module name rules - get_property (type TARGET ${name} PROPERTY TYPE) - if (type STREQUAL "MODULE_LIBRARY") - set_property (TARGET ${name} PROPERTY PREFIX "") - if(CMAKE_SYSTEM_NAME STREQUAL "Windows") - set_property (TARGET ${name} PROPERTY SUFFIX ".pyd") - endif() - endif() - endfunction() - endif() - - if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_NumPy_FOUND - AND NOT TARGET ${_PYTHON_PREFIX}::NumPy AND TARGET ${_PYTHON_PREFIX}::Python) - add_library (${_PYTHON_PREFIX}::NumPy INTERFACE IMPORTED) - set_property (TARGET ${_PYTHON_PREFIX}::NumPy - PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}") - target_link_libraries (${_PYTHON_PREFIX}::NumPy INTERFACE ${_PYTHON_PREFIX}::Python) - endif() -endif() - -# final clean-up - -# Restore CMAKE_FIND_APPBUNDLE -if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) - set (CMAKE_FIND_APPBUNDLE ${_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE}) - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) -else() - unset (CMAKE_FIND_APPBUNDLE) -endif() -# Restore CMAKE_FIND_FRAMEWORK -if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) - set (CMAKE_FIND_FRAMEWORK ${_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK}) - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) -else() - unset (CMAKE_FIND_FRAMEWORK) -endif() - -unset (_${_PYTHON_PREFIX}_CONFIG CACHE) \ No newline at end of file diff --git a/cmake/utils/SetUploadMethod.cmake b/cmake/utils/SetUploadMethod.cmake deleted file mode 100644 index 4f38db2..0000000 --- a/cmake/utils/SetUploadMethod.cmake +++ /dev/null @@ -1,281 +0,0 @@ -# CMakeLists file to handle the different upload methods to mbed targets - -# Step 1: determine supported upload methods -# ------------------------------------------------------------- - -set(UPLOAD_METHOD_DEFAULT NONE) - -# Start with NONE upload method which does not allow any uploading -set(SUPPORTED_UPLOAD_METHODS NONE) - -# Mbed is always supported -list(APPEND SUPPORTED_UPLOAD_METHODS MBED) - -# JLINK requires the J-link package -if(JLINK_FOUND) - list(APPEND SUPPORTED_UPLOAD_METHODS JLINK) -endif() - -# NXPPROG requires pyserial -check_python_package(serial HAVE_PYSERIAL) -if(HAVE_PYSERIAL) - list(APPEND SUPPORTED_UPLOAD_METHODS NXPPROG) -endif() - -# pyOCD requires pyocd -check_python_package(pyocd HAVE_PYOCD) -if(HAVE_PYOCD) - list(APPEND SUPPORTED_UPLOAD_METHODS PYOCD) -endif() - -# OPENOCD required openocd -if(OpenOCD_FOUND) - list(APPEND SUPPORTED_UPLOAD_METHODS OPENOCD) -endif() - - -# decide default method based on what can work -# ------------------------------------------------------------- - - -set(UPLOAD_METHOD "${UPLOAD_METHOD_DEFAULT}" CACHE STRING "Method for uploading programs to the mbed") - -if((NOT "${UPLOAD_METHOD}" STREQUAL "NONE") AND (NOT "${${UPLOAD_METHOD}_UPLOAD_ENABLED}")) - message(FATAL_ERROR "The upload method ${UPLOAD_METHOD} is not enabled for this project.") -endif() - -if(NOT "${UPLOAD_METHOD}" IN_LIST SUPPORTED_UPLOAD_METHODS) - message(FATAL_ERROR "The upload method ${UPLOAD_METHOD} cannot run on this system due to missing prerequisites. See its docs for details.") -endif() - -message(STATUS "Board upload method set to ${UPLOAD_METHOD}") - - -# path where the gdbinit file will be written -set(GDBINIT_PATH ${CMAKE_CURRENT_BINARY_DIR}/mbed-cmake.gdbinit) - - -# create function to upload code -# ------------------------------------------------------------- -if("${UPLOAD_METHOD}" STREQUAL NONE) - function(gen_upload_target TARGET_NAME BIN_FILE) - add_custom_target(flash-${TARGET_NAME} - COMMAND ${CMAKE_COMMAND} - -E echo "Cannot flash, no UPLOAD_METHOD configured!") - - add_dependencies(flash-${TARGET_NAME} ${TARGET_NAME}) - - endfunction(gen_upload_target) - -elseif("${UPLOAD_METHOD}" STREQUAL MBED) - - set(MBED_PATH "" CACHE PATH "Path to mbed virtual device to upload to") - - function(gen_upload_target TARGET_NAME BIN_FILE) - - add_custom_target(flash-${TARGET_NAME} - COMMAND ${CMAKE_COMMAND} - -DBIN_FILE=${BIN_FILE} - -DMBED_PATH=${MBED_PATH} - -P ${MBED_CMAKE_SOURCE_DIR}/cmake/install_bin_file.cmake) - - add_dependencies(flash-${TARGET_NAME} ${TARGET_NAME}) - - endfunction(gen_upload_target) - -elseif("${UPLOAD_METHOD}" STREQUAL "JLINK") - - set(GENERATE_GDBINIT TRUE) - - function(gen_upload_target TARGET_NAME BIN_FILE) - - # create command file for j-link - set(COMMAND_FILE_PATH ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/flash-${TARGET_NAME}.jlink) - file(GENERATE OUTPUT ${COMMAND_FILE_PATH} CONTENT -" -loadbin ${BIN_FILE}, 0x0 -r -exit -") - add_custom_target(flash-${TARGET_NAME} - COMMENT "Flashing ${TARGET_NAME} with J-Link..." - COMMAND ${JLINK} - -Device ${JLINK_CPU_NAME} - -Speed ${JLINK_JTAG_SPEED} - -if JTAG - -JTAGConf -1,-1 - -AutoConnect 1 - -ExitOnError - -CommandFile ${COMMAND_FILE_PATH}) - - - add_dependencies(flash-${TARGET_NAME} ${TARGET_NAME}) - - # create debug target - add_custom_target(debug-${TARGET_NAME} - COMMENT "starting GDB to debug ${TARGET_NAME}..." - COMMAND arm-none-eabi-gdb - --command=${GDBINIT_PATH} - $) - - - add_dependencies(debug-${TARGET_NAME} ${TARGET_NAME}) - - endfunction(gen_upload_target) - - # also create a target to run GDB server - add_custom_target(start-gdbserver - COMMENT "Starting J-Link GDB server" - COMMAND - "${JLINK_GDBSERVER}" - -Select USB - -Device ${JLINK_CPU_NAME} - -Speed ${JLINK_JTAG_SPEED} - -endian little - -if JTAG - -JTAGConf -1,-1 - -LocalhostOnly - -noIR - -port ${GDB_PORT} - ) - -elseif("${UPLOAD_METHOD}" STREQUAL "PYOCD") - - set(GENERATE_GDBINIT TRUE) - - set(PYOCD_PROBE_ARGS "") - if(DEFINED PYOCD_PROBE_UID) - if(NOT "${PYOCD_PROBE_UID}" STREQUAL "") - set(PYOCD_PROBE_ARGS --probe ${PYOCD_PROBE_UID}) - endif() - endif() - - function(gen_upload_target TARGET_NAME BIN_FILE) - - add_custom_target(flash-${TARGET_NAME} - COMMENT "Flashing ${TARGET_NAME} with pyOCD..." - COMMAND ${Python3_EXECUTABLE} - -m pyocd - flash - -v - --no-wait - -t ${PYOCD_TARGET_NAME} - ${PYOCD_PROBE_ARGS} - ${BIN_FILE}) - - - add_dependencies(flash-${TARGET_NAME} ${TARGET_NAME}) - - # create debug target - add_custom_target(debug-${TARGET_NAME} - COMMENT "starting GDB to debug ${TARGET_NAME}..." - COMMAND arm-none-eabi-gdb - --command=${GDBINIT_PATH} - $) - - - add_dependencies(debug-${TARGET_NAME} ${TARGET_NAME}) - - endfunction(gen_upload_target) - - # also create a target to run GDB server - add_custom_target(start-gdbserver - COMMENT "Starting pyOCD GDB server" - COMMAND - ${Python3_EXECUTABLE} - -m pyocd - gdbserver - -v - --no-wait - -t ${PYOCD_TARGET_NAME} - ${PYOCD_PROBE_ARGS} - -f ${PYOCD_JTAG_SPEED} - -p ${GDB_PORT} - --persist - --semihosting - ) - -elseif("${UPLOAD_METHOD}" STREQUAL "OPENOCD") - - set(GENERATE_GDBINIT TRUE) - - function(gen_upload_target TARGET_NAME BIN_FILE) - - add_custom_target(flash-${TARGET_NAME} - COMMENT "Flashing ${TARGET_NAME} with OpenOCD..." - COMMAND ${OpenOCD} - ${OPENOCD_CHIP_CONFIG_COMMANDS} - -c init - -c "reset init" - -c "program ${BIN_FILE} reset exit") - - - add_dependencies(flash-${TARGET_NAME} ${TARGET_NAME}) - - # create debug target - add_custom_target(debug-${TARGET_NAME} - COMMENT "starting GDB to debug ${TARGET_NAME}..." - COMMAND arm-none-eabi-gdb - --command=${GDBINIT_PATH} - $) - - - add_dependencies(debug-${TARGET_NAME} ${TARGET_NAME}) - - endfunction(gen_upload_target) - - # also create a target to run GDB server - add_custom_target(start-gdbserver - COMMENT "Starting OpenOCD GDB server" - COMMAND - ${OpenOCD} - ${OPENOCD_CHIP_CONFIG_COMMANDS} - -c "gdb_port ${GDB_PORT}" - -c init - -c "reset init" - ) - - - -elseif("${UPLOAD_METHOD}" STREQUAL NXPPROG) - - set(NXPPROG_COM_PORT "" CACHE STRING "COM port for bootloader upload. Should be \"COMXX\" on Windows, and /dev/ttyXX on Linux/Mac") - - message(STATUS "COM port for bootloader upload: ${NXPPROG_COM_PORT}") - - function(gen_upload_target TARGET_NAME BIN_FILE) - - if("${NXPPROG_COM_PORT}" STREQUAL "") - add_custom_target(flash-${TARGET_NAME} - COMMAND ${CMAKE_COMMAND} - -E echo "ERROR: Cannot flash, no COM_PORT configured!") - else() - add_custom_target(flash-${TARGET_NAME} - COMMENT "Flashing ${TARGET_NAME} through bootloader..." - COMMAND ${Python3_EXECUTABLE} ${MBED_CMAKE_SOURCE_DIR}/scripts/nxpprog.py - --control - --oscfreq=${NXPPROG_OSCFREQ} - --baud=${NXPPROG_BAUD} - ${NXPPROG_COM_PORT} - ${BIN_FILE}) - endif() - - add_dependencies(flash-${TARGET_NAME} ${TARGET_NAME}) - - endfunction(gen_upload_target) - -endif() - -# Common actions -# ------------------------------------------------------------- - - -if(GENERATE_GDBINIT) - - # create init file for GDB client - file(GENERATE OUTPUT ${GDBINIT_PATH} CONTENT - " -# connect to GDB server -target remote localhost:${GDB_PORT} -") -endif() diff --git a/cmake/utils/Shorthand.cmake b/cmake/utils/Shorthand.cmake deleted file mode 100644 index 49ed116..0000000 --- a/cmake/utils/Shorthand.cmake +++ /dev/null @@ -1,219 +0,0 @@ -# File containing some little functions which wrap things which are very verbose in CMake in something a little easier to type -# Since these functions are used all over the place in the build system, this must be included after Utils.cmake but before anything else. - -#shorthand for installing a library or libraries, shared or static. -#the normal way is way, WAY too long. -#usage: install_libraries( [SUBDIR ] [COMPONENT ]) - -function(install_libraries) # LIBRARIES... - cmake_parse_arguments( - INSTALL_LIBS - "" - "SUBDIR;COMPONENT" - "" - ${ARGN}) - - if("${INSTALL_LIBS_COMPONENT}" STREQUAL "") - install(TARGETS ${INSTALL_LIBS_UNPARSED_ARGUMENTS} - RUNTIME DESTINATION ${DLLDIR} - ARCHIVE DESTINATION ${LIBDIR}/${INSTALL_LIBS_SUBDIR} - LIBRARY DESTINATION ${LIBDIR}/${INSTALL_LIBS_SUBDIR}) - else() - install(TARGETS ${INSTALL_LIBS_UNPARSED_ARGUMENTS} COMPONENT ${INSTALL_LIBS_COMPONENT} - RUNTIME DESTINATION ${DLLDIR} - ARCHIVE DESTINATION ${LIBDIR}/${INSTALL_LIBS_SUBDIR} - LIBRARY DESTINATION ${LIBDIR}/${INSTALL_LIBS_SUBDIR}) - endif() -endfunction(install_libraries) - -#Shorthand for linking multiple targets to one or more libraries. -#usage: targets_link_libraries(fooexe1 fooexe2 LIBRARIES libbar libbaz) -macro(targets_link_libraries) - #parse the arguents - cmake_parse_arguments( - TARGETS_LINK_LIB - "" - "" - "LIBRARIES" - ${ARGN}) - - #note: targets will end up in the "unparsed arguments" list - if("${TARGETS_LINK_LIB_LIBRARIES}" STREQUAL "") - message(SEND_ERROR "Incorrect usage: no libraries provided") - endif() - - if("${TARGETS_LINK_LIB_UNPARSED_ARGUMENTS}" STREQUAL "") - message(SEND_ERROR "Incorrect usage: no targets provided") - endif() - - foreach(TARGET ${TARGETS_LINK_LIB_UNPARSED_ARGUMENTS}) - target_link_libraries(${TARGET} ${TARGETS_LINK_LIB_LIBRARIES}) - endforeach() -endmacro(targets_link_libraries) - - -# Shorthand for adding an imported executable. -# Sets it up so that using NAME as the program in a custom command will invoke the executable at PATH -macro(import_executable NAME PATH) - add_executable(${NAME} IMPORTED) - set_property(TARGET ${NAME} PROPERTY IMPORTED_LOCATION ${PATH}) -endmacro(import_executable) - -#Add dependencies to a test -#In other words, make TEST not be run until all tests in DEPENDENCIES have -macro(test_depends TEST) #DEPENDENCIES... - set_property(TEST ${TEST} APPEND PROPERTY DEPENDS ${ARGN}) -endmacro(test_depends) - -# Shorthand for setting a boolean based on a logical expression -#NOTE: does not work for testing if a string is empty because any empty strings ("") in the arguments get removed completely -macro(test OUTPUT_VAR) #LOGICAL_EXPRESSION... - if(${ARGN}) - set(${OUTPUT_VAR} TRUE) - else() - set(${OUTPUT_VAR} FALSE) - endif() -endmacro() - -# sets OUTPUT_VARIABLE to true if STRING is empty, false otherwise -macro(empty_string OUTPUT_VARIABLE STRING) - if("${STRING}" STREQUAL "") - set(${OUTPUT_VARIABLE} TRUE) - else() - set(${OUTPUT_VARIABLE} FALSE) - endif() -endmacro(empty_string) - -# sets OUTPUT_VARIABLE to true if STRING is not empty, false otherwise -macro(not_empty_string OUTPUT_VARIABLE STRING) - if("${STRING}" STREQUAL "") - set(${OUTPUT_VARIABLE} FALSE) - else() - set(${OUTPUT_VARIABLE} TRUE) - endif() -endmacro(not_empty_string) - -#sets OUTPUT_VAR to TRUE if LIST contains ELEMENT -# If only we could use recent CMake versions this wouldn't be needed, sigh -macro(list_contains OUTPUT ELEMENT) #3rd arg: LIST... - #change macro argument to variable - set(ARGN_LIST ${ARGN}) - - list(FIND ARGN_LIST "${ELEMENT}" ELEMENT_INDEX) - - if(${ELEMENT_INDEX} EQUAL -1) - set(${OUTPUT} FALSE) - else() - set(${OUTPUT} TRUE) - endif() - -endmacro(list_contains) - -# Checks for the presence of all include files provided and sets variables corresponding to their names. -# Variable naming follows the Automake convention -# foo.h -> HAVE_FOO_H -# sys/stat.h -> HAVE_SYS_STAT_H -# _underscore.h -> HAVE__UNDERSCORE_H -# cstdio -> HAVE_CSTDIO - -#LANGUAGE should be C or CXX -macro(check_all_includes LANGUAGE) - - foreach(INCLUDE ${ARGN}) - # figure out variable name - string(TOUPPER "HAVE_${INCLUDE}" VAR_NAME) - string(REPLACE "." "_" VAR_NAME ${VAR_NAME}) - string(REPLACE "/" "_" VAR_NAME ${VAR_NAME}) - - #message("${INCLUDE} -> ${VAR_NAME}") - - if(${LANGUAGE} STREQUAL C) - check_include_file(${INCLUDE} ${VAR_NAME}) - elseif(${LANGUAGE} STREQUAL CXX) - check_include_file_cxx(${INCLUDE} ${VAR_NAME}) - else() - message(FATAL_ERROR "Invalid value for LANGUAGE") - endif() - endforeach() -endmacro(check_all_includes) - - -# Checks for the presence all of the functions provided and sets variables corresponding to their names. -# Set CMAKE_REQUIRED_LIBRARIES to point to libraries that you want this test to link. -# Variable naming follows the Automake convention -# strlen -> HAVE_STRLEN -# _underscore -> HAVE__UNDERSCORE - -macro(check_all_functions) - - foreach(FUNCTION ${ARGN}) - # figure out variable name - string(TOUPPER "HAVE_${FUNCTION}" VAR_NAME) - - #message("${FUNCTION} -> ${VAR_NAME}") - - check_function_exists(${FUNCTION} ${VAR_NAME}) - endforeach() -endmacro(check_all_functions) - -# Checks for the presence in system headers of all the types provided and sets variables corresponding to their names and sizes. -# Set CMAKE_EXTRA_INCLUDE_FILES to name extra headers that you want this function to include, and CMAKE_REQUIRED_INCLUDES to point to additional directories to search for those headers in. -# Variable naming follows the Automake convention -# off_t -> HAVE_OFF_T, SIZEOF_OFF_T -# _underscore -> HAVE__UNDERSCORE, SIZEOF__UNDERSCORE -# "long long" -> HAVE_LONG_LONG, SIZEOF_LONG_LONG -# "((struct something*)0)->member" -> HAVE_STRUCT_SOMETHING_MEMBER, SIZEOF_STRUCT_SOMETHING_MEMBER -# num10 -> HAVE_NUM10, SIZEOF_NUM10 (numbers are only removed if they are adjacent to a closing parenthesis) -macro(check_all_types) - - foreach(TYPE ${ARGN}) - # figure out variable name - string(TOUPPER "${TYPE}" NAME_UCASE) - string(REPLACE " " "_" NAME_UCASE "${NAME_UCASE}") - string(REPLACE "->" "_" NAME_UCASE "${NAME_UCASE}") - string(REGEX REPLACE "[0-9]\\\)" "" NAME_UCASE "${NAME_UCASE}") - string(REPLACE "(" "" NAME_UCASE "${NAME_UCASE}") - string(REPLACE ")" "" NAME_UCASE "${NAME_UCASE}") - string(REPLACE "*" "" NAME_UCASE "${NAME_UCASE}") - - #message("${TYPE} -> ${NAME_UCASE}") - - check_type_size("${TYPE}" "SIZEOF_${NAME_UCASE}") - - set(HAVE_${NAME_UCASE} ${HAVE_SIZEOF_${NAME_UCASE}}) - endforeach() -endmacro(check_all_types) - -# Checks for all of the symbol or constant names provided in the given header and sets variables corresponding to their names -# Variable naming follows the Automake convention -# strlen -> HAVE_STRLEN -# _underscore -> HAVE__UNDERSCORE - -function(check_all_symbols HEADER) - - foreach(SYMBOL ${ARGN}) - # figure out variable name - string(TOUPPER "HAVE_${SYMBOL}" VAR_NAME) - - #message("${FUNCTION} -> ${VAR_NAME}") - - # check symbol first - check_symbol_exists(${SYMBOL} ${HEADER} ${VAR_NAME}_AS_SYMBOL) - - # if it was not found as a symbol, then check for it as an enum/constant - if(NOT ${VAR_NAME}_AS_SYMBOL) - check_constant_exists(${SYMBOL} ${HEADER} ${VAR_NAME}_AS_CONSTANT) - endif() - - test(${VAR_NAME}_EITHER ${VAR_NAME}_AS_SYMBOL OR ${VAR_NAME}_AS_CONSTANT) - - # create cache variable from results - set(${VAR_NAME} ${${VAR_NAME}_EITHER} CACHE INTERNAL "Whether ${SYMBOL} is available in ${HEADER} as a function, global variable, preprocessor constant, or enum value") - - endforeach() -endfunction(check_all_symbols) - -# Prints a variable name and its value to the standard output. Useful for debugging. -function(printvar VARNAME) - message("${VARNAME}: \"${${VARNAME}}\"") -endfunction(printvar) \ No newline at end of file diff --git a/cmake/utils/Utils.cmake b/cmake/utils/Utils.cmake deleted file mode 100644 index fbac992..0000000 --- a/cmake/utils/Utils.cmake +++ /dev/null @@ -1,146 +0,0 @@ -include(CMakeParseArguments) - -#converts a list into a string with each of its elements seperated by a space -macro(list_to_space_separated OUTPUT_VAR)# 2nd arg: LIST... - string(REPLACE ";" " " ${OUTPUT_VAR} "${ARGN}") -endmacro(list_to_space_separated) - -#causes a symlink between FILE and SYMLINK to be created at install time. -# the paths of FILE and SYMLINK are appended to the install prefix -#only works on UNIX -macro(installtime_create_symlink FILE SYMLINK) # 3rd optional arg: COMPONENT - #cmake -E create_symlink doesn't work on non-UNIX OS's - - if(HOST_WINDOWS) - message(FATAL_ERROR "installtime_create_symlink called on a non-UNIX platform") - endif() - - if("${ARGN}" STREQUAL "") - install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${FILE} \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${SYMLINK})") - else() - install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${FILE} \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${SYMLINK})" COMPONENT ${ARGN}) - endif() - -endmacro(installtime_create_symlink) - -#creates a rule to make OUTPUTFILE from the output of running m4 on INPUTFILE -macro(m4_target INPUTFILE OUTPUTFILE) # 3rd arg: M4_OPTIONS - add_custom_command( - OUTPUT ${OUTPUTFILE} - COMMAND m4 ${ARGN} - ARGS ${INPUTFILE} > ${OUTPUTFILE} VERBATIM) -endmacro(m4_target) - -#Checks that the cache variable VARIABLE is set to one of VALID_VALUES and prints an error if is not. -#Also creates a pull-down menu for the variable in the GUI containing these choices -macro(validate_configuration_enum VARIABLE) #2nd argument: VALID_VALUES... - - list_contains(VALID ${${VARIABLE}} ${ARGN}) - - if(NOT VALID) - list_to_space_separated(VALID_VALUES_STRING ${ARGN}) - - message(FATAL_ERROR "${${VARIABLE}} is not a valid value for ${VARIABLE} -- must be one of: ${VALID_VALUES_STRING}") - endif() - - set_property(CACHE ${VARIABLE} PROPERTY STRINGS ${ARGN}) -endmacro(validate_configuration_enum) - -# Remove the last file extension from a filename. -# foo.bar.s > foo.bar -# This is different from get_filename_component(.. NAME_WE), where foo.bar.s > foo -macro(strip_last_extension OUTPUT_VAR FILENAME) - #from http://stackoverflow.com/questions/30049180/strip-filename-shortest-extension-by-cmake-get-filename-removing-the-last-ext - string(REGEX REPLACE "\\.[^.]*$" "" ${OUTPUT_VAR} ${FILENAME}) -endmacro() - - -#several times in this codebase we have a library and an executable named the same thing. -#in that case, we use a "lib" prefix on the target to distinguish the two. -#normally, that would mean we'd get a library file like "liblibsander.so" - -# this macro removes the lib prefix on each of the library targets provided so that this doesn't happen -macro(remove_prefix) #LIBRARIES - set_target_properties(${ARGN} PROPERTIES PREFIX "") - set_target_properties(${ARGN} PROPERTIES IMPORT_PREFIX "") -endmacro(remove_prefix) - -#make the provided object library position independent if shared libraries are turned on -function(make_pic_if_needed OBJECT_LIBRARY) - set_property(TARGET ${OBJECT_LIBRARY} PROPERTY POSITION_INDEPENDENT_CODE ${SHARED}) -endfunction(make_pic_if_needed) - -#Append NEW_FLAGS to the COMPILE_FLAGS property of each source file in SOURCE -macro(append_compile_flags NEW_FLAGS) # SOURCE... - foreach(SOURCE_FILE ${ARGN}) - get_property(CURRENT_COMPILE_FLAGS SOURCE ${SOURCE_FILE} PROPERTY COMPILE_FLAGS) - - set(NEW_COMPILE_FLAGS "${CURRENT_COMPILE_FLAGS} ${NEW_FLAGS}") - - set_property(SOURCE ${SOURCE_FILE} PROPERTY COMPILE_FLAGS ${NEW_COMPILE_FLAGS}) - endforeach() -endmacro(append_compile_flags) - -# removes the given directory from cmake's PATH environment variable -function(remove_from_path DIRECTORY) - - if(HOST_WINDOWS) - set(CONVERTED_PATH $ENV{PATH}) - else() - string(REPLACE ":" ";" CONVERTED_PATH $ENV{PATH}) - endif() - - get_filename_component(TO_REMOVE_REALPATH "${DIRECTORY}" REALPATH) - - set(NEW_PATH "") - - foreach(PATHCOMPONENT ${CONVERTED_PATH}) - get_filename_component(PATHCOMPONENT_REALPATH "${PATHCOMPONENT}" REALPATH) - - #message("Comparing \"${TO_REMOVE_REALPATH}\" and \"${PATHCOMPONENT_REALPATH}\"") - - # make sure to compare their real paths, so we aren't folled by any path weirdness in PATH - if(NOT "${TO_REMOVE_REALPATH}" STREQUAL "${PATHCOMPONENT_REALPATH}") - list(APPEND NEW_PATH "${PATHCOMPONENT}") - endif() - endforeach() - - #printvar(ENV{PATH}) - #printvar(NEW_PATH) - - # now set the new path - if(HOST_WINDOWS) - set($ENV{PATH} "${NEW_PATH}") - else() - string(REPLACE ";" ":" ENV{PATH} "${NEW_PATH}") - endif() - #printvar(ENV{PATH}) - -endfunction(remove_from_path) - -function (add_target_subdirectory TARGET_BOARD) - if (${TARGET_BOARD} MATCHES "\-x") - string(REPLACE "\-x " "" CUSTOM_BOARD ${TARGET_BOARD}) - add_subdirectory(${TARGETS_DIR}/TARGET_${CUSTOM_BOARD}) - endif() -endfunction() - -function (add_target_board_subdirectory TARGET_BOARD) - if (${TARGET_BOARD} MATCHES "\-x") - string(REPLACE "\-x " "" CUSTOM_BOARD ${TARGET_BOARD}) - add_subdirectory(${TARGETS_DIR}/TARGET_${CUSTOM_BOARD}) - endif() -endfunction() - -function (target_link_target_board_libraries TARGET) - if (${TARGET_BOARD} MATCHES "\-x") - string(REPLACE "\-x " "" CUSTOM_BOARD ${TARGET_BOARD}) - foreach(board IN ITEMS ${ARGN}) - if (${CUSTOM_BOARD} MATCHES ${board}) - message(STATUS ">> Linking ${TARGET} with custom target library ${board}") - target_link_libraries(${TARGET} target_${board}) - endif() - endforeach() - endif() -endfunction() - diff --git a/libs/HelloWorld/CMakeLists.txt b/libs/HelloWorld/CMakeLists.txt index d0233a9..a484b84 100644 --- a/libs/HelloWorld/CMakeLists.txt +++ b/libs/HelloWorld/CMakeLists.txt @@ -2,16 +2,19 @@ # Copyright 2020 Ladislas de Toldi (ladislas [at] detoldi.me) # SPDX-License-Identifier: Apache-2.0 -add_library(lib_hello_world STATIC) +add_library(HelloWorld STATIC) -target_sources(lib_hello_world - PRIVATE - HelloWorld.cpp +target_include_directories(HelloWorld + PUBLIC + . ) -target_include_directories(lib_hello_world - PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR} +target_sources(HelloWorld + PRIVATE + HelloWorld.cpp ) -target_link_libraries(lib_hello_world mbed-os) +target_link_libraries(HelloWorld + PRIVATE + mbed_for_my_app +) diff --git a/mbed-cmake.cmake b/mbed-cmake.cmake deleted file mode 100644 index cfce737..0000000 --- a/mbed-cmake.cmake +++ /dev/null @@ -1,173 +0,0 @@ -# mbed-cmake requires CMake >= 3.12 for the new FindPython3 module -cmake_policy(VERSION 3.19) - -message(STATUS [==[ _ _ ____ ______ ___ ____ _ _ _ _ _ ______ ]==]) -message(STATUS [==[| \ / | / _ \ / ____) / _ \_ / ____) | \ / | / \ / \ / | / ____) ]==]) -message(STATUS [==[| \ / | | |_| | | |____ | | \_ \ ______ / / | \ / | / _ \ | | / / | |____ ]==]) -message(STATUS [==[| \ / | | / | ____) | | | | (______) | | | \ / | / /_\ \ | _ / / | ____) ]==]) -message(STATUS [==[| |\ - /| | | _ \ | | | | _| | \ \ | |\ - /| | / _____ \ | _ \ | | ]==]) -message(STATUS [==[| | \_/ | | | |_| | | |____ | |_/ _/ \ \___ | | \_/ | | / / \ \ | | \ \ | |____ ]==]) -message(STATUS [==[\_/ \_/ \_____ / \______) \___ / \____) \_/ \_/ |_/ \_| \_/ \_/ \______) ]==]) - -message(STATUS "") - -set(MBED_CMAKE_VERSION 1.3.0) -message(STATUS "mbed-cmake version ${MBED_CMAKE_VERSION}, running on CMake ${CMAKE_VERSION}") - -set(MBED_CMAKE_ROOT_DIR ${ROOT_DIR}/cmake) -set(MBED_CMAKE_SCRIPTS_DIR ${MBED_CMAKE_ROOT_DIR}/scripts) -set(MBED_CMAKE_CONFIG_DIR ${ROOT_DIR}/_build/cmake_config/${TARGET_BOARD}) - -list(APPEND CMAKE_MODULE_PATH ${MBED_CMAKE_ROOT_DIR}) -list(APPEND CMAKE_MODULE_PATH ${MBED_CMAKE_ROOT_DIR}/utils) - -# Fix error: The C Compiler is not able to compile a simple test program -set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY") - -# Add custom flags -add_compile_options(-fdiagnostics-color) - -include(CheckTypeSize) -include(Shorthand) -include(Utils) -include(CheckPythonPackage) -include(FindPackageHandleStandardArgs) - -# build configuration -# ------------------------------------------------------------- -# default to RelWithDebInfo to match Mbed OS default -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING - "Type of build, options are: Debug, RelWithDebInfo, Release" FORCE) -endif() - -# Allowed build types are Debug and Release -set(CMAKE_CONFIGURATION_TYPES Debug RelWithDebInfo Release) - -# check configuration files -# ------------------------------------------------------------- - -set(MBED_CMAKE_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) - -# relative to CMakeLists.txt inside mbed-cmake -if(NOT DEFINED MBED_CMAKE_GENERATED_CONFIG_RELPATH) - set(MBED_CMAKE_GENERATED_CONFIG_RELPATH ${MBED_CMAKE_CONFIG_DIR}) -endif() -set(MBED_CMAKE_GENERATED_CONFIG_PATH ${MBED_CMAKE_CONFIG_DIR}) - -if(NOT DEFINED MBED_CMAKE_CONFIG_HEADERS_PATH) - set(MBED_CMAKE_CONFIG_HEADERS_PATH ${CMAKE_CURRENT_SOURCE_DIR}/config-headers) -endif() - -if(NOT EXISTS ${MBED_CMAKE_GENERATED_CONFIG_PATH}/cmake/MbedOSConfig.cmake) - message(FATAL_ERROR "Mbed config files and headers do not exist! You need to run mbed-cmake/configure_for_target.py from the top source dir!") -endif() - -# unit test config -# ------------------------------------------------------------- -option(MBED_UNITTESTS "If true, compile for the local system and run unit tests" FALSE) - -# load compilers and flags -# ------------------------------------------------------------- - -# read flags from generated configuration file -include(${MBED_CMAKE_GENERATED_CONFIG_PATH}/cmake/MbedOSConfig.cmake) - -# load toolchain -if(MBED_UNITTESTS) - message(STATUS "Unit tests enabled, not loading mbed-cmake toolchain file") -elseif("${MBED_TOOLCHAIN_NAME}" STREQUAL "ARMC6") - - if(${CMAKE_VERSION} VERSION_LESS 3.15.0) - message(FATAL_ERROR "CMake >= 3.15.0 is required for Arm Compiler support") - endif() - - include(ToolchainArmClangDefine) -elseif("${MBED_TOOLCHAIN_NAME}" STREQUAL "GCC_ARM") - include(ToolchainGCCArmDefine) -else() - message(FATAL_ERROR "Unknown toolchain \"${MBED_TOOLCHAIN_NAME}\"") -endif() - -# search for and load compilers -enable_language(C CXX ASM) - -if(NOT MBED_UNITTESTS) - # Set config-specific flags - # Note: unlike CMAKE_C_FLAGS etc, we need to set these AFTER the project() call in order to override CMake's default values for these flags. - # CMAKE_C_FLAGS_INIT etc need to be set BEFORE the project() call so that it's used when CMake scans compiler properties. - foreach(BUILD_TYPE RELWITHDEBINFO DEBUG RELEASE) - list_to_space_separated(CMAKE_C_FLAGS_${BUILD_TYPE} ${MCU_COMPILE_OPTIONS_${BUILD_TYPE}}) - list_to_space_separated(CMAKE_CXX_FLAGS_${BUILD_TYPE} ${MCU_COMPILE_OPTIONS_${BUILD_TYPE}}) - list_to_space_separated(CMAKE_ASM_FLAGS_${BUILD_TYPE} ${MCU_COMPILE_OPTIONS_${BUILD_TYPE}}) - endforeach() -endif() - -# Set language standard -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_EXTENSIONS TRUE) -set(CMAKE_C_STANDARD 11) -set(CMAKE_C_EXTENSIONS TRUE) - -# find python (used for memap and several upload methods) -# ------------------------------------------------------------- - -find_package(Python3 COMPONENTS Interpreter) - -# Configure unit tests -# ------------------------------------------------------------- - -if(MBED_UNITTESTS) - # Build internal GTest. - # We use an internal GTest because hardly any platform has a complete package available - # for it for some reason. - # add_subdirectory(${MBED_CMAKE_SOURCE_DIR}/gtest-external-project) - # include(GoogleTest) - # enable_testing() -endif() - -# load the Mbed CMake functions -# ------------------------------------------------------------- - -if(MBED_UNITTESTS) - include(AddMbedUnitTestsExecutable) -else() - include(AddMbedExecutable) -endif() - -# Configure upload methods -# ------------------------------------------------------------- - -if(NOT MBED_UNITTESTS) - set(CMAKE_EXECUTABLE_SUFFIX .elf) - - # find upload tools - # find_package(OpenOCD) - # find_package(JLINK) - # include(SetUploadMethod) -endif() - -# add Mbed OS source -# ------------------------------------------------------------- - -set(MBED_CMAKE_CONFIG_HEADERS_PATH ${MBED_CMAKE_GENERATED_CONFIG_PATH}/config-headers) -add_subdirectory(${MBED_OS_DIR}) #first get Mbed standard library - -# build report -# ------------------------------------------------------------- -function(mbed_cmake_print_build_report) - - message(STATUS "---- Completed configuration of ${PROJECT_NAME} ----") - - # build type - message(STATUS ">> Current Build Type: ${CMAKE_BUILD_TYPE}") - - # build flags - string(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_UCASE) - message(STATUS ">> C Compile Flags (Global): ${CMAKE_C_FLAGS}") - message(STATUS ">> C Compile Flags (For ${CMAKE_BUILD_TYPE}): ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UCASE}}") - message(STATUS ">> CXX Compile Flags (Global): ${CMAKE_CXX_FLAGS}") - message(STATUS ">> CXX Compile Flags (For ${CMAKE_BUILD_TYPE}): ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UCASE}}") - message(STATUS ">> Linker Flags: ${CMAKE_EXE_LINKER_FLAGS}") - -endfunction(mbed_cmake_print_build_report) diff --git a/spikes/blinky/CMakeLists.txt b/spikes/blinky/CMakeLists.txt index 37fc940..3a5e59d 100644 --- a/spikes/blinky/CMakeLists.txt +++ b/spikes/blinky/CMakeLists.txt @@ -2,14 +2,19 @@ # Copyright 2020 Ladislas de Toldi (ladislas [at] detoldi.me) # SPDX-License-Identifier: Apache-2.0 -add_mbed_executable(blinky) +add_executable(blinky) + +mbed_configure_app_target(blinky) +mbed_set_mbed_target_linker_script_patched(blinky) target_sources(blinky - PRIVATE - main.cpp + PRIVATE + main.cpp ) -target_include_directories(blinky - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} +target_link_libraries(blinky + PRIVATE + mbed_for_my_app ) + +mbed_set_post_build(blinky) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2966ae4..68bcd21 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,16 +2,20 @@ # Copyright 2020 Ladislas de Toldi (ladislas [at] detoldi.me) # SPDX-License-Identifier: Apache-2.0 -add_mbed_executable(main_project) +add_executable(main_program) -target_sources(main_project - PRIVATE - main.cpp +mbed_configure_app_target(main_program) +mbed_set_mbed_target_linker_script_patched(main_program) + +target_sources(main_program + PRIVATE + main.cpp ) -target_include_directories(main_project - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} +target_link_libraries(main_program + PRIVATE + HelloWorld + mbed_for_my_app ) -target_link_libraries(main_project lib_hello_world) +mbed_set_post_build(main_program)