Skip to content
Open
163 changes: 120 additions & 43 deletions simplicity-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,56 +7,111 @@ fn main() {
// rerun if changes to the C code
println!("cargo:rerun-if-changed=depend");
let simplicity_path = Path::new("depend/simplicity");
let jet_files: Vec<_> = vec![
"frame.c",
"jets.c",
"jets-secp256k1.c",
"rsort.c",
"sha256.c",
"elements/env.c",
"elements/ops.c",
"elements/elementsJets.c",
"elements/txEnv.c",
]
.into_iter()
.map(|x| simplicity_path.join(x))
.collect();

let mut build = cc::Build::new();
build
.std("c11")
.flag_if_supported("-fno-inline-functions")
.opt_level(2)
.files(jet_files)
.file(Path::new("depend/wrapper.c"))
.file(Path::new("depend/env.c"))
.file(Path::new("depend/jets_wrapper.c"))
.include(simplicity_path.join("include"));
let mut files = vec![];

// 1. Base files.
files.extend(
[
"frame.c",
"jets.c",
"jets-secp256k1.c",
"rsort.c",
"sha256.c",
]
.into_iter()
.map(|x| simplicity_path.join(x)),
);
// 2. Test files.
if cfg!(feature = "test-utils") {
let test_files: Vec<_> = vec![
"bitstream.c",
"dag.c",
"deserialize.c",
"eval.c",
"type.c",
"typeInference.c",
"elements/exec.c",
"elements/primitive.c",
"ctx8Pruned.c",
"ctx8Unpruned.c",
"hashBlock.c",
"schnorr0.c",
"schnorr6.c",
"elements/checkSigHashAllTx1.c",
files.extend(
[
"bitstream.c",
"dag.c",
"deserialize.c",
"eval.c",
"type.c",
"typeInference.c",
"ctx8Pruned.c",
"ctx8Unpruned.c",
"hashBlock.c",
"schnorr0.c",
"schnorr6.c",
]
.into_iter()
.map(|x| simplicity_path.join(x)),
);
}

// Common files are compiled once into their own static library; Bitcoin
// and Elements each get their own library with only the chain-specific
// files. Duplicating the common files into both the Bitcoin and Elements
// libraries (as before) builds fine on stable (the linker only pulls the
// archive members it needs), but MSRV (1.74.0) forces `--whole-archive`
// on every native static lib, which pulls every object from both copies
// and fails with "multiple definition of" for every common symbol.
let common_files = files;

// 3B. Bitcoin base files.
let mut bitcoin_files = vec![];
bitcoin_files.extend(
[
"bitcoin/env.c",
"bitcoin/ops.c",
"bitcoin/bitcoinJets.c",
"bitcoin/txEnv.c",
]
.into_iter()
.map(|x| simplicity_path.join(x)),
);
bitcoin_files.push("depend/bitcoin_env.c".into());

// 3E. Elements base files.
let mut elements_files = vec![];
elements_files.extend(
[
"elements/env.c",
"elements/ops.c",
"elements/elementsJets.c",
"elements/txEnv.c",
]
.into_iter()
.map(|x| simplicity_path.join(x))
.collect();
.map(|x| simplicity_path.join(x)),
);
elements_files.push("depend/env.c".into());

if cfg!(feature = "test-utils") {
// 4B. Bitcoin base files.
bitcoin_files.extend(
[
"bitcoin/exec.c",
"bitcoin/primitive.c",
// "bitcoin/checkSigHashAllTx1.c", // no sighashall test

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depending on the intention of this comment, we could remove it if this check is redundant. Or, we could add a TODO here to say that we will add the Bitcoin version later.

Either way, if somebody is even bored enough to do this, let's maybe do it in a follow-up, so we don't stall the review with small stuff.

]
.into_iter()
.map(|x| simplicity_path.join(x)),
);

build.files(test_files);
// 4E. Elements base files.
elements_files.extend(
[
"elements/exec.c",
"elements/primitive.c",
"elements/checkSigHashAllTx1.c",
]
.into_iter()
.map(|x| simplicity_path.join(x)),
);
}

// General build
let mut build = cc::Build::new();
build
.std("c11")
.flag_if_supported("-fno-inline-functions")
.opt_level(2)
.include(simplicity_path.join("include"));

if cfg!(not(fuzzing)) {
build.define("PRODUCTION", None);
}
Expand All @@ -66,5 +121,27 @@ fn main() {
build.include("wasm-sysroot");
}

build.compile("ElementsSimplicity");
let mut common_build = build.clone();
let mut bitcoin_build = build.clone();
let mut elements_build = build;

// Common build: files shared between Bitcoin and Elements, including the
// wrapper files. Compiled once into its own static library so neither
// the Bitcoin nor the Elements library contains these object files --
// see the comment above `common_files` for why that matters.
common_build
.file(Path::new("depend/wrapper.c"))
.file(Path::new("depend/jets_wrapper.c"))
.files(common_files)
.compile("RustSimplicityCommon");

// Bitcoin build
bitcoin_build
.files(bitcoin_files)
.compile("BitcoinSimplicity");

// Elements build
elements_build
.files(elements_files)
.compile("ElementsSimplicity");
}
31 changes: 31 additions & 0 deletions simplicity-sys/depend/bitcoin_env.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <stdlib.h>
#include <stdalign.h>
#include "simplicity/bitcoin/env.h"
#include "simplicity/bitcoin/txEnv.h"
#include "simplicity/bitcoin/primitive.h"

typedef rawBitcoinBuffer rawBuffer;
typedef rawBitcoinBuffer rawBuffer;
typedef rawBitcoinOutput rawOutput;
typedef rawBitcoinInput rawInput;
typedef rawBitcoinTransaction rawTransaction;
typedef rawBitcoinTapEnv rawTapEnv;

const size_t rustsimplicity_0_8_c_sizeof_rawBitcoinBuffer = sizeof(rawBitcoinBuffer);
const size_t rustsimplicity_0_8_c_sizeof_rawBitcoinOutput = sizeof(rawBitcoinOutput);
const size_t rustsimplicity_0_8_c_sizeof_rawBitcoinInput = sizeof(rawBitcoinInput);
const size_t rustsimplicity_0_8_c_sizeof_rawBitcoinTransaction = sizeof(rawBitcoinTransaction);
const size_t rustsimplicity_0_8_c_sizeof_rawBitcoinTapEnv = sizeof(rawBitcoinTapEnv);
const size_t rustsimplicity_0_8_c_sizeof_bitcoinTxEnv = sizeof(txEnv);

const size_t rustsimplicity_0_8_c_alignof_rawBitcoinBuffer = alignof(rawBitcoinBuffer);
const size_t rustsimplicity_0_8_c_alignof_rawBitcoinOutput = alignof(rawBitcoinOutput);
const size_t rustsimplicity_0_8_c_alignof_rawBitcoinInput = alignof(rawBitcoinInput);
const size_t rustsimplicity_0_8_c_alignof_rawBitcoinTransaction = alignof(rawBitcoinTransaction);
const size_t rustsimplicity_0_8_c_alignof_rawBitcoinTapEnv = alignof(rawBitcoinTapEnv);
const size_t rustsimplicity_0_8_c_alignof_bitcoinTxEnv = alignof(txEnv);

void rustsimplicity_0_8_c_bitcoin_set_txEnv(txEnv *result, const bitcoinTransaction *tx, const bitcoinTapEnv *taproot, unsigned int ix)
{
*result = rustsimplicity_0_8_bitcoin_build_txEnv(tx, taproot, ix);
}
36 changes: 36 additions & 0 deletions simplicity-sys/depend/simplicity/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
cmake_minimum_required(VERSION 3.16)

project(BitcoinSimplicity)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_EXTENSIONS OFF)

