Skip to content

Commit

Permalink
feat: refine library resolution procedure (#167)
Browse files Browse the repository at this point in the history
* feat: refine library resolution procedure

- use `libname.so` instead of `libname_.so` when potential arch mark is
unknown
- lookup `.dylib` on OSX first and then fallback to `.so` file
- include `.dylib` suffix as absolute paths

* update: collect candidates with and without archmarks including arm64

* fix: drop without archmark solution
  • Loading branch information
i10416 authored Apr 22, 2023
1 parent 6e49510 commit 8ace772
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 7 deletions.
3 changes: 2 additions & 1 deletion core/src/fr/hammons/slinc/annotations/NeedsFile.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ final case class NeedsFile(val path: String)
val fileName = filePath.getFileName().toString()
Dependency.FilePath(
filePath,
fileName.endsWith(".so") || fileName.endsWith(".dll")
fileName.endsWith(".so") || fileName.endsWith(".dylib") || fileName
.endsWith(".dll")
)

object NeedsFile:
Expand Down
2 changes: 1 addition & 1 deletion core/src/fr/hammons/slinc/annotations/NeedsResource.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ final case class NeedsResource(val resourcePath: String)
case path =>
Dependency.LibraryResource(
path,
path.endsWith(".so") || path.endsWith(".dll")
path.endsWith(".so") || path.endsWith(".dylib") || path.endsWith(".dll")
)

object NeedsResource:
Expand Down
35 changes: 30 additions & 5 deletions core/src/fr/hammons/slinc/modules/LinkageTools.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ import scala.sys.process.*

object LinkageTools:
private val dependenciesLoaded = AtomicReference(Set.empty[Dependency])
private lazy val libSuffixCandidates = os match
case OS.Linux => Seq(".so")
// prefer .dylib over .so on darwin
case OS.Darwin => Seq(".dylib", ".so")
case OS.Windows => Seq(".dll")
case OS.Unknown => Seq.empty

private lazy val libSuffix = os match
case OS.Linux | OS.Darwin => ".so"
Expand All @@ -23,6 +29,7 @@ object LinkageTools:

private lazy val potentialArchMarks = arch match
case Arch.X64 => Set("x64", "x86_64", "amd64")
case Arch.AArch64 => Set("arm64", "aarch64")
case Arch.Unknown | _ => Set.empty

private val resourcesLocation = "/native"
Expand Down Expand Up @@ -80,14 +87,16 @@ object LinkageTools:
load(cachedFile.cachePath)

case Dependency.LibraryResource(path, false) =>
val resolvedPath = potentialArchMarks.view
.map(archMark => s"${path}_$archMark$libSuffix")
val candidates =
resolveCandidates(path, libSuffixCandidates, potentialArchMarks)
val resolvedPath = candidates
.find(path =>
getClass().getResource(s"$resourcesLocation/$path") != null
)
.getOrElse(
throw Error(
s"No library resource found for $arch $os with path like $path"
s"No library resource found for $arch $os. Make sure one of ${candidates
.mkString("[", ", ", "]")} is located in resources/native."
)
)

Expand All @@ -104,8 +113,13 @@ object LinkageTools:
load(path)

case Dependency.FilePath(path, false) =>
val resolvedPath = potentialArchMarks.view
.map(archMark => Paths.get(s"${path}_$archMark$libSuffix").nn)
val candidates = resolveCandidates(
path,
libSuffixCandidates,
potentialArchMarks
)
val resolvedPath = candidates
.map(Paths.get(_).nn)
.find(Files.exists(_))
.getOrElse(
throw Error(
Expand All @@ -121,6 +135,17 @@ object LinkageTools:
)
}

private def resolveCandidates(
location: String | Path,
suffixCandidates: Seq[String],
archMarks: Set[String]
): Seq[String] =
if archMarks.isEmpty then Seq.empty
else
suffixCandidates.flatMap { suffix =>
archMarks.map(archMark => s"${location}_$archMark$suffix")
}

def compileCachedCCode(cachedFile: CacheFile): Path =
val libLocation = cachedFile.cachePath.toString() match
case s"${baseName}.c" => Paths.get(s"$baseName$libSuffix").nn
Expand Down

0 comments on commit 8ace772

Please sign in to comment.