Skip to content

Commit 0ac015f

Browse files
authored
add nasm support for msvc (#87)
* add nasm support for windows-msvc This will automatically detect whether nasm.exe is installed and try to enable the assembly language routines. These can also be disabled by set the `OPENSSL_RUST_NO_NASM` environment variable to a non-zero value. * don't use '>> $GITHUB_ENV' to overwrite PATH * remove the windows check in CI * give user more control on the env var * add env var in CI, less acceptable values for env var * fix path format for using bash on windows * 'OPENSSL_RUST_USE_NASM' env var only accept 0 or 1
1 parent e634b86 commit 0ac015f

File tree

3 files changed

+93
-9
lines changed

3 files changed

+93
-9
lines changed

.github/workflows/main.yml

+18-6
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ jobs:
7676
rust: stable-x86_64-msvc
7777
os: windows-latest
7878
crt_static: yes
79+
- target: x86_64-pc-windows-msvc
80+
rust: stable-x86_64-msvc
81+
os: windows-latest
82+
nasm_exe: installed
7983

8084
steps:
8185
- uses: actions/checkout@v1
@@ -90,18 +94,26 @@ jobs:
9094
- name: Use strawberry perl
9195
if: startsWith(matrix.os, 'windows')
9296
run: echo OPENSSL_SRC_PERL=C:/Strawberry/perl/bin/perl >> $GITHUB_ENV
93-
- run: |
97+
- name: Run tests (not Windows)
98+
if: "!startsWith(matrix.os, 'windows')"
99+
run: |
94100
set -e
95101
cargo generate-lockfile
96102
./ci/run-docker.sh ${{ matrix.target }}
97-
if: "!startsWith(matrix.os, 'windows')"
98-
name: Run tests (not Windows)
99-
- run: |
103+
- name: Download nasm.exe (Windows)
104+
if: matrix.nasm_exe == 'installed'
105+
run: |
106+
WINNASMVERSION='2.15.05'
107+
curl -O https://www.nasm.us/pub/nasm/releasebuilds/${WINNASMVERSION}/win64/nasm-${WINNASMVERSION}-win64.zip
108+
unzip nasm-${WINNASMVERSION}-win64.zip
109+
echo "$GITHUB_WORKSPACE\\nasm-${WINNASMVERSION}" >> $GITHUB_PATH
110+
echo "OPENSSL_RUST_USE_NASM=1" >> $GITHUB_ENV
111+
- name: Run tests (Windows)
112+
if: startsWith(matrix.os, 'windows')
113+
run: |
100114
cargo test --manifest-path testcrate/Cargo.toml --target ${{ matrix.target }} -vv
101115
cargo test --manifest-path testcrate/Cargo.toml --target ${{ matrix.target }} --release -vv
102116
cargo run --release --target ${{ matrix.target }} --manifest-path testcrate/Cargo.toml --features package -vv
103-
if: startsWith(matrix.os, 'windows')
104-
name: Run tests (Windows)
105117
106118
rustfmt:
107119
name: Rustfmt

README.md

+16
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,22 @@ This project is licensed under either of
1515

1616
at your option.
1717

18+
### Windows MSVC Assembly
19+
Building OpenSSL for `windows-msvc` targets, users can choose whether to enable
20+
assembly language routines, which requires [nasm](https://www.nasm.us/).
21+
The build process will automatically detect whether `nasm.exe` is installed in
22+
PATH. If found, the assembly language routines will be enabled (in other words,
23+
the `no-asm` option will NOT be configured).
24+
You can manipulate this behavior by setting the `OPENSSL_RUST_USE_NASM` environment
25+
variable:
26+
* `1`: Force enable the assembly language routines. (panic if `nasm.exe` is not
27+
availible.)
28+
* `0`: Force disable the assembly language routines even if the `nasm.exe` can be
29+
found in PATH.
30+
* not set: Let the build process automatically detect whether `nasm.exe` is
31+
installed. If found, enable. If not, disable.
32+
However, this environment variable does not take effects on non-windows platforms.
33+
1834
### Contribution
1935

2036
Unless you explicitly state otherwise, any contribution intentionally submitted

src/lib.rs

+59-3
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,53 @@ impl Build {
6565
}
6666
}
6767

68+
#[cfg(windows)]
69+
fn check_env_var(&self, var_name: &str) -> Option<bool> {
70+
env::var_os(var_name).map(|s| {
71+
if s == "1" {
72+
// a message to stdout, let user know asm is force enabled
73+
println!(
74+
"{}: nasm.exe is force enabled by the \
75+
'OPENSSL_RUST_USE_NASM' env var.",
76+
env!("CARGO_PKG_NAME")
77+
);
78+
true
79+
} else if s == "0" {
80+
// a message to stdout, let user know asm is force disabled
81+
println!(
82+
"{}: nasm.exe is force disabled by the \
83+
'OPENSSL_RUST_USE_NASM' env var.",
84+
env!("CARGO_PKG_NAME")
85+
);
86+
false
87+
} else {
88+
panic!(
89+
"The environment variable {} is set to an unacceptable value: {:?}",
90+
var_name, s
91+
);
92+
}
93+
})
94+
}
95+
96+
#[cfg(windows)]
97+
fn is_nasm_ready(&self) -> bool {
98+
self.check_env_var("OPENSSL_RUST_USE_NASM")
99+
.unwrap_or_else(|| {
100+
// On Windows, use cmd `where` command to check if nasm is installed
101+
let wherenasm = Command::new("cmd")
102+
.args(&["/C", "where nasm"])
103+
.output()
104+
.expect("Failed to execute `cmd`.");
105+
wherenasm.status.success()
106+
})
107+
}
108+
109+
#[cfg(not(windows))]
110+
fn is_nasm_ready(&self) -> bool {
111+
// We assume that nobody would run nasm.exe on a non-windows system.
112+
false
113+
}
114+
68115
pub fn build(&mut self) -> Artifacts {
69116
let target = &self.target.as_ref().expect("TARGET dir not set")[..];
70117
let host = &self.host.as_ref().expect("HOST dir not set")[..];
@@ -147,9 +194,18 @@ impl Build {
147194
}
148195

149196
if target.contains("msvc") {
150-
// On MSVC we need nasm.exe to compile the assembly files, but let's
151-
// just pessimistically assume for now that's not available.
152-
configure.arg("no-asm");
197+
// On MSVC we need nasm.exe to compile the assembly files.
198+
// ASM compiling will be enabled if nasm.exe is installed, unless
199+
// the environment variable `OPENSSL_RUST_USE_NASM` is set.
200+
if self.is_nasm_ready() {
201+
// a message to stdout, let user know asm is enabled
202+
println!(
203+
"{}: Enable the assembly language routines in building OpenSSL.",
204+
env!("CARGO_PKG_NAME")
205+
);
206+
} else {
207+
configure.arg("no-asm");
208+
}
153209
}
154210

155211
let os = match target {

0 commit comments

Comments
 (0)