Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example embedded #230

Merged
merged 7 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions embedded/crosscompile_random_forest/CMake/Autodownload.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
## This function auto-downloads mlpack dependencies.
## You need to pass the LINK to download from, the name of
## the dependency, and the name of the compressed package such as
## armadillo.tar.gz
## At each download, this module sets a GENERIC_INCLUDE_DIR path,
## which means that you need to set the main path for the include
## directories for each package.
## Note that, the package should be compressed only as .tar.gz

macro(get_deps LINK DEPS_NAME PACKAGE)
if (NOT EXISTS "${CMAKE_BINARY_DIR}/deps/${PACKAGE}")
file(DOWNLOAD ${LINK}
"${CMAKE_BINARY_DIR}/deps/${PACKAGE}"
STATUS DOWNLOAD_STATUS_LIST LOG DOWNLOAD_LOG
SHOW_PROGRESS)
list(GET DOWNLOAD_STATUS_LIST 0 DOWNLOAD_STATUS)
if (DOWNLOAD_STATUS EQUAL 0)
execute_process(COMMAND ${CMAKE_COMMAND} -E
tar xf "${CMAKE_BINARY_DIR}/deps/${PACKAGE}"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/deps/")
else ()
list(GET DOWNLOAD_STATUS_LIST 1 DOWNLOAD_ERROR)
message(FATAL_ERROR
"Could not download ${DEPS_NAME}! Error code ${DOWNLOAD_STATUS}: ${DOWNLOAD_ERROR}! Error log: ${DOWNLOAD_LOG}")
endif()
endif()
# Get the name of the directory.
file (GLOB DIRECTORIES RELATIVE "${CMAKE_BINARY_DIR}/deps/"
"${CMAKE_BINARY_DIR}/deps/${DEPS_NAME}*.*")
if(${DEPS_NAME} MATCHES "stb")
file (GLOB DIRECTORIES RELATIVE "${CMAKE_BINARY_DIR}/deps/"
"${CMAKE_BINARY_DIR}/deps/${DEPS_NAME}")
endif()
# list(FILTER) is not available on 3.5 or older, but try to keep
# configuring without filtering the list anyway
# (it works only if the file is present as .tar.gz).
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.6.0")
list(FILTER DIRECTORIES EXCLUDE REGEX ".*\.tar\.gz")
endif ()
list(LENGTH DIRECTORIES DIRECTORIES_LEN)
if (DIRECTORIES_LEN GREATER 0)
list(GET DIRECTORIES 0 DEPENDENCY_DIR)
set(GENERIC_INCLUDE_DIR "${CMAKE_BINARY_DIR}/deps/${DEPENDENCY_DIR}/include")
install(DIRECTORY "${GENERIC_INCLUDE_DIR}/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
else ()
message(FATAL_ERROR
"Problem unpacking ${DEPS_NAME}! Expected only one directory ${DEPS_NAME};. Try to remove the directory ${CMAKE_BINARY_DIR}/deps and reconfigure.")
endif ()
endmacro()
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# This file adds the necessary configurations to cross compile
# mlpack for embedded systems. You need to set the following variables
# from the command line: CMAKE_SYSROOT and TOOLCHAIN_PREFIX.
# This file will compile OpenBLAS if it is downloaded and it is not
# available on your system in order to find the BLAS library. If OpenBLAS will
# be compiled, the OPENBLAS_TARGET variable must be set. This can be done
# by, e.g., setting BOARD_NAME (which will set OPENBLAS_TARGET in
# `board/flags-config.cmake`).

if (CMAKE_CROSSCOMPILING)
include(board/flags-config.cmake)
if (NOT CMAKE_SYSROOT AND (NOT TOOLCHAIN_PREFIX))
message(FATAL_ERROR "Neither CMAKE_SYSROOT nor TOOLCHAIN_PREFIX are set; please set both of them and try again.")
elseif(NOT CMAKE_SYSROOT)
message(FATAL_ERROR "Cannot configure: CMAKE_SYSROOT must be set when performing cross-compiling!")
elseif(NOT TOOLCHAIN_PREFIX)
message(FATAL_ERROR "Cannot configure: TOOLCHAIN_PREFIX must be set when performing cross-compiling!")
endif()
endif()

macro(search_openblas version)
set(BLA_STATIC ON)
find_package(BLAS)
if (NOT BLAS_FOUND OR (NOT BLAS_LIBRARIES))
if(NOT OPENBLAS_TARGET)
message(FATAL_ERROR "Cannot compile OpenBLAS: OPENBLAS_TARGET is not set. Either set that variable, or set BOARD_NAME correctly!")
endif()
get_deps(https://github.com/xianyi/OpenBLAS/releases/download/v${version}/OpenBLAS-${version}.tar.gz OpenBLAS OpenBLAS-${version}.tar.gz)
if (NOT MSVC)
if (NOT EXISTS "${CMAKE_BINARY_DIR}/deps/OpenBLAS-${version}/libopenblas.a")
set(ENV{COMMON_OPT} "${CMAKE_OPENBLAS_FLAGS}") # Pass our flags to OpenBLAS
execute_process(COMMAND make TARGET=${OPENBLAS_TARGET} BINARY=${OPENBLAS_BINARY} HOSTCC=gcc CC=${CMAKE_C_COMPILER} FC=${CMAKE_FORTRAN_COMPILER} NO_SHARED=1
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/deps/OpenBLAS-${version})
endif()
file(GLOB OPENBLAS_LIBRARIES "${CMAKE_BINARY_DIR}/deps/OpenBLAS-${version}/libopenblas.a")
set(BLAS_openblas_LIBRARY ${OPENBLAS_LIBRARIES})
set(LAPACK_openblas_LIBRARY ${OPENBLAS_LIBRARIES})
set(BLA_VENDOR OpenBLAS)
set(BLAS_FOUND ON)
endif()
endif()
find_library(GFORTRAN NAMES libgfortran.a)
find_library(PTHREAD NAMES libpthread.a)
set(CROSS_COMPILE_SUPPORT_LIBRARIES ${GFORTRAN} ${PTHREAD})
endmacro()
79 changes: 79 additions & 0 deletions embedded/crosscompile_random_forest/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
cmake_minimum_required(VERSION 3.6)
project(RandomForest)

include(CMake/Autodownload.cmake)
include(CMake/ConfigureCrossCompile.cmake)

option(USE_OPENMP "If available, use OpenMP for parallelization." ON)

# Set required standard to C++17.
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# If we're using gcc, then we need to link against pthreads to use std::thread,
# which we do in the tests.
if (CMAKE_COMPILER_IS_GNUCC)
find_package(Threads)
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
endif()

search_openblas(0.3.26)

get_deps(https://files.mlpack.org/armadillo-12.6.5.tar.gz armadillo armadillo-12.6.5.tar.gz)
set(ARMADILLO_INCLUDE_DIR ${GENERIC_INCLUDE_DIR})
find_package(Armadillo REQUIRED)
# Include directories for the previous dependencies.
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${ARMADILLO_INCLUDE_DIRS})
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} ${ARMADILLO_LIBRARIES})

# Find stb_image.h and stb_image_write.h.
get_deps(https://mlpack.org/files/stb.tar.gz stb stb.tar.gz)
set(STB_IMAGE_INCLUDE_DIR ${GENERIC_INCLUDE_DIR})
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} "${STB_IMAGE_INCLUDE_DIR}")

