code only
This commit is contained in:
commit
dbc707f23f
10 changed files with 605 additions and 0 deletions
223
lib/stockfish.dart
Normal file
223
lib/stockfish.dart
Normal file
|
@ -0,0 +1,223 @@
|
|||
// Using code from https://github.com/ArjanAswal/Stockfish/blob/master/lib/src/stockfish.dart
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:ffi';
|
||||
import 'dart:io';
|
||||
import 'dart:convert';
|
||||
import 'dart:isolate';
|
||||
import 'dart:developer' as developer;
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
||||
import 'stockfish_bindings_generated.dart';
|
||||
import 'stockfish_state.dart';
|
||||
|
||||
const String _libName = 'stockfish';
|
||||
const String _releaseType = kDebugMode ? 'Debug' : 'Release';
|
||||
|
||||
/// The dynamic library in which the symbols for [StockfishChessEngineBindings] can be found.
|
||||
final DynamicLibrary _dylib = () {
|
||||
if (Platform.isMacOS || Platform.isIOS) {
|
||||
return DynamicLibrary.open('$_libName.framework/$_libName');
|
||||
}
|
||||
if (Platform.isAndroid) {
|
||||
return DynamicLibrary.open('lib$_libName.so');
|
||||
}
|
||||
if (Platform.isLinux) {
|
||||
return DynamicLibrary.open(
|
||||
'${File(Platform.resolvedExecutable).parent.parent.path}/plugins/flutter_stockfish_plugin/shared/lib$_libName.so');
|
||||
}
|
||||
if (Platform.isWindows) {
|
||||
return DynamicLibrary.open(
|
||||
'${File(Platform.resolvedExecutable).parent.parent.parent.path}/plugins/flutter_stockfish_plugin/shared/$_releaseType/$_libName.dll');
|
||||
}
|
||||
throw UnsupportedError('Unknown platform: ${Platform.operatingSystem}');
|
||||
}();
|
||||
|
||||
/// The bindings to the native functions in [_dylib].
|
||||
final StockfishChessEngineBindings _bindings =
|
||||
StockfishChessEngineBindings(_dylib);
|
||||
|
||||
/// A wrapper for C++ engine.
|
||||
class Stockfish {
|
||||
final Completer<Stockfish>? completer;
|
||||
|
||||
final _state = _StockfishState();
|
||||
final _stdoutController = StreamController<String>.broadcast();
|
||||
final _mainPort = ReceivePort();
|
||||
final _stdoutPort = ReceivePort();
|
||||
|
||||
late StreamSubscription _mainSubscription;
|
||||
late StreamSubscription _stdoutSubscription;
|
||||
|
||||
Stockfish._({this.completer}) {
|
||||
_mainSubscription =
|
||||
_mainPort.listen((message) => _cleanUp(message is int ? message : 1));
|
||||
_stdoutSubscription = _stdoutPort.listen((message) {
|
||||
if (message is String) {
|
||||
_stdoutController.sink.add(message);
|
||||
} else {
|
||||
developer.log('The stdout isolate sent $message', name: 'Stockfish');
|
||||
}
|
||||
});
|
||||
compute(_spawnIsolates, [_mainPort.sendPort, _stdoutPort.sendPort]).then(
|
||||
(success) {
|
||||
final state = success ? StockfishState.ready : StockfishState.error;
|
||||
_state._setValue(state);
|
||||
if (state == StockfishState.ready) {
|
||||
completer?.complete(this);
|
||||
}
|
||||
},
|
||||
onError: (error) {
|
||||
developer.log('The init isolate encountered an error $error',
|
||||
name: 'Stockfish');
|
||||
_cleanUp(1);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static Stockfish? _instance;
|
||||
|
||||
/// Creates a C++ engine.
|
||||
///
|
||||
/// This may throws a [StateError] if an active instance is being used.
|
||||
/// Owner must [dispose] it before a new instance can be created.
|
||||
factory Stockfish() {
|
||||
if (_instance != null) {
|
||||
throw StateError('Multiple instances are not supported, yet.');
|
||||
}
|
||||
|
||||
_instance = Stockfish._();
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
/// The current state of the underlying C++ engine.
|
||||
ValueListenable<StockfishState> get state => _state;
|
||||
|
||||
/// The standard output stream.
|
||||
Stream<String> get stdout => _stdoutController.stream;
|
||||
|
||||
/// The standard input sink.
|
||||
set stdin(String line) {
|
||||
final stateValue = _state.value;
|
||||
if (stateValue != StockfishState.ready) {
|
||||
throw StateError('Stockfish is not ready ($stateValue)');
|
||||
}
|
||||
|
||||
final unicodePointer = '$line\n'.toNativeUtf8();
|
||||
final pointer = unicodePointer.cast<Char>();
|
||||
_bindings.stockfish_stdin_write(pointer);
|
||||
calloc.free(unicodePointer);
|
||||
}
|
||||
|
||||
/// Stops the C++ engine.
|
||||
void dispose() {
|
||||
final stateValue = _state.value;
|
||||
if (stateValue == StockfishState.ready) {
|
||||
stdin = 'quit';
|
||||
}
|
||||
}
|
||||
|
||||
void _cleanUp(int exitCode) {
|
||||
_stdoutController.close();
|
||||
|
||||
_mainSubscription.cancel();
|
||||
_stdoutSubscription.cancel();
|
||||
|
||||
_state._setValue(
|
||||
exitCode == 0 ? StockfishState.disposed : StockfishState.error);
|
||||
|
||||
_instance = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a C++ engine asynchronously.
|
||||
///
|
||||
/// This method is different from the factory method [Stockfish] that
|
||||
/// it will wait for the engine to be ready before returning the instance.
|
||||
Future<Stockfish> stockfishAsync() {
|
||||
if (Stockfish._instance != null) {
|
||||
return Future.error(StateError('Only one instance can be used at a time'));
|
||||
}
|
||||
|
||||
final completer = Completer<Stockfish>();
|
||||
Stockfish._instance = Stockfish._(completer: completer);
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
class _StockfishState extends ChangeNotifier
|
||||
implements ValueListenable<StockfishState> {
|
||||
StockfishState _value = StockfishState.starting;
|
||||
|
||||
@override
|
||||
StockfishState get value => _value;
|
||||
|
||||
_setValue(StockfishState v) {
|
||||
if (v == _value) return;
|
||||
_value = v;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void _isolateMain(SendPort mainPort) {
|
||||
final exitCode = _bindings.stockfish_main();
|
||||
mainPort.send(exitCode);
|
||||
|
||||
developer.log('nativeMain returns $exitCode', name: 'Stockfish');
|
||||
print("stoped");
|
||||
}
|
||||
|
||||
void _isolateStdout(SendPort stdoutPort) {
|
||||
String previous = '';
|
||||
|
||||
while (true) {
|
||||
final pointer = _bindings.stockfish_stdout_read();
|
||||
|
||||
if (pointer.address == 0) {
|
||||
developer.log('nativeStdoutRead returns NULL', name: 'Stockfish');
|
||||
return;
|
||||
}
|
||||
|
||||
Uint8List newContentCharList;
|
||||
|
||||
final newContentLength = pointer.cast<Utf8>().length;
|
||||
newContentCharList = Uint8List.view(
|
||||
pointer.cast<Uint8>().asTypedList(newContentLength).buffer,
|
||||
0,
|
||||
newContentLength);
|
||||
|
||||
final newContent = utf8.decode(newContentCharList);
|
||||
|
||||
final data = previous + newContent;
|
||||
final lines = data.split('\n');
|
||||
previous = lines.removeLast();
|
||||
for (final line in lines) {
|
||||
stdoutPort.send(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> _spawnIsolates(List<SendPort> mainAndStdout) async {
|
||||
final initResult = _bindings.stockfish_init();
|
||||
if (initResult != 0) {
|
||||
developer.log('initResult=$initResult', name: 'Stockfish');
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
await Isolate.spawn(_isolateStdout, mainAndStdout[1]);
|
||||
} catch (error) {
|
||||
developer.log('Failed to spawn stdout isolate: $error', name: 'Stockfish');
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
await Isolate.spawn(_isolateMain, mainAndStdout[0]);
|
||||
} catch (error) {
|
||||
developer.log('Failed to spawn main isolate: $error', name: 'Stockfish');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
71
lib/stockfish_bindings_generated.dart
Normal file
71
lib/stockfish_bindings_generated.dart
Normal file
|
@ -0,0 +1,71 @@
|
|||
// ignore_for_file: always_specify_types
|
||||
// ignore_for_file: camel_case_types
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
|
||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||
//
|
||||
// Generated by `package:ffigen`.
|
||||
import 'dart:ffi' as ffi;
|
||||
|
||||
/// Bindings for `src/stockfish.h`.
|
||||
///
|
||||
/// Regenerate bindings with `dart run ffigen --config ffigen.yaml`.
|
||||
///
|
||||
class StockfishChessEngineBindings {
|
||||
/// Holds the symbol lookup function.
|
||||
final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
|
||||
_lookup;
|
||||
|
||||
/// The symbols are looked up in [dynamicLibrary].
|
||||
StockfishChessEngineBindings(ffi.DynamicLibrary dynamicLibrary)
|
||||
: _lookup = dynamicLibrary.lookup;
|
||||
|
||||
/// The symbols are looked up with [lookup].
|
||||
StockfishChessEngineBindings.fromLookup(
|
||||
ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
|
||||
lookup)
|
||||
: _lookup = lookup;
|
||||
|
||||
int stockfish_init() {
|
||||
return _stockfish_init();
|
||||
}
|
||||
|
||||
late final _stockfish_initPtr =
|
||||
_lookup<ffi.NativeFunction<ffi.Int Function()>>('stockfish_init');
|
||||
late final _stockfish_init = _stockfish_initPtr.asFunction<int Function()>();
|
||||
|
||||
int stockfish_main() {
|
||||
return _stockfish_main();
|
||||
}
|
||||
|
||||
late final _stockfish_mainPtr =
|
||||
_lookup<ffi.NativeFunction<ffi.Int Function()>>('stockfish_main');
|
||||
late final _stockfish_main = _stockfish_mainPtr.asFunction<int Function()>();
|
||||
|
||||
int stockfish_stdin_write(
|
||||
ffi.Pointer<ffi.Char> data,
|
||||
) {
|
||||
return _stockfish_stdin_write(
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
late final _stockfish_stdin_writePtr =
|
||||
_lookup<ffi.NativeFunction<ssize_t Function(ffi.Pointer<ffi.Char>)>>(
|
||||
'stockfish_stdin_write');
|
||||
late final _stockfish_stdin_write = _stockfish_stdin_writePtr
|
||||
.asFunction<int Function(ffi.Pointer<ffi.Char>)>();
|
||||
|
||||
ffi.Pointer<ffi.Char> stockfish_stdout_read() {
|
||||
return _stockfish_stdout_read();
|
||||
}
|
||||
|
||||
late final _stockfish_stdout_readPtr =
|
||||
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
|
||||
'stockfish_stdout_read');
|
||||
late final _stockfish_stdout_read =
|
||||
_stockfish_stdout_readPtr.asFunction<ffi.Pointer<ffi.Char> Function()>();
|
||||
}
|
||||
|
||||
typedef ssize_t = __ssize_t;
|
||||
typedef __ssize_t = ffi.Long;
|
16
lib/stockfish_state.dart
Normal file
16
lib/stockfish_state.dart
Normal file
|
@ -0,0 +1,16 @@
|
|||
// Taken from https://github.com/ArjanAswal/Stockfish/blob/master/lib/src/stockfish_state.dart
|
||||
|
||||
/// C++ engine state.
|
||||
enum StockfishState {
|
||||
/// Engine has been stopped.
|
||||
disposed,
|
||||
|
||||
/// An error occured (engine could not start).
|
||||
error,
|
||||
|
||||
/// Engine is running.
|
||||
ready,
|
||||
|
||||
/// Engine is starting.
|
||||
starting,
|
||||
}
|
22
linux/CMakeLists.txt
Normal file
22
linux/CMakeLists.txt
Normal file
|
@ -0,0 +1,22 @@
|
|||
# The Flutter tooling requires that developers have CMake 3.22 or later
|
||||
# installed. You should not increase this version, as doing so will cause
|
||||
# the plugin to fail to compile for some customers of the plugin.
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
# Project-level configuration.
|
||||
set(PROJECT_NAME "stockfish")
|
||||
project(${PROJECT_NAME} LANGUAGES CXX)
|
||||
|
||||
# Invoke the build for native code shared with the other target platforms.
|
||||
# This can be changed to accomodate different builds.
|
||||
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../src" "${CMAKE_CURRENT_BINARY_DIR}/shared")
|
||||
|
||||
# List of absolute paths to libraries that should be bundled with the plugin.
|
||||
# This list could contain prebuilt libraries, or libraries created by an
|
||||
# external build triggered from this build file.
|
||||
set(stockfish_bundled_libraries
|
||||
# Defined in ../src/CMakeLists.txt.
|
||||
# This can be changed to accomodate different builds.
|
||||
$<TARGET_FILE:stockfish>
|
||||
PARENT_SCOPE
|
||||
)
|
41
src/CMakeLists.txt
Normal file
41
src/CMakeLists.txt
Normal file
|
@ -0,0 +1,41 @@
|
|||
# The Flutter tooling requires that developers have CMake 3.18 or later
|
||||
# installed. You should not increase this version, as doing so will cause
|
||||
# the plugin to fail to compile for some customers of the plugin.
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
project(stockfish VERSION 0.0.1 LANGUAGES CXX)
|
||||
file(GLOB_RECURSE cppPaths "Stockfish/src/*.cpp")
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(NNUE_NAME nn-0000000000a0.nnue)
|
||||
|
||||
add_library(stockfish SHARED
|
||||
"stockfish.cpp"
|
||||
"stream_fix.cpp"
|
||||
${cppPaths}
|
||||
)
|
||||
|
||||
set_target_properties(stockfish PROPERTIES
|
||||
PUBLIC_HEADER stockfish.h
|
||||
OUTPUT_NAME "stockfish"
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(/FI"stream_fix.h")
|
||||
else()
|
||||
add_definitions(-include stream_fix.h)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(stockfish PUBLIC DART_SHARED_LIB)
|
||||
|
||||
target_include_directories(stockfish
|
||||
PUBLIC
|
||||
"./"
|
||||
)
|
||||
|
||||
|
||||
if (MSVC)
|
||||
file(DOWNLOAD https://tests.stockfishchess.org/api/nn/${NNUE_NAME} ${CMAKE_BINARY_DIR}/runner/Debug/${NNUE_NAME})
|
||||
file(COPY ${CMAKE_BINARY_DIR}/runner/Debug/${NNUE_NAME} DESTINATION ${CMAKE_BINARY_DIR}/runner/Release)
|
||||
else ()
|
||||
file(DOWNLOAD https://tests.stockfishchess.org/api/nn/${NNUE_NAME} ${CMAKE_BINARY_DIR}/${NNUE_NAME})
|
||||
endif ()
|
66
src/stockfish.cpp
Normal file
66
src/stockfish.cpp
Normal file
|
@ -0,0 +1,66 @@
|
|||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#ifdef _WIN32
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#define STDIN_FILENO 0
|
||||
#define STDOUT_FILENO 1
|
||||
#define STDERR_FILENO 2
|
||||
#ifdef _WIN64
|
||||
#define ssize_t __int64
|
||||
#else
|
||||
#define ssize_t long
|
||||
#endif
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define BUFFER_SIZE 1024
|
||||
|
||||
#include "stockfish.h"
|
||||
|
||||
const char *QUITOK = "quitok\n";
|
||||
|
||||
int main(int, char **);
|
||||
|
||||
int stockfish_init() {
|
||||
std::cout << "Init Stockfish: Nothing todo!";
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stockfish_main() {
|
||||
int argc = 1;
|
||||
char *argv[] = {(char *)""};
|
||||
int exitCode = main(argc, argv);
|
||||
|
||||
fakeout << QUITOK << "\n";
|
||||
|
||||
usleep(100000);
|
||||
|
||||
fakeout.close();
|
||||
fakein.close();
|
||||
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
ssize_t stockfish_stdin_write(char *data) {
|
||||
std::string val(data);
|
||||
fakein << val << fakeendl;
|
||||
return val.length();
|
||||
}
|
||||
|
||||
std::string data;
|
||||
char buffer[BUFFER_SIZE + 1];
|
||||
|
||||
char *stockfish_stdout_read() {
|
||||
if (getline(fakeout, data)) {
|
||||
size_t len = data.length();
|
||||
size_t i;
|
||||
for (i = 0; i < len && i < BUFFER_SIZE; i++) {
|
||||
buffer[i] = data[i];
|
||||
}
|
||||
buffer[i] = 0;
|
||||
return buffer;
|
||||
}
|
||||
return NULL;
|
||||
}
|
46
src/stockfish.h
Normal file
46
src/stockfish.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
//#define _ffigen
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <BaseTsd.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define FFI_PLUGIN_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define FFI_PLUGIN_EXPORT __attribute__((visibility("default"))) __attribute__((used))
|
||||
#endif
|
||||
|
||||
// Initialisation of Stockfish.
|
||||
#ifndef _ffigen
|
||||
extern "C"
|
||||
#endif
|
||||
FFI_PLUGIN_EXPORT int stockfish_init();
|
||||
|
||||
// Stockfish main loop.
|
||||
#ifndef _ffigen
|
||||
extern "C"
|
||||
#endif
|
||||
FFI_PLUGIN_EXPORT int stockfish_main();
|
||||
|
||||
// Writing to Stockfish STDIN.
|
||||
#ifndef _ffigen
|
||||
extern "C"
|
||||
#endif
|
||||
FFI_PLUGIN_EXPORT ssize_t stockfish_stdin_write(char *data);
|
||||
|
||||
// Reading Stockfish STDOUT
|
||||
#ifndef _ffigen
|
||||
extern "C"
|
||||
#endif
|
||||
FFI_PLUGIN_EXPORT char * stockfish_stdout_read();
|
31
src/stream_fix.cpp
Normal file
31
src/stream_fix.cpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
#include "stream_fix.h"
|
||||
|
||||
bool FakeStream::try_get_line(std::string& val) {
|
||||
std::unique_lock<std::mutex> lock(mutex_guard);
|
||||
if (string_queue.empty() || closed) return false;
|
||||
val = string_queue.front();
|
||||
string_queue.pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
void FakeStream::close() {
|
||||
std::lock_guard<std::mutex> lock(mutex_guard);
|
||||
closed = true;
|
||||
mutex_signal.notify_one();
|
||||
}
|
||||
bool FakeStream::is_closed() { return closed; }
|
||||
|
||||
std::streambuf* FakeStream::rdbuf() { return nullptr; }
|
||||
|
||||
std::streambuf* FakeStream::rdbuf(std::streambuf* __sb) { return nullptr; }
|
||||
|
||||
bool std::getline(FakeStream& is, std::string& str) {
|
||||
if (is.is_closed()) return false;
|
||||
is >> str;
|
||||
if (is.is_closed()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
FakeStream fakeout;
|
||||
FakeStream fakein;
|
||||
std::string fakeendl("\n");
|
66
src/stream_fix.h
Normal file
66
src/stream_fix.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
#ifndef _STREAM_FIX_H_
|
||||
#define _STREAM_FIX_H_
|
||||
#include <condition_variable>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <sstream>
|
||||
|
||||
template <typename T>
|
||||
inline std::string stringify(const T& input) {
|
||||
std::ostringstream output; // from www .ja va 2s . com
|
||||
output << input;
|
||||
return output.str();
|
||||
}
|
||||
|
||||
class FakeStream {
|
||||
public:
|
||||
template <typename T>
|
||||
FakeStream& operator<<(const T& val) {
|
||||
if (closed) return *this;
|
||||
std::lock_guard<std::mutex> lock(mutex_guard);
|
||||
string_queue.push(stringify(val));
|
||||
mutex_signal.notify_one();
|
||||
return *this;
|
||||
};
|
||||
template <typename T>
|
||||
FakeStream& operator>>(T& val) {
|
||||
if (closed) return *this;
|
||||
std::unique_lock<std::mutex> lock(mutex_guard);
|
||||
mutex_signal.wait(lock,
|
||||
[this] { return !string_queue.empty() || closed; });
|
||||
if (closed) return *this;
|
||||
val = string_queue.front();
|
||||
string_queue.pop();
|
||||
return *this;
|
||||
};
|
||||
|
||||
bool try_get_line(std::string& val);
|
||||
|
||||
void close();
|
||||
bool is_closed();
|
||||
|
||||
std::streambuf* rdbuf();
|
||||
std::streambuf* rdbuf(std::streambuf* __sb);
|
||||
|
||||
private:
|
||||
bool closed = false;
|
||||
std::queue<std::string> string_queue;
|
||||
std::string line;
|
||||
std::mutex mutex_guard;
|
||||
std::condition_variable mutex_signal;
|
||||
};
|
||||
|
||||
namespace std {
|
||||
bool getline(FakeStream& is, std::string& str);
|
||||
} // namespace std
|
||||
|
||||
// #define endl fakeendl
|
||||
// #define cout fakeout
|
||||
// #define cin fakein
|
||||
|
||||
extern FakeStream fakeout;
|
||||
extern FakeStream fakein;
|
||||
extern std::string fakeendl;
|
||||
|
||||
#endif
|
23
windows/CMakeLists.txt
Normal file
23
windows/CMakeLists.txt
Normal file
|
@ -0,0 +1,23 @@
|
|||
# The Flutter tooling requires that developers have a version of Visual Studio
|
||||
# installed that includes CMake 3.22 or later. You should not increase this
|
||||
# version, as doing so will cause the plugin to fail to compile for some
|
||||
# customers of the plugin.
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
# Project-level configuration.
|
||||
set(PROJECT_NAME "stockfish")
|
||||
project(${PROJECT_NAME} LANGUAGES CXX)
|
||||
|
||||
# Invoke the build for native code shared with the other target platforms.
|
||||
# This can be changed to accomodate different builds.
|
||||
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../src" "${CMAKE_CURRENT_BINARY_DIR}/shared")
|
||||
|
||||
# List of absolute paths to libraries that should be bundled with the plugin.
|
||||
# This list could contain prebuilt libraries, or libraries created by an
|
||||
# external build triggered from this build file.
|
||||
set(stockfish_bundled_libraries
|
||||
# Defined in ../src/CMakeLists.txt.
|
||||
# This can be changed to accomodate different builds.
|
||||
$<TARGET_FILE:stockfish>
|
||||
PARENT_SCOPE
|
||||
)
|
Loading…
Reference in a new issue