diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a27cc20..95bf212 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,6 +57,11 @@ jobs: cd go go build -o ruapu-go ./ruapu-go + - uses: dart-lang/setup-dart@v1 + - name: build-test-dart + run: | + cd dart + bash ./build.sh macos: runs-on: macos-latest @@ -92,6 +97,11 @@ jobs: cd go go build -o ruapu-go ./ruapu-go + - uses: dart-lang/setup-dart@v1 + - name: build-test-dart + run: | + cd dart + bash ./build.sh macos-arm64: runs-on: macos-14 @@ -127,6 +137,11 @@ jobs: cd go go build -o ruapu-go ./ruapu-go + - uses: dart-lang/setup-dart@v1 + - name: build-test-dart + run: | + cd dart + bash ./build.sh windows: runs-on: windows-latest @@ -174,6 +189,11 @@ jobs: cd go go build -o ruapu-go.exe ./ruapu-go.exe + - uses: dart-lang/setup-dart@v1 + - name: build-test-dart + run: | + cd dart + .\build.ps1 qemu: runs-on: ubuntu-latest diff --git a/README.md b/README.md index e87f43f..c462227 100644 --- a/README.md +++ b/README.md @@ -46,17 +46,17 @@ int main() ## Features * Detect **CPU ISA with single-file**    -_`sse2`, `avx`, `avx512f`, `neon`, etc._ + _`sse2`, `avx`, `avx512f`, `neon`, etc._ * Detect **vendor extended ISA**     -_apple `amx`, risc-v vendor ISA, etc._ + _apple `amx`, risc-v vendor ISA, etc._ * Detect **richer ISA on Windows ARM**   -_`IsProcessorFeaturePresent()` returns little ISA information_ + _`IsProcessorFeaturePresent()` returns little ISA information_ * Detect **`x86-avx512` on macOS correctly**  -_macOS hides it in `cpuid`_ + _macOS hides it in `cpuid`_ * Detect **new CPU's ISA on old systems**  -_they are usually not exposed in `auxv` or `MISA`_ + _they are usually not exposed in `auxv` or `MISA`_ * Detect **CPU hidden ISA**        -_`fma4` on zen1, ISA in hypervisor, etc._ + _`fma4` on zen1, ISA in hypervisor, etc._ ## Supported ISA _ (more is comming ... :)_ @@ -544,6 +544,58 @@ main(): Int64 { + +### ruapu with Dart + + + + + +
+ +Compile ruapu library + +```bash +cd dart +bash build.sh +``` + + +Use ruapu in dart + +```dart +void main() { + var libraryPath = + path.join(Directory.current.path, 'build', 'libruapu.so'); + + if (Platform.isMacOS) { + libraryPath = + path.join(Directory.current.path, 'build', 'libruapu.dylib'); + } + + if (Platform.isWindows) { + libraryPath = path.join( + Directory.current.path, 'build', 'Debug', 'ruapu.dll'); + } + + Ruapu ruapu = Ruapu(libraryPath); + + ruapu.init(); + + List isas = ruapu.rua(); + print("This CPU Support:"); + for (String isa in isas) { + print(isa); + } + print("================="); + + String isaToCheck = 'aes'; + bool isSupported = ruapu.supports(isaToCheck); + print('Does the system support $isaToCheck? $isSupported'); +} +``` +
+
Github-hosted runner result (Linux) @@ -787,4 +839,4 @@ ruapu determines whether the CPU supports certain instruction sets by trying to * [@whyb](https://github.com/whyb)  _Detect more x86 AMX*, SHA*, AVX512*, SM*_ ## License -MIT License +MIT License \ No newline at end of file diff --git a/dart/build.ps1 b/dart/build.ps1 new file mode 100644 index 0000000..de41b53 --- /dev/null +++ b/dart/build.ps1 @@ -0,0 +1,20 @@ +$PROJECT_DIR = Get-Location +$RUAPU_API_DIR = Join-Path -Path $PROJECT_DIR -ChildPath "ruapu-api" +$BUILD_DIR = Join-Path -Path $PROJECT_DIR -ChildPath "build" + +New-Item -ItemType Directory -Force -Path $BUILD_DIR +Set-Location $BUILD_DIR + +cmake $RUAPU_API_DIR +cmake --build $BUILD_DIR + +if ($LASTEXITCODE -ne 0) { + Write-Host "Build Error!!! Plz Check!!!" + exit 1 +} + +Set-Location $PROJECT_DIR + +dart pub get + +dart run main.dart \ No newline at end of file diff --git a/dart/build.sh b/dart/build.sh new file mode 100644 index 0000000..f6c1ab5 --- /dev/null +++ b/dart/build.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +PROJECT_DIR=$(pwd) +RUAPU_API_DIR="$PROJECT_DIR/ruapu-api" +BUILD_DIR="$PROJECT_DIR/build" + +mkdir -p "$BUILD_DIR" +cd "$BUILD_DIR" || exit + +cmake "$RUAPU_API_DIR" +cmake --build "$BUILD_DIR" + +if [ $? -ne 0 ]; then + echo "Build Error!!! Plz Check!!!" + exit 1 +fi + +cd "$PROJECT_DIR" || exit + +dart pub get + +dart run main.dart \ No newline at end of file diff --git a/dart/main.dart b/dart/main.dart new file mode 100644 index 0000000..c4f2789 --- /dev/null +++ b/dart/main.dart @@ -0,0 +1,33 @@ +import 'dart:io'; +import 'ruapu_api.dart'; +import 'package:path/path.dart' as path; + +void main() { + var libraryPath = + path.join(Directory.current.path, 'build', 'libruapu.so'); + + if (Platform.isMacOS) { + libraryPath = + path.join(Directory.current.path, 'build', 'libruapu.dylib'); + } + + if (Platform.isWindows) { + libraryPath = path.join( + Directory.current.path, 'build', 'Debug', 'ruapu.dll'); + } + + Ruapu ruapu = Ruapu(libraryPath); + + ruapu.init(); + + List isas = ruapu.rua(); + print("This CPU Support:"); + for (String isa in isas) { + print(isa); + } + print("================="); + + String isaToCheck = 'aes'; + bool isSupported = ruapu.supports(isaToCheck); + print('Does the system support $isaToCheck? $isSupported'); +} \ No newline at end of file diff --git a/dart/pubspec.yaml b/dart/pubspec.yaml new file mode 100644 index 0000000..fbf7885 --- /dev/null +++ b/dart/pubspec.yaml @@ -0,0 +1,17 @@ +name: dartRuapu +version: 1.0.0 +description: >- + Use ruapu with Dart. + +publish_to: none + +environment: + sdk: ^3.4.0 + +dependencies: + path: ^1.9.0 + ffi: ^1.0.0 + +dev_dependencies: + lints: ^4.0.0 + test: ^1.25.0 \ No newline at end of file diff --git a/dart/ruapu-api/CMakeLists.txt b/dart/ruapu-api/CMakeLists.txt new file mode 100644 index 0000000..3e843f7 --- /dev/null +++ b/dart/ruapu-api/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.7 FATAL_ERROR) +project(ruapu_library VERSION 1.0.0 LANGUAGES C) +add_library(ruapu_library SHARED ruapu.c ruapu.def) +include_directories(../../) + +set_target_properties(ruapu_library PROPERTIES + PUBLIC_HEADER ../../ruapu.h + VERSION ${PROJECT_VERSION} + SOVERSION 1 + OUTPUT_NAME "ruapu" + XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Hex_Identity_ID_Goes_Here" +) \ No newline at end of file diff --git a/dart/ruapu-api/ruapu.c b/dart/ruapu-api/ruapu.c new file mode 100644 index 0000000..45494ce --- /dev/null +++ b/dart/ruapu-api/ruapu.c @@ -0,0 +1,3 @@ +#define RUAPU_IMPLEMENTATION +#include "ruapu.h" + diff --git a/dart/ruapu-api/ruapu.def b/dart/ruapu-api/ruapu.def new file mode 100644 index 0000000..d47cb12 --- /dev/null +++ b/dart/ruapu-api/ruapu.def @@ -0,0 +1,5 @@ +LIBRARY ruapu +EXPORTS + ruapu_rua + ruapu_supports + ruapu_init \ No newline at end of file diff --git a/dart/ruapu_api.dart b/dart/ruapu_api.dart new file mode 100644 index 0000000..4861970 --- /dev/null +++ b/dart/ruapu_api.dart @@ -0,0 +1,63 @@ +import 'dart:ffi'; +import 'package:ffi/ffi.dart'; + + +typedef RuapuRUA_C = Pointer> Function(); +typedef RuapuRUA_Dart = Pointer> Function(); + +typedef RuapuInit_C = Void Function(); +typedef RuapuInit_Dart = void Function(); + +typedef RuapuSupports_C = Int32 Function(Pointer); +typedef RuapuSupports_Dart = int Function(Pointer); + +class Ruapu { + final DynamicLibrary _nativeLib; + + Ruapu(String libraryPath) : _nativeLib = DynamicLibrary.open(libraryPath); + + /// Init the ruapu environment + void init() { + final RuapuInit_Dart ruapu_init = _nativeLib + .lookup>('ruapu_init') + .asFunction(); + ruapu_init(); + } + + /// Get the ISA support list of the CPU + List rua() { + final RuapuRUA_Dart ruapu_rua = _nativeLib + .lookup>('ruapu_rua') + .asFunction(); + + Pointer> result = ruapu_rua(); + + List isas = []; + int index = 0; + while (true) { + Pointer strPtr = result.elementAt(index).value; + if (strPtr.address == 0) break; + String str = strPtr.toDartString(); + isas.add(str); + index++; + } + + return isas; + } + + /// Check the support status of a given isa + bool supports(String isa) { + final Pointer cIsa = isa.toNativeUtf8(); + + final RuapuSupports_Dart ruapu_supports = _nativeLib + .lookup>('ruapu_supports') + .asFunction(); + + int result = ruapu_supports(cIsa); + + malloc.free(cIsa); + + return result != 0; + } + +} \ No newline at end of file