@@ -12,20 +12,14 @@ import {
1212 assertFixable ,
1313 wrapAction ,
1414} from "@react-native-node-api/cli-utils" ;
15- import { isSupportedTriplet } from "react-native-node-api" ;
16- import * as cmakeFileApi from "cmake-file-api" ;
1715
18- import {
19- getCmakeJSVariables ,
20- getWeakNodeApiVariables ,
21- } from "./weak-node-api.js" ;
2216import {
2317 platforms ,
2418 allTriplets as allTriplets ,
2519 findPlatformForTriplet ,
2620 platformHasTriplet ,
2721} from "./platforms.js" ;
28- import { BaseOpts , TripletContext , Platform } from "./platforms/types.js" ;
22+ import { BaseOpts , Platform } from "./platforms/types.js" ;
2923
3024// We're attaching a lot of listeners when spawning in parallel
3125EventEmitter . defaultMaxListeners = 100 ;
@@ -74,7 +68,9 @@ const tripletOption = new Option(
7468const buildPathOption = new Option (
7569 "--build <path>" ,
7670 "Specify the build directory to store the configured CMake project" ,
77- ) ;
71+ )
72+ . argParser ( ( input ) => path . resolve ( process . cwd ( ) , input ) )
73+ . default ( path . resolve ( process . cwd ( ) , "build" ) , "./build" ) ;
7874
7975const cleanOption = new Option (
8076 "--clean" ,
@@ -84,7 +80,7 @@ const cleanOption = new Option(
8480const outPathOption = new Option (
8581 "--out <path>" ,
8682 "Specify the output directory to store the final build artifacts" ,
87- ) . default ( false , "./ {build}/{configuration}") ;
83+ ) . default ( " {build}/{configuration}") ;
8884
8985const defineOption = new Option (
9086 "-D,--define <entry...>" ,
@@ -151,18 +147,33 @@ for (const platform of platforms) {
151147 program = platform . amendCommand ( program ) ;
152148}
153149
150+ function expandTemplate (
151+ input : string ,
152+ values : Record < string , unknown > ,
153+ ) : string {
154+ return input . replaceAll ( / { ( [ ^ } ] + ) } / g, ( _ , key : string ) =>
155+ typeof values [ key ] === "string" ? values [ key ] : "" ,
156+ ) ;
157+ }
158+
154159program = program . action (
155160 wrapAction ( async ( { triplet : requestedTriplets , ...baseOptions } ) => {
161+ const buildPath = getBuildPath ( baseOptions ) ;
162+ baseOptions . out = path . resolve (
163+ process . cwd ( ) ,
164+ expandTemplate ( baseOptions . out , baseOptions ) ,
165+ ) ;
166+ const { verbose, clean, source, out } = baseOptions ;
167+
156168 assertFixable (
157- fs . existsSync ( path . join ( baseOptions . source , "CMakeLists.txt" ) ) ,
158- `No CMakeLists.txt found in source directory: ${ chalk . dim ( baseOptions . source ) } ` ,
169+ fs . existsSync ( path . join ( source , "CMakeLists.txt" ) ) ,
170+ `No CMakeLists.txt found in source directory: ${ chalk . dim ( source ) } ` ,
159171 {
160172 instructions : `Change working directory into a directory with a CMakeLists.txt, create one or specify the correct source directory using --source` ,
161173 } ,
162174 ) ;
163175
164- const buildPath = getBuildPath ( baseOptions ) ;
165- if ( baseOptions . clean ) {
176+ if ( clean ) {
166177 await fs . promises . rm ( buildPath , { recursive : true , force : true } ) ;
167178 }
168179 const triplets = new Set < string > ( requestedTriplets ) ;
@@ -197,31 +208,49 @@ program = program.action(
197208 }
198209 }
199210
200- if ( ! baseOptions . out ) {
201- baseOptions . out = path . join ( buildPath , baseOptions . configuration ) ;
202- }
203-
204211 const tripletContexts = [ ...triplets ] . map ( ( triplet ) => {
205212 const platform = findPlatformForTriplet ( triplet ) ;
206- const tripletBuildPath = getTripletBuildPath ( buildPath , triplet ) ;
213+
207214 return {
208215 triplet,
209216 platform,
210- buildPath : tripletBuildPath ,
211- outputPath : path . join ( tripletBuildPath , "out" ) ,
212- options : baseOptions ,
217+ async spawn ( command : string , args : string [ ] , cwd ?: string ) {
218+ await spawn ( command , args , {
219+ outputMode : verbose ? "inherit" : "buffered" ,
220+ outputPrefix : verbose ? chalk . dim ( `[${ triplet } ] ` ) : undefined ,
221+ cwd,
222+ } ) ;
223+ } ,
213224 } ;
214225 } ) ;
215226
216227 // Configure every triplet project
217228 const tripletsSummary = chalk . dim (
218229 `(${ getTripletsSummary ( tripletContexts ) } )` ,
219230 ) ;
231+
232+ // Perform configure steps for each platform in sequence
220233 await oraPromise (
221234 Promise . all (
222- tripletContexts . map ( ( { platform, ...context } ) =>
223- configureProject ( platform , context , baseOptions ) ,
224- ) ,
235+ platforms . map ( async ( platform ) => {
236+ const relevantTriplets = tripletContexts . filter ( ( { triplet } ) =>
237+ platformHasTriplet ( platform , triplet ) ,
238+ ) ;
239+ if ( relevantTriplets . length > 0 ) {
240+ await platform . configure (
241+ relevantTriplets ,
242+ baseOptions ,
243+ ( command , args , cwd ) =>
244+ spawn ( command , args , {
245+ outputMode : verbose ? "inherit" : "buffered" ,
246+ outputPrefix : verbose
247+ ? chalk . dim ( `[${ platform . name } ] ` )
248+ : undefined ,
249+ cwd,
250+ } ) ,
251+ ) ;
252+ }
253+ } ) ,
225254 ) ,
226255 {
227256 text : `Configuring projects ${ tripletsSummary } ` ,
@@ -235,13 +264,14 @@ program = program.action(
235264 await oraPromise (
236265 Promise . all (
237266 tripletContexts . map ( async ( { platform, ...context } ) => {
238- // Delete any stale build artifacts before building
239- // This is important, since we might rename the output files
240- await fs . promises . rm ( context . outputPath , {
241- recursive : true ,
242- force : true ,
243- } ) ;
244- await buildProject ( platform , context , baseOptions ) ;
267+ // TODO: Consider if this is still important 😬
268+ // // Delete any stale build artifacts before building
269+ // // This is important, since we might rename the output files
270+ // await fs.promises.rm(context.outputPath, {
271+ // recursive: true,
272+ // force: true,
273+ // });
274+ await platform . build ( context , baseOptions ) ;
245275 } ) ,
246276 ) ,
247277 {
@@ -253,20 +283,15 @@ program = program.action(
253283 ) ;
254284
255285 // Perform post-build steps for each platform in sequence
286+ // console.log("📦 Writing prebuilds to:", prettyPath(out));
256287 for ( const platform of platforms ) {
257288 const relevantTriplets = tripletContexts . filter ( ( { triplet } ) =>
258289 platformHasTriplet ( platform , triplet ) ,
259290 ) ;
260291 if ( relevantTriplets . length == 0 ) {
261292 continue ;
262293 }
263- await platform . postBuild (
264- {
265- outputPath : baseOptions . out || baseOptions . source ,
266- triplets : relevantTriplets ,
267- } ,
268- baseOptions ,
269- ) ;
294+ await platform . postBuild ( out , relevantTriplets , baseOptions ) ;
270295 }
271296 } ) ,
272297) ;
@@ -293,92 +318,4 @@ function getBuildPath({ build, source }: BaseOpts) {
293318 return path . resolve ( process . cwd ( ) , build || path . join ( source , "build" ) ) ;
294319}
295320
296- /**
297- * Namespaces the output path with a triplet name
298- */
299- function getTripletBuildPath ( buildPath : string , triplet : unknown ) {
300- assert ( typeof triplet === "string" , "Expected triplet to be a string" ) ;
301- return path . join ( buildPath , triplet . replace ( / ; / g, "_" ) ) ;
302- }
303-
304- async function configureProject < T extends string > (
305- platform : Platform < T [ ] , Record < string , unknown > > ,
306- context : TripletContext < T > ,
307- options : BaseOpts ,
308- ) {
309- const { triplet, buildPath, outputPath } = context ;
310- const { verbose, source, weakNodeApiLinkage, cmakeJs } = options ;
311-
312- // TODO: Make the two following definitions a part of the platform definition
313-
314- const nodeApiDefinitions =
315- weakNodeApiLinkage && isSupportedTriplet ( triplet )
316- ? [ getWeakNodeApiVariables ( triplet ) ]
317- : [ ] ;
318-
319- const cmakeJsDefinitions =
320- cmakeJs && isSupportedTriplet ( triplet )
321- ? [ getCmakeJSVariables ( triplet ) ]
322- : [ ] ;
323-
324- const definitions = [
325- ...nodeApiDefinitions ,
326- ...cmakeJsDefinitions ,
327- ...options . define ,
328- { CMAKE_LIBRARY_OUTPUT_DIRECTORY : outputPath } ,
329- ] ;
330-
331- await cmakeFileApi . createSharedStatelessQuery ( buildPath , "codemodel" , "2" ) ;
332-
333- await spawn (
334- "cmake" ,
335- [
336- "-S" ,
337- source ,
338- "-B" ,
339- buildPath ,
340- ...platform . configureArgs ( context , options ) ,
341- ...toDefineArguments ( definitions ) ,
342- ] ,
343- {
344- outputMode : verbose ? "inherit" : "buffered" ,
345- outputPrefix : verbose ? chalk . dim ( `[${ triplet } ] ` ) : undefined ,
346- } ,
347- ) ;
348- }
349-
350- async function buildProject < T extends string > (
351- platform : Platform < T [ ] , Record < string , unknown > > ,
352- context : TripletContext < T > ,
353- options : BaseOpts ,
354- ) {
355- const { triplet, buildPath } = context ;
356- const { verbose, configuration } = options ;
357- await spawn (
358- "cmake" ,
359- [
360- "--build" ,
361- buildPath ,
362- "--config" ,
363- configuration ,
364- ...( options . target . length > 0 ? [ "--target" , ...options . target ] : [ ] ) ,
365- "--" ,
366- ...platform . buildArgs ( context , options ) ,
367- ] ,
368- {
369- outputMode : verbose ? "inherit" : "buffered" ,
370- outputPrefix : verbose ? chalk . dim ( `[${ triplet } ] ` ) : undefined ,
371- } ,
372- ) ;
373- }
374-
375- function toDefineArguments ( declarations : Array < Record < string , string > > ) {
376- return declarations . flatMap ( ( values ) =>
377- Object . entries ( values ) . flatMap ( ( [ key , definition ] ) => [
378- "-D" ,
379- `${ key } =${ definition } ` ,
380- ] ) ,
381- ) ;
382- }
383-
384321export { program } ;
0 commit comments