# Find ensmallen.
get_deps(https://www.ensmallen.org/files/ensmallen-latest.tar.gz ensmallen ensmallen-latest.tar.gz)
set(ENSMALLEN_INCLUDE_DIR ${GENERIC_INCLUDE_DIR})
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} "${ENSMALLEN_INCLUDE_DIR}")

# Find cereal.
get_deps(https://github.com/USCiLab/cereal/archive/refs/tags/v1.3.0.tar.gz cereal cereal-1.3.0.tar.gz)
set(CEREAL_INCLUDE_DIR ${GENERIC_INCLUDE_DIR})
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${CEREAL_INCLUDE_DIR})

# Detect OpenMP support in a compiler. If the compiler supports OpenMP, flags
# to compile with OpenMP are returned and added. Note that MSVC does not
# support a new-enough version of OpenMP to be useful.
if (USE_OPENMP)
find_package(OpenMP)
endif ()

if (OpenMP_FOUND AND OpenMP_CXX_VERSION VERSION_GREATER_EQUAL 3.0.0)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} ${OpenMP_CXX_LIBRARIES})
else ()
# Disable warnings for all the unknown OpenMP pragmas.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas")
set(OpenMP_CXX_FLAGS "")
endif ()

include_directories(BEFORE ${MLPACK_INCLUDE_DIRS})
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/src/)

