@@ -193,6 +193,17 @@ async function readCmakeSharedLibraryTarget(
193193 return sharedLibrary ;
194194}
195195
196+ async function getCompilerPath (
197+ name : "clang" | "clang++" ,
198+ { buildBinPath, ccachePath } : { buildBinPath : string ; ccachePath : string } ,
199+ ) {
200+ const result = path . join ( buildBinPath , name ) ;
201+ if ( ! fs . existsSync ( result ) ) {
202+ await fs . promises . symlink ( ccachePath , result ) ;
203+ }
204+ return result ;
205+ }
206+
196207export const platform : Platform < Triplet [ ] , AppleOpts > = {
197208 id : "apple" ,
198209 name : "Apple" ,
@@ -245,16 +256,40 @@ export const platform: Platform<Triplet[], AppleOpts> = {
245256 } ,
246257 async configure (
247258 triplets ,
248- { source, build, define, weakNodeApiLinkage, cmakeJs } ,
249- spawn ,
259+ { source, build, define, weakNodeApiLinkage, cmakeJs, ccachePath } ,
250260 ) {
261+ // When using ccache, we're creating symlinks for the clang and clang++ binaries to the ccache binary
262+ // This is needed for ccache to understand it's being invoked as clang and clang++ respectively.
263+ const buildBinPath = path . join ( build , "bin" ) ;
264+ await fs . promises . mkdir ( buildBinPath , { recursive : true } ) ;
265+ const compilerDefinitions = ccachePath
266+ ? {
267+ CMAKE_XCODE_ATTRIBUTE_CC : await getCompilerPath ( "clang" , {
268+ buildBinPath,
269+ ccachePath,
270+ } ) ,
271+ CMAKE_XCODE_ATTRIBUTE_CXX : await getCompilerPath ( "clang++" , {
272+ buildBinPath,
273+ ccachePath,
274+ } ) ,
275+ CMAKE_XCODE_ATTRIBUTE_LD : await getCompilerPath ( "clang" , {
276+ buildBinPath,
277+ ccachePath,
278+ } ) ,
279+ CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS : await getCompilerPath ( "clang++" , {
280+ buildBinPath,
281+ ccachePath,
282+ } ) ,
283+ }
284+ : { } ;
285+
251286 // Ideally, we would generate a single Xcode project supporting all architectures / platforms
252287 // However, CMake's Xcode generator does not support that well, so we generate one project per triplet
253288 // Specifically, the linking of weak-node-api breaks, since the sdk / arch specific framework
254289 // from the xcframework is picked at configure time, not at build time.
255290 // See https://gitlab.kitware.com/cmake/cmake/-/issues/21752#note_1717047 for more information.
256291 await Promise . all (
257- triplets . map ( async ( { triplet } ) => {
292+ triplets . map ( async ( { triplet, spawn } ) => {
258293 const buildPath = getBuildPath ( build , triplet ) ;
259294 // We want to use the CMake File API to query information later
260295 // TODO: Or do we?
@@ -272,16 +307,15 @@ export const platform: Platform<Triplet[], AppleOpts> = {
272307 "Xcode" ,
273308 ...toDefineArguments ( [
274309 ...define ,
275- ...( weakNodeApiLinkage ? [ getWeakNodeApiVariables ( "apple" ) ] : [ ] ) ,
276- ...( cmakeJs ? [ getCmakeJSVariables ( "apple" ) ] : [ ] ) ,
310+ weakNodeApiLinkage ? getWeakNodeApiVariables ( "apple" ) : { } ,
311+ cmakeJs ? getCmakeJSVariables ( "apple" ) : { } ,
312+ compilerDefinitions ,
277313 {
278314 CMAKE_SYSTEM_NAME : CMAKE_SYSTEM_NAMES [ triplet ] ,
279315 CMAKE_OSX_SYSROOT : XCODE_SDK_NAMES [ triplet ] ,
280316 CMAKE_OSX_ARCHITECTURES : APPLE_ARCHITECTURES [ triplet ] ,
281317 // Passing a linker flag to increase the header pad size to allow renaming the install name when linking it into the app.
282318 CMAKE_SHARED_LINKER_FLAGS : "-Wl,-headerpad_max_install_names" ,
283- } ,
284- {
285319 // Setting the output directories works around an issue with Xcode generator
286320 // where an unexpanded variable would emitted in the artifact paths.
287321 // This is okay, since we're generating per triplet build directories anyway.
0 commit comments