Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add c bindings + Updated camke builds #166

Merged
merged 20 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions .github/workflows/build-c-libraries.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Build C Libraries

on:
push:
branches:
- main
release:
types: [published]
pull_request:
branches:
- '**'

concurrency:
# SHA is added to the end if on `main` to let all main workflows run
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 || '' }}
cancel-in-progress: true

permissions:
contents: read
id-token: write

jobs:
build-c-libraries:
name: C Libraries - ${{ matrix.os.name }} ${{ matrix.arch.name }}
runs-on: ${{ matrix.os.runs-on[matrix.arch.matrix] }}
strategy:
fail-fast: false
matrix:
os:
- name: macOS
matrix: macos
runs-on:
arm: [macOS, ARM64]
intel: [macos-11]
- name: Ubuntu
matrix: ubuntu
runs-on:
arm: [Linux, ARM64]
intel: [ubuntu-latest]
- name: Windows
matrix: windows
runs-on:
intel: [windows-latest]
arch:
- name: ARM
matrix: arm
- name: Intel
matrix: intel
exclude:
# Only partial entries are required here by GitHub Actions so generally I
# only specify the `matrix:` entry. The super linter complains so for now
# all entries are included to avoid that. Reported at
# https://github.com/github/super-linter/issues/3016
- os:
name: Windows
matrix: windows
runs-on:
intel: [windows-latest]
arch:
name: ARM
matrix: arm

steps:
- name: Clean workspace
uses: Chia-Network/actions/clean-workspace@main

- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Checkout mpir for windows
if: matrix.os.matrix == 'windows'
uses: actions/checkout@v4
with:
repository: Chia-Network/mpir_gc_x64
fetch-depth: 1
path: mpir_gc_x64

- name: Build
working-directory: src
env:
BUILD_VDF_CLIENT: "N"
run: |
cmake . -DBUILD_CHIAVDFC=ON
cmake --build .

- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: c-libraries-${{ matrix.os.matrix }}-${{ matrix.arch.matrix }}
path: ./src/lib
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
__pycache__/
*.py[cod]
*$py.class
*.so
*.dylib
*.dll
*.a
src/verifier_test

# Generated assembly file
/asm_compiled.s
Expand Down
154 changes: 20 additions & 134 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import subprocess
import sys

from setuptools import Command, Extension, setup, errors
from setuptools import Command, Extension, setup
from setuptools.command.build import build
from setuptools.command.build_ext import build_ext
from setuptools.command.install import install
Expand Down Expand Up @@ -116,7 +116,7 @@ def build_extension(self, ext):
cmake_args += [
"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}".format(cfg.upper(), extdir)
]
if sys.maxsize > 2 ** 32:
if sys.maxsize > 2**32:
cmake_args += ["-A", "x64"]
build_args += ["--", "/m"]
else:
Expand All @@ -131,136 +131,22 @@ def build_extension(self, ext):
subprocess.check_call(["cmake", "--build", "."] + build_args)


class get_pybind_include(object):
"""Helper class to determine the pybind11 include path

The purpose of this class is to postpone importing pybind11
until it is actually installed, so that the ``get_include()``
method can be invoked."""

def __init__(self, user=False):
self.user = user

def __str__(self):
import pybind11

return pybind11.get_include(self.user)


ext_modules = [
Extension(
"chiavdf",
sorted(
[
"src/python_bindings/fastvdf.cpp",
"src/refcode/lzcnt.c",
]
),
include_dirs=[
# Path to pybind11 headers
get_pybind_include(),
get_pybind_include(user=True),
"mpir_gc_x64",
],
library_dirs=["mpir_gc_x64"],
libraries=["mpir"],
language="c++",
build.sub_commands.append(("build_hook", lambda x: True)) # type: ignore
install.sub_commands.append(("install_hook", lambda x: True))

setup(
name="chiavdf",
author="Florin Chirica",
author_email="[email protected]",
description="Chia vdf verification (wraps C++)",
license="Apache License",
python_requires=">=3.8",
long_description=open("README.md").read(),
long_description_content_type="text/markdown",
url="https://github.com/Chia-Network/chiavdf",
ext_modules=[CMakeExtension("chiavdf", "src")],
cmdclass=dict(
build_ext=CMakeBuild, install_hook=install_hook, build_hook=build_hook
),
]


# As of Python 3.6, CCompiler has a `has_flag` method.
# cf http://bugs.python.org/issue26689
def has_flag(compiler, flagname):
"""Return a boolean indicating whether a flag name is supported on
the specified compiler.
"""
import tempfile

with tempfile.NamedTemporaryFile("w", suffix=".cpp") as f:
f.write("int main (int argc, char **argv) { return 0; }")
try:
compiler.compile([f.name], extra_postargs=[flagname])
except errors.CompileError:
return False
return True


def cpp_flag(compiler):
"""Return the -std=c++[11/14/17] compiler flag.

The newer version is prefered over c++11 (when it is available).
"""
flags = ["-std=c++17", "-std=c++14", "-std=c++11"]

for flag in flags:
if has_flag(compiler, flag):
return flag

raise RuntimeError("Unsupported compiler -- at least C++11 support " "is needed!")


class BuildExt(build_ext):
"""A custom build extension for adding compiler-specific options."""

c_opts = {
"msvc": ["/EHsc", "/std:c++17"],
"unix": [""],
}
l_opts = {
"msvc": [],
"unix": [""],
}

def build_extensions(self):
ct = self.compiler.compiler_type
opts = self.c_opts.get(ct, [])
link_opts = self.l_opts.get(ct, [])
if ct == "unix":
opts.append('-DVERSION_INFO="%s"' % self.distribution.get_version())
opts.append(cpp_flag(self.compiler))
if has_flag(self.compiler, "-fvisibility=hidden"):
opts.append("-fvisibility=hidden")
elif ct == "msvc":
opts.append('/DVERSION_INFO=\\"%s\\"' % self.distribution.get_version())
for ext in self.extensions:
ext.extra_compile_args = opts
ext.extra_link_args = link_opts
build_ext.build_extensions(self)


if platform.system() == "Windows":
setup(
name="chiavdf",
author="Mariano Sorgente",
author_email="[email protected]",
description="Chia vdf verification (wraps C++)",
license="Apache License",
python_requires=">=3.8",
long_description=open("README.md").read(),
long_description_content_type="text/markdown",
url="https://github.com/Chia-Network/chiavdf",
ext_modules=ext_modules,
cmdclass={"build_ext": BuildExt},
zip_safe=False,
)
else:
build.sub_commands.append(("build_hook", lambda x: True)) # type: ignore
install.sub_commands.append(("install_hook", lambda x: True))

setup(
name="chiavdf",
author="Florin Chirica",
author_email="[email protected]",
description="Chia vdf verification (wraps C++)",
license="Apache License",
python_requires=">=3.8",
long_description=open("README.md").read(),
long_description_content_type="text/markdown",
url="https://github.com/Chia-Network/chiavdf",
ext_modules=[CMakeExtension("chiavdf", "src")],
cmdclass=dict(
build_ext=CMakeBuild, install_hook=install_hook, build_hook=build_hook
),
zip_safe=False,
)
zip_safe=False,
)
74 changes: 63 additions & 11 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.14 FATAL_ERROR)
option(BUILD_CHIAVDFC "Build the chiavdfc shared library" OFF)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

