From cb46396b677cde80c654c1e89903f1c193d82ca5 Mon Sep 17 00:00:00 2001 From: David Adam Date: Thu, 25 Jan 2024 19:58:50 +0800 Subject: [PATCH] cmake: build executables by driving cargo directly Drops the requirement for Corrosion, as almost none of its extensive features are required. --- CMakeLists.txt | 44 ++++++++++++++++++++++++++++--- cmake/Benchmark.cmake | 3 ++- cmake/Docs.cmake | 4 +-- cmake/Install.cmake | 4 +-- cmake/Rust.cmake | 61 ++++++++++++++++--------------------------- 5 files changed, 69 insertions(+), 47 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 247e69d49..41e1742e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,8 @@ # CMake 3.21 is needed for file(IMPORTED_RUNTIME_ARTIFACTS) cmake_minimum_required(VERSION 3.21) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") + include(cmake/Mac.cmake) project(fish) @@ -73,8 +75,6 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON) # Work around issue where archive-built libs go in the wrong place. set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") - if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) set(FISH_IN_TREE_BUILD TRUE) else() @@ -94,10 +94,46 @@ add_definitions(-DCMAKE_SOURCE_DIR="${REAL_CMAKE_SOURCE_DIR}") # Enable thread-safe errno on Solaris (#5611) add_definitions(-D_REENTRANT) +add_custom_command( + OUTPUT ${rust_target_dir}/${rust_profile}/libfish.rlib + COMMAND ${CMAKE_COMMAND} -E env + ${VARS_FOR_CARGO} + $<$:RUSTFLAGS=-g> + ${Rust_CARGO} ARGS + build --lib + $<$:--release> + --target ${Rust_CARGO_TARGET} + ${CARGO_FLAGS} + ${FEATURES_ARG} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + USES_TERMINAL + # Don't use VERBATIM here, to allow the generator expressions above to expand to nothing rather than an empty string + ) +add_custom_target(libfish DEPENDS ${rust_target_dir}/${rust_profile}/libfish.rlib) + # Define a function to link dependencies. function(FISH_LINK_DEPS_AND_SIGN target) - # Tell Cargo where our build directory is so it can find config.h. - corrosion_set_env_vars(${target} ${VARS_FOR_CARGO}) + add_custom_command( + OUTPUT ${rust_target_dir}/${rust_profile}/${target} + COMMAND ${CMAKE_COMMAND} -E env + ${VARS_FOR_CARGO} + $<$:RUSTFLAGS=-g> + ${Rust_CARGO} ARGS build --bin ${target} + $<$:--release> + --target ${Rust_CARGO_TARGET} + ${CARGO_FLAGS} + ${FEATURES_ARG} + DEPENDS libfish + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + USES_TERMINAL + # Don't use VERBATIM here, to allow the generator expressions above to expand to nothing rather than an empty string + ) + add_custom_target(${target} ALL + COMMAND "${CMAKE_COMMAND}" -E copy + "${rust_target_dir}/${rust_profile}/${target}" + "${CMAKE_CURRENT_BINARY_DIR}" + DEPENDS ${rust_target_dir}/${rust_profile}/${target} + ) codesign_on_mac(${target}) endfunction(FISH_LINK_DEPS_AND_SIGN) diff --git a/cmake/Benchmark.cmake b/cmake/Benchmark.cmake index bb3509199..cb9c6f082 100644 --- a/cmake/Benchmark.cmake +++ b/cmake/Benchmark.cmake @@ -1,6 +1,7 @@ # Support for benchmarking fish. add_custom_target(benchmark - COMMAND ${CMAKE_SOURCE_DIR}/benchmarks/driver.sh $ + COMMAND ${CMAKE_SOURCE_DIR}/benchmarks/driver.sh ${CMAKE_BINARY_DIR}/fish + DEPENDS fish USES_TERMINAL ) diff --git a/cmake/Docs.cmake b/cmake/Docs.cmake index 27e94be22..2a3faf896 100644 --- a/cmake/Docs.cmake +++ b/cmake/Docs.cmake @@ -16,7 +16,7 @@ set(SPHINX_MANPAGE_DIR "${SPHINX_ROOT_DIR}/man") # Prepend the output dir of fish_indent to PATH. add_custom_target(sphinx-docs mkdir -p ${SPHINX_HTML_DIR}/_static/ - COMMAND env PATH="$:$$PATH" + COMMAND env PATH="${CMAKE_BINARY_DIR}:$$PATH" ${SPHINX_EXECUTABLE} -j auto -q -b html @@ -29,7 +29,7 @@ add_custom_target(sphinx-docs # sphinx-manpages needs the fish_indent binary for the version number add_custom_target(sphinx-manpages - env PATH="$:$$PATH" + env PATH="${CMAKE_BINARY_DIR}:$$PATH" ${SPHINX_EXECUTABLE} -j auto -q -b man diff --git a/cmake/Install.cmake b/cmake/Install.cmake index a4f03feab..bf32d749a 100644 --- a/cmake/Install.cmake +++ b/cmake/Install.cmake @@ -7,7 +7,7 @@ set(CMAKE_INSTALL_MESSAGE NEVER) -set(PROGRAMS fish fish_indent fish_key_reader) +set(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fish ${CMAKE_CURRENT_BINARY_DIR}/fish_indent ${CMAKE_CURRENT_BINARY_DIR}/fish_key_reader) set(prefix ${CMAKE_INSTALL_PREFIX}) set(bindir ${CMAKE_INSTALL_BINDIR}) @@ -77,7 +77,7 @@ function(FISH_TRY_CREATE_DIRS) endforeach() endfunction(FISH_TRY_CREATE_DIRS) -install(IMPORTED_RUNTIME_ARTIFACTS ${PROGRAMS} +install(PROGRAMS ${PROGRAMS} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE DESTINATION ${bindir}) diff --git a/cmake/Rust.cmake b/cmake/Rust.cmake index 270ac3f9d..2f30c3782 100644 --- a/cmake/Rust.cmake +++ b/cmake/Rust.cmake @@ -1,52 +1,25 @@ -if(EXISTS "${CMAKE_SOURCE_DIR}/corrosion-vendor/") - add_subdirectory("${CMAKE_SOURCE_DIR}/corrosion-vendor/") -else() - include(FetchContent) +# Trying to build using the resolved toolchain causes all kinds of weird errors +# Just let rustup do its job +set(Rust_RESOLVE_RUSTUP_TOOLCHAINS Off) - # Don't let Corrosion's tests interfere with ours. - set(CORROSION_TESTS OFF CACHE BOOL "" FORCE) +include(FindRust) +find_package(Rust REQUIRED) - FetchContent_Declare( - Corrosion - GIT_REPOSITORY https://github.com/mqudsi/corrosion - GIT_TAG fish - ) +set(FISH_RUST_BUILD_DIR "${CMAKE_BINARY_DIR}/cargo/build") - FetchContent_MakeAvailable(Corrosion) - - add_custom_target(corrosion-vendor.tar.gz - COMMAND git archive --format tar.gz --output "${CMAKE_BINARY_DIR}/corrosion-vendor.tar.gz" - --prefix corrosion-vendor/ HEAD - WORKING_DIRECTORY ${corrosion_SOURCE_DIR} - ) -endif() - -set(fish_rust_target "fish") - -set(FISH_CRATE_FEATURES) -if(NOT DEFINED CARGO_FLAGS) - # Corrosion doesn't like an empty string as FLAGS. This is basically a no-op alternative. - # See https://github.com/corrosion-rs/corrosion/issues/356 - set(CARGO_FLAGS "--config" "foo=0") -endif() if(DEFINED ASAN) list(APPEND CARGO_FLAGS "-Z" "build-std") - list(APPEND FISH_CRATE_FEATURES FEATURES "asan") + list(APPEND FISH_CRATE_FEATURES "asan") endif() -corrosion_import_crate( - MANIFEST_PATH "${CMAKE_SOURCE_DIR}/Cargo.toml" - CRATES "fish" - "${FISH_CRATE_FEATURES}" - FLAGS "${CARGO_FLAGS}" -) - if (Rust_CARGO_TARGET) - set(rust_target_dir "${CMAKE_BINARY_DIR}/cargo/build/${_CORROSION_RUST_CARGO_TARGET}") + set(rust_target_dir "${FISH_RUST_BUILD_DIR}/${Rust_CARGO_TARGET}") else() - set(rust_target_dir "${CMAKE_BINARY_DIR}/cargo/build/${_CORROSION_RUST_CARGO_HOST_TARGET}") + set(rust_target_dir "${FISH_RUST_BUILD_DIR}/${Rust_CARGO_HOST_TARGET}") endif() +set(rust_profile $,debug,release>) + # Temporary hack to propogate CMake flags/options to build.rs. We need to get CMake to evaluate the # truthiness of the strings if they are set. set(CMAKE_WITH_GETTEXT "1") @@ -58,6 +31,16 @@ endif() file(REAL_PATH "${CMAKE_BINARY_DIR}" fish_binary_dir) string(JOIN "," CURSES_LIBRARY_LIST ${CURSES_LIBRARY} ${CURSES_EXTRA_LIBRARY}) +if(FISH_CRATE_FEATURES) + set(FEATURES_ARG ${FISH_CRATE_FEATURES}) + list(PREPEND FEATURES_ARG "--features") +endif() + +get_property( + RUSTC_EXECUTABLE + TARGET Rust::Rustc PROPERTY IMPORTED_LOCATION +) + # Tell Cargo where our build directory is so it can find config.h. set(VARS_FOR_CARGO "FISH_BUILD_DIR=${fish_binary_dir}" @@ -70,5 +53,7 @@ set(VARS_FOR_CARGO "BINDIR=${CMAKE_INSTALL_FULL_BINDIR}" "LOCALEDIR=${CMAKE_INSTALL_FULL_LOCALEDIR}" "CURSES_LIBRARY_LIST=${CURSES_LIBRARY_LIST}" + "CARGO_TARGET_DIR=${FISH_RUST_BUILD_DIR}" + "CARGO_BUILD_RUSTC=${RUSTC_EXECUTABLE}" "${FISH_PCRE2_BUILDFLAG}" )