Skip to content

Commit

Permalink
Merge pull request #25 from peercoin/windows
Browse files Browse the repository at this point in the history
Windows support
  • Loading branch information
MatthewLM committed Feb 8, 2024
2 parents 9fb18e0 + 384a24f commit 73b6c57
Show file tree
Hide file tree
Showing 40 changed files with 1,436 additions and 61 deletions.
9 changes: 9 additions & 0 deletions coinlib/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## 2.0.0-rc.9

- Update secp256k1 to 0.4.1
- Update dart dependencies and FFI bindings

## 2.0.0-rc.8

Add windows build support

## 2.0.0-rc.7

- Add `CoinUnit` class to convert between amount strings and satoshis.
Expand Down
63 changes: 57 additions & 6 deletions coinlib/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,10 @@ dart pub add coinlib
```

If you are using the library for web, the library is ready to use. If you are
using the library on Linux or macOS then please see
["Building for Linux"](#building-for-linux) and
["Building for macOS"](#building-for-macos) below.

No script is included for building on Windows at the present time, however a
`secp256k1.dll` may be built into your `build/` directory separately.
using the library on Linux, macOS, or Windows, then please see
["Building for Linux"](#building-for-linux),
["Building for macOS"](#building-for-macos), or
["Building for Windows"](#building-for-windows) below.

The library can be imported via:

Expand Down Expand Up @@ -85,6 +83,59 @@ framework named `secp256k1.framework`.
To build the dynamic library, run `dart run coinlib:build_macos` which will
place the library under a `build` directory.

## Building for Windows

### Native Windows build

**Please note that native windows builds under this section can sometimes freeze
during the build process.** If this happens please use the WSL build process
described in
["Cross-compiling for Windows using WSL"](#cross-compiling-for-windows-using-wsl).

Building on Windows requires CMake as a dependency.

The Windows shared library can be built using `dart run coinlib:build_windows` in
the root directory of your package which will produce a shared library into
`build/libsecp256k1.dll`. This can also be run in the `coinlib` root directory
via `dart run bin/build_windows.dart`.

Windows builds use the Visual Studio 17 2022 generator. Earlier Visual Studio
toolchains may work by editing `bin/build_windows.dart`.

### Cross-compiling for Windows from Linux

Cross-compile a secp256k1 DLL for Windows on an Ubuntu 20.04 host with
`dart run coinlib:build_windows_crosscompile`. This can also be run in the
`coinlib` root directory via `dart run bin/build_windows_crosscompile.dart`.

### Cross-compiling for Windows using WSL

Builds on Windows can be accomplished using WSL2 (Windows Subsystem for Linux).
First, install the following packages to the WSL(2) host:

- `autoconf`
- `libtool`
- `build-essential`
- `git`
- `cmake`
- `mingw-w64`

as in:

```
apt-get update -y
apt-get install -y autoconf libtool build-essential git cmake mingw-w64
```

Then, cross-compile a secp256k1 DLL for Windows on an Ubuntu 20.04 WSL2 instance
on a Windows host with `dart run coinlib:build_wsl` or
`dart run bin/build_wsl.dart` in the `coinlib` root directory, or complete the
above
["Cross-compiling for Windows on Linux"](#cross-compiling-for-windows-from-linux)
after installing Docker or Podman in WSL. The build can also be completed
without installing Flutter to WSL by following
[bitcoin-core/secp256k1's "Cross compiling" guide](https://github.com/bitcoin-core/secp256k1?tab=readme-ov-file#cross-compiling).

## Development

This section is only relevant to developers of the library.
Expand Down
5 changes: 0 additions & 5 deletions coinlib/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
include: package:lints/recommended.yaml

analyzer:
exclude:
# Exclude generated files which often use alternative styling
- lib/src/generated/

# Lint rules and documentation, see http://dart-lang.github.io/linter/lints
linter:
rules:
Expand Down
7 changes: 3 additions & 4 deletions coinlib/bin/build_linux.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ RUN apt-get update -y \
# Could use secp256k1 already in code-base but this makes the dockerfile more
# independent and avoids complexity of copying everything into the correct
# context. It's not a large library to download.
# Use 0.3.1 release
# Use 0.4.1 release
RUN git clone https://github.com/bitcoin-core/secp256k1 \
&& cd secp256k1 \
&& git checkout 346a053d4c442e08191f075c3932d03140579d47
&& git checkout 1ad5185cd42c0636104129fcc9f6a4bf9c67cc40
WORKDIR /secp256k1
Expand All @@ -34,7 +34,7 @@ RUN make
# maintained.
RUN make install
RUN mkdir output
RUN cp /usr/local/lib/libsecp256k1.so.2.0.1 output/libsecp256k1.so
RUN cp /usr/local/lib/libsecp256k1.so.2.1.1 output/libsecp256k1.so
""";

void main() async {
Expand All @@ -52,5 +52,4 @@ void main() async {
exit(1);
}


}
6 changes: 3 additions & 3 deletions coinlib/bin/build_macos.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ void main() async {
"Could not clone secp256k1 to temporary build directory",
);

// Checkout to 0.3.2 commit
// Checkout to 0.4.1 commit
exitOnCode(
await execWithStdio(
"git", ["checkout", "acf5c55ae6a94e5ca847e07def40427547876101"],
"git", ["checkout", "1ad5185cd42c0636104129fcc9f6a4bf9c67cc40"],
workingDir: libDir,
),
"Could not checkout to v0.3.2 commit",
"Could not checkout to v0.4.1 commit",
);

// Generate configure
Expand Down
4 changes: 2 additions & 2 deletions coinlib/bin/build_wasm.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ RUN wget -nv https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-
RUN tar xvf $WASI_ARCHIVE
RUN rm $WASI_ARCHIVE
# Clone libsecp256k1 and use v0.3.1
# Clone libsecp256k1 and use v0.4.1
RUN git clone https://github.com/bitcoin-core/secp256k1 \
&& cd secp256k1 \
&& git checkout 346a053d4c442e08191f075c3932d03140579d47
&& git checkout 1ad5185cd42c0636104129fcc9f6a4bf9c67cc40
WORKDIR /secp256k1
# Build using wasi-sdk
Expand Down
57 changes: 57 additions & 0 deletions coinlib/bin/build_windows.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import 'dart:io';

import 'util.dart';

/// Follows bitcoin-core/secp256k1's "Building on Windows" instructions.
///
/// Runnable in "Developer Command Prompt for VS 2022".
void main() async {

// Make temporary directory.
final workDir = Directory.current.path;
final tmpDir = createTmpDir();

// Clone bitcoin-core/secp256k1.
await execWithStdio(
"git",
["clone", "https://github.com/bitcoin-core/secp256k1", "$tmpDir/secp256k1"],
);
Directory.current = Directory("$tmpDir/secp256k1");
await execWithStdio(
"git",
// Use version 0.4.1
["checkout", "1ad5185cd42c0636104129fcc9f6a4bf9c67cc40"],
);

// Build in tmpDir/secp256k1/build.
Directory("build").createSync();

// Configure cmake.
await execWithStdio("cmake", [
"-G",
"Visual Studio 17 2022",
"-A",
"x64",
"-S",
".",
"-B",
"build",
]);

// Build.
await execWithStdio("cmake", [
"--build",
"build",
"--config",
"RelWithDebInfo",
]);

// Copy the DLL to build/windows/x64/secp256k1.dll.
Directory("$workDir/build").createSync();
File("$tmpDir/secp256k1/build/src/RelWithDebInfo/secp256k1.dll")
.copySync("$workDir/build/secp256k1.dll");

print("Output libsecp256k1.dll successfully");

}
46 changes: 46 additions & 0 deletions coinlib/bin/build_windows_crosscompile.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import 'dart:io';
import 'docker_util.dart';

/// Build a Windows DLL for secp256k1 using a Dockerfile string.
String dockerfile = r"""
FROM debian:bullseye
# Install dependenices.
RUN apt-get update -y \
&& apt-get install -y autoconf libtool build-essential git cmake gcc-mingw-w64
# Clone libsecp256k1 0.4.1 release.
RUN git clone https://github.com/bitcoin-core/secp256k1 \
&& cd secp256k1 \
&& git checkout 1ad5185cd42c0636104129fcc9f6a4bf9c67cc40 \
&& mkdir build
WORKDIR /secp256k1/build
# Build shared library for Windows.
RUN cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/x86_64-w64-mingw32.toolchain.cmake
RUN make
# Build DLL and copy into output.
RUN make install
RUN mkdir output
RUN cp src/libsecp256k1-2.dll output/secp256k1.dll
""";

void main() async {

String cmd = await getDockerCmd();
print("Using $cmd to run dockerfile");

// Build secp256k1 and copy shared library to build directory
if (!await dockerBuild(
cmd,
dockerfile,
"coinlib_build_secp256k1_windows",
"output/secp256k1.dll",
)) {
exit(1);
}

}
48 changes: 48 additions & 0 deletions coinlib/bin/build_wsl.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import 'dart:io';

import 'util.dart';

/// Follows bitcoin-core/secp256k1's "Cross compiling" instructions.
///
/// Runnable in WSL. Install the dependencies listed in the README:
/// ```
/// apt-get install -y autoconf libtool build-essential git cmake mingw-w64
/// ```
void main() async {
// Make temporary directory.
final workDir = Directory.current.path;
final tmpDir = createTmpDir();

// Clone bitcoin-core/secp256k1.
await execWithStdio(
"git",
["clone", "https://github.com/bitcoin-core/secp256k1", "$tmpDir/secp256k1"],
);
Directory.current = Directory("$tmpDir/secp256k1");
await execWithStdio(
"git",
// Use version 0.4.1
["checkout", "1ad5185cd42c0636104129fcc9f6a4bf9c67cc40"],
);

// Build in tmpDir/secp256k1/lib.
Directory("lib").createSync();
Directory.current = Directory("lib");

// Run cmake with the provided toolchain file.
await execWithStdio("cmake", [
"..",
"-DCMAKE_TOOLCHAIN_FILE=../cmake/x86_64-w64-mingw32.toolchain.cmake",
]);

// Build the project using "make".
await execWithStdio("make", []);

// Copy the DLL to build/libsecp256k1.dll.
Directory("$workDir/build").createSync();
File("src/libsecp256k1.dll").copySync("$workDir/build/secp256k1.dll");

print("Output libsecp256k1.dll successfully");

}
10 changes: 0 additions & 10 deletions coinlib/lib/src/secp256k1/secp256k1.ffi.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -752,9 +752,6 @@ class NativeSecp256k1 {
secp256k1_nonce_function get secp256k1_nonce_function_rfc6979 =>
_secp256k1_nonce_function_rfc6979.value;

set secp256k1_nonce_function_rfc6979(secp256k1_nonce_function value) =>
_secp256k1_nonce_function_rfc6979.value = value;

/// A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979).
late final ffi.Pointer<secp256k1_nonce_function>
_secp256k1_nonce_function_default =
Expand All @@ -763,9 +760,6 @@ class NativeSecp256k1 {
secp256k1_nonce_function get secp256k1_nonce_function_default =>
_secp256k1_nonce_function_default.value;

set secp256k1_nonce_function_default(secp256k1_nonce_function value) =>
_secp256k1_nonce_function_default.value = value;

/// Create an ECDSA signature.
///
/// Returns: 1: signature created
Expand Down Expand Up @@ -1909,10 +1903,6 @@ class NativeSecp256k1 {
secp256k1_nonce_function_hardened get secp256k1_nonce_function_bip340 =>
_secp256k1_nonce_function_bip340.value;

set secp256k1_nonce_function_bip340(
secp256k1_nonce_function_hardened value) =>
_secp256k1_nonce_function_bip340.value = value;

/// Create a Schnorr signature.
///
/// Does _not_ strictly follow BIP-340 because it does not verify the resulting
Expand Down
2 changes: 1 addition & 1 deletion coinlib/lib/src/secp256k1/secp256k1.wasm.g.dart

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion coinlib/lib/src/secp256k1/secp256k1_io.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ String _libraryPath() {
localLib = "lib$_name.dylib";
flutterLib = "$_name.framework/$_name";
} else if (Platform.isWindows) {
// Not provided yet, so should fail to load unless added outside of library
flutterLib = localLib = "$_name.dll";
} else {
throw UnsupportedError('Unknown platform: ${Platform.operatingSystem}');
Expand Down
4 changes: 2 additions & 2 deletions coinlib/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ name: coinlib
description:
A straight-forward, modular library for Peercoin and other Satoshi-based UTXO
blockchains
version: 2.0.0-rc.7
version: 2.0.0-rc.9
repository: https://github.com/peercoin/coinlib

environment:
sdk: '>=3.2.0 <4.0.0'

dev_dependencies:
ffigen: ^10.0.0
ffigen: ^11.0.0
lints: ^3.0.0
test: ^1.21.0

Expand Down

0 comments on commit 73b6c57

Please sign in to comment.