add_library(BitcoinSimplicity STATIC
bitstream.c
dag.c
deserialize.c
eval.c
frame.c
jets-secp256k1.c
jets.c
rsort.c
sha256.c
type.c
typeInference.c
bitcoin/env.c
bitcoin/exec.c
bitcoin/bitcoinJets.c
bitcoin/ops.c
bitcoin/primitive.c
bitcoin/txEnv.c
)

option(PRODUCTION "Enable production build" ON)
if (PRODUCTION)
target_compile_definitions(BitcoinSimplicity PRIVATE "PRODUCTION")
endif()

target_include_directories(BitcoinSimplicity PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
22 changes: 22 additions & 0 deletions simplicity-sys/depend/simplicity/bitcoin/cmr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <simplicity/bitcoin/cmr.h>

#include "../cmr.h"
#include "primitive.h"

/* Deserialize a Simplicity 'program' and compute its CMR.
*
* Caution: no typechecking is performed, only a well-formedness check.
*
* If at any time malloc fails then '*error' is set to 'SIMPLICITY_ERR_MALLOC' and 'false' is returned,
* Otherwise, 'true' is returned indicating that the result was successfully computed and returned in the '*error' value.
*
* If the operation completes successfully then '*error' is set to 'SIMPLICITY_NO_ERROR', and the 'cmr' array is filled in with the program's computed CMR.
*
* Precondition: NULL != error;
* unsigned char cmr[32]
* unsigned char program[program_len]
*/
bool rustsimplicity_0_8_bitcoin_computeCmr( simplicity_err* error, unsigned char* cmr
, const unsigned char* program, size_t program_len) {
return rustsimplicity_0_8_computeCmr(error, cmr, rustsimplicity_0_8_bitcoin_decodeJet, program, program_len);
}
Loading
Loading