@@ -115,13 +115,30 @@ impl callbacks::ParseCallbacks for FilterCargoCallbacks {
115
115
}
116
116
}
117
117
118
+ fn probe_system_ffmpeg ( ) -> Result < ( ) , String > {
119
+ match ( & * LIBS )
120
+ . iter ( )
121
+ . map ( |name| "lib" . to_owned ( ) + name)
122
+ . filter_map ( |libname| {
123
+ pkgconfig:: Config :: new ( )
124
+ . statik ( true )
125
+ // Remove side effect
126
+ . cargo_metadata ( false )
127
+ . probe ( & libname)
128
+ . is_err ( )
129
+ } ) {
130
+ Some ( libname) => Err ( format ! ( "{} not found!" , libname) ) ,
131
+ None => Ok ( ( ) ) ,
132
+ }
133
+ }
134
+
118
135
fn main ( ) {
119
136
// If it's a documentation generation from docs.rs, just copy the bindings
120
137
// generated locally to `OUT_DIR`. We do this because the building
121
138
// environment of docs.rs doesn't have an network connection, so we cannot
122
139
// git clone the FFmpeg. And they also have a limitation on crate's size:
123
- // 10MB, which is not enough to fit in full FFmpeg source files. So the only
124
- // thing we can do is copy the locally generated binding files to the
140
+ // 10MB, which is not enough to fit in FFmpeg source files. So the only
141
+ // thing we can do is copying the locally generated binding files to the
125
142
// `OUT_DIR`.
126
143
if env:: var ( "DOCS_RS" ) . is_ok ( ) {
127
144
fs:: copy ( "src/binding.rs" , & * BINDING_FILE_PATH )
@@ -130,127 +147,128 @@ fn main() {
130
147
}
131
148
132
149
if env:: var ( "PKG_CONFIG_PATH" ) . is_err ( ) {
133
- // All outputs are stored in ./ffmpeg/build/{bin, lib, share, include}
134
- // If no prebuilt FFmpeg libraries provided, we custom build a FFmpeg.
135
- env:: set_var (
136
- "PKG_CONFIG_PATH" ,
137
- format ! ( "{}/build/lib/pkgconfig" , * FFMPEG_DIR ) ,
138
- ) ;
139
- env:: set_var ( "PATH" , format ! ( "{}/build/bin:{}" , * FFMPEG_DIR , * PATH ) ) ;
150
+ match probe_system_ffmpeg ( ) {
151
+ // No system FFmpeg found, download and build one
152
+ Err ( msg) => {
153
+ // All outputs are stored in ./ffmpeg/build/{bin, lib, share, include}
154
+ // If no prebuilt FFmpeg libraries provided, we custom build a FFmpeg.
155
+ env:: set_var (
156
+ "PKG_CONFIG_PATH" ,
157
+ format ! ( "{}/build/lib/pkgconfig" , * FFMPEG_DIR ) ,
158
+ ) ;
159
+ env:: set_var ( "PATH" , format ! ( "{}/build/bin:{}" , * FFMPEG_DIR , * PATH ) ) ;
140
160
141
- // Check if submodule is not get cloned.
142
- if !path:: PathBuf :: from ( format ! ( "{}/fftools" , & * FFMPEG_DIR ) ) . is_dir ( ) {
143
- Command :: new ( "git" )
144
- . current_dir ( & * OUT_DIR )
145
- . args ( [ "clone" , "https://github.com/ffmpeg/ffmpeg" , "--depth" , "1" ] . iter ( ) )
146
- . spawn ( )
147
- . expect ( "FFmpeg submodule failed to clone." )
148
- . wait ( )
149
- . expect ( "FFmpeg submodule failed to clone." ) ;
150
- }
161
+ // Check if FFmpeg is not get cloned.
162
+ if !path:: PathBuf :: from ( format ! ( "{}/fftools" , & * FFMPEG_DIR ) ) . is_dir ( ) {
163
+ Command :: new ( "git" )
164
+ . current_dir ( & * OUT_DIR )
165
+ . args ( [ "clone" , "https://github.com/ffmpeg/ffmpeg" , "--depth" , "1" ] . iter ( ) )
166
+ . spawn ( )
167
+ . expect ( "FFmpeg submodule failed to clone." )
168
+ . wait ( )
169
+ . expect ( "FFmpeg submodule failed to clone." ) ;
170
+ }
151
171
152
- // Corresponding to the shell script below:
153
- // ./configure \
154
- // --prefix="$PWD/build" \
155
- // --extra-cflags="-I$PWD/build/include" \
156
- // --extra-ldflags="-L$PWD/build/lib" \
157
- // --bindir="$PWD/build/bin" \
158
- // --pkg-config-flags="--static" \
159
- // --extra-libs="-lpthread -lm" \
160
- // --enable-gpl \
161
- // --enable-libass \
162
- // --enable-libfdk-aac \
163
- // --enable-libfreetype \
164
- // --enable-libmp3lame \
165
- // --enable-libopus \
166
- // --enable-libvorbis \
167
- // --enable-libvpx \
168
- // --enable-libx264 \
169
- // --enable-libx265 \
170
- // --enable-nonfree
171
- Command :: new ( format ! ( "{}/configure" , * FFMPEG_DIR ) )
172
- . current_dir ( & * FFMPEG_DIR )
173
- . env (
174
- "PKG_CONFIG_PATH" ,
175
- format ! ( "{}/build/lib/pkgconfig" , * FFMPEG_DIR ) ,
176
- )
177
- . args (
178
- [
179
- format ! ( r#"--prefix={}/build"# , * FFMPEG_DIR ) ,
180
- format ! ( r#"--extra-cflags=-I{}/build/include"# , * FFMPEG_DIR ) ,
181
- format ! ( r#"--extra-ldflags=-L{}/build/lib"# , * FFMPEG_DIR ) ,
182
- format ! ( r#"--bindir={}/build/bin"# , * FFMPEG_DIR ) ,
183
- ]
184
- . iter ( ) ,
185
- )
186
- . args (
187
- [
188
- "--pkg-config-flags=--static" ,
189
- "--extra-libs=-lpthread -lm" ,
190
- "--enable-gpl" ,
191
- "--enable-libass" ,
192
- "--enable-libfdk-aac" ,
193
- "--enable-libfreetype" ,
194
- "--enable-libmp3lame" ,
195
- "--enable-libopus" ,
196
- "--enable-libvorbis" ,
197
- "--enable-libvpx" ,
198
- "--enable-libx264" ,
199
- "--enable-libx265" ,
200
- "--enable-nonfree" ,
201
- ]
202
- . iter ( ) ,
203
- )
204
- . spawn ( )
205
- . expect ( "FFmpeg build process: configure failed!" )
206
- . wait ( )
207
- . expect ( "FFmpeg build process: configure failed!" ) ;
172
+ // Corresponding to the shell script below:
173
+ // ./configure \
174
+ // --prefix="$PWD/build" \
175
+ // --extra-cflags="-I$PWD/build/include" \
176
+ // --extra-ldflags="-L$PWD/build/lib" \
177
+ // --bindir="$PWD/build/bin" \
178
+ // --pkg-config-flags="--static" \
179
+ // --extra-libs="-lpthread -lm" \
180
+ // --enable-gpl \
181
+ // --enable-libass \
182
+ // --enable-libfdk-aac \
183
+ // --enable-libfreetype \
184
+ // --enable-libmp3lame \
185
+ // --enable-libopus \
186
+ // --enable-libvorbis \
187
+ // --enable-libvpx \
188
+ // --enable-libx264 \
189
+ // --enable-libx265 \
190
+ // --enable-nonfree
191
+ Command :: new ( format ! ( "{}/configure" , * FFMPEG_DIR ) )
192
+ . current_dir ( & * FFMPEG_DIR )
193
+ . env (
194
+ "PKG_CONFIG_PATH" ,
195
+ format ! ( "{}/build/lib/pkgconfig" , * FFMPEG_DIR ) ,
196
+ )
197
+ . args (
198
+ [
199
+ format ! ( r#"--prefix={}/build"# , * FFMPEG_DIR ) ,
200
+ format ! ( r#"--extra-cflags=-I{}/build/include"# , * FFMPEG_DIR ) ,
201
+ format ! ( r#"--extra-ldflags=-L{}/build/lib"# , * FFMPEG_DIR ) ,
202
+ format ! ( r#"--bindir={}/build/bin"# , * FFMPEG_DIR ) ,
203
+ ]
204
+ . iter ( ) ,
205
+ )
206
+ . args (
207
+ [
208
+ "--pkg-config-flags=--static" ,
209
+ "--extra-libs=-lpthread -lm" ,
210
+ "--enable-gpl" ,
211
+ "--enable-libass" ,
212
+ "--enable-libfdk-aac" ,
213
+ "--enable-libfreetype" ,
214
+ "--enable-libmp3lame" ,
215
+ "--enable-libopus" ,
216
+ "--enable-libvorbis" ,
217
+ "--enable-libvpx" ,
218
+ "--enable-libx264" ,
219
+ "--enable-libx265" ,
220
+ "--enable-nonfree" ,
221
+ ]
222
+ . iter ( ) ,
223
+ )
224
+ . spawn ( )
225
+ . expect ( "FFmpeg build process: configure failed!" )
226
+ . wait ( )
227
+ . expect ( "FFmpeg build process: configure failed!" ) ;
208
228
209
- Command :: new ( "make" )
210
- . current_dir ( & * FFMPEG_DIR )
211
- . arg ( format ! ( "-j{}" , * NUM_CPUS ) )
212
- . spawn ( )
213
- . expect ( "FFmpeg build process: make compile failed!" )
214
- . wait ( )
215
- . expect ( "FFmpeg build process: make compile failed!" ) ;
229
+ Command :: new ( "make" )
230
+ . current_dir ( & * FFMPEG_DIR )
231
+ . arg ( format ! ( "-j{}" , * NUM_CPUS ) )
232
+ . spawn ( )
233
+ . expect ( "FFmpeg build process: make compile failed!" )
234
+ . wait ( )
235
+ . expect ( "FFmpeg build process: make compile failed!" ) ;
216
236
217
- Command :: new ( "make" )
218
- . current_dir ( & * FFMPEG_DIR )
219
- . arg ( format ! ( "-j{}" , * NUM_CPUS ) )
220
- . arg ( "install" )
221
- . spawn ( )
222
- . expect ( "FFmpeg build process: make install failed!" )
223
- . wait ( )
224
- . expect ( "FFmpeg build process: make install failed!" ) ;
237
+ Command :: new ( "make" )
238
+ . current_dir ( & * FFMPEG_DIR )
239
+ . arg ( format ! ( "-j{}" , * NUM_CPUS ) )
240
+ . arg ( "install" )
241
+ . spawn ( )
242
+ . expect ( "FFmpeg build process: make install failed!" )
243
+ . wait ( )
244
+ . expect ( "FFmpeg build process: make install failed!" ) ;
225
245
226
- /* Commented because it's not needed, we are not using any specific shell.
227
- Command::new("hash")
228
- .current_dir(&*FFMPEG_DIR)
229
- .arg("-r")
230
- .spawn()
231
- .expect("FFmpeg build process: clear hash cache failed!")
232
- .wait()
233
- .expect("FFmpeg build process: clear hash cache failed!");
234
- */
246
+ /* Commented because it's not needed, we are not using any specific shell.
247
+ Command::new("hash")
248
+ .current_dir(&*FFMPEG_DIR)
249
+ .arg("-r")
250
+ .spawn()
251
+ .expect("FFmpeg build process: clear hash cache failed!")
252
+ .wait()
253
+ .expect("FFmpeg build process: clear hash cache failed!");
254
+ */
255
+ }
256
+
257
+ // System FFmpeg found.
258
+ Ok ( _) => { }
259
+ }
235
260
}
236
261
237
262
// We currently only support building with static libraries.
238
-
239
- /* Thanks to pkg-config, we don't need this.
240
- // Output link libraries
241
- (&*LIBS)
242
- .iter()
243
- .for_each(|name| println!("cargo:rustc-link-lib={}={}", "static", name));
244
- */
245
-
246
263
// Probe libraries
247
- // TODO if not enabled, we should not probe it
264
+ // TODO if not enabled, we should not probe it. Should modify probe_system_ffmpeg() too.
248
265
let include_paths = ( & * LIBS )
249
266
. iter ( )
250
267
. map ( |name| "lib" . to_owned ( ) + name)
251
268
. map ( |libname| {
252
269
pkgconfig:: Config :: new ( )
253
270
. statik ( true )
271
+ . cargo_metadata ( true )
254
272
. probe ( & libname)
255
273
. unwrap_or_else ( |_| panic ! ( format!( "{} not found!" , libname) ) )
256
274
. include_paths
0 commit comments