Skip to content

Commit

Permalink
vendor pysqlcipher (#136)
Browse files Browse the repository at this point in the history
* vendor pysqlcipher3

* working

* openssl already installed

* fix manifest

* try

* move sqlcipher

* add openssl back

* try

* now

* disable test

* doh

* a

* clean
  • Loading branch information
carderne authored Aug 1, 2024
1 parent 312e5e6 commit e0373c7
Show file tree
Hide file tree
Showing 30 changed files with 5,708 additions and 94 deletions.
49 changes: 8 additions & 41 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,55 +18,16 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: prep pysqlcipher3
run: |
git clone --depth=1 --branch=master https://github.com/rigglemania/pysqlcipher3.git
cd pysqlcipher3
mkdir amalgamation
cp ../sqlcipher/sqlite3.[ch] amalgamation
mkdir src/python3/sqlcipher
cp ../sqlcipher/sqlite3.[ch] src/python3/sqlcipher
pip install setuptools
- name: build pysqlcipher3 linux
if: matrix.os == 'ubuntu-latest'
run: |
cd pysqlcipher3
python setup.py build_amalgamation
python setup.py build
echo 'PLATFORM_TAG="manylinux2014_x86_64"' >> $GITHUB_ENV
- name: build pysqlcipher3 macOS
if: matrix.os == 'macos-latest'
run: |
brew install openssl
export LDFLAGS="-L/opt/homebrew/opt/openssl@3/lib"
export CPPFLAGS="-I/opt/homebrew/opt/openssl@3/include"
cd pysqlcipher3
python setup.py build_amalgamation
python setup.py build
echo 'PLATFORM_TAG="macosx_10_9_universal2"' >> $GITHUB_ENV
- name: post-build pysqlcipher3
run: |
mkdir src/pysqlcipher3
for f in pysqlcipher3/build/lib.*/pysqlcipher3/*.{py,so}; do cp $f src/pysqlcipher3/; done
- name: build
run: |
pip install build
export LDFLAGS="-L/opt/homebrew/opt/openssl@3/lib"
export CPPFLAGS="-I/opt/homebrew/opt/openssl@3/include"
python -m build
cd dist
NEW_NAME=$(ls *.whl | sed "s/any.whl$/${{ env.PLATFORM_TAG }}.whl/")
mv *.whl $NEW_NAME
echo "WHEEL_NAME=$(ls *.whl)" >> $GITHUB_ENV
echo "SDIST_NAME=$(ls *.tar.gz)" >> $GITHUB_ENV
- name: test
run: |
pip install dist/*.whl pytest
pytest
- uses: actions/upload-artifact@v4
with:
name: ${{ env.WHEEL_NAME }}
Expand All @@ -79,6 +40,12 @@ jobs:
name: ${{ env.SDIST_NAME }}
path: "dist/*.tar.gz"

- name: test
run: |
pip install dist/*.whl pytest
pytest
upload:
needs: [build]
if: startsWith(github.ref, 'refs/tags/')
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# Custom
src/pysqlcipher3

# OS generated files
.DS_Store
Expand Down
3 changes: 3 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
graft src

global-exclude *.pyc
17 changes: 7 additions & 10 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,14 @@ dependencies = [
managed = true
generate-hashes = false
dev-dependencies = [
"build",
"pyright",
"pre-commit",
"pytest",
"pytest-cov",
"ruff ~= 0.2",
"setuptools-scm",
"twine",
"types-Markdown",
"types-emoji",
"setuptools-scm~=8.1.0",
"build~=1.2.1",
]

[project.urls]
Expand All @@ -61,14 +59,13 @@ repository = "https://github.com/carderne/signal-export"
sigexport = "sigexport.main:cli"

[build-system]
requires = ["pdm-backend"]
build-backend = "pdm.backend"
requires = ["setuptools>=64", "setuptools_scm>=8"]
build-backend = "setuptools.build_meta"

[tool.pdm.build]
includes = ["src/"]
[tool.setuptools]
package-dir = {"" = "src"}

[tool.pdm.version]
source = "scm"
[tool.setuptools_scm]

[tool.ruff]
target-version = "py39"
Expand Down
45 changes: 3 additions & 42 deletions requirements-dev.lock
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,9 @@
-e file:.
beautifulsoup4==4.12.3
# via signal-export
build==1.1.1
certifi==2024.2.2
# via requests
build==1.2.1
cfgv==3.4.0
# via pre-commit
charset-normalizer==3.3.2
# via requests
click==8.1.7
# via typer
colorama==0.4.6
Expand All @@ -27,43 +23,27 @@ coverage==7.4.4
# via pytest-cov
distlib==0.3.8
# via virtualenv
docutils==0.20.1
# via readme-renderer
emoji==2.10.1
# via signal-export
filelock==3.13.1
# via virtualenv
identify==2.5.35
# via pre-commit
idna==3.6
# via requests
importlib-metadata==7.0.2
# via twine
iniconfig==2.0.0
# via pytest
jaraco-classes==3.3.1
# via keyring
keyring==24.3.1
# via twine
markdown==3.6
# via signal-export
markdown-it-py==3.0.0
# via rich
mdurl==0.1.2
# via markdown-it-py
more-itertools==10.2.0
# via jaraco-classes
nh3==0.2.15
# via readme-renderer
nodeenv==1.8.0
# via pre-commit
# via pyright
packaging==24.0
# via build
# via pytest
# via setuptools-scm
pkginfo==1.10.0
# via twine
platformdirs==4.2.0
# via virtualenv
pluggy==1.4.0
Expand All @@ -72,49 +52,30 @@ pre-commit==3.6.2
pycryptodome==3.20.0
# via signal-export
pygments==2.17.2
# via readme-renderer
# via rich
pyproject-hooks==1.0.0
pyproject-hooks==1.1.0
# via build
pyright==1.1.354
pytest==8.1.1
# via pytest-cov
pytest-cov==4.1.0
pyyaml==6.0.1
# via pre-commit
readme-renderer==43.0
# via twine
requests==2.31.0
# via requests-toolbelt
# via twine
requests-toolbelt==1.0.0
# via twine
rfc3986==2.0.0
# via twine
rich==13.7.1
# via twine
# via typer
ruff==0.3.3
setuptools==69.2.0
# via nodeenv
# via setuptools-scm
setuptools-scm==8.0.4
setuptools-scm==8.1.0
shellingham==1.5.4
# via typer
soupsieve==2.5
# via beautifulsoup4
twine==5.0.0
typer==0.9.0
# via signal-export
types-emoji==2.1.0.3
types-markdown==3.6.0.20240316
typing-extensions==4.10.0
# via setuptools-scm
# via typer
urllib3==2.2.1
# via requests
# via twine
virtualenv==20.25.1
# via pre-commit
zipp==3.18.1
# via importlib-metadata
105 changes: 105 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# -*- coding: ISO-8859-1 -*-
# setup.py: the distutils script
#
# Copyright (C) 2015 David Riggleman <[email protected]>
# Copyright (C) 2013 Kali Kaneko <[email protected]> (sqlcipher support)
# Copyright (C) 2005-2010 Gerhard Häring <[email protected]>
#
# This file is part of pysqlcipher.
#
# This software is provided 'as-is', without any express or implied
# warranty. In no event will the authors be held liable for any damages
# arising from the use of this software.
#
# Permission is granted to anyone to use this software for any purpose,
# including commercial applications, and to alter it and redistribute it
# freely, subject to the following restrictions:
#
# 1. The origin of this software must not be misrepresented; you must not
# claim that you wrote the original software. If you use this software
# in a product, an acknowledgment in the product documentation would be
# appreciated but is not required.
# 2. Altered source versions must be plainly marked as such, and must not be
# misrepresented as being the original software.
# 3. This notice may not be removed or altered from any source distribution.
import os
import sys
from pathlib import Path
from typing import Optional

import setuptools
from setuptools import Extension
from setuptools.command.build_ext import build_ext

# Work around clang raising hard error for unused arguments
if sys.platform == "darwin":
os.environ["CFLAGS"] = "-Qunused-arguments"
print("CFLAGS: " + os.environ["CFLAGS"])


def quote_argument(arg: str) -> str:
quote = '"' if sys.platform != "win32" else '\\"'
return quote + arg + quote


PACKAGE_NAME = "pysqlcipher3"
sources = [str(p) for p in Path("src/pysqlcipher3/c").glob("*.c")]
EXTENSION_MODULE_NAME = "._sqlite3"
define_macros: Optional[list[tuple[str, Optional[str]]]] = [
("MODULE_NAME", quote_argument(PACKAGE_NAME + ".dbapi2"))
]


class AmalgationLibSQLCipherBuilder(build_ext):
def build_extension(self, ext): # noqa # type: ignore
sqlcipher_root = "src/pysqlcipher3/c/sqlcipher"
sqlcipher_header = os.path.join(sqlcipher_root, "sqlite3.h")
sqlcipher_source = os.path.join(sqlcipher_root, "sqlite3.c")
if not os.path.exists(sqlcipher_header) or not os.path.exists(sqlcipher_source):
raise RuntimeError("SQLCipher amalgamation not found")

ext.include_dirs.append(sqlcipher_root)
ext.sources.append(sqlcipher_source)

# build with fulltext search enabled
ext.define_macros.append(("SQLITE_ENABLE_FTS3", "1"))
ext.define_macros.append(("SQLITE_ENABLE_RTREE", "1"))

# SQLCipher options
ext.define_macros.append(("SQLITE_ENABLE_LOAD_EXTENSION", "1"))
ext.define_macros.append(("SQLITE_HAS_CODEC", "1"))
ext.define_macros.append(("SQLITE_TEMP_STORE", "2"))

if sys.platform == "win32":
# Try to locate openssl
openssl_conf = os.environ.get("OPENSSL_CONF")
if not openssl_conf:
error_message = "Fatal error: OpenSSL could not be detected!"
raise RuntimeError(error_message)

openssl = os.path.dirname(os.path.dirname(openssl_conf))
openssl_lib_path = os.path.join(openssl, "lib")

# Configure the compiler
ext.include_dirs.append(os.path.join(openssl, "include"))
ext.define_macros.append(("inline", "__inline"))

# Configure the linker
ext.extra_link_args.append("libeay32.lib")
ext.extra_link_args.append("/LIBPATH:" + openssl_lib_path)
else:
ext.extra_link_args.append("-lcrypto")

build_ext.build_extension(self, ext)


setuptools.setup(
ext_modules=[
Extension(
name=PACKAGE_NAME + EXTENSION_MODULE_NAME,
sources=sources,
define_macros=define_macros,
)
],
cmdclass={"build_ext": AmalgationLibSQLCipherBuilder},
)
17 changes: 17 additions & 0 deletions src/pysqlcipher3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# pysqlcipher3

Source: https://github.com/rigglemania/pysqlcipher3/

All files in this tree include their original copyright statements.

Vendored to make static builds easier.

Build on macOS:
```bash
export LDFLAGS="-L/opt/homebrew/opt/openssl@3/lib"
export CPPFLAGS="-I/opt/homebrew/opt/openssl@3/include"
python setup.py bdist_wheel

# or
python -m build
```
Empty file added src/pysqlcipher3/__init__.py
Empty file.
Loading

0 comments on commit e0373c7

Please sign in to comment.