Add iconv void * overloads for backwards compatibility

Since Xcode 15 the iconv APIs operate on an opaque type __tag_iconv_t* instead of
void*. This causes a runtime exception in older Ktor versions which
depended on iconv.

^KT-62286
This commit is contained in:
Timofey Solonin
2023-10-03 23:05:41 +02:00
parent 057973f4bb
commit 8dc9307f9e
8 changed files with 39 additions and 1 deletions
@@ -431,7 +431,11 @@ class StubIrBuilder(private val context: StubIrContext) {
private fun generateStubsForFunction(func: FunctionDecl) {
try {
addStubs(FunctionStubBuilder(buildingContext, func, skipOverloads = true).build())
addStubs(FunctionStubBuilder(
buildingContext,
func,
skipOverloads = func.name !in context.configuration.allowedOverloadsForCFunctions
).build())
} catch (e: Throwable) {
context.log("Warning: cannot generate stubs for function ${func.name}")
}
@@ -31,6 +31,7 @@ class InteropConfiguration(
val nonStrictEnums: Set<String>,
val noStringConversion: Set<String>,
val exportForwardDeclarations: List<String>,
val allowedOverloadsForCFunctions: Set<String>,
val disableDesignatedInitializerChecks: Boolean,
val disableExperimentalAnnotation: Boolean,
val target: KonanTarget
@@ -324,6 +324,7 @@ private fun processCLib(
nonStrictEnums = def.config.nonStrictEnums.toSet(),
noStringConversion = def.config.noStringConversion.toSet(),
exportForwardDeclarations = def.config.exportForwardDeclarations,
allowedOverloadsForCFunctions = def.config.allowedOverloadsForCFunctions.toSet(),
disableDesignatedInitializerChecks = def.config.disableDesignatedInitializerChecks,
disableExperimentalAnnotation = cinteropArguments.disableExperimentalAnnotation ?: false,
target = target
@@ -3,3 +3,10 @@ package = platform.iconv
headers = iconv.h
headerFilter = **
linkerOpts = -liconv
allowedOverloadsForCFunctions = iconv iconvctl iconv_close
---
typedef void* __kotlin_iconv_t;
size_t __attribute__((overloadable)) iconv(__kotlin_iconv_t, char **, size_t *, char **, size_t *) asm("_iconv");
int __attribute__((overloadable)) iconvctl(__kotlin_iconv_t, int, void *) asm("_iconvctl");
int __attribute__((overloadable)) iconv_close(__kotlin_iconv_t) asm("_iconv_close");
@@ -3,3 +3,10 @@ package = platform.iconv
headers = iconv.h
headerFilter = **
linkerOpts = -liconv
allowedOverloadsForCFunctions = iconv iconvctl iconv_close
---
typedef void* __kotlin_iconv_t;
size_t __attribute__((overloadable)) iconv(__kotlin_iconv_t, char **, size_t *, char **, size_t *) asm("_iconv");
int __attribute__((overloadable)) iconvctl(__kotlin_iconv_t, int, void *) asm("_iconvctl");
int __attribute__((overloadable)) iconv_close(__kotlin_iconv_t) asm("_iconv_close");
@@ -3,3 +3,10 @@ package = platform.iconv
headers = iconv.h
headerFilter = **
linkerOpts = -liconv
allowedOverloadsForCFunctions = iconv iconvctl iconv_close
---
typedef void* __kotlin_iconv_t;
size_t __attribute__((overloadable)) iconv(__kotlin_iconv_t, char **, size_t *, char **, size_t *) asm("_iconv");
int __attribute__((overloadable)) iconvctl(__kotlin_iconv_t, int, void *) asm("_iconvctl");
int __attribute__((overloadable)) iconv_close(__kotlin_iconv_t) asm("_iconv_close");
@@ -3,3 +3,10 @@ package = platform.iconv
headers = iconv.h
headerFilter = **
linkerOpts = -liconv
allowedOverloadsForCFunctions = iconv iconvctl iconv_close
---
typedef void* __kotlin_iconv_t;
size_t __attribute__((overloadable)) iconv(__kotlin_iconv_t, char **, size_t *, char **, size_t *) asm("_iconv");
int __attribute__((overloadable)) iconvctl(__kotlin_iconv_t, int, void *) asm("_iconvctl");
int __attribute__((overloadable)) iconv_close(__kotlin_iconv_t) asm("_iconv_close");
@@ -120,6 +120,10 @@ class DefFile(val file:File?, val config:DefFileConfig, val manifestAddendProper
properties.getSpaceSeparated("exportForwardDeclarations")
}
val allowedOverloadsForCFunctions by lazy {
properties.getSpaceSeparated("allowedOverloadsForCFunctions")
}
val disableDesignatedInitializerChecks by lazy {
properties.getProperty("disableDesignatedInitializerChecks")?.toBoolean() ?: false
}