# Finally, add any cross-compilation support libraries (they may need to come
# last). If we are not cross-compiling, no changes will happen here.
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} ${CROSS_COMPILE_SUPPORT_LIBRARIES})

add_executable(RandomForest main.cpp ${SOURCES_FILES})
target_sources(RandomForest PRIVATE ${SOURCE_FILES})

target_include_directories(RandomForest PRIVATE
${MLPACK_INCLUDE_DIRS}
/meta/mlpack/src/
)

target_link_libraries(RandomForest PRIVATE -static
${MLPACK_LIBRARIES}
)

Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## This file handles cross-compilation configurations for aarch64,
## known as arm64. The objective of this file is to find and assign
## cross-compiler and the entire toolchain.
##
## This configuration works best with the buildroot toolchain. When using this
## file, be sure to set the TOOLCHAIN_PREFIX and CMAKE_SYSROOT variables,
## preferably via the CMake configuration command (e.g. `-DCMAKE_SYSROOT=<...>`).
##
## Currently, we recommend using buildroot toolchain for
## cross-compilation. Here is the link to download the toolchains:
## https://toolchains.bootlin.com/

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSROOT)
set(TOOLCHAIN_PREFIX "" CACHE STRING "Path for toolchain for cross compiler and other compilation tools.")

# Ensure that CMake tries to build static libraries when testing the compiler.
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

set(CMAKE_AR "${TOOLCHAIN_PREFIX}gcc-ar" CACHE FILEPATH "" FORCE)
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++)
set(CMAKE_LINKER ${TOOLCHAIN_PREFIX}ld)
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_C_ARCHIVE_FINISH true)
set(CMAKE_FORTRAN_COMPILER ${TOOLCHAIN_PREFIX}gfortran)
set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy CACHE INTERNAL "objcopy tool")
set(CMAKE_SIZE_UTIL ${TOOLCHAIN_PREFIX}size CACHE INTERNAL "size tool")

## Here are the standard ROOT_PATH if you are using the standard toolchain
## if you are using a different toolchain you have to specify that too.
set(CMAKE_FIND_ROOT_PATH "${CMAKE_SYSROOT}")

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --sysroot=${CMAKE_SYSROOT}" CACHE INTERNAL "" FORCE)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
95 changes: 95 additions & 0 deletions embedded/crosscompile_random_forest/board/flags-config.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# This function provides a set of specific flags for each supported board
# depending on the processor type. The objective is to optimize for size.
# Thus, all of the following flags are chosen carefully to reduce binary
# footprints.

# Set generic minimization flags for all platforms.
# These flags are the same for all cross-compilation cases and they are
# mainly to reduce the binary footprint.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Os -s -fdata-sections -ffunction-sections")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fomit-frame-pointer -fno-unwind-tables")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-asynchronous-unwind-tables -fvisibility=hidden")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fshort-enums -finline-small-functions")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -findirect-inlining -fno-common")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmerge-all-constants -fno-ident")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-unroll-loops -fno-math-errno")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-stack-protector")
set(CMAKE_OPENBLAS_FLAGS "${CMAKE_CXX_FLAGS}") # OpenBLAS does not supoport flto
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--hash-style=gnu -Wl,--build-id=none")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,norelro")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
## Keep the following flag in comment, it will be relevant in the case of MCU's
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,-nmagic,-Bsymbolic -nostartfiles")

set(BOARD_NAME "" CACHE STRING "Specify Board name to optimize for.")
string(TOUPPER ${BOARD_NAME} BOARD)

