[K/N] KT-54001

Add a new DefFile.excludeFilter property that excludes headers
from interop library by given glob.

This change is required to properly support platform libs from Xcode 14
without breaking ABI.
This commit is contained in:
Sergey Bogolepov
2022-09-12 10:55:56 +03:00
committed by Space
parent 6bc9c43952
commit b4b27e9bc6
3 changed files with 29 additions and 8 deletions
@@ -41,10 +41,14 @@ class ImportsImpl(internal val headerIdToPackage: Map<HeaderId, PackageInfo>) :
get() = accessedLibraries.toSet()
}
class HeaderInclusionPolicyImpl(private val nameGlobs: List<String>) : HeaderInclusionPolicy {
class HeaderInclusionPolicyImpl(
private val nameGlobs: List<String>,
private val excludeGlobs: List<String>,
) : HeaderInclusionPolicy {
override fun excludeUnused(headerName: String?): Boolean {
if (nameGlobs.isEmpty()) {
// If we don't have any filters then we should keep the header.
if (nameGlobs.isEmpty() && excludeGlobs.isEmpty()) {
return false
}
@@ -53,7 +57,8 @@ class HeaderInclusionPolicyImpl(private val nameGlobs: List<String>) : HeaderInc
return true
}
return nameGlobs.all { !headerName.matchesToGlob(it) }
// Exclude globs have higher priority then include ones.
return excludeGlobs.any { headerName.matchesToGlob(it) } || nameGlobs.all { !headerName.matchesToGlob(it) }
}
}
@@ -160,12 +160,13 @@ fun getCompilerFlagsForVfsOverlay(headerFilterPrefix: Array<String>, def: DefFil
val filteredIncludeDirs = headerFilterPrefix .map { Paths.get(it) }
if (filteredIncludeDirs.isNotEmpty()) {
val headerFilterGlobs = def.config.headerFilter
val excludeFilterGlobs = def.config.excludeFilter
if (headerFilterGlobs.isEmpty()) {
error("'$HEADER_FILTER_ADDITIONAL_SEARCH_PREFIX' option requires " +
"'headerFilter' to be specified in .def file")
}
relativeToRoot += findFilesByGlobs(roots = filteredIncludeDirs, globs = headerFilterGlobs)
relativeToRoot += findFilesByGlobs(roots = filteredIncludeDirs, includeGlobs = headerFilterGlobs, excludeGlobs = excludeFilterGlobs)
}
if (relativeToRoot.isEmpty()) {
@@ -183,10 +184,11 @@ fun getCompilerFlagsForVfsOverlay(headerFilterPrefix: Array<String>, def: DefFil
return listOf("-I${virtualRoot.toAbsolutePath()}", "-ivfsoverlay", vfsOverlayFile.toAbsolutePath().toString())
}
private fun findFilesByGlobs(roots: List<Path>, globs: List<String>): Map<Path, Path> {
private fun findFilesByGlobs(roots: List<Path>, includeGlobs: List<String>, excludeGlobs: List<String>): Map<Path, Path> {
val relativeToRoot = mutableMapOf<Path, Path>()
val pathMatchers = globs.map { FileSystems.getDefault().getPathMatcher("glob:$it") }
val pathMatchers = includeGlobs.map { FileSystems.getDefault().getPathMatcher("glob:$it") }
val excludePathMatchers = excludeGlobs.map { FileSystems.getDefault().getPathMatcher("glob:$it") }
roots.reversed()
.filter { path ->
@@ -199,7 +201,10 @@ private fun findFilesByGlobs(roots: List<Path>, globs: List<String>): Map<Path,
// TODO: don't scan the entire tree, skip subdirectories according to globs.
Files.walk(root, FileVisitOption.FOLLOW_LINKS).forEach { path ->
val relativePath = root.relativize(path)
if (!Files.isDirectory(path) && pathMatchers.any { it.matches(relativePath) }) {
val shouldInclude = !Files.isDirectory(path)
&& excludePathMatchers.all { !it.matches(relativePath) }
&& pathMatchers.any { it.matches(relativePath) }
if (shouldInclude) {
relativeToRoot[relativePath] = root
}
}
@@ -504,7 +509,8 @@ internal fun buildNativeLibrary(
val excludeDependentModules = def.config.excludeDependentModules
val headerFilterGlobs = def.config.headerFilter
val headerInclusionPolicy = HeaderInclusionPolicyImpl(headerFilterGlobs)
val excludeFilterGlobs = def.config.excludeFilter
val headerInclusionPolicy = HeaderInclusionPolicyImpl(headerFilterGlobs, excludeFilterGlobs)
headerFilter = NativeLibraryHeaderFilter.NameBased(headerInclusionPolicy, excludeDependentModules)
includes = headerFiles
@@ -86,10 +86,20 @@ class DefFile(val file:File?, val config:DefFileConfig, val manifestAddendProper
properties.getProperty("package")
}
/**
* Header inclusion globs.
*/
val headerFilter by lazy {
properties.getSpaceSeparated("headerFilter")
}
/**
* Header exclusion globs. Have higher priority than [headerFilter].
*/
val excludeFilter by lazy {
properties.getSpaceSeparated("excludeFilter")
}
val strictEnums by lazy {
properties.getSpaceSeparated("strictEnums")
}