Skip to content

Commit e572aba

Browse files
committed
chore: wip
1 parent f2ed9a4 commit e572aba

File tree

1 file changed

+49
-34
lines changed

1 file changed

+49
-34
lines changed

scripts/build-php.ts

Lines changed: 49 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,8 +1109,8 @@ async function buildPhp(config: BuildConfig): Promise<string> {
11091109
.map(path => join(path, 'include'))
11101110
.filter(path => existsSync(path))
11111111

1112-
// Add iconv paths back - we need the actual library for linking
1113-
if (config.platform === 'darwin') {
1112+
// Add iconv paths back - we need the actual library for linking (except for x86_64)
1113+
if (config.platform === 'darwin' && config.arch !== 'x86_64') {
11141114
const iconvPath = findLatestVersion(`${launchpadRoot}/gnu.org/libiconv`)
11151115
if (iconvPath && existsSync(iconvPath)) {
11161116
const iconvLibPath = join(iconvPath, 'lib')
@@ -1124,6 +1124,8 @@ async function buildPhp(config: BuildConfig): Promise<string> {
11241124
} else {
11251125
log('⚠️ iconv library not found, may cause linking issues')
11261126
}
1127+
} else if (config.platform === 'darwin' && config.arch === 'x86_64') {
1128+
log(`🔧 ✅ Skipped GNU iconv for x86_64 to prevent dyld conflicts (using system iconv)`)
11271129
}
11281130

11291131
buildEnv.PKG_CONFIG_PATH = pkgConfigPaths.join(':')
@@ -1190,8 +1192,8 @@ async function buildPhp(config: BuildConfig): Promise<string> {
11901192
.map(path => join(path, 'include'))
11911193
.filter(path => existsSync(path))
11921194

1193-
// Add iconv paths after dependency installation on macOS
1194-
if (config.platform === 'darwin') {
1195+
// Add iconv paths after dependency installation on macOS (except for x86_64)
1196+
if (config.platform === 'darwin' && config.arch !== 'x86_64') {
11951197
const iconvPath = findLatestVersion(`${launchpadRoot}/gnu.org/libiconv`)
11961198
if (iconvPath && existsSync(iconvPath)) {
11971199
const iconvLibPath = join(iconvPath, 'lib')
@@ -1271,31 +1273,31 @@ async function buildPhp(config: BuildConfig): Promise<string> {
12711273
// Add platform-specific linker flags with dynamic rpaths
12721274
if (config.platform === 'darwin') {
12731275
// macOS: Use dynamic rpaths based on actual library locations, removing duplicates
1274-
const uniqueLibPaths = [...new Set(libPaths)]
1275-
const rpathFlags = uniqueLibPaths.map(path => `-Wl,-rpath,${path}`).join(' ')
1276+
let uniqueLibPaths = [...new Set(libPaths)]
1277+
let uniqueIncludePaths = [...new Set(includePaths)]
12761278
// Handle libiconv with architecture-specific linking to avoid dyld symbol conflicts
1277-
const iconvLibPath = uniqueLibPaths.find(p => p.includes('libiconv'))
12781279
let iconvFlag = ' -liconv' // fallback to system iconv
12791280

1280-
if (iconvLibPath) {
1281-
if (config.arch === 'x86_64') {
1282-
// For x86_64, use static linking to avoid dyld symbol override conflicts
1283-
const staticLib = join(iconvLibPath, 'libiconv.a')
1284-
if (existsSync(staticLib)) {
1285-
iconvFlag = ` ${staticLib}`
1286-
log(`🔧 ✅ Using static iconv library for x86_64: ${staticLib}`)
1287-
} else {
1288-
// Fallback: use -liconv to link against system library
1289-
iconvFlag = ' -liconv'
1290-
log(`🔧 ⚠️ Static iconv not found, using system iconv for x86_64`)
1291-
}
1292-
} else {
1293-
// ARM64 can use dynamic linking without dyld conflicts
1281+
if (config.arch === 'x86_64') {
1282+
// For x86_64, completely avoid GNU libiconv to prevent dyld symbol conflicts
1283+
// Use system iconv only
1284+
iconvFlag = ' -liconv'
1285+
log(`🔧 ✅ Using system iconv for x86_64 (avoiding GNU libiconv dyld conflicts)`)
1286+
// Remove iconv and libcups from library paths for x86_64 to prevent dyld interference
1287+
uniqueLibPaths = uniqueLibPaths.filter(p => !p.includes('libiconv') && !p.includes('libcups'))
1288+
uniqueIncludePaths = uniqueIncludePaths.filter(p => !p.includes('libiconv') && !p.includes('libcups'))
1289+
log(`🔧 ✅ Excluded libcups from x86_64 library paths to prevent dyld conflicts`)
1290+
} else {
1291+
// ARM64 can use GNU libiconv without issues
1292+
const iconvLibPath = uniqueLibPaths.find(p => p.includes('libiconv'))
1293+
if (iconvLibPath) {
12941294
iconvFlag = ` ${iconvLibPath}/libiconv.2.dylib`
1295-
log(`🔧 ✅ Using dynamic iconv library for ARM64: ${iconvLibPath}`)
1295+
log(`🔧 ✅ Using GNU iconv library for ARM64: ${iconvLibPath}`)
12961296
}
12971297
}
12981298

1299+
const rpathFlags = uniqueLibPaths.map(path => `-Wl,-rpath,${path}`).join(' ')
1300+
12991301
buildEnv.LDFLAGS += ` -lresolv${iconvFlag} ${rpathFlags} -Wl,-headerpad_max_install_names`
13001302
// Set up runtime library path for macOS (build-time only)
13011303
buildEnv.DYLD_LIBRARY_PATH = uniqueLibPaths.join(':')
@@ -1450,11 +1452,21 @@ exec "$@"
14501452
const libraryMappings = [
14511453
{ flag: '--with-bz2', basePath: 'sourceware.org/bzip2' },
14521454
{ flag: '--with-gettext', basePath: 'gnu.org/gettext' },
1453-
// Re-enable iconv library mapping for proper linking
1454-
{ flag: '--with-iconv', basePath: 'gnu.org/libiconv' },
1455+
// Conditionally include iconv library mapping based on architecture
1456+
...(config.arch === 'x86_64' ? [] : [{ flag: '--with-iconv', basePath: 'gnu.org/libiconv' }]),
14551457
{ flag: '--with-readline', basePath: 'gnu.org/readline' },
14561458
]
14571459

1460+
// For x86_64, remove --with-iconv=/path/to/gnu/libiconv to use system iconv instead
1461+
// This prevents GNU libiconv dyld conflicts while still maintaining iconv functionality
1462+
if (config.arch === 'x86_64') {
1463+
const iconvIndex = configureArgs.findIndex(arg => arg.startsWith('--with-iconv'))
1464+
if (iconvIndex !== -1) {
1465+
configureArgs.splice(iconvIndex, 1)
1466+
log(`🔧 ✅ Removed GNU --with-iconv for x86_64, will use system iconv (required for Laravel/Composer)`)
1467+
}
1468+
}
1469+
14581470
for (const mapping of libraryMappings) {
14591471
const libPath = findLatestVersion(`${homeDir}/.local/${mapping.basePath}`)
14601472
const argIndex = configureArgs.findIndex(arg => arg === mapping.flag)
@@ -1988,14 +2000,16 @@ exec ./configure "$@"
19882000
]
19892001

19902002
const patches = [
1991-
// Fix "S" constraint (source register) - incompatible on macOS
1992-
's/asm volatile("([^"]*)" :: "S" ([^)]*))/asm volatile("$1" : : "r" $2 : "memory")/g',
1993-
// Fix "D" constraint (destination register) issues
1994-
's/asm volatile("([^"]*)" :: "D" ([^)]*))/asm volatile("$1" : : "r" $2 : "memory")/g',
1995-
// Fix mixed constraint issues
1996-
's/asm volatile("([^"]*)" :: "([SD])" ([^)]*), "([^"]*)" ([^)]*))/asm volatile("$1" : : "r" $3, "r" $5 : "memory")/g',
1997-
// Fix memory operand issues in inline assembly
1998-
's/__asm__ volatile("([^"]*)" :: "([SD])" ([^)]*))/asm volatile("$1" : : "r" $3 : "memory")/g',
2003+
// Fix "S" constraint (source register) - incompatible on macOS - handle leading whitespace/tabs
2004+
's/^([[:space:]]*)asm volatile\\("([^"]*)"\\s*::\\s*"S"\\s*\\(([^)]*)\\)\\);/\\1asm volatile("\\2" : : "r" \\3 : "memory");/g',
2005+
// Fix "D" constraint (destination register) issues - handle leading whitespace/tabs
2006+
's/^([[:space:]]*)asm volatile\\("([^"]*)"\\s*::\\s*"D"\\s*\\(([^)]*)\\)\\);/\\1asm volatile("\\2" : : "r" \\3 : "memory");/g',
2007+
// Fix __asm__ variant with "S" constraint - handle leading whitespace/tabs
2008+
's/^([[:space:]]*)__asm__ volatile\\("([^"]*)"\\s*::\\s*"S"\\s*\\(([^)]*)\\)\\);/\\1asm volatile("\\2" : : "r" \\3 : "memory");/g',
2009+
// Fix __asm__ variant with "D" constraint - handle leading whitespace/tabs
2010+
's/^([[:space:]]*)__asm__ volatile\\("([^"]*)"\\s*::\\s*"D"\\s*\\(([^)]*)\\)\\);/\\1asm volatile("\\2" : : "r" \\3 : "memory");/g',
2011+
// Fix mixed constraint issues - handle leading whitespace/tabs
2012+
's/^([[:space:]]*)asm volatile\\("([^"]*)"\\s*::\\s*"([SD])"\\s*\\(([^)]*)\\),\\s*"([^"]*)"\\s*\\(([^)]*)\\)\\);/\\1asm volatile("\\2" : : "r" \\4, "r" \\6 : "memory");/g',
19992013
]
20002014

20012015
for (const filePath of jitSourceFiles) {
@@ -2004,7 +2018,7 @@ exec ./configure "$@"
20042018
log(`Patching ${filePath}...`)
20052019
for (const patch of patches) {
20062020
try {
2007-
execSync(`sed -i.jitpatch '${patch}' "${fullFilePath}"`, {
2021+
execSync(`sed -E -i.jitpatch '${patch}' "${fullFilePath}"`, {
20082022
cwd: phpSourceDir,
20092023
stdio: 'pipe'
20102024
})
@@ -2144,7 +2158,8 @@ exec ./configure "$@"
21442158
const readlinePath = findLatestVersion(`${homeDir}/.local/gnu.org/readline`)
21452159

21462160
if (readlinePath) dynamicLibPaths.push(join(readlinePath, 'lib'))
2147-
if (iconvPath) dynamicLibPaths.push(join(iconvPath, 'lib'))
2161+
// Only add GNU iconv for non-x86_64 builds to prevent dyld conflicts
2162+
if (iconvPath && config.arch !== 'x86_64') dynamicLibPaths.push(join(iconvPath, 'lib'))
21482163
if (gettextPath) dynamicLibPaths.push(join(gettextPath, 'lib'))
21492164
if (bz2Path) dynamicLibPaths.push(join(bz2Path, 'lib'))
21502165

0 commit comments

Comments
 (0)