1#
2# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3#
4# SPDX-License-Identifier: BSD-2-Clause
5#
6
7cmake_minimum_required(VERSION 3.8.2)
8include_guard(GLOBAL)
9
10find_path(
11    RUST_TARGET_PATH "x86_64-sel4-none.json"
12    PATHS ${CMAKE_CURRENT_LIST_DIR}/../rust_targets
13    CMAKE_FIND_ROOT_PATH_BOTH
14)
15
16# Return absoulute filepath of the rust custom target directory
17function(RustGetCustomTargetPath return)
18    set(${return} "${RUST_TARGET_PATH}" PARENT_SCOPE)
19endfunction()
20
21# add_library but for rust libraries. Invokes cargo in the SOURCE_DIR that is provided,
22# all build output is placed in BUILD_DIR or CMAKE_CURRENT_BINARY_DIR if BUILD_DIR isn't provided.
23# lib_name: Name of library that is created
24# SOURCE_DIR: source directory of cargo project
25# BUILD_DIR: directory for cargo build output
26# TARGET: custom target to use. See in ../rust_targets/ for list of available targets.
27# LIB_FILENAME: filename of library created by cargo
28# DEPENDS: And target or file dependencies that need to be run before cargo
29function(RustAddLibrary lib_name)
30    cmake_parse_arguments(PARSE_ARGV 1 RUST "" "SOURCE_DIR;BUILD_DIR;TARGET;LIB_FILENAME" "DEPENDS")
31    if(NOT "${RUST_UNPARSED_ARGUMENTS}" STREQUAL "")
32        message(FATAL_ERROR "Unknown arguments to RustAddLibrary ${RUST_UNPARSED_ARGUMENTS}")
33    endif()
34    if("${RUST_SOURCE_DIR}" STREQUAL "")
35        message(FATAL_ERROR "SOURCE_DIR must be set for RustAddLibrary")
36    endif()
37    if("${RUST_LIB_FILENAME}" STREQUAL "")
38        message(FATAL_ERROR "LIB_FILENAME must be set for RustAddLibrary")
39    endif()
40    if("${RUST_BUILD_DIR}" STREQUAL "")
41        set(RUST_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR})
42    endif()
43    RustGetCustomTargetPath(target_path)
44    if("${RUST_TARGET}" STREQUAL "")
45        message(
46            FATAL_ERROR
47                "TARGET must be set for RustAddLibrary. Valid options can be found in: ${target_path}"
48        )
49    endif()
50    string(FIND "${RUST_TARGET}" ".json" pos)
51    if(NOT ${pos} EQUAL -1)
52        message(FATAL_ERROR "${RUST_TARGET} cannot contain .json")
53    endif()
54
55    find_program(XARGO_TOOL xargo)
56    if("${XARGO_TOOL}" STREQUAL "XARGO_TOOL-NOTFOUND")
57        message(FATAL_ERROR "Could not find tool xargo. Install with `cargo install xargo` \
58    or see https://github.com/japaric/xargo")
59    endif()
60
61    add_custom_target(
62        ${libmain}_custom
63        BYPRODUCTS
64        ${RUST_BUILD_DIR}/${RUST_LIB_FILENAME}
65        ${USES_TERMINAL_DEBUG}
66        DEPENDS ${RUST_DEPENDS}
67        WORKING_DIRECTORY ${RUST_SOURCE_DIR}
68        COMMAND
69            ${CMAKE_COMMAND} -E env RUST_TARGET_PATH=${target_path} ${XARGO_TOOL} build
70            --target ${RUST_TARGET}
71            --target-dir ${RUST_BUILD_DIR} -Z unstable-options
72            --out-dir ${RUST_BUILD_DIR}
73    )
74
75    add_library(${lib_name} STATIC IMPORTED GLOBAL)
76    set_property(
77        TARGET ${lib_name}
78        PROPERTY IMPORTED_LOCATION "${RUST_BUILD_DIR}/${RUST_LIB_FILENAME}"
79    )
80    add_dependencies(${lib_name} ${libmain}_custom)
81endfunction()
82