# Set specific platforms CMAKE CXX flags.
if(BOARD MATCHES "RPI0" OR BOARD MATCHES "RPI1" OR BOARD MATCHES "ARM11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mtune=arm1176jzf-s")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp")
set(OPENBLAS_TARGET "ARMV6")
set(OPENBLAS_BINARY "32")
elseif(BOARD MATCHES "RPI2" OR BOARD MATCHES "CORTEXA7")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mtune=cortex-a7")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfloat-abi=hard -mfpu=neon-vfpv4")
set(OPENBLAS_TARGET "ARMV7")
set(OPENBLAS_BINARY "32")
elseif(BOARD MATCHES "CORTEXA8")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mtune=cortex-a8")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfloat-abi=hard -mfpu=neon")
set(OPENBLAS_TARGET "ARMV7")
set(OPENBLAS_BINARY "32")
elseif(BOARD MATCHES "CORTEXA9")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mtune=cortex-a9")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfloat-abi=hard -mfpu=neon")
set(OPENBLAS_TARGET "CORTEXA9")
set(OPENBLAS_BINARY "32")
elseif(BOARD MATCHES "CORTEXA15")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mtune=cortex-a15")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfloat-abi=hard -mfpu=neon")
set(OPENBLAS_TARGET "CORTEXA15")
set(OPENBLAS_BINARY "32")
elseif(BOARD MATCHES "RPI3" OR BOARD MATCHES "CORTEXA53")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mtune=cortex-a53 -mfloat-abi=hard")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon-fp-armv8 -mneon-for-64bit")
set(OPENBLAS_TARGET "CORTEXA53")
set(OPENBLAS_BINARY "64")
elseif(BOARD MATCHES "RPI4" OR BOARD MATCHES "CORTEXA72")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mtune=cortex-a72 -mfloat-abi=hard")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon-fp-armv8 -mneon-for-64bit")
set(OPENBLAS_TARGET "CORTEXA72")
set(OPENBLAS_BINARY "64")
elseif(BOARD MATCHES "JETSONAGX" OR BOARD MATCHES "CORTEXA76")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mtune=cortex-a76 -mfloat-abi=hard")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon-fp-armv8 -mneon-for-64bit")
set(OPENBLAS_TARGET "CORTEXA76")
set(OPENBLAS_BINARY "64")
elseif(BOARD MATCHES "BV")
set(OPENBLAS_TARGET "RISCV64_GENERIC")
set(OPENBLAS_BINARY "64")
elseif(BOARD MATCHES "C906")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mtune=thead-c906")
set(OPENBLAS_TARGET "RISCV64_GENERIC")
set(OPENBLAS_BINARY "64")
elseif(BOARD MATCHES "x280")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mtune=sifive-x280")
set(OPENBLAS_TARGET "x280")
set(OPENBLAS_BINARY "64")
elseif(BOARD MATCHES "KATAMI")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=pentium3")
set(OPENBLAS_TARGET "KATAMI")
set(OPENBLAS_BINARY "32")
elseif(BOARD MATCHES "COPPERMINE")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=pentium3")
set(OPENBLAS_TARGET "COPPERMINE")
set(OPENBLAS_BINARY "32")
elseif(BOARD MATCHES "NORTHWOOD")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=pentium4")
set(OPENBLAS_TARGET "NORTHWOOD")
set(OPENBLAS_BINARY "32")
elseif(BOARD)
## TODO: update documentation with a list of the supported boards.
message(FATAL_ERROR "Given BOARD_NAME is not known; please choose a supported board from the list")
endif()
35 changes: 35 additions & 0 deletions embedded/crosscompile_random_forest/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include <mlpack.hpp>
shrit marked this conversation as resolved.
Show resolved Hide resolved

using namespace mlpack;

