| ... | ... |
@@ -79,22 +79,11 @@ endif() |
| 79 | 79 |
find_package(PkgConfig QUIET) |
| 80 | 80 |
|
| 81 | 81 |
# |
| 82 |
-# Find Build Tools |
|
| 83 |
-# |
|
| 84 |
- |
|
| 85 |
-if(MAINTAINER_MODE) |
|
| 86 |
- # Bison, Flex required to build Yara module for libclamav. |
|
| 87 |
- find_package(BISON REQUIRED) |
|
| 88 |
- find_package(FLEX REQUIRED) |
|
| 89 |
- # TODO: Gperf required to generate JS-normalization code. |
|
| 90 |
- # find_package(GPERF REQUIRED) |
|
| 91 |
-endif() |
|
| 92 |
- |
|
| 93 |
-# |
|
| 94 | 82 |
# Load Build Options |
| 95 | 83 |
# |
| 96 | 84 |
|
| 97 | 85 |
# CMake Option default values: |
| 86 |
+set(MAINTAINER_MODE_DEFAULT OFF) |
|
| 98 | 87 |
set(ENABLE_APP_DEFAULT ON) |
| 99 | 88 |
if(WIN32 OR APPLE) |
| 100 | 89 |
set(ENABLE_MILTER_DEFAULT OFF) |
| ... | ... |
@@ -120,6 +109,25 @@ set(ENABLE_SYSTEMD_DEFAULT ON) |
| 120 | 120 |
# See CMakeOptions.cmake for additional options. |
| 121 | 121 |
include(CMakeOptions.cmake) |
| 122 | 122 |
|
| 123 |
+# |
|
| 124 |
+# Find Build Tools |
|
| 125 |
+# |
|
| 126 |
+if(MAINTAINER_MODE) |
|
| 127 |
+ # cbindgen required to update C headers for Rust libraries. |
|
| 128 |
+ set(cbindgen_REQUIRED 1) |
|
| 129 |
+ set(CBINDGEN ON) |
|
| 130 |
+ |
|
| 131 |
+ # Bison, Flex required to build Yara module for libclamav. |
|
| 132 |
+ find_package(BISON REQUIRED) |
|
| 133 |
+ find_package(FLEX REQUIRED) |
|
| 134 |
+ |
|
| 135 |
+ # TODO: Gperf required to generate JS-normalization code. |
|
| 136 |
+ # find_package(GPERF REQUIRED) |
|
| 137 |
+else() |
|
| 138 |
+ set(CBINDGEN OFF) |
|
| 139 |
+endif() |
|
| 140 |
+find_package(Rust REQUIRED) |
|
| 141 |
+ |
|
| 123 | 142 |
if(ENABLE_FUZZ) |
| 124 | 143 |
# We'd like the fuzz targets to be statically linked |
| 125 | 144 |
set(ENABLE_STATIC_LIB ON) |
| ... | ... |
@@ -1059,6 +1067,7 @@ ${c} Compiler: ${e}
|
| 1059 | 1059 |
${b} Build type: ${e}${CMAKE_BUILD_TYPE}
|
| 1060 | 1060 |
${b} C compiler: ${e}${CMAKE_C_COMPILER}
|
| 1061 | 1061 |
${b} C++ compiler: ${e}${CMAKE_CXX_COMPILER}
|
| 1062 |
+${b} Rust toolchain: ${e}${cargo_EXECUTABLE} (${cargo_VERSION})
|
|
| 1062 | 1063 |
${b} CFLAGS: ${e}${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS}
|
| 1063 | 1064 |
${b} CXXFLAGS: ${e}${CMAKE_CXX_FLAGS_${_build_type}} ${CMAKE_CXX_FLAGS}
|
| 1064 | 1065 |
${b} WARNCFLAGS: ${e}${WARNCFLAGS}")
|
| ... | ... |
@@ -1079,7 +1088,15 @@ ${b} Enable UnRAR: ${e}${ENABLE_UNRAR}
|
| 1079 | 1079 |
${b} Examples: ${e}${ENABLE_EXAMPLES}
|
| 1080 | 1080 |
${b} Tests: ${e}${ENABLE_TESTS}
|
| 1081 | 1081 |
${b} Build man pages: ${e}${ENABLE_MAN_PAGES}
|
| 1082 |
-${b} Build doxygen HTML: ${e}${ENABLE_DOXYGEN}")
|
|
| 1082 |
+${b} Build doxygen HTML: ${e}${ENABLE_DOXYGEN}
|
|
| 1083 |
+${b} Maintainer Mode: ${e}${MAINTAINER_MODE}")
|
|
| 1084 |
+if(MAINTAINER_MODE) |
|
| 1085 |
+message("\
|
|
| 1086 |
+${R} Maintainer Mode Tools: ${e}
|
|
| 1087 |
+${y} cbindgen: ${e}${cbindgen_EXECUTABLE} (${cbindgen_VERSION})
|
|
| 1088 |
+${y} bison: ${e}${BISON_EXECUTABLE} (${BISON_VERSION})
|
|
| 1089 |
+${y} flex: ${e}${FLEX_EXECUTABLE} (${FLEX_VERSION})")
|
|
| 1090 |
+endif() |
|
| 1083 | 1091 |
if(NOT WIN32) |
| 1084 | 1092 |
message("\
|
| 1085 | 1093 |
${c} Build Extras: ${e}")
|
| ... | ... |
@@ -34,6 +34,10 @@ option(OPTIMIZE |
| 34 | 34 |
"Allow compiler optimizations. Set to OFF to disable (i.e. to set -O0)." |
| 35 | 35 |
ON) |
| 36 | 36 |
|
| 37 |
+option(MAINTAINER_MODE |
|
| 38 |
+ "Update generated sources. Requires flex, bison, cbindgen." |
|
| 39 |
+ ${MAINTAINER_MODE_DEFAULT})
|
|
| 40 |
+ |
|
| 37 | 41 |
option(ENABLE_WERROR |
| 38 | 42 |
"Compile time warnings will cause build failures.") |
| 39 | 43 |
|
| 40 | 44 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,255 @@ |
| 0 |
+# Find the Rust toolchain and add the `add_rust_library()` API to build Rust |
|
| 1 |
+# libraries. |
|
| 2 |
+# |
|
| 3 |
+# Copyright (C) 2021 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
|
| 4 |
+# |
|
| 5 |
+# Author: Micah Snyder |
|
| 6 |
+# To see this in a sample project, visit: https://github.com/micahsnyder/cmake-rust-demo |
|
| 7 |
+# |
|
| 8 |
+# Code to set the Cargo arguments was lifted from: |
|
| 9 |
+# https://github.com/Devolutions/CMakeRust |
|
| 10 |
+# |
|
| 11 |
+# This Module defines the following variables: |
|
| 12 |
+# - <program>_FOUND - True if the program was found |
|
| 13 |
+# - <program>_EXECUTABLE - path of the program |
|
| 14 |
+# - <program>_VERSION - version number of the program |
|
| 15 |
+# |
|
| 16 |
+# ... for the following Rust toolchain programs: |
|
| 17 |
+# - cargo |
|
| 18 |
+# - rustc |
|
| 19 |
+# - rustup |
|
| 20 |
+# - rust-gdb |
|
| 21 |
+# - rust-lldb |
|
| 22 |
+# - rustdoc |
|
| 23 |
+# - rustfmt |
|
| 24 |
+# - bindgen |
|
| 25 |
+# - cbindgen |
|
| 26 |
+# |
|
| 27 |
+# Note that `cbindgen` is presently 3rd-party, and is not included with the |
|
| 28 |
+# standard Rust installation. `bindgen` is a part of the rust toolchain, but |
|
| 29 |
+# might need to be installed separately. |
|
| 30 |
+# |
|
| 31 |
+# Callers can make any program mandatory by setting `<program>_REQUIRED` before |
|
| 32 |
+# the call to `find_package(Rust)` |
|
| 33 |
+# |
|
| 34 |
+# Eg: |
|
| 35 |
+# |
|
| 36 |
+# if(MAINTAINER_MODE) |
|
| 37 |
+# set(cbindgen_REQUIRED 1) |
|
| 38 |
+# set(bindgen_REQUIRED 1) |
|
| 39 |
+# endif() |
|
| 40 |
+# find_package(Rust REQUIRED) |
|
| 41 |
+# |
|
| 42 |
+# This module also provides an `add_rust_library()` function which allows a |
|
| 43 |
+# caller to create a Rust static library target which you can link to with |
|
| 44 |
+# `target_link_libraries()`. |
|
| 45 |
+# |
|
| 46 |
+# Your Rust static library target will itself depend on the native static libs |
|
| 47 |
+# you get from `rustc --crate-type staticlib --print=native-static-libs /dev/null` |
|
| 48 |
+# |
|
| 49 |
+# Example `add_rust_library()` usage: |
|
| 50 |
+# |
|
| 51 |
+# add_rust_library(TARGET yourlib WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
|
| 52 |
+# add_library(YourProject::yourlib ALIAS yourlib) |
|
| 53 |
+# |
|
| 54 |
+# add_executable(yourexe) |
|
| 55 |
+# target_link_libraries(yourexe YourProject::yourlib) |
|
| 56 |
+# |
|
| 57 |
+ |
|
| 58 |
+if(NOT DEFINED CARGO_HOME) |
|
| 59 |
+ if(WIN32) |
|
| 60 |
+ set(CARGO_HOME "$ENV{USERPROFILE}/.cargo")
|
|
| 61 |
+ else() |
|
| 62 |
+ set(CARGO_HOME "$ENV{HOME}/.cargo")
|
|
| 63 |
+ endif() |
|
| 64 |
+endif() |
|
| 65 |
+ |
|
| 66 |
+include(FindPackageHandleStandardArgs) |
|
| 67 |
+ |
|
| 68 |
+function(find_rust_program RUST_PROGRAM) |
|
| 69 |
+ find_program(${RUST_PROGRAM}_EXECUTABLE ${RUST_PROGRAM}
|
|
| 70 |
+ HINTS "${CARGO_HOME}"
|
|
| 71 |
+ PATH_SUFFIXES "bin" |
|
| 72 |
+ ) |
|
| 73 |
+ |
|
| 74 |
+ if(${RUST_PROGRAM}_EXECUTABLE)
|
|
| 75 |
+ execute_process(COMMAND "${${RUST_PROGRAM}_EXECUTABLE}" --version
|
|
| 76 |
+ OUTPUT_VARIABLE ${RUST_PROGRAM}_VERSION_OUTPUT
|
|
| 77 |
+ ERROR_VARIABLE ${RUST_PROGRAM}_VERSION_ERROR
|
|
| 78 |
+ RESULT_VARIABLE ${RUST_PROGRAM}_VERSION_RESULT
|
|
| 79 |
+ ) |
|
| 80 |
+ if(NOT ${${RUST_PROGRAM}_VERSION_RESULT} EQUAL 0)
|
|
| 81 |
+ message(STATUS "Rust tool `${RUST_PROGRAM}` not found: Failed to determine version.")
|
|
| 82 |
+ unset(${RUST_PROGRAM}_EXECUTABLE)
|
|
| 83 |
+ else() |
|
| 84 |
+ string(REGEX |
|
| 85 |
+ MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?(-nightly)?" |
|
| 86 |
+ ${RUST_PROGRAM}_VERSION "${${RUST_PROGRAM}_VERSION_OUTPUT}"
|
|
| 87 |
+ ) |
|
| 88 |
+ set(${RUST_PROGRAM}_VERSION "${${RUST_PROGRAM}_VERSION}" PARENT_SCOPE)
|
|
| 89 |
+ message(STATUS "Rust tool `${RUST_PROGRAM}` found: ${${RUST_PROGRAM}_EXECUTABLE}, ${${RUST_PROGRAM}_VERSION}")
|
|
| 90 |
+ endif() |
|
| 91 |
+ |
|
| 92 |
+ mark_as_advanced(${RUST_PROGRAM}_EXECUTABLE ${RUST_PROGRAM}_VERSION)
|
|
| 93 |
+ else() |
|
| 94 |
+ if(${${RUST_PROGRAM}_REQUIRED})
|
|
| 95 |
+ message(FATAL_ERROR "Rust tool `${RUST_PROGRAM}` not found.")
|
|
| 96 |
+ else() |
|
| 97 |
+ message(STATUS "Rust tool `${RUST_PROGRAM}` not found.")
|
|
| 98 |
+ endif() |
|
| 99 |
+ endif() |
|
| 100 |
+endfunction() |
|
| 101 |
+ |
|
| 102 |
+function(add_rust_library) |
|
| 103 |
+ set(options) |
|
| 104 |
+ set(oneValueArgs TARGET WORKING_DIRECTORY) |
|
| 105 |
+ cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
|
| 106 |
+ |
|
| 107 |
+ if(WIN32) |
|
| 108 |
+ set(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${LIB_TARGET}/${LIB_BUILD_TYPE}/${ARGS_TARGET}.lib")
|
|
| 109 |
+ else() |
|
| 110 |
+ set(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${LIB_TARGET}/${LIB_BUILD_TYPE}/lib${ARGS_TARGET}.a")
|
|
| 111 |
+ endif() |
|
| 112 |
+ |
|
| 113 |
+ file(GLOB_RECURSE LIB_SOURCES "${ARGS_WORKING_DIRECTORY}/*.rs")
|
|
| 114 |
+ |
|
| 115 |
+ set(MY_CARGO_ARGS ${CARGO_ARGS})
|
|
| 116 |
+ list(APPEND MY_CARGO_ARGS "--target-dir" ${CMAKE_CURRENT_BINARY_DIR})
|
|
| 117 |
+ list(JOIN MY_CARGO_ARGS " " MY_CARGO_ARGS_STRING) |
|
| 118 |
+ |
|
| 119 |
+ # Build the library and generate the c-binding, if `cbindgen` is required. |
|
| 120 |
+ if(${cbindgen_REQUIRED})
|
|
| 121 |
+ add_custom_command( |
|
| 122 |
+ OUTPUT "${OUTPUT}"
|
|
| 123 |
+ COMMAND ${CMAKE_COMMAND} -E env "CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR}" ${cargo_EXECUTABLE} ARGS ${MY_CARGO_ARGS}
|
|
| 124 |
+ COMMAND ${cbindgen_EXECUTABLE} --lang c -o ${ARGS_WORKING_DIRECTORY}/${ARGS_TARGET}.h ${ARGS_WORKING_DIRECTORY}
|
|
| 125 |
+ WORKING_DIRECTORY "${ARGS_WORKING_DIRECTORY}"
|
|
| 126 |
+ DEPENDS ${LIB_SOURCES}
|
|
| 127 |
+ COMMENT "Building ${ARGS_TARGET} in ${ARGS_WORKING_DIRECTORY} with:\n\t ${cargo_EXECUTABLE} ${MY_CARGO_ARGS_STRING}")
|
|
| 128 |
+ else() |
|
| 129 |
+ add_custom_command( |
|
| 130 |
+ OUTPUT "${OUTPUT}"
|
|
| 131 |
+ COMMAND ${CMAKE_COMMAND} -E env "CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR}" ${cargo_EXECUTABLE} ARGS ${MY_CARGO_ARGS}
|
|
| 132 |
+ WORKING_DIRECTORY "${ARGS_WORKING_DIRECTORY}"
|
|
| 133 |
+ DEPENDS ${LIB_SOURCES}
|
|
| 134 |
+ COMMENT "Building ${ARGS_TARGET} in ${ARGS_WORKING_DIRECTORY} with:\n\t ${cargo_EXECUTABLE} ${MY_CARGO_ARGS_STRING}")
|
|
| 135 |
+ endif() |
|
| 136 |
+ |
|
| 137 |
+ # Create a target from the build output |
|
| 138 |
+ add_custom_target(${ARGS_TARGET}_target
|
|
| 139 |
+ DEPENDS ${OUTPUT})
|
|
| 140 |
+ |
|
| 141 |
+ # Create a static imported library target from library target |
|
| 142 |
+ add_library(${ARGS_TARGET} STATIC IMPORTED GLOBAL)
|
|
| 143 |
+ add_dependencies(${ARGS_TARGET} ${ARGS_TARGET}_target)
|
|
| 144 |
+ target_link_libraries(${ARGS_TARGET} INTERFACE ${RUST_NATIVE_STATIC_LIBS})
|
|
| 145 |
+ |
|
| 146 |
+ # Specify where the library is and where to find the headers |
|
| 147 |
+ set_target_properties(${ARGS_TARGET}
|
|
| 148 |
+ PROPERTIES |
|
| 149 |
+ IMPORTED_LOCATION "${OUTPUT}"
|
|
| 150 |
+ INTERFACE_INCLUDE_DIRECTORIES "${ARGS_WORKING_DIRECTORY}"
|
|
| 151 |
+ ) |
|
| 152 |
+endfunction() |
|
| 153 |
+ |
|
| 154 |
+function(add_rust_test) |
|
| 155 |
+ set(options) |
|
| 156 |
+ set(oneValueArgs NAME WORKING_DIRECTORY) |
|
| 157 |
+ cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
|
| 158 |
+ |
|
| 159 |
+ add_test( |
|
| 160 |
+ NAME test-${ARGS_NAME}
|
|
| 161 |
+ COMMAND ${CMAKE_COMMAND} -E env "CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR}" ${cargo_EXECUTABLE} test -vv --color always
|
|
| 162 |
+ WORKING_DIRECTORY ${ARGS_WORKING_DIRECTORY}
|
|
| 163 |
+ ) |
|
| 164 |
+endfunction() |
|
| 165 |
+ |
|
| 166 |
+# |
|
| 167 |
+# Cargo is the primary tool for using the Rust Toolchain to to build static |
|
| 168 |
+# libs that can include other crate dependencies. |
|
| 169 |
+# |
|
| 170 |
+find_rust_program(cargo) |
|
| 171 |
+ |
|
| 172 |
+# These other programs may also be useful... |
|
| 173 |
+find_rust_program(rustc) |
|
| 174 |
+find_rust_program(rustup) |
|
| 175 |
+find_rust_program(rust-gdb) |
|
| 176 |
+find_rust_program(rust-lldb) |
|
| 177 |
+find_rust_program(rustdoc) |
|
| 178 |
+find_rust_program(rustfmt) |
|
| 179 |
+find_rust_program(bindgen) |
|
| 180 |
+find_rust_program(cbindgen) |
|
| 181 |
+ |
|
| 182 |
+# Determine the native libs required to link w/ rust static libs |
|
| 183 |
+# message(STATUS "Detecting native static libs for rust: ${rustc_EXECUTABLE} --crate-type staticlib --print=native-static-libs /dev/null")
|
|
| 184 |
+execute_process( |
|
| 185 |
+ COMMAND ${CMAKE_COMMAND} -E env "CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR}" ${rustc_EXECUTABLE} --crate-type staticlib --print=native-static-libs /dev/null
|
|
| 186 |
+ OUTPUT_VARIABLE RUST_NATIVE_STATIC_LIBS_OUTPUT |
|
| 187 |
+ ERROR_VARIABLE RUST_NATIVE_STATIC_LIBS_ERROR |
|
| 188 |
+ RESULT_VARIABLE RUST_NATIVE_STATIC_LIBS_RESULT |
|
| 189 |
+) |
|
| 190 |
+string(REGEX REPLACE "\r?\n" ";" LINE_LIST "${RUST_NATIVE_STATIC_LIBS_ERROR}")
|
|
| 191 |
+foreach(LINE ${LINE_LIST})
|
|
| 192 |
+ # do the match on each line |
|
| 193 |
+ string(REGEX MATCH "native-static-libs: .*" LINE "${LINE}")
|
|
| 194 |
+ if(NOT LINE) |
|
| 195 |
+ continue() |
|
| 196 |
+ endif() |
|
| 197 |
+ string(REPLACE "native-static-libs: " "" LINE "${LINE}")
|
|
| 198 |
+ string(REGEX REPLACE " " "" LINE "${LINE}")
|
|
| 199 |
+ string(REGEX REPLACE " " ";" LINE "${LINE}")
|
|
| 200 |
+ if(LINE) |
|
| 201 |
+ message(STATUS "Rust's native static libs: ${LINE}")
|
|
| 202 |
+ set(RUST_NATIVE_STATIC_LIBS "${LINE}")
|
|
| 203 |
+ break() |
|
| 204 |
+ endif() |
|
| 205 |
+endforeach() |
|
| 206 |
+ |
|
| 207 |
+if(WIN32) |
|
| 208 |
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8) |
|
| 209 |
+ set(LIB_TARGET "x86_64-pc-windows-msvc") |
|
| 210 |
+ else() |
|
| 211 |
+ set(LIB_TARGET "i686-pc-windows-msvc") |
|
| 212 |
+ endif() |
|
| 213 |
+elseif(ANDROID) |
|
| 214 |
+ if(ANDROID_SYSROOT_ABI STREQUAL "x86") |
|
| 215 |
+ set(LIB_TARGET "i686-linux-android") |
|
| 216 |
+ elseif(ANDROID_SYSROOT_ABI STREQUAL "x86_64") |
|
| 217 |
+ set(LIB_TARGET "x86_64-linux-android") |
|
| 218 |
+ elseif(ANDROID_SYSROOT_ABI STREQUAL "arm") |
|
| 219 |
+ set(LIB_TARGET "arm-linux-androideabi") |
|
| 220 |
+ elseif(ANDROID_SYSROOT_ABI STREQUAL "arm64") |
|
| 221 |
+ set(LIB_TARGET "aarch64-linux-android") |
|
| 222 |
+ endif() |
|
| 223 |
+elseif(IOS) |
|
| 224 |
+ set(LIB_TARGET "universal") |
|
| 225 |
+elseif(CMAKE_SYSTEM_NAME STREQUAL Darwin) |
|
| 226 |
+ set(LIB_TARGET "x86_64-apple-darwin") |
|
| 227 |
+else() |
|
| 228 |
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8) |
|
| 229 |
+ set(LIB_TARGET "x86_64-unknown-linux-gnu") |
|
| 230 |
+ else() |
|
| 231 |
+ set(LIB_TARGET "i686-unknown-linux-gnu") |
|
| 232 |
+ endif() |
|
| 233 |
+endif() |
|
| 234 |
+ |
|
| 235 |
+if(IOS) |
|
| 236 |
+ set(CARGO_ARGS "lipo") |
|
| 237 |
+else() |
|
| 238 |
+ set(CARGO_ARGS "build") |
|
| 239 |
+ list(APPEND CARGO_ARGS "--target" ${LIB_TARGET})
|
|
| 240 |
+endif() |
|
| 241 |
+ |
|
| 242 |
+if(NOT CMAKE_BUILD_TYPE) |
|
| 243 |
+ set(LIB_BUILD_TYPE "debug") |
|
| 244 |
+elseif(${CMAKE_BUILD_TYPE} STREQUAL "Release")
|
|
| 245 |
+ set(LIB_BUILD_TYPE "release") |
|
| 246 |
+ list(APPEND CARGO_ARGS "--release") |
|
| 247 |
+else() |
|
| 248 |
+ set(LIB_BUILD_TYPE "debug") |
|
| 249 |
+endif() |
|
| 250 |
+ |
|
| 251 |
+find_package_handle_standard_args( Rust |
|
| 252 |
+ REQUIRED_VARS cargo_EXECUTABLE |
|
| 253 |
+ VERSION_VAR cargo_VERSION |
|
| 254 |
+) |