@@ -47,9 +47,10 @@ class RustPlugin {
4747 dockerTag : DEFAULT_DOCKER_TAG ,
4848 dockerImage : DEFAULT_DOCKER_IMAGE ,
4949 dockerless : false ,
50+ strictMode : true ,
5051 } ,
5152 ( this . serverless . service . custom && this . serverless . service . custom . rust ) ||
52- { }
53+ { } ,
5354 ) ;
5455
5556 // Docker can't access resources outside of the current build directory.
@@ -74,15 +75,13 @@ class RustPlugin {
7475 ""
7576 ) . split ( / \s + / ) ;
7677
78+ let target = ( funcArgs || { } ) . target || this . custom . target ;
7779
78- let target = ( funcArgs || { } ) . target || this . custom . target
79-
80- const targetArgs =
81- target ?
82- [ '--target' , target ]
83- : MUSL_PLATFORMS . includes ( platform )
84- ? [ "--target" , "x86_64-unknown-linux-musl" ]
85- : [ ] ;
80+ const targetArgs = target
81+ ? [ "--target" , target ]
82+ : MUSL_PLATFORMS . includes ( platform )
83+ ? [ "--target" , "x86_64-unknown-linux-musl" ]
84+ : [ ] ;
8685 return [
8786 ...defaultArgs ,
8887 ...profileArgs ,
@@ -94,30 +93,29 @@ class RustPlugin {
9493 localBuildEnv ( funcArgs , env , platform ) {
9594 const defaultEnv = { ...env } ;
9695
97- let target = ( funcArgs || { } ) . target || this . custom . target
98- let linker = ( funcArgs || { } ) . linker || this . custom . linker
96+ let target = ( funcArgs || { } ) . target || this . custom . target ;
97+ let linker = ( funcArgs || { } ) . linker || this . custom . linker ;
9998
100- const platformEnv =
101- linker ?
102- {
99+ const platformEnv = linker
100+ ? {
103101 RUSTFLAGS : ( env [ "RUSTFLAGS" ] || "" ) + ` -Clinker=${ linker } ` ,
104102 TARGET_CC : linker ,
105- [ `CC_${ target || ' x86_64_unknown_linux_musl' } ` ] : linker ,
103+ [ `CC_${ target || " x86_64_unknown_linux_musl" } ` ] : linker ,
106104 }
107- : "win32" === platform
105+ : "win32" === platform
106+ ? {
107+ RUSTFLAGS : ( env [ "RUSTFLAGS" ] || "" ) + " -Clinker=rust-lld" ,
108+ TARGET_CC : "rust-lld" ,
109+ CC_x86_64_unknown_linux_musl : "rust-lld" ,
110+ }
111+ : "darwin" === platform
108112 ? {
109- RUSTFLAGS : ( env [ "RUSTFLAGS" ] || "" ) + " -Clinker=rust-lld" ,
110- TARGET_CC : "rust-lld" ,
111- CC_x86_64_unknown_linux_musl : "rust-lld" ,
113+ RUSTFLAGS :
114+ ( env [ "RUSTFLAGS" ] || "" ) + " -Clinker=x86_64-linux-musl-gcc" ,
115+ TARGET_CC : "x86_64-linux-musl-gcc" ,
116+ CC_x86_64_unknown_linux_musl : "x86_64-linux-musl-gcc" ,
112117 }
113- : "darwin" === platform
114- ? {
115- RUSTFLAGS :
116- ( env [ "RUSTFLAGS" ] || "" ) + " -Clinker=x86_64-linux-musl-gcc" ,
117- TARGET_CC : "x86_64-linux-musl-gcc" ,
118- CC_x86_64_unknown_linux_musl : "x86_64-linux-musl-gcc" ,
119- }
120- : { } ;
118+ : { } ;
121119 return {
122120 ...defaultEnv ,
123121 ...platformEnv ,
@@ -127,8 +125,11 @@ class RustPlugin {
127125 localSourceDir ( funcArgs , profile , platform ) {
128126 let executable = "target" ;
129127 if ( MUSL_PLATFORMS . includes ( platform ) ) {
130- let target = ( funcArgs || { } ) . target || this . custom . target
131- executable = path . join ( executable , target ? target : "x86_64-unknown-linux-musl" ) ;
128+ let target = ( funcArgs || { } ) . target || this . custom . target ;
129+ executable = path . join (
130+ executable ,
131+ target ? target : "x86_64-unknown-linux-musl" ,
132+ ) ;
132133 }
133134 return path . join ( executable , profile !== "dev" ? "release" : "debug" ) ;
134135 }
@@ -137,7 +138,7 @@ class RustPlugin {
137138 return path . join (
138139 "target" ,
139140 "lambda" ,
140- profile !== "dev" ? "release" : "debug"
141+ profile !== "dev" ? "release" : "debug" ,
141142 ) ;
142143 }
143144
@@ -147,7 +148,7 @@ class RustPlugin {
147148 cargoPackage ,
148149 binary ,
149150 profile ,
150- platform ( )
151+ platform ( ) ,
151152 ) ;
152153
153154 const env = this . localBuildEnv ( funcArgs , process . env , platform ( ) ) ;
@@ -169,7 +170,7 @@ class RustPlugin {
169170 "bootstrap" ,
170171 readFileSync ( path . join ( sourceDir , binary ) ) ,
171172 "" ,
172- 0o755
173+ 0o755 ,
173174 ) ;
174175 const targetDir = this . localArtifactDir ( profile ) ;
175176 try {
@@ -195,7 +196,7 @@ class RustPlugin {
195196 srcPath ,
196197 cargoRegistry ,
197198 cargoDownloads ,
198- env
199+ env ,
199200 ) {
200201 const defaultArgs = [
201202 "run" ,
@@ -251,7 +252,7 @@ class RustPlugin {
251252 this . srcPath ,
252253 cargoRegistry ,
253254 cargoDownloads ,
254- process . env
255+ process . env ,
255256 ) ;
256257
257258 this . serverless . cli . log ( "Running containerized build" ) ;
@@ -281,6 +282,7 @@ class RustPlugin {
281282
282283 /** the entry point for building functions */
283284 build ( ) {
285+ const strictMode = this . custom . strictMode !== false ;
284286 const service = this . serverless . service ;
285287 if ( service . provider . name != "aws" ) {
286288 return ;
@@ -289,55 +291,65 @@ class RustPlugin {
289291 this . functions ( ) . forEach ( ( funcName ) => {
290292 const func = service . getFunction ( funcName ) ;
291293 const runtime = func . runtime || service . provider . runtime ;
292- if ( runtime != RUST_RUNTIME ) {
294+
295+ func . tags = func . tags || { } ;
296+ if ( ! ( runtime === RUST_RUNTIME || func . tags . language === "rust" ) ) {
293297 // skip functions which don't apply to rust
294298 return ;
295299 }
296300 rustFunctionsFound = true ;
297- const { cargoPackage, binary } = this . cargoBinary ( func ) ;
298301
299- this . serverless . cli . log ( `Building Rust ${ func . handler } func...` ) ;
300- let profile = ( func . rust || { } ) . profile || this . custom . profile ;
301-
302- const res = this . buildLocally ( func )
303- ? this . localBuild ( func . rust , cargoPackage , binary , profile )
304- : this . dockerBuild ( func . rust , cargoPackage , binary , profile ) ;
305- if ( res . error || res . status > 0 ) {
302+ func . package = func . package || { } ;
303+ if ( func . package . artifact && func . package . artifact !== "" ) {
306304 this . serverless . cli . log (
307- `Rust build encountered an error: ${ res . error } ${ res . status } .`
305+ `Artifact defined for ${ func . handler } , skipping build...` ,
308306 ) ;
309- throw new Error ( res . error ) ;
310- }
311- // If all went well, we should now have find a packaged compiled binary under `target/lambda/release`.
312- //
313- // The AWS "provided" lambda runtime requires executables to be named
314- // "bootstrap" -- https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html
315- //
316- // To avoid artifact naming conflicts when we potentially have more than one function
317- // we leverage the ability to declare a package artifact directly
318- // see https://serverless.com/framework/docs/providers/aws/guide/packaging/
319- // for more information
320- const artifactPath = path . join (
321- this . srcPath ,
322- `target/lambda/${ "dev" === profile ? "debug" : "release" } ` ,
323- `${ binary } .zip`
324- ) ;
325- func . package = func . package || { } ;
326- func . package . artifact = artifactPath ;
307+ } else {
308+ const { cargoPackage, binary } = this . cargoBinary ( func ) ;
309+
310+ this . serverless . cli . log ( `Building Rust ${ func . handler } func...` ) ;
311+ let profile = ( func . rust || { } ) . profile || this . custom . profile ;
312+
313+ const res = this . buildLocally ( func )
314+ ? this . localBuild ( func . rust , cargoPackage , binary , profile )
315+ : this . dockerBuild ( func . rust , cargoPackage , binary , profile ) ;
316+ if ( res . error || res . status > 0 ) {
317+ this . serverless . cli . log (
318+ `Rust build encountered an error: ${ res . error } ${ res . status } .` ,
319+ ) ;
320+ throw new Error ( res . error ) ;
321+ }
322+ // If all went well, we should now have find a packaged compiled binary under `target/lambda/release`.
323+ //
324+ // The AWS "provided" lambda runtime requires executables to be named
325+ // "bootstrap" -- https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html
326+ //
327+ // To avoid artifact naming conflicts when we potentially have more than one function
328+ // we leverage the ability to declare a package artifact directly
329+ // see https://serverless.com/framework/docs/providers/aws/guide/packaging/
330+ // for more information
331+ const artifactPath = path . join (
332+ this . srcPath ,
333+ `target/lambda/${ "dev" === profile ? "debug" : "release" } ` ,
334+ `${ binary } .zip` ,
335+ ) ;
336+ func . package = func . package || { } ;
337+ func . package . artifact = artifactPath ;
327338
328- // Ensure the runtime is set to a sane value for other plugins
329- if ( func . runtime == RUST_RUNTIME ) {
330- func . runtime = BASE_RUNTIME ;
339+ // Ensure the runtime is set to a sane value for other plugins
340+ if ( func . runtime == RUST_RUNTIME ) {
341+ func . runtime = BASE_RUNTIME ;
342+ }
331343 }
332344 } ) ;
333345 if ( service . provider . runtime === RUST_RUNTIME ) {
334346 service . provider . runtime = BASE_RUNTIME ;
335347 }
336- if ( ! rustFunctionsFound ) {
348+ if ( ! rustFunctionsFound && strictMode ) {
337349 throw new Error (
338350 `Error: no Rust functions found. ` +
339351 `Use 'runtime: ${ RUST_RUNTIME } ' in global or ` +
340- `function configuration to use this plugin.`
352+ `function configuration to use this plugin.` ,
341353 ) ;
342354 }
343355 }
0 commit comments