int main(int argc, char** argv)
{
arma::mat dataset;
data::Load("../../data/covertype-small.csv", dataset);

// Labels are the last row.\n",
shrit marked this conversation as resolved.
Show resolved Hide resolved
// The dataset stores labels from 1 through 7, but we need 0 through 6\n",
// (in mlpack labels are zero-indexed), so we subtract 1.\n",
arma::Row<size_t> labels = arma::conv_to<arma::Row<size_t>>::from(dataset.row(dataset.n_rows - 1)) - 1;
dataset.shed_row(dataset.n_rows - 1);

arma::mat trainSet, testSet;
arma::Row<size_t> trainLabels, testLabels;

// Split dataset randomly into training set and test set.\n",
data::Split(dataset, labels, trainSet, testSet, trainLabels, testLabels, 0.3
/* Percentage of dataset to use for test set. */);

RandomForest<> rf(trainSet, trainLabels, 7 /* Number of classes in dataset */, 10 /* 10 trees */);
// Predict the labels of the test points.,
arma::Row<size_t> output;
rf.Classify(testSet, output);
// Now print the accuracy. The 'probabilities' output could also be used to\n",
// generate an ROC curve.\n",
const size_t correct = arma::accu(output == testLabels);
std::cout << correct
<< " correct out of "
<< testLabels.n_elem << "\n"
<< 100.0 * correct / testLabels.n_elem
<< "%)." << std::endl;
}
49 changes: 49 additions & 0 deletions embedded/mlpack_embedded_cmake/CMake/Autodownload.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
## This function auto-downloads mlpack dependencies.
## You need to pass the LINK to download from, the name of
## the dependency, and the name of the compressed package such as
## armadillo.tar.gz
## At each download, this module sets a GENERIC_INCLUDE_DIR path,
## which means that you need to set the main path for the include
## directories for each package.
## Note that, the package should be compressed only as .tar.gz

macro(get_deps LINK DEPS_NAME PACKAGE)
if (NOT EXISTS "${CMAKE_BINARY_DIR}/deps/${PACKAGE}")
file(DOWNLOAD ${LINK}
"${CMAKE_BINARY_DIR}/deps/${PACKAGE}"
STATUS DOWNLOAD_STATUS_LIST LOG DOWNLOAD_LOG
SHOW_PROGRESS)
list(GET DOWNLOAD_STATUS_LIST 0 DOWNLOAD_STATUS)
if (DOWNLOAD_STATUS EQUAL 0)
execute_process(COMMAND ${CMAKE_COMMAND} -E
tar xf "${CMAKE_BINARY_DIR}/deps/${PACKAGE}"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/deps/")
else ()
list(GET DOWNLOAD_STATUS_LIST 1 DOWNLOAD_ERROR)
message(FATAL_ERROR
"Could not download ${DEPS_NAME}! Error code ${DOWNLOAD_STATUS}: ${DOWNLOAD_ERROR}! Error log: ${DOWNLOAD_LOG}")
endif()
endif()
# Get the name of the directory.
file (GLOB DIRECTORIES RELATIVE "${CMAKE_BINARY_DIR}/deps/"
"${CMAKE_BINARY_DIR}/deps/${DEPS_NAME}*.*")
if(${DEPS_NAME} MATCHES "stb")
file (GLOB DIRECTORIES RELATIVE "${CMAKE_BINARY_DIR}/deps/"
"${CMAKE_BINARY_DIR}/deps/${DEPS_NAME}")
endif()
# list(FILTER) is not available on 3.5 or older, but try to keep
# configuring without filtering the list anyway
# (it works only if the file is present as .tar.gz).
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.6.0")
list(FILTER DIRECTORIES EXCLUDE REGEX ".*\.tar\.gz")
endif ()
list(LENGTH DIRECTORIES DIRECTORIES_LEN)
if (DIRECTORIES_LEN GREATER 0)
list(GET DIRECTORIES 0 DEPENDENCY_DIR)
set(GENERIC_INCLUDE_DIR "${CMAKE_BINARY_DIR}/deps/${DEPENDENCY_DIR}/include")
install(DIRECTORY "${GENERIC_INCLUDE_DIR}/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
else ()
message(FATAL_ERROR
"Problem unpacking ${DEPS_NAME}! Expected only one directory ${DEPS_NAME};. Try to remove the directory ${CMAKE_BINARY_DIR}/deps and reconfigure.")
endif ()
endmacro()
Loading
Loading