Skip to content

Commit 2e9bc3e

Browse files
authored
Add c bindings + Updated camke builds (#166)
* Add c bindings for create_discriminant, prove, and verify_n_wesolowski * Add chiavdfc shared library target * Don't build the c wrapper library by default (avoid it in the wheel) + add workflow for the c libs * no build vdf client * mpir for windows + unique artifact names per platform * Fix checkout * remove .git * Fix mpir path * Include mpir on windows * mpir before forcing gmp * Fix path to mpir in cmake * Add a windows specific prefix path to help find gmp and gmpxx * Split mpir/gmp(xx) for windows/non-windows * Try cmake --build * Missed . * -pthread flag doesn't apply to windows * Fix windows compile warnings * Update path for dynamic dll * Cleanup setup.py to build windows via cmake, similar to the chiapos cleanup * remove unused import
1 parent fe87454 commit 2e9bc3e

File tree

7 files changed

+253
-145
lines changed

7 files changed

+253
-145
lines changed
+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
name: Build C Libraries
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
release:
8+
types: [published]
9+
pull_request:
10+
branches:
11+
- '**'
12+
13+
concurrency:
14+
# SHA is added to the end if on `main` to let all main workflows run
15+
group: ${{ github.ref }}-${{ github.workflow }}-${{ github.event_name }}-${{ (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/') || startsWith(github.ref, 'refs/heads/long_lived/')) && github.sha || '' }}
16+
cancel-in-progress: true
17+
18+
permissions:
19+
contents: read
20+
id-token: write
21+
22+
jobs:
23+
build-c-libraries:
24+
name: C Libraries - ${{ matrix.os.name }} ${{ matrix.arch.name }}
25+
runs-on: ${{ matrix.os.runs-on[matrix.arch.matrix] }}
26+
strategy:
27+
fail-fast: false
28+
matrix:
29+
os:
30+
- name: macOS
31+
matrix: macos
32+
runs-on:
33+
arm: [macOS, ARM64]
34+
intel: [macos-11]
35+
- name: Ubuntu
36+
matrix: ubuntu
37+
runs-on:
38+
arm: [Linux, ARM64]
39+
intel: [ubuntu-latest]
40+
- name: Windows
41+
matrix: windows
42+
runs-on:
43+
intel: [windows-latest]
44+
arch:
45+
- name: ARM
46+
matrix: arm
47+
- name: Intel
48+
matrix: intel
49+
exclude:
50+
# Only partial entries are required here by GitHub Actions so generally I
51+
# only specify the `matrix:` entry. The super linter complains so for now
52+
# all entries are included to avoid that. Reported at
53+
# https://github.com/github/super-linter/issues/3016
54+
- os:
55+
name: Windows
56+
matrix: windows
57+
runs-on:
58+
intel: [windows-latest]
59+
arch:
60+
name: ARM
61+
matrix: arm
62+
63+
steps:
64+
- name: Clean workspace
65+
uses: Chia-Network/actions/clean-workspace@main
66+
67+
- name: Checkout code
68+
uses: actions/checkout@v4
69+
with:
70+
fetch-depth: 0
71+
72+
- name: Checkout mpir for windows
73+
if: matrix.os.matrix == 'windows'
74+
uses: actions/checkout@v4
75+
with:
76+
repository: Chia-Network/mpir_gc_x64
77+
fetch-depth: 1
78+
path: mpir_gc_x64
79+
80+
- name: Build
81+
working-directory: src
82+
env:
83+
BUILD_VDF_CLIENT: "N"
84+
run: |
85+
cmake . -DBUILD_CHIAVDFC=ON
86+
cmake --build .
87+
88+
- name: Upload artifacts
89+
uses: actions/upload-artifact@v3
90+
with:
91+
name: c-libraries-${{ matrix.os.matrix }}-${{ matrix.arch.matrix }}
92+
path: ./src/lib

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
__pycache__/
33
*.py[cod]
44
*$py.class
5+
*.so
6+
*.dylib
7+
*.dll
8+
*.a
9+
src/verifier_test
510

611
# Generated assembly file
712
/asm_compiled.s

setup.py

+20-134
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import subprocess
55
import sys
66

7-
from setuptools import Command, Extension, setup, errors
7+
from setuptools import Command, Extension, setup
88
from setuptools.command.build import build
99
from setuptools.command.build_ext import build_ext
1010
from setuptools.command.install import install
@@ -116,7 +116,7 @@ def build_extension(self, ext):
116116
cmake_args += [
117117
"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}".format(cfg.upper(), extdir)
118118
]
119-
if sys.maxsize > 2 ** 32:
119+
if sys.maxsize > 2**32:
120120
cmake_args += ["-A", "x64"]
121121
build_args += ["--", "/m"]
122122
else:
@@ -131,136 +131,22 @@ def build_extension(self, ext):
131131
subprocess.check_call(["cmake", "--build", "."] + build_args)
132132

133133

134-
class get_pybind_include(object):
135-
"""Helper class to determine the pybind11 include path
136-
137-
The purpose of this class is to postpone importing pybind11
138-
until it is actually installed, so that the ``get_include()``
139-
method can be invoked."""
140-
141-
def __init__(self, user=False):
142-
self.user = user
143-
144-
def __str__(self):
145-
import pybind11
146-
147-
return pybind11.get_include(self.user)
148-
149-
150-
ext_modules = [
151-
Extension(
152-
"chiavdf",
153-
sorted(
154-
[
155-
"src/python_bindings/fastvdf.cpp",
156-
"src/refcode/lzcnt.c",
157-
]
158-
),
159-
include_dirs=[
160-
# Path to pybind11 headers
161-
get_pybind_include(),
162-
get_pybind_include(user=True),
163-
"mpir_gc_x64",
164-
],
165-
library_dirs=["mpir_gc_x64"],
166-
libraries=["mpir"],
167-
language="c++",
134+
build.sub_commands.append(("build_hook", lambda x: True)) # type: ignore
135+
install.sub_commands.append(("install_hook", lambda x: True))
136+
137+
setup(
138+
name="chiavdf",
139+
author="Florin Chirica",
140+
author_email="[email protected]",
141+
description="Chia vdf verification (wraps C++)",
142+
license="Apache License",
143+
python_requires=">=3.8",
144+
long_description=open("README.md").read(),
145+
long_description_content_type="text/markdown",
146+
url="https://github.com/Chia-Network/chiavdf",
147+
ext_modules=[CMakeExtension("chiavdf", "src")],
148+
cmdclass=dict(
149+
build_ext=CMakeBuild, install_hook=install_hook, build_hook=build_hook
168150
),
169-
]
170-
171-
172-
# As of Python 3.6, CCompiler has a `has_flag` method.
173-
# cf http://bugs.python.org/issue26689
174-
def has_flag(compiler, flagname):
175-
"""Return a boolean indicating whether a flag name is supported on
176-
the specified compiler.
177-
"""
178-
import tempfile
179-
180-
with tempfile.NamedTemporaryFile("w", suffix=".cpp") as f:
181-
f.write("int main (int argc, char **argv) { return 0; }")
182-
try:
183-
compiler.compile([f.name], extra_postargs=[flagname])
184-
except errors.CompileError:
185-
return False
186-
return True
187-
188-
189-
def cpp_flag(compiler):
190-
"""Return the -std=c++[11/14/17] compiler flag.
191-
192-
The newer version is prefered over c++11 (when it is available).
193-
"""
194-
flags = ["-std=c++17", "-std=c++14", "-std=c++11"]
195-
196-
for flag in flags:
197-
if has_flag(compiler, flag):
198-
return flag
199-
200-
raise RuntimeError("Unsupported compiler -- at least C++11 support " "is needed!")
201-
202-
203-
class BuildExt(build_ext):
204-
"""A custom build extension for adding compiler-specific options."""
205-
206-
c_opts = {
207-
"msvc": ["/EHsc", "/std:c++17"],
208-
"unix": [""],
209-
}
210-
l_opts = {
211-
"msvc": [],
212-
"unix": [""],
213-
}
214-
215-
def build_extensions(self):
216-
ct = self.compiler.compiler_type
217-
opts = self.c_opts.get(ct, [])
218-
link_opts = self.l_opts.get(ct, [])
219-
if ct == "unix":
220-
opts.append('-DVERSION_INFO="%s"' % self.distribution.get_version())
221-
opts.append(cpp_flag(self.compiler))
222-
if has_flag(self.compiler, "-fvisibility=hidden"):
223-
opts.append("-fvisibility=hidden")
224-
elif ct == "msvc":
225-
opts.append('/DVERSION_INFO=\\"%s\\"' % self.distribution.get_version())
226-
for ext in self.extensions:
227-
ext.extra_compile_args = opts
228-
ext.extra_link_args = link_opts
229-
build_ext.build_extensions(self)
230-
231-
232-
if platform.system() == "Windows":
233-
setup(
234-
name="chiavdf",
235-
author="Mariano Sorgente",
236-
author_email="[email protected]",
237-
description="Chia vdf verification (wraps C++)",
238-
license="Apache License",
239-
python_requires=">=3.8",
240-
long_description=open("README.md").read(),
241-
long_description_content_type="text/markdown",
242-
url="https://github.com/Chia-Network/chiavdf",
243-
ext_modules=ext_modules,
244-
cmdclass={"build_ext": BuildExt},
245-
zip_safe=False,
246-
)
247-
else:
248-
build.sub_commands.append(("build_hook", lambda x: True)) # type: ignore
249-
install.sub_commands.append(("install_hook", lambda x: True))
250-
251-
setup(
252-
name="chiavdf",
253-
author="Florin Chirica",
254-
author_email="[email protected]",
255-
description="Chia vdf verification (wraps C++)",
256-
license="Apache License",
257-
python_requires=">=3.8",
258-
long_description=open("README.md").read(),
259-
long_description_content_type="text/markdown",
260-
url="https://github.com/Chia-Network/chiavdf",
261-
ext_modules=[CMakeExtension("chiavdf", "src")],
262-
cmdclass=dict(
263-
build_ext=CMakeBuild, install_hook=install_hook, build_hook=build_hook
264-
),
265-
zip_safe=False,
266-
)
151+
zip_safe=False,
152+
)

src/CMakeLists.txt

+63-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
CMAKE_MINIMUM_REQUIRED(VERSION 3.14 FATAL_ERROR)
2+
option(BUILD_CHIAVDFC "Build the chiavdfc shared library" OFF)
23

34
set(CMAKE_CXX_STANDARD 17)
5+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
46
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
57

68
IF(NOT CMAKE_BUILD_TYPE)
@@ -14,17 +16,38 @@ set(CMAKE_MODULE_PATH
1416
${CMAKE_MODULE_PATH}
1517
)
1618

17-
find_package(GMP REQUIRED)
18-
find_package(GMPXX REQUIRED)
19+
if(MSVC)
20+
add_compile_options(/EHsc)
21+
endif()
1922

20-
include_directories(
21-
${INCLUDE_DIRECTORIES}
22-
${CMAKE_CURRENT_SOURCE_DIR}
23-
${GMP_INCLUDE_DIR}
24-
${GMPXX_INCLUDE_DIR}
25-
)
23+
if(WIN32)
24+
set(MPIR_LIBRARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../mpir_gc_x64")
25+
set(MPIR_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../mpir_gc_x64")
26+
include_directories(
27+
${INCLUDE_DIRECTORIES}
28+
${CMAKE_CURRENT_SOURCE_DIR}
29+
${MPIR_INCLUDE_DIR}
30+
)
31+
find_library(MPIR_LIBRARY NAMES mpir PATHS ${MPIR_LIBRARY_DIR} NO_DEFAULT_PATH)
32+
if(MPIR_LIBRARY)
33+
message(STATUS "MPIR library found at ${MPIR_LIBRARY}")
34+
link_libraries(${MPIR_LIBRARY})
35+
else()
36+
message(FATAL_ERROR "MPIR library not found")
37+
endif()
38+
39+
list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../mpir_gc_x64")
40+
else()
41+
find_package(GMP REQUIRED)
42+
find_package(GMPXX REQUIRED)
2643

27-
set (CMAKE_CXX_FLAGS "-std=c++1z")
44+
include_directories(
45+
${INCLUDE_DIRECTORIES}
46+
${CMAKE_CURRENT_SOURCE_DIR}
47+
${GMP_INCLUDE_DIR}
48+
${GMPXX_INCLUDE_DIR}
49+
)
50+
endif()
2851

2952
# CMake 3.14+
3053
include(FetchContent)
@@ -46,5 +69,34 @@ add_executable(verifier_test
4669
${CMAKE_CURRENT_SOURCE_DIR}/refcode/lzcnt.c
4770
)
4871

49-
target_link_libraries(chiavdf PRIVATE ${GMP_LIBRARIES} ${GMPXX_LIBRARIES} -pthread)
50-
target_link_libraries(verifier_test ${GMP_LIBRARIES} ${GMPXX_LIBRARIES} -pthread)
72+
target_link_libraries(chiavdf PRIVATE ${GMP_LIBRARIES} ${GMPXX_LIBRARIES})
73+
target_link_libraries(verifier_test PRIVATE ${GMP_LIBRARIES} ${GMPXX_LIBRARIES})
74+
75+
if(UNIX)
76+
target_link_libraries(chiavdf PRIVATE -pthread)
77+
target_link_libraries(verifier_test PRIVATE -pthread)
78+
endif()
79+
80+
if(BUILD_CHIAVDFC)
81+
add_library(chiavdfc_shared SHARED
82+
${CMAKE_CURRENT_SOURCE_DIR}/c_bindings/c_wrapper.cpp
83+
${CMAKE_CURRENT_SOURCE_DIR}/refcode/lzcnt.c
84+
)
85+
add_library(chiavdfc_static STATIC
86+
${CMAKE_CURRENT_SOURCE_DIR}/c_bindings/c_wrapper.cpp
87+
${CMAKE_CURRENT_SOURCE_DIR}/refcode/lzcnt.c
88+
)
89+
target_link_libraries(chiavdfc_shared ${GMP_LIBRARIES} ${GMPXX_LIBRARIES})
90+
target_link_libraries(chiavdfc_static ${GMP_LIBRARIES} ${GMPXX_LIBRARIES})
91+
92+
set_target_properties(chiavdfc_shared PROPERTIES
93+
OUTPUT_NAME chiavdfc
94+
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/shared"
95+
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/shared"
96+
)
97+
98+
set_target_properties(chiavdfc_static PROPERTIES
99+
OUTPUT_NAME chiavdfc
100+
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/static"
101+
)
102+
endif()

0 commit comments

Comments
 (0)