gettext-sys-0.21.3/.cargo_vcs_info.json0000644000000001510000000000100134140ustar { "git": { "sha1": "de7ed4a6052b674d772bc94e5af7619b9e00adfd" }, "path_in_vcs": "gettext-sys" }gettext-sys-0.21.3/CHANGELOG.md000064400000000000000000000030120072674642500140440ustar 00000000000000# Changelog ## 0.21.3 - 2022-03-16 ### Changed - `wbindtextdomain` is now a Rust function rather than a C symbol. The symbol is now named `libintl_wbindtextdomain`, for better compatibility with MinGW. This change only affects Windows (Marin) ### Fixed - Only check for build dependencies when actually building the library (Ignacio Casal Quinteiro) ## 0.21.2 - 2021-07-21 ### Fixed - Build failure on some systems which put libraries into "lib64" directory (#73) (Alexander Batischev) ## 0.21.1 - 2021-07-16 ### Changed - Dependency on `tempdir` is replaced by dependency on `temp-dir`, which is way more lightweight (Amrit Brar) ## 0.21.0 - 2021-03-03 ### Added - A note regarding GNU gettext's LGPL license (Alexander Batischev) - Checks for build tools required by GNU gettext (Dean Leggo) - Bindings for `wbindtextdomain` (only available on Windows) (Alexander Batischev) - Build-time dependency on `tempfile` (Alexander Batischev) ### Changed - Bump bundled GNU gettext to 0.21 (Alexander Batischev) ### Fixed - Build failure when a path contains spaces (Alexander Batischev) ## 0.19.9 - 2019-07-26 ### Added - Support for Windows+GNU (François Laignel) - Support for musl libc (Rasmus Thomsen) - `gettext-system` feature which asks the crate to use gettext that's built into libc (if available) (François Laignel) - Use xz to compress the bundled GNU gettext tarball, to save space (Daniel García Moreno) ## 0.19.8 - 2018-05-23 Initial release (Konstantin V. Salikhov, Faizaan). gettext-sys-0.21.3/Cargo.toml0000644000000021050000000000100114130ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2015" name = "gettext-sys" version = "0.21.3" authors = ["Brian Olsen ", "Alexander Batischev "] build = "build.rs" links = "gettext" description = "Raw FFI bindings for gettext" homepage = "https://github.com/Koka/gettext-rs" documentation = "https://docs.rs/gettext-sys/" readme = "README.md" keywords = ["gettext", "binding", "ffi", "i18n", "l10n"] license = "MIT" repository = "https://github.com/Koka/gettext-rs" [lib] path = "lib.rs" [build-dependencies.cc] version = "1.0" [build-dependencies.temp-dir] version = "0.1.11" [features] gettext-system = [] gettext-sys-0.21.3/Cargo.toml.orig0000644000000011150000000000100123520ustar [package] name = "gettext-sys" description = "Raw FFI bindings for gettext" license = "MIT" version = "0.21.3" authors = ["Brian Olsen ", "Alexander Batischev "] build = "build.rs" links = "gettext" readme = "README.md" documentation = "https://docs.rs/gettext-sys/" homepage = "https://github.com/Koka/gettext-rs" repository = "https://github.com/Koka/gettext-rs" edition = "2015" keywords = ["gettext", "binding", "ffi", "i18n", "l10n"] [lib] path = "lib.rs" [features] gettext-system = [] [build-dependencies] cc = "1.0" temp-dir = "0.1.11" gettext-sys-0.21.3/Cargo.toml.orig000064400000000000000000000011150072674642500151240ustar 00000000000000[package] name = "gettext-sys" description = "Raw FFI bindings for gettext" license = "MIT" version = "0.21.3" authors = ["Brian Olsen ", "Alexander Batischev "] build = "build.rs" links = "gettext" readme = "README.md" documentation = "https://docs.rs/gettext-sys/" homepage = "https://github.com/Koka/gettext-rs" repository = "https://github.com/Koka/gettext-rs" edition = "2015" keywords = ["gettext", "binding", "ffi", "i18n", "l10n"] [lib] path = "lib.rs" [features] gettext-system = [] [build-dependencies] cc = "1.0" temp-dir = "0.1.11" gettext-sys-0.21.3/LICENSE.txt000064400000000000000000000021010072674642500140540ustar 00000000000000The MIT License (MIT) Copyright (c) 2016 Konstantin V. Salikhov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. gettext-sys-0.21.3/README.md000064400000000000000000000061620072674642500135230ustar 00000000000000# gettext-sys Raw FFI bindings for gettext. Please see [documentation](https://docs.rs/gettext-sys) for details. ## Licensing On platforms that don't have a native gettext implementation, this crate compiles GNU gettext, which is licensed under LGPL. This means **you have to abide by LGPL**. If you don't want or can't do that, there are two ways out: 1. in a GNU environment, enable `gettext-system` feature (see below); 2. dynamically link to GNU gettext library you obtained by some other means, like a package manager. See environment variables below. ## Features - `gettext-system`: if enabled, _asks_ the crate to use the gettext implementation that's part of glibc or musl libc. This only works on: * Linux with glibc or musl libc; * Windows + GNU (e.g. [MSYS2](https://www.msys2.org/)) with `gettext-devel` installed e.g. using: ``` pacman --noconfirm -S base-devel mingw-w64-x86_64-gcc libxml2-devel tar ``` If none of those conditions hold, the crate will proceed to building and statically linking its own copy of GNU gettext! ## Environment variables - `GETTEXT_SYSTEM`: same as enabling `gettext-system` feature (see above). - `GETTEXT_DIR`: if specified, a directory that will be used to find gettext installation. It's expected that under this directory, the _include_ folder has header files, the _bin_ folder has gettext binary, and a _lib_ folder has the runtime libraries. - `GETTEXT_LIB_DIR`: if specified, a directory that will be used to find gettext libraries. Overrides the _lib_ folder implied by `GETTEXT_DIR` (if specified). - `GETTEXT_INCLUDE_DIR`: if specified, a directory that will be used to find gettext header files. Overrides the _include_ folder implied by `GETTEXT_DIR` (if specified). - `GETTEXT_BIN_DIR`: if specified, a directory that will be used to find gettext binaries. Overrides the _bin_ folder implied by `GETTEXT_DIR` (if specified). - `GETTEXT_STATIC`: if specified, gettext libraries will be statically rather than dynamically linked. This only affects `GETTEXT_DIR` and `GETTEXT_*_DIR` scenarios; the default behaviour and `GETTEXT_SYSTEM` still use static and dynamic linking respectively. - `NUM_JOBS`: sets the number of parallel build jobs. - `TMPDIR` (on Unix), `TMP`, `TEMP`, `USERPROFILE` (on Windows): set the parent directory for the temporary build directory. GNU gettext uses autotools, which [don't allow some characters][chars] in paths, notably a space character. To get around that, this crate performs the build in a temporary directory which usually resides somewhere under _/tmp_ or _C:\\Temp_. The aforementioned env vars allow you to move the build directory elsewhere. [chars]: https://www.gnu.org/software/autoconf/manual/autoconf-2.60/autoconf.html#Special-Chars-in-Variables For target-specific configuration, each of these environment variables can be prefixed by an upper-cased target, for example, `X86_64_UNKNOWN_LINUX_GNU_GETTEXT_DIR`. This can be useful in cross compilation contexts. This doesn't work on AppVeyor ATM. Use `SET GETTEXT_SYSTEM=true` instead. gettext-sys-0.21.3/build.rs000064400000000000000000000245310072674642500137110ustar 00000000000000extern crate cc; extern crate temp_dir; use std::env; use std::ffi::OsString; use std::fs; use std::io::ErrorKind; use std::path::{Path, PathBuf}; use std::process::Command; use temp_dir::TempDir; fn env(name: &str) -> Option { let prefix = env::var("TARGET").unwrap().to_uppercase().replace("-", "_"); let prefixed = format!("{}_{}", prefix, name); println!("cargo:rerun-if-env-changed={}", prefixed); if let Ok(var) = env::var(&prefixed) { return Some(var); } println!("cargo:rerun-if-env-changed={}", name); env::var(name).ok() } fn get_windows_gnu_root() -> String { // attempt to find the installation directory for the gnu distribution env("MSYSTEM_PREFIX") .or_else(|| env("MINGW_PREFIX")) .or_else(|| { // AppVeyor env doesn't declare any usable prefix let arch = if env::var("TARGET").unwrap().contains("x86_64") { "64" } else { "32" }; let root_test = PathBuf::from(format!("C:/msys64/mingw{}", arch)); if root_test.is_dir() { Some(root_test.to_str().unwrap().to_owned()) } else { None } }) .unwrap_or_else(|| fail("Failed to get gnu installation root dir")) } fn posix_path(path: &Path) -> String { let path = path .to_str() .unwrap_or_else(|| fail(&format!("Couldn't convert path {:?} to string", path))); if env::var("HOST").unwrap().contains("windows") { let path = path.replace("\\", "/"); if path.find(":") == Some(1) { // absolute path with a drive letter format!("/{}{}", &path[0..1], &path[2..]) } else { path.to_owned() } } else { path.to_owned() } } fn check_dependencies(required_programs: Vec<&str>) { let command = |x| { let status = Command::new("sh") .arg("-c") .arg(format!("command -v {}", x)) .status() .expect("failed to excute process"); if status.success() { "".to_owned() } else { format!(" {},", x) } }; let errors: String = required_programs.iter().map(|x| command(x)).collect(); if !errors.is_empty() { fail(&format!("The following programs were not found:{}", errors)); } } fn main() { let target = env::var("TARGET").unwrap(); if cfg!(feature = "gettext-system") || env("GETTEXT_SYSTEM").is_some() { if target.contains("linux") && (target.contains("-gnu") || target.contains("-musl")) { // intl is part of glibc and musl return; } else if target.contains("windows") && target.contains("-gnu") { // gettext doesn't come with a pkg-config file let gnu_root = get_windows_gnu_root(); println!("cargo:rustc-link-search=native={}/lib", &gnu_root); println!("cargo:rustc-link-search=native={}/../usr/lib", &gnu_root); println!("cargo:rustc-link-lib=dylib=intl"); // FIXME: should pthread support be optional? // It is needed by `cargo test` while generating doc println!("cargo:rustc-link-lib=dylib=pthread"); println!("cargo:include={}/../usr/include", &gnu_root); return; } // else can't use system gettext on this target } if target.contains("apple-darwin") { println!("cargo:rustc-link-lib=framework=CoreFoundation"); println!("cargo:rustc-link-lib=dylib=iconv"); } if let Some(gettext_dir) = env("GETTEXT_DIR") { println!("cargo:root={}", gettext_dir); if let Some(bin) = env("GETTEXT_BIN_DIR") { println!("cargo:bin={}", bin); } else { println!("cargo:bin={}/bin", gettext_dir); } if let Some(lib) = env("GETTEXT_LIB_DIR") { println!("cargo:lib={}", lib); println!("cargo:rustc-link-search=native={}", lib); } else { println!("cargo:lib={}/lib", gettext_dir); println!("cargo:rustc-link-search=native={}/lib", gettext_dir); } if let Some(include) = env("GETTEXT_INCLUDE_DIR") { println!("cargo:include={}", include); } else { println!("cargo:include={}/include", gettext_dir); } if env("GETTEXT_STATIC").is_some() { println!("cargo:rustc-link-lib=static=intl"); } else { println!("cargo:rustc-link-lib=dylib=intl"); } return; } else if let (Some(bin), Some(lib), Some(include)) = ( env("GETTEXT_BIN_DIR"), env("GETTEXT_LIB_DIR"), env("GETTEXT_INCLUDE_DIR"), ) { println!("cargo:rustc-link-search=native={}", lib); if env("GETTEXT_STATIC").is_some() { println!("cargo:rustc-link-lib=static=intl"); } else { println!("cargo:rustc-link-lib=dylib=intl"); } println!("cargo:bin={}", bin); println!("cargo:lib={}", lib); println!("cargo:include={}", include); return; } // Programs required to compile GNU gettext check_dependencies(vec!["cmp", "diff", "find", "xz"]); let host = env::var("HOST").unwrap(); let src = env::current_dir().unwrap(); let build_dir = TempDir::new().unwrap(); let build_dir = build_dir.path(); let cfg = cc::Build::new(); let compiler = cfg.get_compiler(); let _ = fs::create_dir(&build_dir.join("build")); let _ = fs::create_dir(&build_dir.join("gettext")); let mut cflags = OsString::new(); for arg in compiler.args() { cflags.push(arg); cflags.push(" "); } if target.contains("windows") { // Avoid undefined reference to `__imp_xmlFree' cflags.push("-DLIBXML_STATIC"); } let mut cmd = Command::new("tar"); cmd.current_dir(&build_dir.join("gettext")) .arg("xJf") .arg(&src.join("gettext-0.21.tar.xz")) .arg("--strip-components") .arg("1"); if host.contains("windows") { // tar confuses local path with a remote resource because of ':' cmd.arg("--force-local"); } run(&mut cmd, "tar"); let mut cmd = Command::new("sh"); cmd.env("CC", compiler.path()) .env("CFLAGS", cflags) .env("LD", &which("ld").unwrap()) .env("VERBOSE", "1") .current_dir(&build_dir.join("build")) .arg(&posix_path(&build_dir.join("gettext").join("configure"))); cmd.arg("--without-emacs"); cmd.arg("--disable-java"); cmd.arg("--disable-csharp"); cmd.arg("--disable-c++"); cmd.arg("--disable-shared"); cmd.arg("--enable-static"); cmd.arg("--enable-fast-install"); cmd.arg("--with-included-gettext"); cmd.arg("--with-included-glib"); cmd.arg("--with-included-libcroco"); cmd.arg("--with-included-libunistring"); if target.contains("windows") { // FIXME: should pthread support be optional? // It is needed by `cargo test` while generating doc cmd.arg("--enable-threads=windows"); } cmd.arg(format!("--prefix={}", &posix_path(&build_dir))); cmd.arg(format!("--libdir={}", &posix_path(&build_dir.join("lib")))); if target != host && (!target.contains("windows") || !host.contains("windows")) { // NOTE GNU terminology // BUILD = machine where we are (cross) compiling curl // HOST = machine where the compiled curl will be used // TARGET = only relevant when compiling compilers if target.contains("windows") { // curl's configure can't parse `-windows-` triples when used // as `--host`s. In those cases we use this combination of // `host` and `target` that appears to do the right thing. cmd.arg(format!("--host={}", host)); cmd.arg(format!("--target={}", target)); } else { cmd.arg(format!("--build={}", host)); cmd.arg(format!("--host={}", target)); } } run(&mut cmd, "sh"); run( make() .arg(&format!("-j{}", env::var("NUM_JOBS").unwrap())) .current_dir(&build_dir.join("build")), "make", ); run( make().arg("install").current_dir(&build_dir.join("build")), "make", ); let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap()); let mut cmd = Command::new("cp"); cmd.current_dir(&build_dir) .arg("-r") .arg(&build_dir.join("bin")) .arg(&build_dir.join("include")) .arg(&build_dir.join("lib")) .arg(&dst); run(&mut cmd, "cp"); println!("cargo:rustc-link-lib=static=intl"); println!("cargo:rustc-link-search=native={}/lib", dst.display()); println!("cargo:lib={}/lib", dst.display()); println!("cargo:include={}/include", dst.display()); println!("cargo:bin={}/bin", dst.display()); println!("cargo:root={}", dst.display()); if target.contains("windows") { println!( "cargo:rustc-link-search=native={}/lib", &get_windows_gnu_root() ); println!("cargo:rustc-link-lib=dylib=iconv"); } } fn run(cmd: &mut Command, program: &str) { println!("running: {:?}", cmd); let status = match cmd.status() { Ok(status) => status, Err(ref e) if e.kind() == ErrorKind::NotFound => { fail(&format!( "failed to execute command: {}\nis `{}` not installed?", e, program )); } Err(e) => fail(&format!("failed to execute command: {}", e)), }; if !status.success() { fail(&format!( "command did not execute successfully, got: {}", status )); } } fn fail(s: &str) -> ! { panic!("\n{}\n\nbuild script failed, must exit now", s) } fn which(cmd: &str) -> Option { let cmd = format!("{}{}", cmd, env::consts::EXE_SUFFIX); let paths = env::var_os("PATH").unwrap(); env::split_paths(&paths) .map(|p| p.join(&cmd)) .find(|p| fs::metadata(p).is_ok()) } fn make() -> Command { let cmd = if cfg!(target_os = "freebsd") { "gmake" } else { "make" }; let mut cmd = Command::new(cmd); // We're using the MSYS make which doesn't work with the mingw32-make-style // MAKEFLAGS, so remove that from the env if present. if cfg!(windows) { cmd.env_remove("MAKEFLAGS").env_remove("MFLAGS"); } return cmd; } gettext-sys-0.21.3/lib.rs000064400000000000000000000027610072674642500133610ustar 00000000000000use std::os::raw::{c_char, c_int, c_ulong}; #[cfg(windows)] #[allow(non_camel_case_types)] type wchar_t = u16; extern "C" { pub fn gettext(s: *const c_char) -> *mut c_char; pub fn dgettext(domain: *const c_char, s: *const c_char) -> *mut c_char; pub fn dcgettext(domain: *const c_char, s: *const c_char, category: c_int) -> *mut c_char; pub fn ngettext(s1: *const c_char, s2: *const c_char, n: c_ulong) -> *mut c_char; pub fn dngettext( domain: *const c_char, s1: *const c_char, s2: *const c_char, n: c_ulong, ) -> *mut c_char; pub fn dcngettext( domain: *const c_char, s1: *const c_char, s2: *const c_char, n: c_ulong, category: c_int, ) -> *mut c_char; pub fn bindtextdomain(domain: *const c_char, dir: *const c_char) -> *mut c_char; #[cfg(windows)] // The "wbindtextdomain" symbol is not exposed directly in the compiled // .DLL file when building using MinGW. See: https://github.com/Koka/gettext-rs/pull/79 fn libintl_wbindtextdomain(domain: *const c_char, dir: *const wchar_t) -> *mut wchar_t; pub fn textdomain(domain: *const c_char) -> *mut c_char; pub fn bind_textdomain_codeset(domain: *const c_char, codeset: *const c_char) -> *mut c_char; pub fn setlocale(category: c_int, locale: *const c_char) -> *mut c_char; } #[cfg(windows)] pub unsafe fn wbindtextdomain(domain: *const c_char, dir: *const wchar_t) -> *mut wchar_t { libintl_wbindtextdomain(domain, dir) }