Implement -headerFilterAdditionalSearchPrefix option in cinterop
This commit is contained in:
committed by
GitHub
parent
9bc9003cdd
commit
78873c5f4d
@@ -20,6 +20,8 @@ import clang.*
|
||||
import kotlinx.cinterop.*
|
||||
import java.io.Closeable
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import java.security.DigestInputStream
|
||||
import java.security.MessageDigest
|
||||
@@ -542,3 +544,58 @@ internal fun CValue<CXSourceLocation>.getContainingFile(): CXFile? = memScoped {
|
||||
clang_getFileLocation(this@getContainingFile, fileVar.ptr, null, null, null)
|
||||
fileVar.value
|
||||
}
|
||||
|
||||
private fun createVfsOverlayFileContents(virtualPathToReal: Map<Path, Path>): ByteArray {
|
||||
val overlay = clang_VirtualFileOverlay_create(0)
|
||||
|
||||
try {
|
||||
fun addFileMapping(realPath: Path, virtualPath: Path) {
|
||||
clang_VirtualFileOverlay_addFileMapping(
|
||||
overlay,
|
||||
virtualPath = virtualPath.toAbsolutePath().toString(),
|
||||
realPath = realPath.toAbsolutePath().toString()
|
||||
)
|
||||
}
|
||||
|
||||
virtualPathToReal.forEach { virtualPath, realPath ->
|
||||
if (Files.isDirectory(realPath)) {
|
||||
realPath.toFile().walkTopDown().forEach {
|
||||
if (!it.isDirectory) {
|
||||
addFileMapping(
|
||||
realPath = it.toPath(),
|
||||
virtualPath = virtualPath.resolve(realPath.relativize(it.toPath()))
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
addFileMapping(realPath = realPath, virtualPath = virtualPath)
|
||||
}
|
||||
}
|
||||
|
||||
memScoped {
|
||||
val bufferVar = alloc<CPointerVar<ByteVar>>().apply { value = null }
|
||||
val bufferSizeVar = alloc<IntVar>()
|
||||
|
||||
val res = clang_VirtualFileOverlay_writeToBuffer(overlay, 0, bufferVar.ptr, bufferSizeVar.ptr)
|
||||
if (res != CXErrorCode.CXError_Success) {
|
||||
// TODO: shall we free the buffer in this case?
|
||||
error(res)
|
||||
}
|
||||
|
||||
return bufferVar.value!!.readBytes(bufferSizeVar.value)
|
||||
}
|
||||
} finally {
|
||||
clang_VirtualFileOverlay_dispose(overlay)
|
||||
}
|
||||
}
|
||||
|
||||
fun createVfsOverlayFile(virtualPathToReal: Map<Path, Path>): Path {
|
||||
val bytes = createVfsOverlayFileContents(virtualPathToReal)
|
||||
|
||||
return createTempFile(prefix = "konan", suffix = ".vfsoverlay").apply {
|
||||
bufferedWriter().use {
|
||||
writeBytes(bytes)
|
||||
}
|
||||
deleteOnExit()
|
||||
}.toPath()
|
||||
}
|
||||
|
||||
+51
-1
@@ -23,8 +23,8 @@ import org.jetbrains.kotlin.native.interop.gen.ImportsImpl
|
||||
import org.jetbrains.kotlin.native.interop.indexer.*
|
||||
import java.io.File
|
||||
import java.lang.IllegalArgumentException
|
||||
import java.nio.file.*
|
||||
import java.util.*
|
||||
import kotlin.reflect.KFunction
|
||||
|
||||
fun main(args: Array<String>) = interop(args, null)
|
||||
|
||||
@@ -211,6 +211,55 @@ private fun parseImports(args: Map<String, List<String>>): ImportsImpl {
|
||||
return ImportsImpl(headerIdToPackage)
|
||||
}
|
||||
|
||||
fun getCompilerFlagsForVfsOverlay(args: Map<String, List<String>>, def: DefFile): List<String> {
|
||||
val relativeToRoot = mutableMapOf<Path, Path>() // TODO: handle clashes
|
||||
|
||||
val HEADER_FILTER_ADDITIONAL_SEARCH_PREFIX = "-headerFilterAdditionalSearchPrefix"
|
||||
|
||||
val filteredIncludeDirs = args[HEADER_FILTER_ADDITIONAL_SEARCH_PREFIX]?.map { Paths.get(it) }
|
||||
if (filteredIncludeDirs != null) {
|
||||
val headerFilterGlobs = def.config.headerFilter
|
||||
if (headerFilterGlobs.isEmpty()) {
|
||||
error("'$HEADER_FILTER_ADDITIONAL_SEARCH_PREFIX' option requires " +
|
||||
"'headerFilter' to be specified in .def file")
|
||||
}
|
||||
|
||||
relativeToRoot += findFilesByGlobs(roots = filteredIncludeDirs, globs = headerFilterGlobs)
|
||||
}
|
||||
|
||||
if (relativeToRoot.isEmpty()) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
val virtualRoot = Paths.get(System.getProperty("java.io.tmpdir")).resolve("konanSystemInclude")
|
||||
|
||||
val virtualPathToReal = relativeToRoot.map { (relativePath, realRoot) ->
|
||||
virtualRoot.resolve(relativePath) to realRoot.resolve(relativePath)
|
||||
}.toMap()
|
||||
|
||||
val vfsOverlayFile = createVfsOverlayFile(virtualPathToReal)
|
||||
|
||||
return listOf("-I${virtualRoot.toAbsolutePath()}", "-ivfsoverlay", vfsOverlayFile.toAbsolutePath().toString())
|
||||
}
|
||||
|
||||
private fun findFilesByGlobs(roots: List<Path>, globs: List<String>): Map<Path, Path> {
|
||||
val relativeToRoot = mutableMapOf<Path, Path>()
|
||||
|
||||
val pathMatchers = globs.map { FileSystems.getDefault().getPathMatcher("glob:$it") }
|
||||
|
||||
roots.reversed().forEach { root ->
|
||||
// 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) }) {
|
||||
relativeToRoot[relativePath] = root
|
||||
}
|
||||
}
|
||||
}
|
||||
return relativeToRoot
|
||||
}
|
||||
|
||||
|
||||
private fun processLib(args: Map<String, List<String>>,
|
||||
argsToCompiler: MutableList<String>?) {
|
||||
|
||||
@@ -250,6 +299,7 @@ private fun processLib(args: Map<String, List<String>>,
|
||||
addAll(def.config.compilerOpts)
|
||||
addAll(tool.defaultCompilerOpts)
|
||||
addAll(additionalCompilerOpts)
|
||||
addAll(getCompilerFlagsForVfsOverlay(args, def))
|
||||
addAll(when (language) {
|
||||
Language.C -> emptyList()
|
||||
Language.OBJECTIVE_C -> {
|
||||
|
||||
Reference in New Issue
Block a user