Skip to content

Commit

Permalink
Add Windows support
Browse files Browse the repository at this point in the history
* flutter create --platforms=windows .

I did not make any changes to these files, they were just generated using the command above.

* generated plugin registrants

autogenerated changes, no manual edits

* add script to cross-compile secp256k1 for windows  77227a

* include secp256k1 DLL in coinlib_flutter projects

confirmed working with `flutter run -d windows` in `example`

* ignore coinlib/src folder

do not check secp256k1 submodule into git

* document Windows builds

* add tip about optionally skipping flutter installation in wsl2 instance

* be more specific in docs re: building on windows without wsl2

* use dockerfile for native-ubuntu builds, use old approach only for wsl

and update docs and docs formatting

fix dockerfile

* move depenedencies from script to docs

* replace processSync with execWithStdio

* move DLL to build/secp256k1.dll IAW lib/src/secp256k1/secp256k1_io.dart

* remove unnecessary autogenerated files

* use tmp dir to avoid polluting project dir

* docs update and formatting

* formatting

remove double newlines and debugging print

* remove unneeded gitignore line

* correct relative path to secp256k1.dll

* add ffiPlugin property to windows

* correct relative path to secp256k1.dll

* do not add unfruitful linux build of secp256k1 on windows

TODO re-enable.  TODO make CMake work on Windows natively

* correct relative path to secp256k1.dll

previous fixes fixed the example app but broke consumer apps.  this version works for both the example app and consumers of this plugin the same way.  the example just needs to get its secp256k1 built for it, too (but that makes sense)

* bump version to rc 6 to denote windows support

* bump example app pubspec bump version to rc 6 to denote windows support

* place secp256k1.dll in build/windows

* create build/windows folder if it doesn't exist

* don't add extra windows folder in secp256k1 dll path

it's included in the cmake var

force pushing to fix typo

* add a native windows build script and document its use

* move dll output from build/windows to build

in accordance with coinlib convention

* minor docs update

mention windows support and point to coinlib docs for lib-building guide

* mention Visual Studio 17 2022 dependency

* typofix: linux->windows in docs

* clarify Windows library-building

re: #24 (comment)

* reduce example app version number to 1.0.0: partial reversion of 9573a05
  • Loading branch information
sneurlax authored Jan 6, 2024
1 parent b4fb192 commit ebc0c7f
Show file tree
Hide file tree
Showing 31 changed files with 1,344 additions and 25 deletions.
52 changes: 46 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,48 @@ 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

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` or `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`, or complete the above
["Building for Windows on Linux"](#building-for-windows-on-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
1 change: 0 additions & 1 deletion coinlib/bin/build_linux.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,4 @@ void main() async {
exit(1);
}


}
51 changes: 51 additions & 0 deletions coinlib/bin/build_windows.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
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",
["checkout", "346a053d4c442e08191f075c3932d03140579d47"],
);

// 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");
}
45 changes: 45 additions & 0 deletions coinlib/bin/build_windows_crosscompile.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
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
# Clone libsecp256k1 0.3.1 release.
RUN git clone https://github.com/bitcoin-core/secp256k1 \
&& cd secp256k1 \
&& git checkout 346a053d4c442e08191f075c3932d03140579d47
&& mkdir -p secp256k1/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 cp src/libsecp256k1-2.dll output/libsecp256k1.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",
"/secp256k1/output/libsecp256k1.dll",
)) {
exit(1);
}

}
44 changes: 44 additions & 0 deletions coinlib/bin/build_wsl.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
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",
["checkout", "346a053d4c442e08191f075c3932d03140579d47"],
);

// 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");
}
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
2 changes: 1 addition & 1 deletion coinlib/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: coinlib
description:
A straight-forward, modular library for Peercoin and other Satoshi-based UTXO
blockchains
version: 2.0.0-rc.5
version: 2.0.0-rc.6
repository: https://github.com/peercoin/coinlib

environment:
Expand Down
32 changes: 19 additions & 13 deletions coinlib_flutter/.metadata
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled.
# This file should be version controlled and should not be manually edited.

version:
revision: 9944297138845a94256f1cf37beb88ff9a8e811a
channel: stable
revision: "2524052335ec76bb03e04ede244b071f1b86d190"
channel: "[user-branch]"

project_type: plugin_ffi

# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
create_revision: 2524052335ec76bb03e04ede244b071f1b86d190
base_revision: 2524052335ec76bb03e04ede244b071f1b86d190
- platform: android
create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
create_revision: 2524052335ec76bb03e04ede244b071f1b86d190
base_revision: 2524052335ec76bb03e04ede244b071f1b86d190
- platform: ios
create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
create_revision: 2524052335ec76bb03e04ede244b071f1b86d190
base_revision: 2524052335ec76bb03e04ede244b071f1b86d190
- platform: linux
create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
create_revision: 2524052335ec76bb03e04ede244b071f1b86d190
base_revision: 2524052335ec76bb03e04ede244b071f1b86d190
- platform: macos
create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
create_revision: 2524052335ec76bb03e04ede244b071f1b86d190
base_revision: 2524052335ec76bb03e04ede244b071f1b86d190
- platform: web
create_revision: 2524052335ec76bb03e04ede244b071f1b86d190
base_revision: 2524052335ec76bb03e04ede244b071f1b86d190
- platform: windows
create_revision: 2524052335ec76bb03e04ede244b071f1b86d190
base_revision: 2524052335ec76bb03e04ede244b071f1b86d190

# User provided section

Expand Down
2 changes: 1 addition & 1 deletion coinlib_flutter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ An example app is provided in `example/` that demonstrates use of the loader
widget. Beyond this, the [coinlib](https://pub.dev/packages/coinlib) library
documentation can be followed.

Android, iOS, Linux, macOS and Web are supported.
Android, iOS, Linux, macOS, web, and Windows are supported. If you are using the library for web, Android, or iOS, the library is ready to use. For Windows, run `dart run coinlib:build_windows` to build the library. See [coinlib's documentation](https://pub.dev/packages/coinlib) for more detailed instructions on and options for building the native library.
2 changes: 1 addition & 1 deletion coinlib_flutter/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ environment:
dependencies:
flutter:
sdk: flutter
coinlib_flutter: ^2.0.0-rc.5
coinlib_flutter: ^2.0.0-rc.6
cupertino_icons: ^1.0.2

dev_dependencies:
Expand Down
17 changes: 17 additions & 0 deletions coinlib_flutter/example/windows/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
flutter/ephemeral/

# Visual Studio user-specific files.
*.suo
*.user
*.userosscache
*.sln.docstates

# Visual Studio build-related files.
x64/
x86/

# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
Loading

0 comments on commit ebc0c7f

Please sign in to comment.