IF(NOT CMAKE_BUILD_TYPE)
Expand All @@ -14,17 +16,38 @@ set(CMAKE_MODULE_PATH
${CMAKE_MODULE_PATH}
)

find_package(GMP REQUIRED)
find_package(GMPXX REQUIRED)
if(MSVC)
add_compile_options(/EHsc)
endif()

include_directories(
${INCLUDE_DIRECTORIES}
${CMAKE_CURRENT_SOURCE_DIR}
${GMP_INCLUDE_DIR}
${GMPXX_INCLUDE_DIR}
)
if(WIN32)
set(MPIR_LIBRARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../mpir_gc_x64")
set(MPIR_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../mpir_gc_x64")
include_directories(
${INCLUDE_DIRECTORIES}
${CMAKE_CURRENT_SOURCE_DIR}
${MPIR_INCLUDE_DIR}
)
find_library(MPIR_LIBRARY NAMES mpir PATHS ${MPIR_LIBRARY_DIR} NO_DEFAULT_PATH)
if(MPIR_LIBRARY)
message(STATUS "MPIR library found at ${MPIR_LIBRARY}")
link_libraries(${MPIR_LIBRARY})
else()
message(FATAL_ERROR "MPIR library not found")
endif()

list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../mpir_gc_x64")
else()
find_package(GMP REQUIRED)
find_package(GMPXX REQUIRED)

set (CMAKE_CXX_FLAGS "-std=c++1z")
include_directories(
${INCLUDE_DIRECTORIES}
${CMAKE_CURRENT_SOURCE_DIR}
${GMP_INCLUDE_DIR}
${GMPXX_INCLUDE_DIR}
)
endif()

# CMake 3.14+
include(FetchContent)
Expand All @@ -46,5 +69,34 @@ add_executable(verifier_test
${CMAKE_CURRENT_SOURCE_DIR}/refcode/lzcnt.c
)

target_link_libraries(chiavdf PRIVATE ${GMP_LIBRARIES} ${GMPXX_LIBRARIES} -pthread)
target_link_libraries(verifier_test ${GMP_LIBRARIES} ${GMPXX_LIBRARIES} -pthread)
target_link_libraries(chiavdf PRIVATE ${GMP_LIBRARIES} ${GMPXX_LIBRARIES})
target_link_libraries(verifier_test PRIVATE ${GMP_LIBRARIES} ${GMPXX_LIBRARIES})

if(UNIX)
target_link_libraries(chiavdf PRIVATE -pthread)
target_link_libraries(verifier_test PRIVATE -pthread)
endif()

if(BUILD_CHIAVDFC)
add_library(chiavdfc_shared SHARED
${CMAKE_CURRENT_SOURCE_DIR}/c_bindings/c_wrapper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/refcode/lzcnt.c
)
add_library(chiavdfc_static STATIC
${CMAKE_CURRENT_SOURCE_DIR}/c_bindings/c_wrapper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/refcode/lzcnt.c
)
target_link_libraries(chiavdfc_shared ${GMP_LIBRARIES} ${GMPXX_LIBRARIES})
target_link_libraries(chiavdfc_static ${GMP_LIBRARIES} ${GMPXX_LIBRARIES})

set_target_properties(chiavdfc_shared PROPERTIES
OUTPUT_NAME chiavdfc
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/shared"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/shared"
)

set_target_properties(chiavdfc_static PROPERTIES
OUTPUT_NAME chiavdfc
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/static"
)
endif()
Loading
Loading