build.rs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. use std::env;
  2. //use std::ffi::OsString;
  3. //use std::process::Command;
  4. fn main() {
  5. // We don't currently need to check the Version anymore...
  6. // But leaving this in place in case we need to in the future.
  7. /*
  8. let rustc = env::var_os("RUSTC").unwrap_or(OsString::from("rustc"));
  9. let output = Command::new(&rustc)
  10. .arg("--version")
  11. .output()
  12. .expect("failed to check 'rustc --version'")
  13. .stdout;
  14. let version = String::from_utf8(output)
  15. .expect("rustc version output should be utf-8");
  16. */
  17. enable_new_features(/*&version*/);
  18. }
  19. fn enable_new_features(/*raw_version: &str*/) {
  20. /*
  21. let version = match Version::parse(raw_version) {
  22. Ok(version) => version,
  23. Err(err) => {
  24. println!("cargo:warning=failed to parse `rustc --version`: {}", err);
  25. return;
  26. }
  27. };
  28. */
  29. enable_simd(/*version*/);
  30. }
  31. fn enable_simd(/*version: Version*/) {
  32. if env::var_os("CARGO_FEATURE_STD").is_none() {
  33. println!("cargo:warning=building for no_std disables httparse SIMD");
  34. return;
  35. }
  36. if env::var_os("CARGO_CFG_MIRI").is_some() {
  37. println!("cargo:warning=building for Miri disables httparse SIMD");
  38. return;
  39. }
  40. let env_disable = "CARGO_CFG_HTTPARSE_DISABLE_SIMD";
  41. if var_is(env_disable, "1") {
  42. println!("cargo:warning=detected {} environment variable, disabling SIMD", env_disable);
  43. return;
  44. }
  45. println!("cargo:rustc-cfg=httparse_simd");
  46. // cfg(target_feature) isn't stable yet, but CARGO_CFG_TARGET_FEATURE has
  47. // a list... We aren't doing anything unsafe, since the is_x86_feature_detected
  48. // macro still checks in the actual lib, BUT!
  49. //
  50. // By peeking at the list here, we can change up slightly how we do feature
  51. // detection in the lib. If our features aren't in the feature list, we
  52. // stick with a cached runtime detection strategy.
  53. //
  54. // But if the features *are* in the list, we benefit from removing our cache,
  55. // since the compiler will eliminate several branches with its internal
  56. // cfg(target_feature) usage.
  57. let env_runtime_only = "CARGO_CFG_HTTPARSE_DISABLE_SIMD_COMPILETIME";
  58. if var_is(env_runtime_only, "1") {
  59. println!("cargo:warning=detected {} environment variable, using runtime SIMD detection only", env_runtime_only);
  60. return;
  61. }
  62. let feature_list = match env::var_os("CARGO_CFG_TARGET_FEATURE") {
  63. Some(var) => match var.into_string() {
  64. Ok(s) => s,
  65. Err(_) => {
  66. println!("cargo:warning=CARGO_CFG_TARGET_FEATURE was not valid utf-8");
  67. return;
  68. },
  69. },
  70. None => {
  71. println!("cargo:warning=CARGO_CFG_TARGET_FEATURE was not set");
  72. return
  73. },
  74. };
  75. let mut saw_sse42 = false;
  76. let mut saw_avx2 = false;
  77. for feature in feature_list.split(',') {
  78. let feature = feature.trim();
  79. if !saw_sse42 && feature == "sse4.2" {
  80. saw_sse42 = true;
  81. println!("cargo:rustc-cfg=httparse_simd_target_feature_sse42");
  82. }
  83. if !saw_avx2 && feature == "avx2" {
  84. saw_avx2 = true;
  85. println!("cargo:rustc-cfg=httparse_simd_target_feature_avx2");
  86. }
  87. }
  88. }
  89. /*
  90. #[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
  91. struct Version {
  92. major: u32,
  93. minor: u32,
  94. patch: u32,
  95. }
  96. impl Version {
  97. fn parse(mut s: &str) -> Result<Version, String> {
  98. if !s.starts_with("rustc ") {
  99. return Err(format!("unrecognized version string: {}", s));
  100. }
  101. s = &s["rustc ".len()..];
  102. let parts: Vec<&str> = s.split(".").collect();
  103. if parts.len() < 3 {
  104. return Err(format!("not enough version parts: {:?}", parts));
  105. }
  106. let mut num = String::new();
  107. for c in parts[0].chars() {
  108. if !c.is_digit(10) {
  109. break;
  110. }
  111. num.push(c);
  112. }
  113. let major = num.parse::<u32>().map_err(|e| e.to_string())?;
  114. num.clear();
  115. for c in parts[1].chars() {
  116. if !c.is_digit(10) {
  117. break;
  118. }
  119. num.push(c);
  120. }
  121. let minor = num.parse::<u32>().map_err(|e| e.to_string())?;
  122. num.clear();
  123. for c in parts[2].chars() {
  124. if !c.is_digit(10) {
  125. break;
  126. }
  127. num.push(c);
  128. }
  129. let patch = num.parse::<u32>().map_err(|e| e.to_string())?;
  130. Ok(Version {
  131. major: major,
  132. minor: minor,
  133. patch: patch,
  134. })
  135. }
  136. }
  137. */
  138. fn var_is(key: &str, val: &str) -> bool {
  139. match env::var(key) {
  140. Ok(v) => v == val,
  141. Err(_) => false,
  142. }
  143. }