@@ -2,19 +2,54 @@ extern crate bindgen;
22
33use std:: env;
44use std:: fs;
5+ use std:: io:: { self , Result } ;
56use std:: path:: Path ;
67use std:: path:: PathBuf ;
78use std:: process:: Command ;
89
10+ /// Version-related constants for WolfSSL
11+ const WOLFSSL_DIR : & str = "wolfssl-5.7.4-stable" ;
12+ const WOLFSSL_ZIP : & str = "wolfssl-5.7.4-stable.zip" ;
13+ const WOLFSSL_URL : & str = "https://github.com/wolfSSL/wolfssl/archive/refs/tags/v5.7.4-stable.zip" ;
14+
15+ /// Entry point for the build script.
16+ /// Handles the main build process and exits with an error code if anything fails.
917fn main ( ) {
10- // We check if the release was already fetched, if not,
11- // we fetch it and setup it.
12- if fs:: metadata ( "wolfssl-5.7.6-stable" ) . is_err ( ) {
13- setup_wolfssl ( ) ;
18+ if let Err ( e) = run_build ( ) {
19+ eprintln ! ( "Build failed: {}" , e) ;
20+ std:: process:: exit ( 1 ) ;
1421 }
22+ }
23+
24+ /// Orchestrates the entire build process.
25+ ///
26+ /// This function:
27+ /// 1. Checks if WolfSSL needs to be set up
28+ /// 2. Sets up WolfSSL if necessary
29+ /// 3. Generates Rust bindings for the WolfSSL library
30+ ///
31+ /// Returns `Ok(())` if successful, or an error if any step fails.
32+ fn run_build ( ) -> Result < ( ) > {
33+ if fs:: metadata ( WOLFSSL_DIR ) . is_err ( ) {
34+ setup_wolfssl ( ) ?;
35+ }
36+
37+ generate_bindings ( ) ?;
38+ Ok ( ( ) )
39+ }
1540
16- let wolfssl_lib_dir = Path :: new ( & "/opt/wolfssl-rs/lib/" ) ;
17- let wolfssl_include_dir = Path :: new ( & "/opt/wolfssl-rs/include/" ) ;
41+ /// Generates Rust bindings for the WolfSSL library using bindgen.
42+ ///
43+ /// This function:
44+ /// 1. Sets up the library and include paths
45+ /// 2. Configures the build environment
46+ /// 3. Generates Rust bindings using bindgen
47+ /// 4. Writes the bindings to a file
48+ ///
49+ /// Returns `Ok(())` if successful, or an error if binding generation fails.
50+ fn generate_bindings ( ) -> Result < ( ) > {
51+ let wolfssl_lib_dir = Path :: new ( "/opt/wolfssl-rs/lib/" ) ;
52+ let wolfssl_include_dir = Path :: new ( "/opt/wolfssl-rs/include/" ) ;
1853
1954 println ! (
2055 "cargo:rustc-link-search={}" ,
@@ -27,130 +62,163 @@ fn main() {
2762 . clang_arg ( format ! ( "-I{}/" , wolfssl_include_dir. to_str( ) . unwrap( ) ) )
2863 . parse_callbacks ( Box :: new ( bindgen:: CargoCallbacks :: new ( ) ) )
2964 . generate ( )
30- . expect ( "Unable to generate bindings") ;
65+ . map_err ( |_| io :: Error :: new ( io :: ErrorKind :: Other , "Failed to generate bindings") ) ? ;
3166
3267 let out_path = PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) ;
3368 bindings
3469 . write_to_file ( out_path. join ( "bindings.rs" ) )
35- . expect ( "Couldn't write bindings!" ) ;
70+ . map_err ( |e| {
71+ io:: Error :: new (
72+ io:: ErrorKind :: Other ,
73+ format ! ( "Couldn't write bindings: {}" , e) ,
74+ )
75+ } )
76+ }
77+
78+ /// Coordinates the complete setup process for WolfSSL.
79+ ///
80+ /// This function executes all necessary steps in sequence:
81+ /// 1. Downloads the WolfSSL source
82+ /// 2. Extracts the archive
83+ /// 3. Removes the downloaded archive
84+ /// 4. Builds WolfSSL from source
85+ /// 5. Returns to the original directory
86+ ///
87+ /// Returns `Ok(())` if all steps complete successfully, or an error if any step fails.
88+ fn setup_wolfssl ( ) -> Result < ( ) > {
89+ download_wolfssl ( ) ?;
90+ unzip_wolfssl ( ) ?;
91+ remove_zip ( ) ?;
92+ build_wolfssl ( ) ?;
93+ change_back_to_root ( ) ?;
94+ Ok ( ( ) )
3695}
3796
38- fn setup_wolfssl ( ) {
39- // Step 1: Download the ZIP file using curl
97+ /// Downloads the WolfSSL source code archive using curl.
98+ ///
99+ /// Uses curl to download the specified version of WolfSSL from the official repository.
100+ /// The download URL and filename are defined in the constants.
101+ ///
102+ /// Returns `Ok(())` if the download succeeds, or an error if the download fails.
103+ fn download_wolfssl ( ) -> Result < ( ) > {
40104 let output = Command :: new ( "curl" )
41105 . arg ( "-L" )
42106 . arg ( "-o" )
43- . arg ( "wolfssl-5.7.6-stable.zip" )
44- . arg ( "https://github.com/wolfSSL/wolfssl/archive/refs/tags/v5.7.6-stable.zip" )
45- . output ( )
46- . expect ( "Failed to execute curl command" ) ;
47-
48- if output. status . success ( ) {
49- println ! ( "Download completed successfully." ) ;
50-
51- // Step 2: Unzip the downloaded file
52- let output = Command :: new ( "unzip" )
53- . arg ( "wolfssl-5.7.6-stable.zip" )
54- . output ( )
55- . expect ( "Failed to execute unzip command" ) ;
56-
57- if output. status . success ( ) {
58- println ! ( "Unzipping completed successfully." ) ;
59-
60- // Step 3: Remove the ZIP file
61- if let Err ( e) = fs:: remove_file ( "wolfssl-5.7.6-stable.zip" ) {
62- eprintln ! ( "Error removing ZIP file: {}" , e) ;
63- } else {
64- println ! ( "Removed ZIP file successfully." ) ;
65- }
66-
67- // Step 4: Change the current working directory to the unzipped folder
68- if let Err ( e) = env:: set_current_dir ( "wolfssl-5.7.6-stable" ) {
69- eprintln ! ( "Error changing directory: {}" , e) ;
70- } else {
71- println ! ( "Changed directory to wolfssl-5.7.6-stable." ) ;
72-
73- // Step 5: Execute ./autogen.sh
74- let output = Command :: new ( "./autogen.sh" )
75- . output ( )
76- . expect ( "Failed to execute ./autogen.sh" ) ;
77-
78- if output. status . success ( ) {
79- println ! ( "./autogen.sh completed successfully." ) ;
80-
81- // Step 6: Execute ./configure
82- let output = Command :: new ( "./configure" )
83- . arg ( "--enable-all" )
84- . arg ( "--enable-all-crypto" )
85- . arg ( "--enable-debug" )
86- . arg ( "--disable-shared" )
87- . arg ( "--prefix=/opt/wolfssl-rs/" )
88- . output ( )
89- . expect ( "Failed to execute ./configure" ) ;
90-
91- if output. status . success ( ) {
92- println ! ( "./configure completed successfully." ) ;
93-
94- // Step 7: Execute make
95- let output = Command :: new ( "make" )
96- . output ( )
97- . expect ( "Failed to execute make" ) ;
98-
99- if output. status . success ( ) {
100- println ! ( "make completed successfully." ) ;
101-
102- // Step 8: Execute sudo make install
103- let output = Command :: new ( "sudo" )
104- . arg ( "make" )
105- . arg ( "install" )
106- . output ( )
107- . expect ( "Failed to execute sudo make install" ) ;
108-
109- if output. status . success ( ) {
110- println ! ( "sudo make install completed successfully." ) ;
111- } else {
112- eprintln ! (
113- "Error executing sudo make install: {}" ,
114- String :: from_utf8_lossy( & output. stderr)
115- ) ;
116- }
117- } else {
118- eprintln ! (
119- "Error executing make: {}" ,
120- String :: from_utf8_lossy( & output. stderr)
121- ) ;
122- }
123- } else {
124- eprintln ! (
125- "Error executing ./configure: {}" ,
126- String :: from_utf8_lossy( & output. stderr)
127- ) ;
128- }
129- } else {
130- eprintln ! (
131- "Error executing ./autogen.sh: {}" ,
132- String :: from_utf8_lossy( & output. stderr)
133- ) ;
134- }
135- }
136- } else {
137- eprintln ! (
138- "Error unzipping file: {}" ,
107+ . arg ( WOLFSSL_ZIP )
108+ . arg ( WOLFSSL_URL )
109+ . output ( ) ?;
110+
111+ if !output. status . success ( ) {
112+ return Err ( io:: Error :: new (
113+ io:: ErrorKind :: Other ,
114+ format ! (
115+ "Failed to download: {}" ,
116+ String :: from_utf8_lossy( & output. stderr)
117+ ) ,
118+ ) ) ;
119+ }
120+ println ! ( "Download completed successfully." ) ;
121+ Ok ( ( ) )
122+ }
123+
124+ /// Extracts the downloaded WolfSSL archive.
125+ ///
126+ /// Uses the unzip command to extract the contents of the downloaded ZIP file.
127+ /// The archive name is defined in the constants.
128+ ///
129+ /// Returns `Ok(())` if extraction succeeds, or an error if it fails.
130+ fn unzip_wolfssl ( ) -> Result < ( ) > {
131+ let output = Command :: new ( "unzip" ) . arg ( WOLFSSL_ZIP ) . output ( ) ?;
132+
133+ if !output. status . success ( ) {
134+ return Err ( io:: Error :: new (
135+ io:: ErrorKind :: Other ,
136+ format ! (
137+ "Failed to unzip: {}" ,
139138 String :: from_utf8_lossy( & output. stderr)
140- ) ;
141- }
142- } else {
143- eprintln ! (
144- "Error downloading file: {}" ,
145- String :: from_utf8_lossy( & output. stderr)
146- ) ;
139+ ) ,
140+ ) ) ;
147141 }
142+ println ! ( "Unzipping completed successfully." ) ;
143+ Ok ( ( ) )
144+ }
145+
146+ /// Removes the downloaded ZIP file after extraction.
147+ ///
148+ /// This cleanup step removes the ZIP file to save disk space.
149+ ///
150+ /// Returns `Ok(())` if removal succeeds, or an error if it fails.
151+ fn remove_zip ( ) -> Result < ( ) > {
152+ fs:: remove_file ( WOLFSSL_ZIP ) ?;
153+ println ! ( "Removed ZIP file successfully." ) ;
154+ Ok ( ( ) )
155+ }
148156
149- // Final step: we change the directory back to the root directory
150- // to finally generate the bindings.
151- if let Err ( e) = env:: set_current_dir ( "../" ) {
152- eprintln ! ( "Error changing directory: {}" , e) ;
153- } else {
154- println ! ( "Changed directory to wolfssl-5.7.6-stable." ) ;
157+ /// Builds WolfSSL from source.
158+ ///
159+ /// This function:
160+ /// 1. Changes to the source directory
161+ /// 2. Runs autogen.sh to generate build files
162+ /// 3. Configures the build with specific options
163+ /// 4. Builds the library
164+ /// 5. Installs the library system-wide
165+ ///
166+ /// Returns `Ok(())` if all build steps succeed, or an error if any step fails.
167+ fn build_wolfssl ( ) -> Result < ( ) > {
168+ env:: set_current_dir ( WOLFSSL_DIR ) ?;
169+ println ! ( "Changed directory to {}." , WOLFSSL_DIR ) ;
170+
171+ run_command ( "./autogen.sh" , & [ ] ) ?;
172+ run_command (
173+ "./configure" ,
174+ & [
175+ "--enable-all" ,
176+ "--enable-all-crypto" ,
177+ "--enable-debug" ,
178+ "--disable-shared" ,
179+ "--prefix=/opt/wolfssl-rs/" ,
180+ ] ,
181+ ) ?;
182+ run_command ( "make" , & [ ] ) ?;
183+ run_command ( "sudo" , & [ "make" , "install" ] ) ?;
184+
185+ Ok ( ( ) )
186+ }
187+
188+ /// Helper function to execute shell commands.
189+ ///
190+ /// Executes a command with given arguments and handles the output appropriately.
191+ ///
192+ /// # Arguments
193+ /// * `cmd` - The command to execute
194+ /// * `args` - Array of arguments for the command
195+ ///
196+ /// Returns `Ok(())` if the command executes successfully, or an error if it fails.
197+ fn run_command ( cmd : & str , args : & [ & str ] ) -> Result < ( ) > {
198+ let output = Command :: new ( cmd) . args ( args) . output ( ) ?;
199+
200+ if !output. status . success ( ) {
201+ return Err ( io:: Error :: new (
202+ io:: ErrorKind :: Other ,
203+ format ! (
204+ "Failed to execute {}: {}" ,
205+ cmd,
206+ String :: from_utf8_lossy( & output. stderr)
207+ ) ,
208+ ) ) ;
155209 }
210+ println ! ( "{} completed successfully." , cmd) ;
211+ Ok ( ( ) )
212+ }
213+
214+ /// Changes the working directory back to the root directory.
215+ ///
216+ /// This function is called after building WolfSSL to return to the original
217+ /// working directory for the rest of the build process.
218+ ///
219+ /// Returns `Ok(())` if the directory change succeeds, or an error if it fails.
220+ fn change_back_to_root ( ) -> Result < ( ) > {
221+ env:: set_current_dir ( "../" ) ?;
222+ println ! ( "Changed directory back to root." ) ;
223+ Ok ( ( ) )
156224}
0 commit comments