Integrate cbindgen via build.rs

pull/419/head
Scott Hutton 4 years ago committed by Micah Snyder
parent e8d7b2f236
commit 278ba2923e
  1. 3
      .gitignore
  2. 16
      CMakeLists.txt
  3. 2
      CMakeOptions.cmake
  4. 64
      cmake/FindRust.cmake
  5. 3
      libclamav_rust/Cargo.toml
  6. 31
      libclamav_rust/build.rs
  7. 17
      libclamav_rust/clamav_rust.h

3
.gitignore vendored

@ -228,6 +228,9 @@ libclamav/c++/llvm/tools/llvmc/plugins/Base/Base.td
debug/
target/
# Generated by libclamav_rust/build.rs in IDEs
libclamav_rust/clamav_rust.h
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

@ -113,18 +113,12 @@ include(CMakeOptions.cmake)
# Find Build Tools
#
if(MAINTAINER_MODE)
# cbindgen required to update C headers for Rust libraries.
set(cbindgen_REQUIRED 1)
set(CBINDGEN ON)
# Bison, Flex required to build Yara module for libclamav.
find_package(BISON REQUIRED)
find_package(FLEX REQUIRED)
# TODO: Gperf required to generate JS-normalization code.
# find_package(GPERF REQUIRED)
else()
set(CBINDGEN OFF)
endif()
find_package(Rust REQUIRED)
@ -962,6 +956,12 @@ else()
COMPONENT libraries)
endif()
# include CTest to enable testing before we add any subdirectories which may
# add additional tests (like with `add_rust_test()`)
if(ENABLE_TESTS)
include(CTest)
endif()
#
# ClamAV Build targets!
#
@ -987,8 +987,8 @@ if(WIN32)
add_subdirectory( win32/compat )
endif()
add_subdirectory( libclamav_rust )
add_subdirectory( libclamav )
add_subdirectory( libclamav_rust )
if(NOT ENABLE_LIBCLAMAV_ONLY)
add_subdirectory( common )
@ -1035,7 +1035,6 @@ if(ENABLE_EXAMPLES)
add_subdirectory( examples )
endif()
include(CTest)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
if(ENABLE_TESTS)
add_subdirectory( unit_tests )
@ -1097,7 +1096,6 @@ ${b} Maintainer Mode: ${e}${MAINTAINER_MODE}")
if(MAINTAINER_MODE)
message("\
${R} Maintainer Mode Tools: ${e}
${y} cbindgen: ${e}${cbindgen_EXECUTABLE} (${cbindgen_VERSION})
${y} bison: ${e}${BISON_EXECUTABLE} (${BISON_VERSION})
${y} flex: ${e}${FLEX_EXECUTABLE} (${FLEX_VERSION})")
endif()

@ -35,7 +35,7 @@ option(OPTIMIZE
ON)
option(MAINTAINER_MODE
"Update generated sources. Requires flex, bison, cbindgen."
"Update generated sources. Requires flex, bison."
${MAINTAINER_MODE_DEFAULT})
option(ENABLE_WERROR

@ -23,11 +23,6 @@
# - rustdoc
# - rustfmt
# - bindgen
# - cbindgen
#
# Note that `cbindgen` is presently 3rd-party, and is not included with the
# standard Rust installation. `bindgen` is a part of the rust toolchain, but
# might need to be installed separately.
#
# Callers can make any program mandatory by setting `<program>_REQUIRED` before
# the call to `find_package(Rust)`
@ -35,7 +30,6 @@
# Eg:
#
# if(MAINTAINER_MODE)
# set(cbindgen_REQUIRED 1)
# set(bindgen_REQUIRED 1)
# endif()
# find_package(Rust REQUIRED)
@ -152,47 +146,24 @@ function(add_rust_library)
list(APPEND MY_CARGO_ARGS "--target-dir" ${CMAKE_CURRENT_BINARY_DIR})
list(JOIN MY_CARGO_ARGS " " MY_CARGO_ARGS_STRING)
# Build the library and generate the c-binding, if `cbindgen` is required.
if(${cbindgen_REQUIRED})
if ("${CMAKE_OSX_ARCHITECTURES}" MATCHES "^arm64;x86_64$")
add_custom_command(
OUTPUT "${OUTPUT}"
COMMAND ${CMAKE_COMMAND} -E env "CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR}" ${cargo_EXECUTABLE} ARGS ${MY_CARGO_ARGS} --target=x86_64-apple-darwin
COMMAND ${CMAKE_COMMAND} -E env "CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR}" ${cargo_EXECUTABLE} ARGS ${MY_CARGO_ARGS} --target=aarch64-apple-darwin
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/${LIB_TARGET}/${LIB_BUILD_TYPE}"
COMMAND lipo ARGS -create ${CMAKE_CURRENT_BINARY_DIR}/x86_64-apple-darwin/${LIB_BUILD_TYPE}/lib${ARGS_TARGET}.a ${CMAKE_CURRENT_BINARY_DIR}/aarch64-apple-darwin/${LIB_BUILD_TYPE}/lib${ARGS_TARGET}.a -output "${OUTPUT}"
COMMAND ${cbindgen_EXECUTABLE} --lang c -o ${ARGS_WORKING_DIRECTORY}/${ARGS_TARGET}.h ${ARGS_WORKING_DIRECTORY}
WORKING_DIRECTORY "${ARGS_WORKING_DIRECTORY}"
DEPENDS ${LIB_SOURCES}
COMMENT "Building ${ARGS_TARGET} in ${ARGS_WORKING_DIRECTORY} with: ${cargo_EXECUTABLE} ${MY_CARGO_ARGS_STRING}")
else()
add_custom_command(
OUTPUT "${OUTPUT}"
COMMAND ${CMAKE_COMMAND} -E env "CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR}" ${cargo_EXECUTABLE} ARGS ${MY_CARGO_ARGS}
COMMAND ${cbindgen_EXECUTABLE} --lang c -o ${ARGS_WORKING_DIRECTORY}/${ARGS_TARGET}.h ${ARGS_WORKING_DIRECTORY}
WORKING_DIRECTORY "${ARGS_WORKING_DIRECTORY}"
DEPENDS ${LIB_SOURCES}
COMMENT "Building ${ARGS_TARGET} in ${ARGS_WORKING_DIRECTORY} with: ${cargo_EXECUTABLE} ${MY_CARGO_ARGS_STRING}")
endif()
# Build the library and generate the c-binding
if ("${CMAKE_OSX_ARCHITECTURES}" MATCHES "^arm64;x86_64$")
add_custom_command(
OUTPUT "${OUTPUT}"
COMMAND ${CMAKE_COMMAND} -E env "CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR}" ${cargo_EXECUTABLE} ARGS ${MY_CARGO_ARGS} --target=x86_64-apple-darwin
COMMAND ${CMAKE_COMMAND} -E env "CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR}" ${cargo_EXECUTABLE} ARGS ${MY_CARGO_ARGS} --target=aarch64-apple-darwin
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/${LIB_TARGET}/${LIB_BUILD_TYPE}"
COMMAND lipo ARGS -create ${CMAKE_CURRENT_BINARY_DIR}/x86_64-apple-darwin/${LIB_BUILD_TYPE}/lib${ARGS_TARGET}.a ${CMAKE_CURRENT_BINARY_DIR}/aarch64-apple-darwin/${LIB_BUILD_TYPE}/lib${ARGS_TARGET}.a -output "${OUTPUT}"
WORKING_DIRECTORY "${ARGS_WORKING_DIRECTORY}"
DEPENDS ${LIB_SOURCES}
COMMENT "Building ${ARGS_TARGET} in ${ARGS_WORKING_DIRECTORY} with: ${cargo_EXECUTABLE} ${MY_CARGO_ARGS_STRING}")
else()
if ("${CMAKE_OSX_ARCHITECTURES}" MATCHES "^arm64;x86_64$")
add_custom_command(
OUTPUT "${OUTPUT}"
COMMAND ${CMAKE_COMMAND} -E env "CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR}" ${cargo_EXECUTABLE} ARGS ${MY_CARGO_ARGS} --target=x86_64-apple-darwin
COMMAND ${CMAKE_COMMAND} -E env "CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR}" ${cargo_EXECUTABLE} ARGS ${MY_CARGO_ARGS} --target=aarch64-apple-darwin
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/${LIB_TARGET}/${LIB_BUILD_TYPE}"
COMMAND lipo ARGS -create ${CMAKE_CURRENT_BINARY_DIR}/x86_64-apple-darwin/${LIB_BUILD_TYPE}/lib${ARGS_TARGET}.a ${CMAKE_CURRENT_BINARY_DIR}/aarch64-apple-darwin/${LIB_BUILD_TYPE}/lib${ARGS_TARGET}.a -output "${OUTPUT}"
WORKING_DIRECTORY "${ARGS_WORKING_DIRECTORY}"
DEPENDS ${LIB_SOURCES}
COMMENT "Building ${ARGS_TARGET} in ${ARGS_WORKING_DIRECTORY} with: ${cargo_EXECUTABLE} ${MY_CARGO_ARGS_STRING}")
else()
add_custom_command(
OUTPUT "${OUTPUT}"
COMMAND ${CMAKE_COMMAND} -E env "CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR}" ${cargo_EXECUTABLE} ARGS ${MY_CARGO_ARGS}
WORKING_DIRECTORY "${ARGS_WORKING_DIRECTORY}"
DEPENDS ${LIB_SOURCES}
COMMENT "Building ${ARGS_TARGET} in ${ARGS_WORKING_DIRECTORY} with: ${cargo_EXECUTABLE} ${MY_CARGO_ARGS_STRING}")
endif()
add_custom_command(
OUTPUT "${OUTPUT}"
COMMAND ${CMAKE_COMMAND} -E env "CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR}" ${cargo_EXECUTABLE} ARGS ${MY_CARGO_ARGS}
WORKING_DIRECTORY "${ARGS_WORKING_DIRECTORY}"
DEPENDS ${LIB_SOURCES}
COMMENT "Building ${ARGS_TARGET} in ${ARGS_WORKING_DIRECTORY} with: ${cargo_EXECUTABLE} ${MY_CARGO_ARGS_STRING}")
endif()
# Create a target from the build output
@ -255,7 +226,6 @@ find_rust_program(rust-lldb)
find_rust_program(rustdoc)
find_rust_program(rustfmt)
find_rust_program(bindgen)
find_rust_program(cbindgen)
# Determine the native libs required to link w/ rust static libs
# message(STATUS "Detecting native static libs for rust: ${rustc_EXECUTABLE} --crate-type staticlib --print=native-static-libs /dev/null")

@ -13,3 +13,6 @@ log = {version = "*", features = ["std"]}
[lib]
crate-type = ["staticlib"]
name = "clamav_rust"
[build-dependencies]
cbindgen = "0.20.0"

@ -27,13 +27,32 @@ const LIB_LINK_WINDOWS: [&str; 4] = ["wsock32", "ws2_32", "Shell32", "User32"];
// Windows library names that must have the leading `lib` trimmed (if encountered)
const WINDOWS_TRIM_LOCAL_LIB: [&str; 2] = ["libclamav", "libclammspack"];
fn main() {
println!("cargo:rerun-if-env-changed=LIBCLAMAV");
const C_HEADER_OUTPUT: &str = "clamav_rust.h";
fn main() -> Result<(), &'static str> {
detect_clamav_build()?;
execute_cbindgen()?;
Ok(())
}
let found_libclamav = search_and_link_lib("LIBCLAMAV").unwrap();
dbg!(&found_libclamav);
fn execute_cbindgen() -> Result<(), &'static str> {
let crate_dir = env::var("CARGO_MANIFEST_DIR").or(Err("CARGO_MANIFEST_DIR not specified"))?;
let build_dir = PathBuf::from(env::var("BUILD").unwrap_or(".".into()));
let outfile_path = build_dir.join(C_HEADER_OUTPUT);
if found_libclamav {
// Useful for build diagnostics
eprintln!("cbindgen outputting {:?}", &outfile_path);
cbindgen::generate(crate_dir)
.expect("Unable to generate bindings")
.write_to_file(&outfile_path);
Ok(())
}
fn detect_clamav_build() -> Result<(), &'static str> {
println!("cargo:rerun-if-env-changed=LIBCLAMAV");
if search_and_link_lib("LIBCLAMAV")? {
// Need to link with libclamav dependencies
for var in &LIB_ENV_LINK {
let _ = search_and_link_lib(var);
@ -48,6 +67,8 @@ fn main() {
}
}
}
Ok(())
}
//

@ -1,17 +0,0 @@
/* Copyright (C) 2021 Cisco Systems, Inc. and/or its affiliates. All rights reserved. */
#ifndef __CLAMAV_RUST_H
#define __CLAMAV_RUST_H
/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "libclamav/others.h"
bool clrs_log_init(void);
#endif /* __CLAMAV_RUST_H */
Loading…
Cancel
Save