Files
fish-shell/cmake/Rust.cmake

33 lines
1.1 KiB
CMake
Raw Normal View History

include(FindRust)
find_package(Rust REQUIRED)
set(FISH_RUST_BUILD_DIR "${CMAKE_BINARY_DIR}/cargo/build")
2023-01-14 14:56:24 -08:00
Use standalone code paths by default When users update fish by replacing files, existing shells might throw weird errors because internal functions in share/functions/ might have changed. This is easy to remedy by restarting the shell, but I guess it would be nice if old shells kept using old data. This is somewhat at odds with lazy-loading. But we can use the standalone mode. Turn that on by default. Additionally, this could simplify packaging. Some packages incorrectly put third party files into /usr/share/fish/completion/ when they ought to use /usr/share/fish/vendor_completions.d/ for that. That packaging mistake can make file conflicts randomly appearing when either fish or foo ships a completion for foo. Once we actually stop installing /usr/share/fish/completions, there will no longer be a conflict (for better or worse, things will silently not work, unless packagers notice that the directory doesn't actually exist anymore). The only advantage of having /usr/share/fish/ on the file system is discoverability. But getting the full source code is better anyway. Note that we still install (redundant) $__fish_data_dir when using CMake. This is to not unnecessarily break both 1. already running (old) shells as users upgrade to 4.2 2. plugins (as mentioned in an earlier commit), We can stop installing $__fish_data_dir once we expect 99% of users to upgrade from at least 4.2. If we end up reverting this, we should try to get rid of the embed-data knob in another way, but I'm not sure how. Closes #11921 To-do: - maybe make it a feature flag so users can turn it off without recompiling with "set -Ua no-embed-data".
2025-10-26 23:08:22 +01:00
list(APPEND FISH_CARGO_FEATURES_LIST "embed-data")
if(DEFINED ASAN)
list(APPEND CARGO_FLAGS "-Z" "build-std")
Switch to builtin gettext implementation This completely removes our runtime dependency on gettext. As a replacement, we have our own code for runtime localization in `src/wutil/gettext.rs`. It considers the relevant locale variables to decide which message catalogs to take localizations from. The use of locale variables is mostly the same as in gettext, with the notable exception that we do not support "default dialects". If `LANGUAGE=ll` is set and we don't have a `ll` catalog but a `ll_CC` catalog, we will use the catalog with the country code suffix. If multiple such catalogs exist, we use an arbitrary one. (At the moment we have at most one catalog per language, so this is not particularly relevant.) By using an `EnvStack` to pass variables to gettext at runtime, we now respect locale variables which are not exported. For early output, we don't have an `EnvStack` to pass, so we add an initialization function which constructs an `EnvStack` containing the relevant locale variables from the corresponding Environment variables. Treat `LANGUAGE` as path variable. This add automatic colon-splitting. The sourcing of catalogs is completely reworked. Instead of looking for MO files at runtime, we create catalogs as Rust maps at build time, by converting PO files into MO data, which is not stored, but immediately parsed to extract the mappings. From the mappings, we create Rust source code as a build artifact, which is then macro-included in the crate's library, i.e. `crates/gettext-maps/src/lib.rs`. The code in `src/wutil/gettext.rs` includes the message catalogs from this library, resulting in the message catalogs being built into the executable. The `localize-messages` feature can now be used to control whether to build with gettext support. By default, it is enabled. If `msgfmt` is not available at build time, and `gettext` is enabled, a warning will be emitted and fish is built with gettext support, but without any message catalogs, so localization will not work then. As a performance optimization, for each language we cache a separate Rust source file containing its catalog as a map. This allows us to reuse parsing results if the corresponding PO files have not changed since we cached the parsing result. Note that this approach does not eliminate our build-time dependency on gettext. The process for generating PO files (which uses `msguniq` and `msgmerge`) is unchanged, and we still need `msgfmt` to translate from PO to MO. We could parse PO files directly, but these are significantly more complex to parse, so we use `msgfmt` to do it for us and parse the resulting MO data. Advantages of the new approach: - We have no runtime dependency on gettext anymore. - The implementation has the same behavior everywhere. - Our implementation is significantly simpler than GNU gettext. - We can have localization in cargo-only builds by embedding localizations into the code. Previously, localization in such builds could only work reliably as long as the binary was not moved from the build directory. - We no longer have to take care of building and installing MO files in build systems; everything we need for localization to work happens automatically when building fish. - Reduced overhead when disabling localization, both in compilation time and binary size. Disadvantages of this approach: - Our own runtime implementation of gettext needs to be maintained. - The implementation has a more limited feature set (but I don't think it lacks any features which have been in use by fish). Part of #11726 Closes #11583 Closes #11725 Closes #11683
2025-08-22 20:03:45 +02:00
list(APPEND FISH_CARGO_FEATURES_LIST "asan")
endif()
if(DEFINED TSAN)
list(APPEND CARGO_FLAGS "-Z" "build-std")
Switch to builtin gettext implementation This completely removes our runtime dependency on gettext. As a replacement, we have our own code for runtime localization in `src/wutil/gettext.rs`. It considers the relevant locale variables to decide which message catalogs to take localizations from. The use of locale variables is mostly the same as in gettext, with the notable exception that we do not support "default dialects". If `LANGUAGE=ll` is set and we don't have a `ll` catalog but a `ll_CC` catalog, we will use the catalog with the country code suffix. If multiple such catalogs exist, we use an arbitrary one. (At the moment we have at most one catalog per language, so this is not particularly relevant.) By using an `EnvStack` to pass variables to gettext at runtime, we now respect locale variables which are not exported. For early output, we don't have an `EnvStack` to pass, so we add an initialization function which constructs an `EnvStack` containing the relevant locale variables from the corresponding Environment variables. Treat `LANGUAGE` as path variable. This add automatic colon-splitting. The sourcing of catalogs is completely reworked. Instead of looking for MO files at runtime, we create catalogs as Rust maps at build time, by converting PO files into MO data, which is not stored, but immediately parsed to extract the mappings. From the mappings, we create Rust source code as a build artifact, which is then macro-included in the crate's library, i.e. `crates/gettext-maps/src/lib.rs`. The code in `src/wutil/gettext.rs` includes the message catalogs from this library, resulting in the message catalogs being built into the executable. The `localize-messages` feature can now be used to control whether to build with gettext support. By default, it is enabled. If `msgfmt` is not available at build time, and `gettext` is enabled, a warning will be emitted and fish is built with gettext support, but without any message catalogs, so localization will not work then. As a performance optimization, for each language we cache a separate Rust source file containing its catalog as a map. This allows us to reuse parsing results if the corresponding PO files have not changed since we cached the parsing result. Note that this approach does not eliminate our build-time dependency on gettext. The process for generating PO files (which uses `msguniq` and `msgmerge`) is unchanged, and we still need `msgfmt` to translate from PO to MO. We could parse PO files directly, but these are significantly more complex to parse, so we use `msgfmt` to do it for us and parse the resulting MO data. Advantages of the new approach: - We have no runtime dependency on gettext anymore. - The implementation has the same behavior everywhere. - Our implementation is significantly simpler than GNU gettext. - We can have localization in cargo-only builds by embedding localizations into the code. Previously, localization in such builds could only work reliably as long as the binary was not moved from the build directory. - We no longer have to take care of building and installing MO files in build systems; everything we need for localization to work happens automatically when building fish. - Reduced overhead when disabling localization, both in compilation time and binary size. Disadvantages of this approach: - Our own runtime implementation of gettext needs to be maintained. - The implementation has a more limited feature set (but I don't think it lacks any features which have been in use by fish). Part of #11726 Closes #11583 Closes #11725 Closes #11683
2025-08-22 20:03:45 +02:00
list(APPEND FISH_CARGO_FEATURES_LIST "tsan")
endif()
if (Rust_CARGO_TARGET)
set(rust_target_dir "${FISH_RUST_BUILD_DIR}/${Rust_CARGO_TARGET}")
else()
set(rust_target_dir "${FISH_RUST_BUILD_DIR}/${Rust_CARGO_HOST_TARGET}")
endif()
set(rust_profile $<IF:$<CONFIG:Debug>,debug,$<IF:$<CONFIG:RelWithDebInfo>,release-with-debug,release>>)
set(rust_debugflags "$<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g>")
Switch to builtin gettext implementation This completely removes our runtime dependency on gettext. As a replacement, we have our own code for runtime localization in `src/wutil/gettext.rs`. It considers the relevant locale variables to decide which message catalogs to take localizations from. The use of locale variables is mostly the same as in gettext, with the notable exception that we do not support "default dialects". If `LANGUAGE=ll` is set and we don't have a `ll` catalog but a `ll_CC` catalog, we will use the catalog with the country code suffix. If multiple such catalogs exist, we use an arbitrary one. (At the moment we have at most one catalog per language, so this is not particularly relevant.) By using an `EnvStack` to pass variables to gettext at runtime, we now respect locale variables which are not exported. For early output, we don't have an `EnvStack` to pass, so we add an initialization function which constructs an `EnvStack` containing the relevant locale variables from the corresponding Environment variables. Treat `LANGUAGE` as path variable. This add automatic colon-splitting. The sourcing of catalogs is completely reworked. Instead of looking for MO files at runtime, we create catalogs as Rust maps at build time, by converting PO files into MO data, which is not stored, but immediately parsed to extract the mappings. From the mappings, we create Rust source code as a build artifact, which is then macro-included in the crate's library, i.e. `crates/gettext-maps/src/lib.rs`. The code in `src/wutil/gettext.rs` includes the message catalogs from this library, resulting in the message catalogs being built into the executable. The `localize-messages` feature can now be used to control whether to build with gettext support. By default, it is enabled. If `msgfmt` is not available at build time, and `gettext` is enabled, a warning will be emitted and fish is built with gettext support, but without any message catalogs, so localization will not work then. As a performance optimization, for each language we cache a separate Rust source file containing its catalog as a map. This allows us to reuse parsing results if the corresponding PO files have not changed since we cached the parsing result. Note that this approach does not eliminate our build-time dependency on gettext. The process for generating PO files (which uses `msguniq` and `msgmerge`) is unchanged, and we still need `msgfmt` to translate from PO to MO. We could parse PO files directly, but these are significantly more complex to parse, so we use `msgfmt` to do it for us and parse the resulting MO data. Advantages of the new approach: - We have no runtime dependency on gettext anymore. - The implementation has the same behavior everywhere. - Our implementation is significantly simpler than GNU gettext. - We can have localization in cargo-only builds by embedding localizations into the code. Previously, localization in such builds could only work reliably as long as the binary was not moved from the build directory. - We no longer have to take care of building and installing MO files in build systems; everything we need for localization to work happens automatically when building fish. - Reduced overhead when disabling localization, both in compilation time and binary size. Disadvantages of this approach: - Our own runtime implementation of gettext needs to be maintained. - The implementation has a more limited feature set (but I don't think it lacks any features which have been in use by fish). Part of #11726 Closes #11583 Closes #11725 Closes #11683
2025-08-22 20:03:45 +02:00
option(WITH_GETTEXT "Build with gettext localization support. Requires `msgfmt` to work." ON)
# Enable gettext feature unless explicitly disabled.
if(NOT DEFINED WITH_GETTEXT OR "${WITH_GETTEXT}")
list(APPEND FISH_CARGO_FEATURES_LIST "localize-messages")
endif()
Switch to builtin gettext implementation This completely removes our runtime dependency on gettext. As a replacement, we have our own code for runtime localization in `src/wutil/gettext.rs`. It considers the relevant locale variables to decide which message catalogs to take localizations from. The use of locale variables is mostly the same as in gettext, with the notable exception that we do not support "default dialects". If `LANGUAGE=ll` is set and we don't have a `ll` catalog but a `ll_CC` catalog, we will use the catalog with the country code suffix. If multiple such catalogs exist, we use an arbitrary one. (At the moment we have at most one catalog per language, so this is not particularly relevant.) By using an `EnvStack` to pass variables to gettext at runtime, we now respect locale variables which are not exported. For early output, we don't have an `EnvStack` to pass, so we add an initialization function which constructs an `EnvStack` containing the relevant locale variables from the corresponding Environment variables. Treat `LANGUAGE` as path variable. This add automatic colon-splitting. The sourcing of catalogs is completely reworked. Instead of looking for MO files at runtime, we create catalogs as Rust maps at build time, by converting PO files into MO data, which is not stored, but immediately parsed to extract the mappings. From the mappings, we create Rust source code as a build artifact, which is then macro-included in the crate's library, i.e. `crates/gettext-maps/src/lib.rs`. The code in `src/wutil/gettext.rs` includes the message catalogs from this library, resulting in the message catalogs being built into the executable. The `localize-messages` feature can now be used to control whether to build with gettext support. By default, it is enabled. If `msgfmt` is not available at build time, and `gettext` is enabled, a warning will be emitted and fish is built with gettext support, but without any message catalogs, so localization will not work then. As a performance optimization, for each language we cache a separate Rust source file containing its catalog as a map. This allows us to reuse parsing results if the corresponding PO files have not changed since we cached the parsing result. Note that this approach does not eliminate our build-time dependency on gettext. The process for generating PO files (which uses `msguniq` and `msgmerge`) is unchanged, and we still need `msgfmt` to translate from PO to MO. We could parse PO files directly, but these are significantly more complex to parse, so we use `msgfmt` to do it for us and parse the resulting MO data. Advantages of the new approach: - We have no runtime dependency on gettext anymore. - The implementation has the same behavior everywhere. - Our implementation is significantly simpler than GNU gettext. - We can have localization in cargo-only builds by embedding localizations into the code. Previously, localization in such builds could only work reliably as long as the binary was not moved from the build directory. - We no longer have to take care of building and installing MO files in build systems; everything we need for localization to work happens automatically when building fish. - Reduced overhead when disabling localization, both in compilation time and binary size. Disadvantages of this approach: - Our own runtime implementation of gettext needs to be maintained. - The implementation has a more limited feature set (but I don't think it lacks any features which have been in use by fish). Part of #11726 Closes #11583 Closes #11725 Closes #11683
2025-08-22 20:03:45 +02:00
list(JOIN FISH_CARGO_FEATURES_LIST , FISH_CARGO_FEATURES)