如何修复 test.nativeLink scala.scalanative.build.BuildException 错误

问题描述 投票:0回答:1

我试图在 scala 本机代码上运行测试,该代码从其中调用 C 函数,但出现此错误。修改以提供更多错误输出

[build.mill-57/61] compile
[build.mill-57] [info] compiling 1 Scala source to /workspaces/test/saturday/mill/example/scalalib/native/2-interop/out/mill-build/compile.dest/classes ...
[build.mill-57] [info] done compiling
[134/147] compile
[134] [info] compiling 1 Scala source to /workspaces/test/saturday/mill/example/scalalib/native/2-interop/out/compile.dest/classes ...
[134] [info] done compiling
[141/147] test.compile
[141] [info] compiling 1 Scala source to /workspaces/test/saturday/mill/example/scalalib/native/2-interop/out/test/compile.dest/classes ...
[141] [info] done compiling
[build.mill-57] [info] Linking (multithreadingEnabled=true, disable if not used) (3274 ms)
[build.mill-57] [info] Discovered 1944 classes and 14162 methods after classloading
[build.mill-57] [info] Checking intermediate code (quick) (175 ms)
[build.mill-57] [info] Discovered 1904 classes and 10865 methods after optimization
[build.mill-57] [info] Optimizing (debug mode) (7396 ms)
[build.mill-57] [info] Produced 3 LLVM IR files
[build.mill-57] [info] Generating intermediate code (8943 ms)
[build.mill-57] [info] Compiling to native code (9752 ms)
[build.mill-57] [info] Linking with [pthread, dl, HelloWorld]
[build.mill-57] [error] /usr/bin/ld: cannot find -lHelloWorld: No such file or directory
[build.mill-57] [error] clang: error: linker command failed with exit code 1 (use -v to see invocation)
[build.mill-57] [info] Total (27675 ms)
[147/147] ==================================================== test ====================================================== 51s
1 tasks failed
test.nativeLink scala.scalanative.build.BuildException: Failed to link /workspaces/test/saturday/mill/example/scalalib/native/2-interop/out/test/nativeWorkdir.dest/native/scala.scalanative.testinterface.TestMain
build.mill
src/foo/
  HelloWorld.scala
  native-src/
HelloWorld.c
test/
  src/
    foo/
      HelloWorldTests.scala

我正在使用工厂构建工具。 我觉得奇怪的是

mill run
编译并成功工作,但是当我尝试运行
mill test
时,对于测试我收到了链接错误

HelloWorld.scala

package foo
import scala.scalanative.libc._
import scala.scalanative.unsafe._

object Main {
  def main(args: Array[String]): Unit = {
    println("Running HelloWorld function")
    stdio.printf(c"Reversed: %s\n", HelloWorld.reverseString(c"Hello, World!"))
    println("Done...")
  }
}

// Define the external module, the C library containing our function "reverseString"
@extern
@link("HelloWorld")
// Arbitrary object name
object HelloWorld {
  // Name and signature of C function
  def reverseString(str: CString): CString = extern
}

HelloWorld.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char* reverseString(const char *str) {
  int length = strlen(str);
  char *reversed = (char*) malloc((length + 1) * sizeof(char));

  for (int i = 0; i < length; i++) {
    reversed[i] = str[length - i - 1];
  }
  reversed[length] = '\0'; // Null-terminate the string

  return reversed;
}

HelloWorldTests.scala

package foo

import utest._
import scala.scalanative.unsafe._

object HelloWorldTest extends TestSuite {
  val tests = Tests {
    test("reverseString should reverse a C string correctly") {
      val expected = "!dlrow olleH"

      val result = HelloWorld.reverseString(c"Hello World!")

      // Check if the reversed string matches the expected result
      assert(fromCString(result) == expected)
      fromCString(result)
    }
  }
}

最后是我的配置文件

build.mill

package build
import mill._, scalalib._, scalanativelib._

object `package` extends RootModule with ScalaNativeModule {
  def scalaVersion = "2.13.11"
  def scalaNativeVersion = "0.5.5"

  object test extends ScalaNativeTests {
    def ivyDeps = Agg(ivy"com.lihaoyi::utest::0.8.4")
    def testFramework = "utest.runner.Framework"
  }

  def nativeLinkingOptions = Seq("-L" + millSourcePath.toString + "/target")

  // Compiled C
  def nativeCompiled = T {
    os.makeDir.all(millSourcePath / "target")

    os.proc("gcc", "-m64", "-shared",
      "-c", millSourcePath.toString + "/native-src/HelloWorld.c",
      "-o", millSourcePath.toString + "/target/libHelloWorld.so"
    ).call(stdout = os.Inherit)

    PathRef(T.dest / "target/libHelloWorld.so")    
  }
}

构建文件更改将

nativeLinkingOptions
更改为名为
target

的自定义路径

我尝试更改测试框架版本,并将

nativelinkOptions
包含在测试中

我期待它能够成功编译并运行测试

c scala interop scala-native utest
1个回答
0
投票

错误的解决方案是将 C 源文件保留在

resources/scala-native
中,并从
@link("HelloWorld")
中删除
HelloWorld.scala
,因为我已经在我的
.so
 中使用 nativeLinkingOptions 配置指向自定义路径来查找 
build.mill

文件

该解决方案由 Scala 论坛中的 Scala Native Lead 开发人员提供。链接到这里

© www.soinside.com 2019 - 2024. All rights reserved.