Only rerun bindgen when its dependencies change This took a bit of wrangling to get the depfiles working, but I eventually figured it out. ninja -d explain is very useful. Fixed: 597 Change-Id: I909a4c9418e9dc954e3d328da8f3a825e62544e4 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/59005 Reviewed-by: Bob Beck <bbe@google.com> Auto-Submit: David Benjamin <davidben@google.com> Commit-Queue: Bob Beck <bbe@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt index a1fb153..aac5f0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -17,6 +17,7 @@ include(sources.cmake) include(cmake/go.cmake) +include(cmake/paths.cmake) include(cmake/perlasm.cmake) enable_language(C)
diff --git a/cmake/go.cmake b/cmake/go.cmake index 61a01f5..966ad32 100644 --- a/cmake/go.cmake +++ b/cmake/go.cmake
@@ -34,10 +34,7 @@ else() # Ninja expects the target in the depfile to match the output. This is a # relative path from the build directory. - string(LENGTH "${CMAKE_BINARY_DIR}" root_dir_length) - math(EXPR root_dir_length "${root_dir_length} + 1") - string(SUBSTRING "${CMAKE_CURRENT_BINARY_DIR}" ${root_dir_length} -1 target) - set(target "${target}/${dest}") + binary_dir_relative_path(${dest} target) set(depfile "${CMAKE_CURRENT_BINARY_DIR}/${dest}.d") add_custom_command(OUTPUT ${dest}
diff --git a/cmake/paths.cmake b/cmake/paths.cmake new file mode 100644 index 0000000..43ebc40 --- /dev/null +++ b/cmake/paths.cmake
@@ -0,0 +1,11 @@ +# binary_dir_relative_path sets outvar to +# ${CMAKE_CURRENT_BINARY_DIR}/${cur_bin_dir_relative}, but expressed relative to +# ${CMAKE_BINARY_DIR}. +# +# TODO(davidben): When we require CMake 3.20 or later, this can be replaced with +# the built-in cmake_path(RELATIVE_PATH) function. +function(binary_dir_relative_path cur_bin_dir_relative outvar) + string(LENGTH "${CMAKE_BINARY_DIR}/" root_dir_length) + string(SUBSTRING "${CMAKE_CURRENT_BINARY_DIR}/${cur_bin_dir_relative}" ${root_dir_length} -1 result) + set(${outvar} ${result} PARENT_SCOPE) +endfunction()
diff --git a/rust/bssl-sys/CMakeLists.txt b/rust/bssl-sys/CMakeLists.txt index c11510b..5e5f446 100644 --- a/rust/bssl-sys/CMakeLists.txt +++ b/rust/bssl-sys/CMakeLists.txt
@@ -2,48 +2,51 @@ add_library(rust_wrapper STATIC rust_wrapper.c) target_link_libraries(rust_wrapper crypto) +# Generate architecture-specific wrappers. bindgen must be called from +# ${CMAKE_BINARY_DIR}, with the output path as a relative path. bindgen writes +# the depfile using the same syntax as the command-line argument, and ninja +# requires a path relative to the top-level build directory. +set(wrapper src/wrapper_${RUST_BINDINGS}.rs) +binary_dir_relative_path(${wrapper} wrapper_relative) +binary_dir_relative_path(${wrapper}.d depfile_relative) -# Generate architecture-specific wrappers. -set(WRAPPER_TARGET ${CMAKE_BINARY_DIR}/rust/bssl-sys/src/wrapper_${RUST_BINDINGS}.rs) -set(COMMAND ${BINDGEN_EXECUTABLE} wrapper.h - -o ${WRAPPER_TARGET} - --no-derive-default - --enable-function-attribute-detection - --use-core - --default-macro-constant-type=signed - --rustified-enum=point_conversion_form_t - # These regexes need to accept both / and \ to handle Windows file - # path differences, due a bindgen issue. See - # https://crbug.com/boringssl/595. Ideally, we would write [/\\], - # but there are many layers of escaping here. First, CMake - # interprets backslashes. Then CMake generates a Ninja or Make file. - # That, in turn, launches passes inputs to the shell on POSIX, and - # does something else on Windows. - # - # It is unlikely that every layer here has sufficiently well-defined - # escaping and correctly handled the next layer's escaping. On top - # of that, we'd likely need to detect Windows vs POSIX hosts and - # change the input. Instead, just use [[:punct:]] which is more - # permissive than necessary, but we only need to exclude unwanted - # libc heaaders. - # - # If bindgen ever supports some file-based config (see - # https://github.com/rust-lang/rust-bindgen/issues/2508), we can - # switch to that. - --allowlist-file=".*[[:punct:]]include[[:punct:]]openssl[[:punct:]].*\\.h" - --allowlist-file=".*[[:punct:]]rust_wrapper\\.h" - -- # these are LLVM arg passthroughs - -I../../include - # https://doc.rust-lang.org/nightly/rustc/platform-support.html - --target=${RUST_BINDINGS}) - -add_custom_target( - bindgen_rust_${RUST_BINDINGS} - ALL - ${COMMAND} - BYPRODUCTS ${WRAPPER_TARGET} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +add_custom_command( + OUTPUT ${wrapper} + COMMAND ${BINDGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/wrapper.h + -o ${wrapper_relative} + --depfile=${depfile_relative} + --no-derive-default + --enable-function-attribute-detection + --use-core + --default-macro-constant-type=signed + --rustified-enum=point_conversion_form_t + # These regexes need to accept both / and \ to handle Windows file + # path differences, due a bindgen issue. See + # https://crbug.com/boringssl/595. Ideally, we would write [/\\], but + # there are many layers of escaping here. First, CMake interprets + # backslashes. Then CMake generates a Ninja or Make file. That, in + # turn, uses the shell on POSIX, and does something else on Windows. + # + # It is unlikely that every layer here has sufficiently well-defined + # escaping and correctly handled the next layer's escaping. On top of + # that, we'd likely need to detect Windows vs POSIX hosts and change + # the input. Instead, just use [[:punct:]] which is more permissive + # than necessary, but we only need to exclude unwanted libc headers. + # + # If bindgen ever supports some file-based config (see + # https://github.com/rust-lang/rust-bindgen/issues/2508), we can + # switch to that. + --allowlist-file=".*[[:punct:]]include[[:punct:]]openssl[[:punct:]].*\\.h" + --allowlist-file=".*[[:punct:]]rust_wrapper\\.h" + -- # these are LLVM arg passthroughs + -I${PROJECT_SOURCE_DIR}/include + # https://doc.rust-lang.org/nightly/rustc/platform-support.html + --target=${RUST_BINDINGS} + DEPENDS wrapper.h + DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/${wrapper}.d + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) +add_custom_target(bssl_sys ALL DEPENDS ${wrapper}) # move files into build directory configure_file("src/lib.rs" "src/lib.rs")