diff --git a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/Imports.kt b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/Imports.kt index a3f65856d15..f15f2ed3cb6 100644 --- a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/Imports.kt +++ b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/Imports.kt @@ -41,10 +41,14 @@ class ImportsImpl(internal val headerIdToPackage: Map) : get() = accessedLibraries.toSet() } -class HeaderInclusionPolicyImpl(private val nameGlobs: List) : HeaderInclusionPolicy { +class HeaderInclusionPolicyImpl( + private val nameGlobs: List, + private val excludeGlobs: List, +) : 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) : 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) } } } diff --git a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt index ae7755cb2f6..3a19b6ab429 100644 --- a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt +++ b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt @@ -160,12 +160,13 @@ fun getCompilerFlagsForVfsOverlay(headerFilterPrefix: Array, 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, def: DefFil return listOf("-I${virtualRoot.toAbsolutePath()}", "-ivfsoverlay", vfsOverlayFile.toAbsolutePath().toString()) } -private fun findFilesByGlobs(roots: List, globs: List): Map { +private fun findFilesByGlobs(roots: List, includeGlobs: List, excludeGlobs: List): Map { val relativeToRoot = mutableMapOf() - 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, globs: List): Map 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 diff --git a/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/DefFile.kt b/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/DefFile.kt index 5bca0601399..00a5004745d 100644 --- a/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/DefFile.kt +++ b/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/DefFile.kt @@ -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") }