mirror of https://github.com/oxen-io/lokinet
Compare commits
No commits in common. 'dev' and 'v0.7.0-rc3' have entirely different histories.
dev
...
v0.7.0-rc3
@ -1,2 +1,2 @@
|
||||
HeaderFilterRegex: 'llarp/.*'
|
||||
Checks: 'readability-else-after-return,clang-analyzer-core-*,modernize-*,-modernize-use-trailing-return-type,-modernize-use-nodiscard,bugprone-*,-bugprone-easily-swappable-parameters'
|
||||
Checks: 'readability-else-after-return,clang-analyzer-core-*,modernize-*'
|
||||
|
@ -1,450 +0,0 @@
|
||||
local default_deps_base = [
|
||||
'libsystemd-dev',
|
||||
'python3-dev',
|
||||
'libuv1-dev',
|
||||
'libunbound-dev',
|
||||
'nettle-dev',
|
||||
'libssl-dev',
|
||||
'libevent-dev',
|
||||
'libsqlite3-dev',
|
||||
'libcurl4-openssl-dev',
|
||||
'libzmq3-dev',
|
||||
'make',
|
||||
];
|
||||
local default_deps_nocxx = ['libsodium-dev'] + default_deps_base; // libsodium-dev needs to be >= 1.0.18
|
||||
local default_deps = ['g++'] + default_deps_nocxx;
|
||||
local docker_base = 'registry.oxen.rocks/lokinet-ci-';
|
||||
|
||||
local submodule_commands = [
|
||||
'git fetch --tags',
|
||||
'git submodule update --init --recursive --depth=1 --jobs=4',
|
||||
];
|
||||
local submodules = {
|
||||
name: 'submodules',
|
||||
image: 'drone/git',
|
||||
commands: submodule_commands,
|
||||
};
|
||||
|
||||
// cmake options for static deps mirror
|
||||
local ci_dep_mirror(want_mirror) = (if want_mirror then ' -DLOCAL_MIRROR=https://oxen.rocks/deps ' else '');
|
||||
|
||||
local apt_get_quiet = 'apt-get -o=Dpkg::Use-Pty=0 -q';
|
||||
|
||||
// Regular build on a debian-like system:
|
||||
local debian_pipeline(name,
|
||||
image,
|
||||
arch='amd64',
|
||||
deps=default_deps,
|
||||
build_type='Release',
|
||||
lto=false,
|
||||
werror=true,
|
||||
cmake_extra='',
|
||||
local_mirror=true,
|
||||
extra_cmds=[],
|
||||
jobs=6,
|
||||
tests=true,
|
||||
oxen_repo=false,
|
||||
allow_fail=false) = {
|
||||
kind: 'pipeline',
|
||||
type: 'docker',
|
||||
name: name,
|
||||
platform: { arch: arch },
|
||||
trigger: { branch: { exclude: ['debian/*', 'ubuntu/*'] } },
|
||||
steps: [
|
||||
submodules,
|
||||
{
|
||||
name: 'build',
|
||||
image: image,
|
||||
pull: 'always',
|
||||
[if allow_fail then 'failure']: 'ignore',
|
||||
environment: { SSH_KEY: { from_secret: 'SSH_KEY' } },
|
||||
commands: [
|
||||
'echo "Building on ${DRONE_STAGE_MACHINE}"',
|
||||
'echo "man-db man-db/auto-update boolean false" | debconf-set-selections',
|
||||
apt_get_quiet + ' update',
|
||||
apt_get_quiet + ' install -y eatmydata',
|
||||
] + (
|
||||
if oxen_repo then [
|
||||
'eatmydata ' + apt_get_quiet + ' install --no-install-recommends -y lsb-release',
|
||||
'cp contrib/deb.oxen.io.gpg /etc/apt/trusted.gpg.d',
|
||||
'echo deb http://deb.oxen.io $$(lsb_release -sc) main >/etc/apt/sources.list.d/oxen.list',
|
||||
'eatmydata ' + apt_get_quiet + ' update',
|
||||
] else []
|
||||
) + [
|
||||
'eatmydata ' + apt_get_quiet + ' dist-upgrade -y',
|
||||
'eatmydata ' + apt_get_quiet + ' install --no-install-recommends -y gdb cmake git pkg-config ccache ' + std.join(' ', deps),
|
||||
'mkdir build',
|
||||
'cd build',
|
||||
'cmake .. -DWITH_SETCAP=OFF -DCMAKE_CXX_FLAGS=-fdiagnostics-color=always -DCMAKE_BUILD_TYPE=' + build_type + ' ' +
|
||||
(if build_type == 'Debug' then ' -DWARN_DEPRECATED=OFF ' else '') +
|
||||
(if werror then '-DWARNINGS_AS_ERRORS=ON ' else '') +
|
||||
'-DWITH_LTO=' + (if lto then 'ON ' else 'OFF ') +
|
||||
'-DWITH_TESTS=' + (if tests then 'ON ' else 'OFF ') +
|
||||
cmake_extra +
|
||||
ci_dep_mirror(local_mirror),
|
||||
'VERBOSE=1 make -j' + jobs,
|
||||
'cd ..',
|
||||
]
|
||||
+ (if tests then ['./contrib/ci/drone-gdb.sh ./build/test/testAll --use-colour yes'] else [])
|
||||
+ extra_cmds,
|
||||
},
|
||||
],
|
||||
};
|
||||
local apk_builder(name, image, extra_cmds=[], allow_fail=false, jobs=6) = {
|
||||
kind: 'pipeline',
|
||||
type: 'docker',
|
||||
name: name,
|
||||
platform: { arch: 'amd64' },
|
||||
trigger: { branch: { exclude: ['debian/*', 'ubuntu/*'] } },
|
||||
steps: [
|
||||
submodules,
|
||||
{
|
||||
name: 'build',
|
||||
image: image,
|
||||
pull: 'always',
|
||||
[if allow_fail then 'failure']: 'ignore',
|
||||
environment: { SSH_KEY: { from_secret: 'SSH_KEY' }, ANDROID: 'android' },
|
||||
commands: [
|
||||
'VERBOSE=1 JOBS=' + jobs + ' NDK=/usr/lib/android-ndk ./contrib/android.sh',
|
||||
'git clone https://github.com/oxen-io/lokinet-flutter-app lokinet-mobile',
|
||||
'cp -av build-android/out/* lokinet-mobile/lokinet_lib/android/src/main/jniLibs/',
|
||||
'cd lokinet-mobile',
|
||||
'flutter build apk --debug',
|
||||
'cd ..',
|
||||
'cp lokinet-mobile/build/app/outputs/apk/debug/app-debug.apk lokinet.apk',
|
||||
] + extra_cmds,
|
||||
},
|
||||
],
|
||||
};
|
||||
// windows cross compile on debian
|
||||
local windows_cross_pipeline(name,
|
||||
image,
|
||||
gui_image=docker_base + 'nodejs-lts',
|
||||
arch='amd64',
|
||||
build_type='Release',
|
||||
lto=false,
|
||||
werror=false,
|
||||
cmake_extra='',
|
||||
local_mirror=true,
|
||||
extra_cmds=[],
|
||||
jobs=6,
|
||||
allow_fail=false) = {
|
||||
kind: 'pipeline',
|
||||
type: 'docker',
|
||||
name: name,
|
||||
platform: { arch: arch },
|
||||
trigger: { branch: { exclude: ['debian/*', 'ubuntu/*'] } },
|
||||
steps: [
|
||||
submodules,
|
||||
{
|
||||
name: 'GUI',
|
||||
image: gui_image,
|
||||
pull: 'always',
|
||||
[if allow_fail then 'failure']: 'ignore',
|
||||
commands: [
|
||||
'echo "Building on ${DRONE_STAGE_MACHINE}"',
|
||||
'echo "man-db man-db/auto-update boolean false" | debconf-set-selections',
|
||||
apt_get_quiet + ' update',
|
||||
apt_get_quiet + ' install -y eatmydata',
|
||||
'eatmydata ' + apt_get_quiet + ' install --no-install-recommends -y p7zip-full wine',
|
||||
'cd gui',
|
||||
'yarn install --frozen-lockfile',
|
||||
'USE_SYSTEM_7ZA=true DISPLAY= WINEDEBUG=-all yarn win32',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'build',
|
||||
image: image,
|
||||
pull: 'always',
|
||||
[if allow_fail then 'failure']: 'ignore',
|
||||
environment: { SSH_KEY: { from_secret: 'SSH_KEY' }, WINDOWS_BUILD_NAME: 'x64' },
|
||||
commands: [
|
||||
'echo "Building on ${DRONE_STAGE_MACHINE}"',
|
||||
'echo "man-db man-db/auto-update boolean false" | debconf-set-selections',
|
||||
apt_get_quiet + ' update',
|
||||
apt_get_quiet + ' install -y eatmydata',
|
||||
'eatmydata ' + apt_get_quiet + ' install --no-install-recommends -y build-essential cmake git pkg-config ccache g++-mingw-w64-x86-64-posix nsis zip icoutils automake libtool librsvg2-bin bison',
|
||||
'JOBS=' + jobs + ' VERBOSE=1 ./contrib/windows.sh -DSTRIP_SYMBOLS=ON -DGUI_EXE=$${DRONE_WORKSPACE}/gui/release/Lokinet-GUI_portable.exe' +
|
||||
ci_dep_mirror(local_mirror),
|
||||
] + extra_cmds,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// linux cross compile on debian
|
||||
local linux_cross_pipeline(name,
|
||||
cross_targets,
|
||||
arch='amd64',
|
||||
build_type='Release',
|
||||
cmake_extra='',
|
||||
local_mirror=true,
|
||||
extra_cmds=[],
|
||||
jobs=6,
|
||||
allow_fail=false) = {
|
||||
kind: 'pipeline',
|
||||
type: 'docker',
|
||||
name: name,
|
||||
platform: { arch: arch },
|
||||
trigger: { branch: { exclude: ['debian/*', 'ubuntu/*'] } },
|
||||
steps: [
|
||||
submodules,
|
||||
{
|
||||
name: 'build',
|
||||
image: docker_base + 'debian-stable-cross',
|
||||
pull: 'always',
|
||||
[if allow_fail then 'failure']: 'ignore',
|
||||
environment: { SSH_KEY: { from_secret: 'SSH_KEY' }, CROSS_TARGETS: std.join(':', cross_targets) },
|
||||
commands: [
|
||||
'echo "Building on ${DRONE_STAGE_MACHINE}"',
|
||||
'VERBOSE=1 JOBS=' + jobs + ' ./contrib/cross.sh ' + std.join(' ', cross_targets) +
|
||||
' -- ' + cmake_extra + ci_dep_mirror(local_mirror),
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// Builds a snapshot .deb on a debian-like system by merging into the debian/* or ubuntu/* branch
|
||||
local deb_builder(image, distro, distro_branch, arch='amd64', oxen_repo=true) = {
|
||||
kind: 'pipeline',
|
||||
type: 'docker',
|
||||
name: 'DEB (' + distro + (if arch == 'amd64' then '' else '/' + arch) + ')',
|
||||
platform: { arch: arch },
|
||||
environment: { distro_branch: distro_branch, distro: distro },
|
||||
steps: [
|
||||
submodules,
|
||||
{
|
||||
name: 'build',
|
||||
image: image,
|
||||
pull: 'always',
|
||||
failure: 'ignore',
|
||||
environment: { SSH_KEY: { from_secret: 'SSH_KEY' } },
|
||||
commands: [
|
||||
'echo "Building on ${DRONE_STAGE_MACHINE}"',
|
||||
'echo "man-db man-db/auto-update boolean false" | debconf-set-selections',
|
||||
] + (if oxen_repo then [
|
||||
'cp contrib/deb.oxen.io.gpg /etc/apt/trusted.gpg.d',
|
||||
'echo deb http://deb.oxen.io $${distro} main >/etc/apt/sources.list.d/oxen.list',
|
||||
] else []) + [
|
||||
apt_get_quiet + ' update',
|
||||
apt_get_quiet + ' install -y eatmydata',
|
||||
'eatmydata ' + apt_get_quiet + ' install --no-install-recommends -y git devscripts equivs ccache git-buildpackage python3-dev',
|
||||
|||
|
||||
# Look for the debian branch in this repo first, try upstream if that fails.
|
||||
if ! git checkout $${distro_branch}; then
|
||||
git remote add --fetch upstream https://github.com/oxen-io/lokinet.git &&
|
||||
git checkout $${distro_branch}
|
||||
fi
|
||||
|||,
|
||||
// Tell the merge how to resolve conflicts in the source .drone.jsonnet (we don't
|
||||
// care about it at all since *this* .drone.jsonnet is already loaded).
|
||||
'git config merge.ours.driver true',
|
||||
'echo .drone.jsonnet merge=ours >>.gitattributes',
|
||||
|
||||
'git merge ${DRONE_COMMIT}',
|
||||
'export DEBEMAIL="${DRONE_COMMIT_AUTHOR_EMAIL}" DEBFULLNAME="${DRONE_COMMIT_AUTHOR_NAME}"',
|
||||
'gbp dch -S -s "HEAD^" --spawn-editor=never -U low',
|
||||
'eatmydata mk-build-deps --install --remove --tool "' + apt_get_quiet + ' -o Debug::pkgProblemResolver=yes --no-install-recommends -y"',
|
||||
'export DEB_BUILD_OPTIONS="parallel=$$(nproc)"',
|
||||
//'grep -q lib debian/lokinet-bin.install || echo "/usr/lib/lib*.so*" >>debian/lokinet-bin.install',
|
||||
'debuild -e CCACHE_DIR -b',
|
||||
'./contrib/ci/drone-debs-upload.sh ' + distro,
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
local clang(version) = debian_pipeline(
|
||||
'Debian sid/clang-' + version + ' (amd64)',
|
||||
docker_base + 'debian-sid-clang',
|
||||
deps=['clang-' + version] + default_deps_nocxx,
|
||||
cmake_extra='-DCMAKE_C_COMPILER=clang-' + version + ' -DCMAKE_CXX_COMPILER=clang++-' + version + ' '
|
||||
);
|
||||
|
||||
local full_llvm(version) = debian_pipeline(
|
||||
'Debian sid/llvm-' + version + ' (amd64)',
|
||||
docker_base + 'debian-sid-clang',
|
||||
deps=['clang-' + version, ' lld-' + version, ' libc++-' + version + '-dev', 'libc++abi-' + version + '-dev']
|
||||
+ default_deps_nocxx,
|
||||
cmake_extra='-DCMAKE_C_COMPILER=clang-' + version +
|
||||
' -DCMAKE_CXX_COMPILER=clang++-' + version +
|
||||
' -DCMAKE_CXX_FLAGS=-stdlib=libc++ ' +
|
||||
std.join(' ', [
|
||||
'-DCMAKE_' + type + '_LINKER_FLAGS=-fuse-ld=lld-' + version
|
||||
for type in ['EXE', 'MODULE', 'SHARED']
|
||||
])
|
||||
);
|
||||
|
||||
// Macos build
|
||||
local mac_builder(name,
|
||||
build_type='Release',
|
||||
werror=true,
|
||||
cmake_extra='',
|
||||
local_mirror=true,
|
||||
extra_cmds=[],
|
||||
jobs=6,
|
||||
codesign='-DCODESIGN=OFF',
|
||||
allow_fail=false) = {
|
||||
kind: 'pipeline',
|
||||
type: 'exec',
|
||||
name: name,
|
||||
platform: { os: 'darwin', arch: 'amd64' },
|
||||
steps: [
|
||||
{ name: 'submodules', commands: submodule_commands },
|
||||
{
|
||||
name: 'build',
|
||||
environment: { SSH_KEY: { from_secret: 'SSH_KEY' } },
|
||||
commands: [
|
||||
'echo "Building on ${DRONE_STAGE_MACHINE}"',
|
||||
// If you don't do this then the C compiler doesn't have an include path containing
|
||||
// basic system headers. WTF apple:
|
||||
'export SDKROOT="$(xcrun --sdk macosx --show-sdk-path)"',
|
||||
'ulimit -n 1024', // because macos sets ulimit to 256 for some reason yeah idk
|
||||
'./contrib/mac-configure.sh ' +
|
||||
ci_dep_mirror(local_mirror) +
|
||||
(if build_type == 'Debug' then ' -DWARN_DEPRECATED=OFF ' else '') +
|
||||
codesign,
|
||||
'cd build-mac',
|
||||
// We can't use the 'package' target here because making a .dmg requires an active logged in
|
||||
// macos gui to invoke Finder to invoke the partitioning tool to create a partitioned (!)
|
||||
// disk image. Most likely the GUI is required because if you lose sight of how pretty the
|
||||
// surface of macOS is you might see how ugly the insides are.
|
||||
'ninja -j' + jobs + ' assemble_gui',
|
||||
'cd ..',
|
||||
] + extra_cmds,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
local docs_pipeline(name, image, extra_cmds=[], allow_fail=false) = {
|
||||
kind: 'pipeline',
|
||||
type: 'docker',
|
||||
name: name,
|
||||
platform: { arch: 'amd64' },
|
||||
trigger: { branch: { exclude: ['debian/*', 'ubuntu/*'] } },
|
||||
steps: [
|
||||
submodules,
|
||||
{
|
||||
name: 'build',
|
||||
image: image,
|
||||
pull: 'always',
|
||||
[if allow_fail then 'failure']: 'ignore',
|
||||
environment: { SSH_KEY: { from_secret: 'SSH_KEY' } },
|
||||
commands: [
|
||||
'cmake -S . -B build-docs',
|
||||
'make -C build-docs doc',
|
||||
] + extra_cmds,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
[
|
||||
{
|
||||
name: 'lint check',
|
||||
kind: 'pipeline',
|
||||
type: 'docker',
|
||||
steps: [{
|
||||
name: 'build',
|
||||
image: docker_base + 'lint',
|
||||
pull: 'always',
|
||||
commands: [
|
||||
'echo "Building on ${DRONE_STAGE_MACHINE}"',
|
||||
apt_get_quiet + ' update',
|
||||
apt_get_quiet + ' install -y eatmydata',
|
||||
'eatmydata ' + apt_get_quiet + ' install --no-install-recommends -y git clang-format-14 jsonnet',
|
||||
'./contrib/ci/drone-format-verify.sh',
|
||||
],
|
||||
}],
|
||||
},
|
||||
// documentation builder
|
||||
docs_pipeline('Documentation',
|
||||
docker_base + 'docbuilder',
|
||||
extra_cmds=['UPLOAD_OS=docs ./contrib/ci/drone-static-upload.sh']),
|
||||
|
||||
// Various debian builds
|
||||
debian_pipeline('Debian sid (amd64)', docker_base + 'debian-sid'),
|
||||
debian_pipeline('Debian sid/Debug (amd64)', docker_base + 'debian-sid', build_type='Debug'),
|
||||
clang(13),
|
||||
full_llvm(13),
|
||||
debian_pipeline('Debian stable (i386)', docker_base + 'debian-stable/i386'),
|
||||
debian_pipeline('Debian buster (amd64)', docker_base + 'debian-buster', cmake_extra='-DDOWNLOAD_SODIUM=ON'),
|
||||
debian_pipeline('Ubuntu latest (amd64)', docker_base + 'ubuntu-rolling'),
|
||||
debian_pipeline('Ubuntu LTS (amd64)', docker_base + 'ubuntu-lts'),
|
||||
debian_pipeline('Ubuntu bionic (amd64)',
|
||||
docker_base + 'ubuntu-bionic',
|
||||
deps=['g++-8'] + default_deps_nocxx,
|
||||
cmake_extra='-DCMAKE_C_COMPILER=gcc-8 -DCMAKE_CXX_COMPILER=g++-8',
|
||||
oxen_repo=true),
|
||||
|
||||
// ARM builds (ARM64 and armhf)
|
||||
debian_pipeline('Debian sid (ARM64)', docker_base + 'debian-sid', arch='arm64', jobs=4),
|
||||
debian_pipeline('Debian stable (armhf)', docker_base + 'debian-stable/arm32v7', arch='arm64', jobs=4),
|
||||
|
||||
// cross compile targets
|
||||
// Aug 11: these are exhibiting some dumb failures in libsodium and external deps, TOFIX later
|
||||
//linux_cross_pipeline('Cross Compile (arm/arm64)', cross_targets=['arm-linux-gnueabihf', 'aarch64-linux-gnu']),
|
||||
//linux_cross_pipeline('Cross Compile (ppc64le)', cross_targets=['powerpc64le-linux-gnu']),
|
||||
|
||||
// Not currently building successfully:
|
||||
//linux_cross_pipeline('Cross Compile (mips)', cross_targets=['mips-linux-gnu', 'mipsel-linux-gnu']),
|
||||
|
||||
// android apk builder
|
||||
// Aug 11: this is also failing in openssl, TOFIX later
|
||||
//apk_builder('android apk', docker_base + 'flutter', extra_cmds=['UPLOAD_OS=android ./contrib/ci/drone-static-upload.sh']),
|
||||
|
||||
// Windows builds (x64)
|
||||
windows_cross_pipeline('Windows (amd64)',
|
||||
docker_base + 'debian-bookworm',
|
||||
extra_cmds=[
|
||||
'./contrib/ci/drone-static-upload.sh',
|
||||
]),
|
||||
|
||||
// Static build (on bionic) which gets uploaded to builds.lokinet.dev:
|
||||
debian_pipeline('Static (bionic amd64)',
|
||||
docker_base + 'ubuntu-bionic',
|
||||
deps=['g++-8', 'python3-dev', 'automake', 'libtool'],
|
||||
lto=true,
|
||||
tests=false,
|
||||
oxen_repo=true,
|
||||
cmake_extra='-DBUILD_STATIC_DEPS=ON -DBUILD_SHARED_LIBS=OFF -DSTATIC_LINK=ON ' +
|
||||
'-DCMAKE_C_COMPILER=gcc-8 -DCMAKE_CXX_COMPILER=g++-8 ' +
|
||||
'-DCMAKE_CXX_FLAGS="-march=x86-64 -mtune=haswell" ' +
|
||||
'-DCMAKE_C_FLAGS="-march=x86-64 -mtune=haswell" ' +
|
||||
'-DNATIVE_BUILD=OFF -DWITH_SYSTEMD=OFF -DWITH_BOOTSTRAP=OFF -DBUILD_LIBLOKINET=OFF',
|
||||
extra_cmds=[
|
||||
'./contrib/ci/drone-check-static-libs.sh',
|
||||
'./contrib/ci/drone-static-upload.sh',
|
||||
]),
|
||||
// Static armhf build (gets uploaded)
|
||||
debian_pipeline('Static (buster armhf)',
|
||||
docker_base + 'debian-buster/arm32v7',
|
||||
arch='arm64',
|
||||
deps=['g++', 'python3-dev', 'automake', 'libtool'],
|
||||
cmake_extra='-DBUILD_STATIC_DEPS=ON -DBUILD_SHARED_LIBS=OFF -DSTATIC_LINK=ON ' +
|
||||
'-DCMAKE_CXX_FLAGS="-march=armv7-a+fp -Wno-psabi" -DCMAKE_C_FLAGS="-march=armv7-a+fp" ' +
|
||||
'-DNATIVE_BUILD=OFF -DWITH_SYSTEMD=OFF -DWITH_BOOTSTRAP=OFF',
|
||||
extra_cmds=[
|
||||
'./contrib/ci/drone-check-static-libs.sh',
|
||||
'UPLOAD_OS=linux-armhf ./contrib/ci/drone-static-upload.sh',
|
||||
],
|
||||
jobs=4),
|
||||
|
||||
// integration tests
|
||||
debian_pipeline('Router Hive',
|
||||
docker_base + 'ubuntu-lts',
|
||||
deps=['python3-dev', 'python3-pytest', 'python3-pybind11'] + default_deps,
|
||||
cmake_extra='-DWITH_HIVE=ON'),
|
||||
|
||||
// Deb builds:
|
||||
deb_builder(docker_base + 'debian-sid-builder', 'sid', 'debian/sid'),
|
||||
deb_builder(docker_base + 'debian-bullseye-builder', 'bullseye', 'debian/bullseye'),
|
||||
deb_builder(docker_base + 'ubuntu-jammy-builder', 'jammy', 'ubuntu/jammy'),
|
||||
deb_builder(docker_base + 'debian-sid-builder', 'sid', 'debian/sid', arch='arm64'),
|
||||
|
||||
// Macos builds:
|
||||
mac_builder('macOS (Release)', extra_cmds=[
|
||||
'./contrib/ci/drone-check-static-libs.sh',
|
||||
'./contrib/ci/drone-static-upload.sh',
|
||||
]),
|
||||
mac_builder('macOS (Debug)', build_type='Debug'),
|
||||
]
|
@ -1,22 +0,0 @@
|
||||
name: Close incomplete issues
|
||||
on:
|
||||
schedule:
|
||||
- cron: "30 1 * * *"
|
||||
|
||||
jobs:
|
||||
close-issues:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
- uses: actions/stale@v4.1.1
|
||||
with:
|
||||
only-labels: incomplete
|
||||
days-before-issue-stale: 14
|
||||
days-before-issue-close: 7
|
||||
stale-issue-label: "stale"
|
||||
stale-issue-message: "This issue is stale because it has been 'incomplete' for 14 days with no activity."
|
||||
close-issue-message: "This issue was closed because it has been inactive for 7 days since being marked as stale."
|
||||
days-before-pr-stale: -1
|
||||
days-before-pr-close: -1
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
@ -0,0 +1,90 @@
|
||||
variables:
|
||||
GIT_STRATEGY: fetch
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
|
||||
# disabled because gcc9 can't build net_if.hpp
|
||||
#build:linux:
|
||||
# image: alpine:latest
|
||||
# tags:
|
||||
# - linux
|
||||
# stage: build
|
||||
# before_script:
|
||||
# - apk add --update g++ make cmake linux-headers libcap-dev libuv-dev curl-dev git
|
||||
# script:
|
||||
# - make STATIC_LINK=ON DOWNLOAD_SODIUM=ON
|
||||
# artifacts:
|
||||
# paths:
|
||||
# - "lokinet"
|
||||
|
||||
# we'll just try our travis set up for now
|
||||
build:linux_release:
|
||||
image: ubuntu:xenial
|
||||
tags:
|
||||
- linux
|
||||
stage: build
|
||||
before_script:
|
||||
- apt-get update && apt-get install -y apt-transport-https curl
|
||||
- curl https://apt.kitware.com/keys/kitware-archive-latest.asc | apt-key add -
|
||||
- echo 'deb https://apt.kitware.com/ubuntu/ xenial main' >/etc/apt/sources.list.d/kitware.list
|
||||
- apt-get update && apt-get install -y build-essential ca-certificates cmake curl git libcap-dev pkg-config wget xz-utils
|
||||
script:
|
||||
- make static DOWNLOAD_SODIUM=ON
|
||||
# alternatively: git describe --tag
|
||||
- LOKINET_VERSION=$(./lokinet-static --version|sed s/lokinet-//)
|
||||
- echo lokinet-linux-x64-v$LOKINET_VERSION
|
||||
- mkdir lokinet-linux-x64-v$LOKINET_VERSION
|
||||
- cp lokinet-bootstrap lokinet-linux-x64-v$LOKINET_VERSION
|
||||
- cp build/daemon/lokinet lokinet-linux-x64-v$LOKINET_VERSION
|
||||
- cp build/daemon/lokinetctl lokinet-linux-x64-v$LOKINET_VERSION
|
||||
- cp docs/linux-setcap-readme.txt lokinet-linux-x64-v$LOKINET_VERSION
|
||||
- tar cJf lokinet-linux-x64-v$LOKINET_VERSION.tar.xz lokinet-linux-x64-v$LOKINET_VERSION
|
||||
- echo "lokinet-linux-x64-v$LOKINET_VERSION.tar.xz should be ready"
|
||||
artifacts:
|
||||
paths:
|
||||
- lokinet-linux-x64-v*.tar.xz
|
||||
|
||||
build:linux_debug:
|
||||
image: ubuntu:xenial
|
||||
tags:
|
||||
- linux
|
||||
stage: build
|
||||
before_script:
|
||||
- apt-get update && apt-get install -y apt-transport-https curl
|
||||
- curl https://apt.kitware.com/keys/kitware-archive-latest.asc | apt-key add -
|
||||
- echo 'deb https://apt.kitware.com/ubuntu/ xenial main' >/etc/apt/sources.list.d/kitware.list
|
||||
- apt-get update && apt-get install -y build-essential ca-certificates cmake curl git libcap-dev libcurl4-openssl-dev libuv1-dev ninja-build
|
||||
script:
|
||||
- DOWNLOAD_SODIUM=ON IS_NOTIFICATION=1 STATIC_LINK=OFF make
|
||||
artifacts:
|
||||
paths:
|
||||
- build/daemon/lokinet
|
||||
- build/daemon/lokinetctl
|
||||
|
||||
# needs libuv and libcurl
|
||||
#build:freebsd:
|
||||
# tags:
|
||||
# - freebsd
|
||||
# stage: build
|
||||
# script:
|
||||
# - gmake DOWNLOAD_SODIUM=ON
|
||||
# artifacts:
|
||||
# paths:
|
||||
# - "lokinet"
|
||||
|
||||
# need windows runner on lokiproject
|
||||
#build:windows:
|
||||
# tags:
|
||||
# - windows
|
||||
# stage: build
|
||||
# script:
|
||||
#- make static CC=gcc CXX=g++
|
||||
# can't use STATIC because LTO doesn't work on cross-compiled targets
|
||||
# -DSTATIC_LINK_RUNTIME=ON -DLIBUV_ROOT=libuv
|
||||
# - cmake .. -G Ninja -DCMAKE_TOOLCHAIN_FILE=../contrib/cross/mingw[32].cmake -DDOWNLOAD_SODIUM=ON
|
||||
# artifacts:
|
||||
# paths:
|
||||
# - "lokinet.exe"
|
@ -1,41 +1,21 @@
|
||||
[submodule "external/nlohmann"]
|
||||
path = external/nlohmann
|
||||
url = https://github.com/nlohmann/json.git
|
||||
[submodule "external/googletest"]
|
||||
path = external/googletest
|
||||
url = https://github.com/google/googletest.git
|
||||
[submodule "external/cxxopts"]
|
||||
path = external/cxxopts
|
||||
url = https://github.com/jarro2783/cxxopts.git
|
||||
[submodule "external/ghc-filesystem"]
|
||||
path = external/ghc-filesystem
|
||||
url = https://github.com/gulrak/filesystem.git
|
||||
[submodule "test/Catch2"]
|
||||
path = test/Catch2
|
||||
url = https://github.com/catchorg/Catch2
|
||||
[submodule "external/pybind11"]
|
||||
path = external/pybind11
|
||||
url = https://github.com/pybind/pybind11
|
||||
branch = stable
|
||||
[submodule "external/sqlite_orm"]
|
||||
path = external/sqlite_orm
|
||||
url = https://github.com/fnc12/sqlite_orm
|
||||
[submodule "external/oxen-mq"]
|
||||
path = external/oxen-mq
|
||||
url = https://github.com/oxen-io/oxen-mq
|
||||
[submodule "external/uvw"]
|
||||
path = external/uvw
|
||||
url = https://github.com/jagerman/uvw.git
|
||||
[submodule "external/cpr"]
|
||||
path = external/cpr
|
||||
url = https://github.com/whoshuu/cpr
|
||||
[submodule "external/ngtcp2"]
|
||||
path = external/ngtcp2
|
||||
url = https://github.com/ngtcp2/ngtcp2.git
|
||||
branch = v0.1.0
|
||||
[submodule "external/oxen-encoding"]
|
||||
path = external/oxen-encoding
|
||||
url = https://github.com/oxen-io/oxen-encoding.git
|
||||
[submodule "external/oxen-logging"]
|
||||
path = external/oxen-logging
|
||||
url = https://github.com/oxen-io/oxen-logging.git
|
||||
[submodule "gui"]
|
||||
path = gui
|
||||
url = https://github.com/oxen-io/lokinet-gui.git
|
||||
[submodule "external/CLI11"]
|
||||
path = external/CLI11
|
||||
url = https://github.com/CLIUtils/CLI11.git
|
||||
[submodule "external/optional-lite"]
|
||||
path = external/optional-lite
|
||||
url = https://github.com/martinmoene/optional-lite.git
|
||||
[submodule "external/date"]
|
||||
path = external/date
|
||||
url = https://github.com/HowardHinnant/date.git
|
||||
|
@ -1 +0,0 @@
|
||||
5.4.2
|
@ -0,0 +1,182 @@
|
||||
language: cpp
|
||||
dist: bionic
|
||||
osx_image: xcode11.3
|
||||
|
||||
cache: ccache
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- name: "lint check"
|
||||
os: linux
|
||||
compiler: gcc
|
||||
env: MAKE_TARGET=format-verify PATH="/usr/lib/llvm-8/bin:$PATH"
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- llvm-toolchain-bionic-8
|
||||
packages:
|
||||
- clang-format-8
|
||||
- name: "make debug (linux/gcc)"
|
||||
os: linux
|
||||
compiler: gcc
|
||||
env: BUILD_TYPE=Debug IS_NOTIFICATION=1
|
||||
addons: &core_apt_addons
|
||||
apt:
|
||||
packages:
|
||||
- build-essential
|
||||
- cmake
|
||||
- curl
|
||||
- git
|
||||
- libcap-dev
|
||||
- libcurl4-openssl-dev
|
||||
- libuv1-dev
|
||||
- ninja-build
|
||||
- libsodium-dev
|
||||
- libsystemd-dev
|
||||
- name: "make release (linux/gcc)"
|
||||
os: linux
|
||||
compiler: gcc
|
||||
env: BUILD_TYPE=Release
|
||||
addons: *core_apt_addons
|
||||
- name: "make release (old linux/gcc)"
|
||||
os: linux
|
||||
dist: xenial
|
||||
compiler: gcc
|
||||
env: BUILD_TYPE=Release
|
||||
addons: *core_apt_addons
|
||||
- name: "make debug (linux/clang)"
|
||||
os: linux
|
||||
compiler: clang
|
||||
env: BUILD_TYPE=Debug
|
||||
addons: *core_apt_addons
|
||||
- name: "make release (linux/clang)"
|
||||
os: linux
|
||||
compiler: clang
|
||||
env: BUILD_TYPE=Release
|
||||
addons: *core_apt_addons
|
||||
- name: "make debug (macOS/clang)"
|
||||
os: osx
|
||||
env: BUILD_TYPE=Debug PATH="/usr/local/opt/ccache/libexec:$PATH"
|
||||
- name: "make release (macOS/clang)"
|
||||
os: osx
|
||||
env: BUILD_TYPE=Release PATH="/usr/local/opt/ccache/libexec:$PATH"
|
||||
- name: "make release (linux/gcc/arm64)"
|
||||
arch: arm64
|
||||
compiler: gcc
|
||||
env: BUILD_TYPE=Release
|
||||
addons: *core_apt_addons
|
||||
- name: "make release (linux/gcc/s390x)"
|
||||
arch: s390x
|
||||
compiler: gcc
|
||||
env: BUILD_TYPE=Release
|
||||
addons: *core_apt_addons
|
||||
- name: "make release (linux/gcc/ppc64le)"
|
||||
arch: ppc64le
|
||||
compiler: gcc
|
||||
env: BUILD_TYPE=Release
|
||||
addons: *core_apt_addons
|
||||
# - name: "make iOS"
|
||||
# os: osx
|
||||
# env: MAKE_TARGET=ios PATH="/usr/local/opt/ccache/libexec:$PATH"
|
||||
# - name: "make windows (macOS)"
|
||||
# os: osx
|
||||
# env: MAKE_TARGET=windows PATH="/usr/local/opt/ccache/libexec:$PATH"
|
||||
# - name: "make windows-release (macOS)"
|
||||
# os: osx
|
||||
# env: MAKE_TARGET=windows-release PATH="/usr/local/opt/ccache/libexec:$PATH"
|
||||
# - name: "make release (macOS beta/clang)"
|
||||
# os: osx
|
||||
# env: BUILD_TYPE=Release PATH="/usr/local/opt/ccache/libexec:$PATH"
|
||||
# - name: "address sanitizer"
|
||||
# os: osx
|
||||
# env: BUILD_TYPE=Debug XSAN=address PATH="/usr/local/opt/ccache/libexec:$PATH" CC=/usr/local/opt/llvm/bin/clang CXX=/usr/local/opt/llvm/bin/clang++
|
||||
# - name: "thread sanitizer"
|
||||
# os: osx
|
||||
# env: BUILD_TYPE=Debug XSAN=thread PATH="/usr/local/opt/ccache/libexec:$PATH" CC=/usr/local/opt/llvm/bin/clang CXX=/usr/local/opt/llvm/bin/clang++
|
||||
# - name: "undefined sanitizer"
|
||||
# os: osx
|
||||
# env: BUILD_TYPE=Debug XSAN=undefined PATH="/usr/local/opt/ccache/libexec:$PATH" CC=/usr/local/opt/llvm/bin/clang CXX=/usr/local/opt/llvm/bin/clang++
|
||||
# - name: "memory sanitizer"
|
||||
# os: linux
|
||||
# compiler: clang
|
||||
# env: BUILD_TYPE=Debug XSAN=memory
|
||||
# addons: *core_apt_addons
|
||||
# - name: "router docker image"
|
||||
# os: linux
|
||||
# dist: xenial
|
||||
# env: DOCKER_FILE=docker/router.Dockerfile
|
||||
# services: docker
|
||||
- name: "make windows docker image"
|
||||
os: linux
|
||||
dist: xenial
|
||||
env: DOCKER_FILE=docker/alpine-windows.Dockerfile
|
||||
services: docker
|
||||
- name: "gcc trunk"
|
||||
os: linux
|
||||
dist: xenial
|
||||
env: DOCKER_FILE=docker/gcc-trunk.Dockerfile
|
||||
services: docker
|
||||
# - name: "native windows debug"
|
||||
# os: windows
|
||||
# env: BUILD_TYPE=Debug
|
||||
# - name: "native windows release"
|
||||
# os: windows
|
||||
# env: BUILD_TYPE=Release
|
||||
allow_failures:
|
||||
- name: "make windows docker image"
|
||||
- name: "native windows debug"
|
||||
- name: "native windows release"
|
||||
- name: "router docker image"
|
||||
- name: "gcc trunk"
|
||||
- arch: ppc64le
|
||||
|
||||
env:
|
||||
global:
|
||||
- NINJA=ninja
|
||||
- STATIC_LINK=OFF
|
||||
|
||||
addons:
|
||||
homebrew:
|
||||
update: true
|
||||
packages:
|
||||
- ccache
|
||||
- cmake
|
||||
- curl
|
||||
- libuv
|
||||
- make
|
||||
- ninja
|
||||
- libsodium
|
||||
|
||||
before_install:
|
||||
- if [ "$TRAVIS_OS_NAME" == "windows" ]; then
|
||||
choco install curl make ninja;
|
||||
choco upgrade cmake.install;
|
||||
export CC="/c/Program Files/LLVM/bin/clang-cl";
|
||||
export CXX="/c/Program Files/LLVM/bin/clang-cl";
|
||||
fi
|
||||
|
||||
script:
|
||||
- if [ "$TRAVIS_OS_NAME" == "windows" ]; then
|
||||
cmd.exe /C '"C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" amd64 && make test';
|
||||
elif [[ ! -z $DOCKER_FILE ]]; then
|
||||
docker build -f $DOCKER_FILE .;
|
||||
else
|
||||
make DOWNLOAD_SODIUM=ON ${MAKE_TARGET:-test};
|
||||
fi
|
||||
|
||||
after_script:
|
||||
- echo $TRAVIS_COMMIT_RANGE
|
||||
- echo $TRAVIS_COMMIT_LOG
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
urls: $WEBHOOK_URL
|
||||
irc:
|
||||
on_success: change
|
||||
on_failure: change
|
||||
channels:
|
||||
- "chat.freenode.net#llarp"
|
||||
nick: lokinet-ci
|
||||
template:
|
||||
- "%{result} | %{repository}#%{build_number} (%{commit} : %{author}) | Build details : %{build_url}"
|
@ -0,0 +1,58 @@
|
||||
# Cross Compile
|
||||
|
||||
Currently supported targets:
|
||||
|
||||
Tier 1:
|
||||
|
||||
* Linux (arm/x86)
|
||||
* Windows (32 and 64 bit x86)
|
||||
* FreeBSD (amd64)
|
||||
|
||||
Tier 2:
|
||||
|
||||
* Mac OSX (> 10.10)
|
||||
* Android (arm/x86)
|
||||
* Apple IOS
|
||||
* Linux PPC64 (little endian)
|
||||
|
||||
Tier 3:
|
||||
|
||||
* Big Endian Linux
|
||||
* NetBSD
|
||||
* OpenBSD
|
||||
|
||||
Unsupported (feel free to support this yourself)
|
||||
|
||||
* AIX
|
||||
* zOS
|
||||
|
||||
## For Windows
|
||||
|
||||
To cross compile for windows on non windows platforms run:
|
||||
|
||||
$ make windows
|
||||
|
||||
## For Other Linux
|
||||
|
||||
## deps
|
||||
|
||||
this setup assumes ubuntu
|
||||
|
||||
first you need to cross compile and install libuv:
|
||||
|
||||
$ git clone https://github.com/libuv/libuv
|
||||
$ mkdir -p build && cd build
|
||||
$ export TOOLCHAIN=arm-linux-gnueabihf # or whatever your compiler is
|
||||
$ cmake -DCMAKE_C_COMPILER=$(TOOLCHAIN)-gcc-8 -DCMAKE_INSTALL_PREFIX=/usr/$(TOOLCHAIN)
|
||||
$ make
|
||||
$ sudo make install
|
||||
|
||||
## build
|
||||
|
||||
To cross compile on linux for another archietecture:
|
||||
|
||||
# for rpi 3
|
||||
$ make CROSS=ON TOOLCHAIN=contrib/armhf.toolchain.cmake
|
||||
|
||||
# for ppc64le
|
||||
$ make CROSS=ON TOOLCHAIN=contrib/ppc64le.toolchain.cmake
|
@ -1,674 +1,23 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
LokiNET is the reference implementation of LLARP (Low Latency Anonymous
|
||||
Routing Protocol) and is licensed under ZLIB license, however the protocol
|
||||
specifications are placed into the public domian using the CC0 License.
|
||||
|
||||
Copyright (c) 2018-2020 The Loki Project
|
||||
Copyright (c) 2018-2020 Jeff Becker
|
||||
Windows NT port and portions Copyright (c) 2018-2020 Rick V.
|
||||
|
||||
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.
|
||||
|
@ -0,0 +1,356 @@
|
||||
|
||||
|
||||
REPO := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
|
||||
|
||||
NO_GIT := $(shell test -e $(REPO)/.git/ || echo 1)
|
||||
ifeq ($(NO_GIT),1)
|
||||
all: release
|
||||
else
|
||||
GIT_BRANCH ?= $(shell test -e $(REPO)/.git/ && git rev-parse --abbrev-ref HEAD)
|
||||
ifeq ($(GIT_BRANCH),master)
|
||||
all: release
|
||||
else
|
||||
all: test
|
||||
endif
|
||||
endif
|
||||
|
||||
BUILD_ROOT = $(REPO)/build
|
||||
|
||||
DESTDIR ?=
|
||||
|
||||
CC ?= cc
|
||||
CXX ?= c++
|
||||
|
||||
BUILD_TYPE ?= Debug
|
||||
|
||||
PYTHON ?= python
|
||||
PYTHON3 ?= python3
|
||||
|
||||
FORMAT ?= clang-format-8
|
||||
|
||||
SETCAP ?= which setcap && setcap cap_net_admin,cap_net_bind_service=+eip
|
||||
|
||||
SHADOW_ROOT ?= $(HOME)/.shadow
|
||||
SHADOW_BIN=$(SHADOW_ROOT)/bin/shadow
|
||||
SHADOW_CONFIG=$(REPO)/shadow.config.xml
|
||||
SHADOW_PLUGIN=$(BUILD_ROOT)/libshadow-plugin-lokinet-shared.so
|
||||
SHADOW_LOG=$(REPO)/shadow.log.txt
|
||||
|
||||
SHADOW_SRC ?= $(HOME)/local/shadow
|
||||
SHADOW_PARSE ?= $(PYTHON) $(SHADOW_SRC)/src/tools/parse-shadow.py - -m 0 --packet-data
|
||||
SHADOW_PLOT ?= $(PYTHON) $(SHADOW_SRC)/src/tools/plot-shadow.py -d $(REPO) LokiNET -c $(SHADOW_CONFIG) -r 10000 -e '.*'
|
||||
SHADOW_OPTS ?=
|
||||
|
||||
LIBUV_VERSION ?= v1.30.1
|
||||
LIBUV_PREFIX = $(BUILD_ROOT)/libuv
|
||||
|
||||
LIBCURL_PREFIX = $(BUILD_ROOT)/curl
|
||||
LIBCURL_VERSION = 7.67.0
|
||||
LIBCURL_URL = https://github.com/curl/curl/releases/download/curl-7_67_0/curl-7.67.0.tar.xz
|
||||
LIBCURL_SHA256 = f5d2e7320379338c3952dcc7566a140abb49edb575f9f99272455785c40e536c
|
||||
|
||||
TESTNET_ROOT=/tmp/lokinet_testnet_tmp
|
||||
TESTNET_CONF=$(TESTNET_ROOT)/supervisor.conf
|
||||
TESTNET_LOG=$(TESTNET_ROOT)/testnet.log
|
||||
|
||||
TESTNET_VENV=$(TESTNET_ROOT)/v
|
||||
TESTNET_EXE=$(REPO)/lokinet-testnet
|
||||
TESTNET_CLIENTS ?= 50
|
||||
TESTNET_SERVERS ?= 50
|
||||
TESTNET_DEBUG ?= 0
|
||||
TESTNET_IFNAME ?= lo
|
||||
TESTNET_BASEPORT ?= 1900
|
||||
TESTNET_IP ?= 127.0.0.1
|
||||
TESTNET_NETID ?= loopback
|
||||
|
||||
ANDROID_NDK ?= $(HOME)/Android/Ndk
|
||||
ANDROID_SDK ?= $(HOME)/Android/Sdk
|
||||
ANDROID_ABI ?= armeabi-v7a
|
||||
ANDROID_API_LEVEL ?= 24
|
||||
|
||||
ANDROID_DIR=$(REPO)/android
|
||||
JNI_DIR=$(ANDROID_DIR)/jni
|
||||
ANDROID_MK=$(JNI_DIR)/Android.mk
|
||||
ANDROID_PROPS=$(ANDROID_DIR)/gradle.properties
|
||||
ANDROID_LOCAL_PROPS=$(ANDROID_DIR)/local.properties
|
||||
|
||||
GRADLE ?= gradle
|
||||
JAVA_HOME ?= /usr/lib/jvm/default-java
|
||||
|
||||
TOOLCHAIN ?=
|
||||
|
||||
# native avx2 code
|
||||
AVX2 ?= OFF
|
||||
# statically link everything
|
||||
STATIC_LINK ?= OFF
|
||||
# statically link dependencies
|
||||
STATIC ?= OFF
|
||||
# enable network namespace isolation
|
||||
NETNS ?= OFF
|
||||
# enable shell hooks callbacks
|
||||
SHELL_HOOKS ?= OFF
|
||||
# cross compile?
|
||||
CROSS ?= OFF
|
||||
# build liblokinet-shared.so
|
||||
SHARED_LIB ?= OFF
|
||||
# enable generating coverage
|
||||
COVERAGE ?= OFF
|
||||
# allow downloading libsodium if >= 1.0.18 not installed
|
||||
DOWNLOAD_SODIUM ?= OFF
|
||||
|
||||
COVERAGE_OUTDIR ?= "$(TMPDIR)/lokinet-coverage"
|
||||
|
||||
# tracy profiler
|
||||
TRACY_ROOT ?=
|
||||
# enable sanitizer
|
||||
XSAN ?= False
|
||||
|
||||
# cmake generator type
|
||||
CMAKE_GEN ?= Unix Makefiles
|
||||
|
||||
|
||||
ifdef NINJA
|
||||
MAKE = $(NINJA)
|
||||
CMAKE_GEN = Ninja
|
||||
endif
|
||||
|
||||
|
||||
|
||||
SCAN_BUILD ?= scan-build
|
||||
|
||||
UNAME = $(shell which uname)
|
||||
|
||||
COMMON_CMAKE_OPTIONS = -DSTATIC_LINK_RUNTIME=$(STATIC_LINK) -DUSE_NETNS=$(NETNS) -DUSE_AVX2=$(AVX2) -DWITH_SHARED=$(SHARED_LIB) -DDOWNLOAD_SODIUM=$(DOWNLOAD_SODIUM) -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DXSAN=$(XSAN)
|
||||
|
||||
ifeq ($(shell $(UNAME)),SunOS)
|
||||
CONFIG_CMD = $(shell gecho -n "cd '$(BUILD_ROOT)' && " ; gecho -n "cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=$(CROSS) -DUSE_SHELLHOOKS=$(SHELL_HOOKS) $(COMMON_CMAKE_OPTIONS) '$(REPO)'")
|
||||
CONFIG_CMD_WINDOWS = $(shell gecho -n "cd '$(BUILD_ROOT)' && " ; gecho -n "cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=ON -DUSE_SHELLHOOKS=$(SHELL_HOOKS) $(COMMON_CMAKE_OPTIONS) '$(REPO)'")
|
||||
|
||||
ANALYZE_CONFIG_CMD = $(shell gecho -n "cd '$(BUILD_ROOT)' && " ; gecho -n "$(SCAN_BUILD) cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=$(CROSS) $(COMMON_CMAKE_OPTIONS) '$(REPO)'")
|
||||
|
||||
COVERAGE_CONFIG_CMD = $(shell gecho -n "cd '$(BUILD_ROOT)' && " ; gecho -n "cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=$(CROSS) -DWITH_COVERAGE=yes $(COMMON_CMAKE_OPTIONS) '$(REPO)'")
|
||||
else
|
||||
CONFIG_CMD = $(shell /bin/echo -n "cd '$(BUILD_ROOT)' && " ; /bin/echo -n "cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=$(CROSS) -DUSE_SHELLHOOKS=$(SHELL_HOOKS) -DTRACY_ROOT=$(TRACY_ROOT) $(COMMON_CMAKE_OPTIONS) '$(REPO)'")
|
||||
CONFIG_CMD_WINDOWS = $(shell /bin/echo -n "cd '$(BUILD_ROOT)' && " ; /bin/echo -n "cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=ON -DUSE_SHELLHOOKS=$(SHELL_HOOKS) $(COMMON_CMAKE_OPTIONS) '$(REPO)'")
|
||||
|
||||
ANALYZE_CONFIG_CMD = $(shell /bin/echo -n "cd '$(BUILD_ROOT)' && " ; /bin/echo -n "$(SCAN_BUILD) cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=$(CROSS) $(COMMON_CMAKE_OPTIONS) '$(REPO)'")
|
||||
|
||||
COVERAGE_CONFIG_CMD = $(shell /bin/echo -n "cd '$(BUILD_ROOT)' && " ; /bin/echo -n "cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=$(CROSS) -DWITH_COVERAGE=yes $(COMMON_CMAKE_OPTIONS) '$(REPO)'")
|
||||
endif
|
||||
|
||||
TARGETS = $(REPO)/lokinet
|
||||
SIGS = $(TARGETS:=.sig)
|
||||
EXE = $(BUILD_ROOT)/daemon/lokinet
|
||||
TEST_EXE = $(BUILD_ROOT)/test/testAll
|
||||
ABYSS_EXE = $(BUILD_ROOT)/abyss-main
|
||||
|
||||
LINT_FILES = $(wildcard llarp/*.cpp)
|
||||
|
||||
LINT_CHECK = $(LINT_FILES:.cpp=.cpp-check)
|
||||
|
||||
clean: android-clean
|
||||
rm -f $(TARGETS)
|
||||
rm -rf $(BUILD_ROOT)
|
||||
rm -f $(SHADOW_PLUGIN) $(SHADOW_CONFIG)
|
||||
rm -f *.sig
|
||||
rm -f *.a *.so
|
||||
|
||||
android-clean:
|
||||
rm -rf $(ANDROID_DIR)/.externalNativeBuild
|
||||
|
||||
debug-configure:
|
||||
mkdir -p '$(BUILD_ROOT)'
|
||||
(test x$(TOOLCHAIN) = x && $(CONFIG_CMD) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)') || (test x$(TOOLCHAIN) != x && $(CONFIG_CMD) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)' -DCMAKE_TOOLCHAIN_FILE=$(TOOLCHAIN) )
|
||||
|
||||
|
||||
release-configure: clean
|
||||
mkdir -p '$(BUILD_ROOT)'
|
||||
$(CONFIG_CMD) -DCMAKE_BUILD_TYPE=Release -DRELEASE_MOTTO="$(shell cat motto.txt)" -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)'
|
||||
|
||||
debug: debug-configure
|
||||
$(MAKE) -C $(BUILD_ROOT)
|
||||
cp $(EXE) $(REPO)/lokinet
|
||||
|
||||
release-compile: release-configure
|
||||
$(MAKE) -C $(BUILD_ROOT)
|
||||
strip $(EXE)
|
||||
|
||||
$(TARGETS): release-compile
|
||||
|
||||
release: $(TARGETS)
|
||||
make -C '$(BUILD_ROOT)' check
|
||||
|
||||
shadow-configure: clean
|
||||
mkdir -p $(BUILD_ROOT)
|
||||
$(CONFIG_CMD) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DSHADOW=ON
|
||||
|
||||
shadow-build: shadow-configure
|
||||
$(MAKE) -C $(BUILD_ROOT)
|
||||
|
||||
shadow-run: shadow-build
|
||||
$(PYTHON3) $(REPO)/contrib/shadow/genconf.py $(SHADOW_CONFIG)
|
||||
cp $(SHADOW_PLUGIN) $(REPO)/libshadow-plugin-lokinet.so
|
||||
$(SHADOW_BIN) $(SHADOW_OPTS) $(SHADOW_CONFIG) | $(SHADOW_PARSE)
|
||||
|
||||
shadow-plot: shadow-run
|
||||
$(SHADOW_PLOT)
|
||||
|
||||
shadow: shadow-plot
|
||||
|
||||
testnet-clean: clean
|
||||
rm -rf $(TESTNET_ROOT)
|
||||
|
||||
testnet-configure: testnet-clean
|
||||
mkdir -p $(BUILD_ROOT)
|
||||
$(CONFIG_CMD) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DTESTNET=1
|
||||
|
||||
testnet-build: testnet-configure
|
||||
$(MAKE) -C $(BUILD_ROOT)
|
||||
|
||||
$(TESTNET_VENV):
|
||||
$(PYTHON3) -m venv $(TESTNET_VENV) --system-site-packages
|
||||
$(TESTNET_VENV)/bin/pip install -r $(REPO)/contrib/testnet/requirements.txt
|
||||
|
||||
testnet: $(TESTNET_VENV)
|
||||
cp $(EXE) $(TESTNET_EXE)
|
||||
mkdir -p $(TESTNET_ROOT)
|
||||
$(PYTHON3) $(REPO)/contrib/testnet/genconf.py --bin=$(TESTNET_EXE) --svc=$(TESTNET_SERVERS) --clients=$(TESTNET_CLIENTS) --dir=$(TESTNET_ROOT) --out $(TESTNET_CONF) --ifname=$(TESTNET_IFNAME) --baseport=$(TESTNET_BASEPORT) --ip=$(TESTNET_IP) --netid=$(TESTNET_NETID) --lokid='$(TESTNET_VENV)/bin/python $(REPO)/contrib/testnet/lokid.py'
|
||||
LLARP_DEBUG=$(TESTNET_DEBUG) supervisord -n -d $(TESTNET_ROOT) -l $(TESTNET_LOG) -c $(TESTNET_CONF)
|
||||
|
||||
gtest: debug
|
||||
test x$(CROSS) = xOFF && $(MAKE) -C $(BUILD_ROOT) rungtest || test x$(CROSS) = xON
|
||||
|
||||
catch: debug
|
||||
test x$(CROSS) = xOFF && $(MAKE) -C $(BUILD_ROOT) catch || test x$(CROSS) = xON
|
||||
|
||||
check: debug
|
||||
test x$(CROSS) = xOFF && $(MAKE) -C $(BUILD_ROOT) check || test x$(CROSS) = xON
|
||||
|
||||
test: check
|
||||
|
||||
static-configure: $(LIBUV_PREFIX) $(LIBCURL_PREFIX)
|
||||
(test x$(TOOLCHAIN) = x && $(CONFIG_CMD) -DCMAKE_BUILD_TYPE=Release -DSTATIC_LINK=ON -DRELEASE_MOTTO="$(shell cat motto.txt)" -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)' -DLIBUV_ROOT='$(LIBUV_PREFIX)' -DLIBCURL_ROOT='$(LIBCURL_PREFIX)' ) || (test x$(TOOLCHAIN) != x && $(CONFIG_CMD) -DCMAKE_BUILD_TYPE=Release -DSTATIC_LINK=ON -DRELEASE_MOTTO="$(shell cat motto.txt)" -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)' -DLIBUV_ROOT='$(LIBUV_PREFIX)' -DLIBCURL_ROOT='$(LIBCURL_PREFIX)' -DCMAKE_TOOLCHAIN_FILE=$(TOOLCHAIN) -DNATIVE_BUILD=OFF )
|
||||
|
||||
static: static-configure
|
||||
$(MAKE) -C '$(BUILD_ROOT)'
|
||||
cp $(EXE) $(REPO)/lokinet-static
|
||||
|
||||
$(LIBCURL_PREFIX):
|
||||
mkdir -p '$(BUILD_ROOT)'
|
||||
wget '$(LIBCURL_URL)' -O '$(BUILD_ROOT)/curl.tar.xz'
|
||||
bash -c 'sha256sum -c <<<"$(LIBCURL_SHA256) $(BUILD_ROOT)/curl.tar.xz"'
|
||||
tar -xJf '$(BUILD_ROOT)/curl.tar.xz' -C '$(BUILD_ROOT)'
|
||||
mv '$(BUILD_ROOT)/curl-$(LIBCURL_VERSION)' '$(LIBCURL_PREFIX)'
|
||||
|
||||
$(LIBUV_PREFIX):
|
||||
mkdir -p $(BUILD_ROOT)
|
||||
git clone -b "$(LIBUV_VERSION)" https://github.com/libuv/libuv "$(LIBUV_PREFIX)"
|
||||
|
||||
ios:
|
||||
cmake -S ui-ios -B build -G Xcode -DCMAKE_TOOLCHAIN_FILE=$(shell pwd)/ui-ios/ios-toolchain.cmake -DCMAKE_SYSTEM_NAME=iOS "-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64" -DCMAKE_OSX_DEPLOYMENT_TARGET=12.2 -DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=NO -DCMAKE_IOS_INSTALL_COMBINED=YES
|
||||
cmake --build build
|
||||
|
||||
android-gradle-prepare: $(LIBUV_PREFIX)
|
||||
rm -f $(ANDROID_PROPS)
|
||||
rm -f $(ANDROID_LOCAL_PROPS)
|
||||
echo "#auto generated don't modify kthnx" >> $(ANDROID_PROPS)
|
||||
echo "libuvsrc=$(LIBUV_PREFIX)" >> $(ANDROID_PROPS)
|
||||
echo "lokinetCMake=$(REPO)/CMakeLists.txt" >> $(ANDROID_PROPS)
|
||||
echo "org.gradle.parallel=true" >> $(ANDROID_PROPS)
|
||||
echo "org.gradle.jvmargs=-Xmx1536M" >> $(ANDROID_PROPS)
|
||||
echo "#auto generated don't modify kthnx" >> $(ANDROID_LOCAL_PROPS)
|
||||
echo "sdk.dir=$(ANDROID_SDK)" >> $(ANDROID_LOCAL_PROPS)
|
||||
echo "ndk.dir=$(ANDROID_NDK)" >> $(ANDROID_LOCAL_PROPS)
|
||||
|
||||
android-gradle: android-gradle-prepare
|
||||
cd $(ANDROID_DIR) && JAVA_HOME=$(JAVA_HOME) $(GRADLE) clean assemble
|
||||
|
||||
android: android-gradle
|
||||
cp -f $(ANDROID_DIR)/build/outputs/apk/*.apk $(REPO)
|
||||
|
||||
windows-debug-configure: $(LIBUV_PREFIX)
|
||||
mkdir -p '$(BUILD_ROOT)'
|
||||
$(CONFIG_CMD_WINDOWS) -DCMAKE_TOOLCHAIN_FILE='$(REPO)/contrib/cross/mingw.cmake' -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DCMAKE_ASM_FLAGS='$(ASFLAGS)' -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)' -DLIBUV_ROOT=$(LIBUV_PREFIX)
|
||||
|
||||
windows-debug: windows-debug-configure
|
||||
$(MAKE) -C '$(BUILD_ROOT)'
|
||||
cp '$(BUILD_ROOT)/daemon/lokinet.exe' '$(REPO)/lokinet.exe'
|
||||
|
||||
windows-release-configure: $(LIBUV_PREFIX)
|
||||
mkdir -p '$(BUILD_ROOT)'
|
||||
$(CONFIG_CMD_WINDOWS) -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE='$(REPO)/contrib/cross/mingw.cmake' -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DCMAKE_ASM_FLAGS='$(ASFLAGS)' -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)' -DLIBUV_ROOT=$(LIBUV_PREFIX)
|
||||
|
||||
windows-release: windows-release-configure
|
||||
$(MAKE) -C '$(BUILD_ROOT)'
|
||||
cp '$(BUILD_ROOT)/daemon/lokinet.exe' '$(REPO)/lokinet.exe'
|
||||
|
||||
windows: windows-debug
|
||||
|
||||
abyss: debug
|
||||
$(ABYSS_EXE)
|
||||
|
||||
format:
|
||||
$(FORMAT) -i $$(find jni daemon llarp include libabyss | grep -E '\.[h,c](pp)?$$')
|
||||
|
||||
format-verify: format
|
||||
(type $(FORMAT))
|
||||
$(FORMAT) --version
|
||||
git diff --quiet || (echo 'Please run make format!!' && git --no-pager diff ; exit 1)
|
||||
|
||||
analyze-config: clean
|
||||
mkdir -p '$(BUILD_ROOT)'
|
||||
$(ANALYZE_CONFIG_CMD)
|
||||
|
||||
analyze: analyze-config
|
||||
$(SCAN_BUILD) $(MAKE) -C $(BUILD_ROOT)
|
||||
|
||||
coverage-config: clean
|
||||
mkdir -p '$(BUILD_ROOT)'
|
||||
$(COVERAGE_CONFIG_CMD)
|
||||
|
||||
coverage: coverage-config
|
||||
$(MAKE) -C $(BUILD_ROOT)
|
||||
test x$(CROSS) = xOFF && $(MAKE) -C $(BUILD_ROOT) check || true # continue even if tests fail
|
||||
mkdir -p "$(COVERAGE_OUTDIR)"
|
||||
ifeq ($(CLANG),OFF)
|
||||
gcovr -r . --branches --html --html-details -o "$(COVERAGE_OUTDIR)/lokinet.html"
|
||||
else
|
||||
llvm-profdata merge default.profraw -output $(BUILD_ROOT)/profdata
|
||||
llvm-cov show -format=html -output-dir="$(COVERAGE_OUTDIR)" -instr-profile "$(BUILD_ROOT)/profdata" "$(BUILD_ROOT)/testAll" $(shell find ./llarp -type f)
|
||||
endif
|
||||
|
||||
lint: $(LINT_CHECK)
|
||||
|
||||
%.cpp-check: %.cpp
|
||||
clang-tidy $^ -- -I$(REPO)/include -I$(REPO)/crypto/include -I$(REPO)/llarp -I$(REPO)/vendor/cppbackport-master/lib
|
||||
|
||||
docker-kubernetes:
|
||||
docker build -f docker/loki-svc-kubernetes.Dockerfile .
|
||||
|
||||
install-pylokinet:
|
||||
cd $(REPO)/contrib/py/pylokinet && $(PYTHON3) setup.py install
|
||||
|
||||
kubernetes-install: install install-pylokinet
|
||||
|
||||
docker-debian:
|
||||
docker build -f docker/debian.Dockerfile .
|
||||
|
||||
docker-fedora:
|
||||
docker build -f docker/fedora.Dockerfile .
|
||||
|
||||
debian-configure:
|
||||
mkdir -p '$(BUILD_ROOT)'
|
||||
$(CONFIG_CMD) -DDEBIAN=ON -DRELEASE_MOTTO="$(shell cat $(REPO)/motto.txt)" -DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
debian: debian-configure
|
||||
$(MAKE) -C '$(BUILD_ROOT)'
|
||||
cp $(EXE) lokinet
|
||||
|
||||
debian-test:
|
||||
test x$(CROSS) = xOFF && $(MAKE) -C $(BUILD_ROOT) check || test x$(CROSS) = xON
|
||||
|
||||
install:
|
||||
DESTDIR=$(DESTDIR) $(MAKE) -C '$(BUILD_ROOT)' install
|
||||
|
||||
.PHONY: debian-install
|
@ -0,0 +1,18 @@
|
||||
gen
|
||||
tests
|
||||
bin
|
||||
libs
|
||||
log*
|
||||
obj
|
||||
.gradle
|
||||
.idea
|
||||
.externalNativeBuild
|
||||
ant.properties
|
||||
local.properties
|
||||
build.sh
|
||||
android.iml
|
||||
build
|
||||
gradle
|
||||
gradlew
|
||||
gradlew.bat
|
||||
gradle.properties
|
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="network.loki.lokinet"
|
||||
android:installLocation="auto"
|
||||
android:versionCode="1"
|
||||
android:versionName="0.3.2">
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="14"
|
||||
android:targetSdkVersion="28" />
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" /> <!-- normal perm, per https://developer.android.com/guide/topics/permissions/normal-permissions.html -->
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<!-- normal perm -->
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@drawable/icon"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@android:style/Theme.Holo.Light.DarkActionBar"
|
||||
>
|
||||
<receiver android:name=".NetworkStateChangeReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<activity
|
||||
android:name=".LokiNetActivity"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<service android:name=".LokinetService"
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BIND_VPN_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.net.VpnService"/>
|
||||
</intent-filter>
|
||||
</service>
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -0,0 +1,75 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.3.3'
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
maven {
|
||||
url 'https://maven.google.com'
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
buildToolsVersion "28.0.1"
|
||||
defaultConfig {
|
||||
applicationId "network.loki.lokinet"
|
||||
targetSdkVersion 28
|
||||
minSdkVersion 23
|
||||
versionCode 1
|
||||
versionName "0.4.0"
|
||||
ndk {
|
||||
abiFilters 'armeabi'
|
||||
}
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
targets "lokinetandroid"
|
||||
arguments "-DANDROID=ON", "-DANDROID_STL=c++_static", "-DANDROID_ARM_NEON=TRUE", "-DLIBUV_ROOT=" + libuvsrc, "-DANDROID_TOOLCHAIN=clang", "-DANDROID_ARM_MODE=arm"
|
||||
cppFlags "-fexceptions -std=c++14 -frtti"
|
||||
}
|
||||
}
|
||||
packagingOptions{
|
||||
doNotStrip "*/armeabi/*.so"
|
||||
doNotStrip "*/armeabi-v7a/*.so"
|
||||
doNotStrip "*/x86/*.so"
|
||||
}
|
||||
}
|
||||
sourceSets {
|
||||
main {
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
java.srcDirs = ['src']
|
||||
res.srcDirs = ['res']
|
||||
jniLibs.srcDirs = ['libs']
|
||||
assets.srcDirs = ['assets']
|
||||
}
|
||||
}
|
||||
signingConfigs {
|
||||
jeff {
|
||||
storeFile file("jeff-apk.jks")
|
||||
keyAlias "jeff-apk"
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled true
|
||||
//signingConfig signingConfigs.jeff
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
|
||||
}
|
||||
}
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path lokinetCMake
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="lokinet" default="help">
|
||||
|
||||
<!-- The local.properties file is created and updated by the 'android' tool.
|
||||
It contains the path to the SDK. It should *NOT* be checked into
|
||||
Version Control Systems. -->
|
||||
<property file="local.properties" />
|
||||
|
||||
<!-- The ant.properties file can be created by you. It is only edited by the
|
||||
'android' tool to add properties to it.
|
||||
This is the place to change some Ant specific build properties.
|
||||
Here are some properties you may want to change/update:
|
||||
|
||||
source.dir
|
||||
The name of the source directory. Default is 'src'.
|
||||
out.dir
|
||||
The name of the output directory. Default is 'bin'.
|
||||
|
||||
For other overridable properties, look at the beginning of the rules
|
||||
files in the SDK, at tools/ant/build.xml
|
||||
|
||||
Properties related to the SDK location or the project target should
|
||||
be updated using the 'android' tool with the 'update' action.
|
||||
|
||||
This file is an integral part of the build system for your
|
||||
application and should be checked into Version Control Systems.
|
||||
|
||||
-->
|
||||
<property file="ant.properties" />
|
||||
|
||||
<!-- if sdk.dir was not set from one of the property file, then
|
||||
get it from the ANDROID_HOME env var.
|
||||
This must be done before we load project.properties since
|
||||
the proguard config can use sdk.dir -->
|
||||
<property environment="env" />
|
||||
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
|
||||
<isset property="env.ANDROID_HOME" />
|
||||
</condition>
|
||||
|
||||
<!-- The project.properties file is created and updated by the 'android'
|
||||
tool, as well as ADT.
|
||||
|
||||
This contains project specific properties such as project target, and library
|
||||
dependencies. Lower level build properties are stored in ant.properties
|
||||
(or in .classpath for Eclipse projects).
|
||||
|
||||
This file is an integral part of the build system for your
|
||||
application and should be checked into Version Control Systems. -->
|
||||
<loadproperties srcFile="project.properties" />
|
||||
|
||||
<!-- quick check on sdk.dir -->
|
||||
<fail
|
||||
message="sdk.dir is missing. Insert sdk.dir=... into './local.properties'. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
|
||||
unless="sdk.dir"
|
||||
/>
|
||||
|
||||
<fail
|
||||
message="ndk.dir is missing. Insert ndk.dir=... into './local.properties'."
|
||||
unless="ndk.dir"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Import per project custom build rules if present at the root of the project.
|
||||
This is the place to put custom intermediary targets such as:
|
||||
-pre-build
|
||||
-pre-compile
|
||||
-post-compile (This is typically used for code obfuscation.
|
||||
Compiled code location: ${out.classes.absolute.dir}
|
||||
If this is not done in place, override ${out.dex.input.absolute.dir})
|
||||
-post-package
|
||||
-post-build
|
||||
-pre-clean
|
||||
-->
|
||||
<import file="custom_rules.xml" optional="true" />
|
||||
|
||||
<!-- Import the actual build file.
|
||||
|
||||
To customize existing targets, there are two options:
|
||||
- Customize only one target:
|
||||
- copy/paste the target into this file, *before* the
|
||||
<import> task.
|
||||
- customize it to your needs.
|
||||
- Customize the whole content of build.xml
|
||||
- copy/paste the content of the rules files (minus the top node)
|
||||
into this file, replacing the <import> task.
|
||||
- customize to your needs.
|
||||
|
||||
***********************
|
||||
****** IMPORTANT ******
|
||||
***********************
|
||||
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
|
||||
in order to avoid having your file be overridden by tools such as "android update project"
|
||||
-->
|
||||
<!-- version-tag: 1 -->
|
||||
<import file="${sdk.dir}/tools/ant/build.xml" />
|
||||
</project>
|
@ -0,0 +1,20 @@
|
||||
# To enable ProGuard in your project, edit project.properties
|
||||
# to define the proguard.config property as described in that file.
|
||||
#
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the ProGuard
|
||||
# include property in project.properties.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
@ -0,0 +1,14 @@
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system edit
|
||||
# "ant.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
#
|
||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||
|
||||
# Project target.
|
||||
target=android-28
|
Binary file not shown.
After Width: | Height: | Size: 6.4 KiB |
@ -0,0 +1,27 @@
|
||||
<LinearLayout android:id="@+id/main_layout"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/vertical_page_margin"
|
||||
android:paddingLeft="@dimen/horizontal_page_margin"
|
||||
android:paddingRight="@dimen/horizontal_page_margin"
|
||||
android:paddingTop="@dimen/vertical_page_margin"
|
||||
tools:context=".PermsAskerActivity">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textview_retry"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/horizontal_page_margin"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_request_write_ext_storage_perms"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Retry requesting VPN"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
@ -0,0 +1,27 @@
|
||||
<LinearLayout android:id="@+id/layout_prompt"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/vertical_page_margin"
|
||||
android:paddingLeft="@dimen/horizontal_page_margin"
|
||||
android:paddingRight="@dimen/horizontal_page_margin"
|
||||
android:paddingTop="@dimen/vertical_page_margin"
|
||||
tools:context=".PermsAskerActivity">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textview_explanation"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/horizontal_page_margin"
|
||||
android:text="VPN permissions are required for lokinet usage."
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_ok"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="OK"
|
||||
/>
|
||||
</LinearLayout>
|
@ -0,0 +1,16 @@
|
||||
<menu
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context=".LokiNetActivity">
|
||||
<item
|
||||
android:id="@+id/action_start"
|
||||
android:title="@string/action_start"
|
||||
android:orderInCategory="98"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/action_stop"
|
||||
android:title="@string/action_stop"
|
||||
android:orderInCategory="99"
|
||||
/>
|
||||
</menu>
|
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">lokinet</string>
|
||||
<string name="action_start">Start</string>
|
||||
<string name="action_stop">Stop</string>
|
||||
<string name="already_stopped">Already stopped</string>
|
||||
<string name="loaded">lokinet loaded</string>
|
||||
<string name="starting">lokinet is starting</string>
|
||||
<string name="jniLibraryLoaded">lokinet: loaded JNI libraries</string>
|
||||
<string name="startedOkay">lokinet started</string>
|
||||
<string name="startFailed">lokinet start failed</string>
|
||||
<string name="stopped">lokinet has stopped</string>
|
||||
<string name="remaining">remaining</string>
|
||||
<string name="title_activity_perms_asker_prompt">Prompt</string>
|
||||
<string name="bootstrap_ok">got bootstrap node info</string>
|
||||
<string name="bootstrap_fail">failed to bootstrap</string>
|
||||
<string name="netdb_create_fail">failed to create netdb directory</string>
|
||||
<string name="vpn_setup_fail">failed to set up vpn tunnel</string>
|
||||
</resources>
|
@ -0,0 +1,16 @@
|
||||
<resources>
|
||||
|
||||
<!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
|
||||
|
||||
<dimen name="margin_tiny">4dp</dimen>
|
||||
<dimen name="margin_small">8dp</dimen>
|
||||
<dimen name="margin_medium">16dp</dimen>
|
||||
<dimen name="margin_large">32dp</dimen>
|
||||
<dimen name="margin_huge">64dp</dimen>
|
||||
|
||||
<!-- Semantic definitions -->
|
||||
|
||||
<dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
|
||||
<dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
|
||||
|
||||
</resources>
|
@ -0,0 +1 @@
|
||||
rootProject.name = "lokinet"
|
@ -0,0 +1,157 @@
|
||||
package network.loki.lokinet;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.net.URL;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.ServiceConnection;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import android.os.IBinder;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.TextView;
|
||||
|
||||
|
||||
public class LokiNetActivity extends Activity {
|
||||
private static final String TAG = "lokinet-activity";
|
||||
private TextView textView;
|
||||
private static final String DefaultBootstrapURL = "https://seed.lokinet.org/bootstrap.signed";
|
||||
|
||||
private AsyncBootstrap bootstrapper;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
textView = new TextView(this);
|
||||
setContentView(textView);
|
||||
System.loadLibrary("lokinetandroid");
|
||||
}
|
||||
|
||||
|
||||
private static void writeFile(File out, InputStream instream) throws IOException {
|
||||
OutputStream outstream = new FileOutputStream(out);
|
||||
byte[] buffer = new byte[512];
|
||||
int len;
|
||||
try {
|
||||
do {
|
||||
len = instream.read(buffer);
|
||||
if (len > 0) {
|
||||
outstream.write(buffer, 0, len);
|
||||
}
|
||||
}
|
||||
while (len != -1);
|
||||
} finally {
|
||||
outstream.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void startLokinet()
|
||||
{
|
||||
if(bootstrapper != null)
|
||||
return;
|
||||
bootstrapper = new AsyncBootstrap();
|
||||
bootstrapper.execute(DefaultBootstrapURL);
|
||||
}
|
||||
|
||||
|
||||
public void runLokinetService()
|
||||
{
|
||||
startService(new Intent(LokiNetActivity.this,
|
||||
LokinetService.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
textView = null;
|
||||
}
|
||||
|
||||
public File getRootDir()
|
||||
{
|
||||
return getFilesDir();
|
||||
}
|
||||
|
||||
private class AsyncBootstrap extends AsyncTask<String, String, String>
|
||||
{
|
||||
public String doInBackground(String ... urls) {
|
||||
try
|
||||
{
|
||||
File bootstrapFile = new File(getRootDir(), "bootstrap.signed");
|
||||
URL bootstrapURL = new URL(urls[0]);
|
||||
InputStream instream = bootstrapURL.openStream();
|
||||
writeFile(bootstrapFile, instream);
|
||||
instream.close();
|
||||
return getString(R.string.bootstrap_ok);
|
||||
}
|
||||
catch(Exception thrown)
|
||||
{
|
||||
return getString(R.string.bootstrap_fail) + ": " + throwableToString(thrown);
|
||||
}
|
||||
}
|
||||
public void onPostExecute(String val) {
|
||||
textView.setText(val);
|
||||
if(val.equals(getString(R.string.bootstrap_ok)))
|
||||
runLokinetService();
|
||||
bootstrapDone();
|
||||
}
|
||||
}
|
||||
|
||||
private void bootstrapDone()
|
||||
{
|
||||
bootstrapper = null;
|
||||
}
|
||||
|
||||
private CharSequence throwableToString(Throwable tr) {
|
||||
StringWriter sw = new StringWriter(8192);
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
tr.printStackTrace(pw);
|
||||
pw.close();
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
getMenuInflater().inflate(R.menu.options_main, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
// Handle action bar item clicks here. The action bar will
|
||||
// automatically handle clicks on the Home/Up button, so long
|
||||
// as you specify a parent activity in AndroidManifest.xml.
|
||||
int id = item.getItemId();
|
||||
|
||||
switch(id){
|
||||
case R.id.action_start:
|
||||
startLokinet();
|
||||
return true;
|
||||
case R.id.action_stop:
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package network.loki.lokinet;
|
||||
|
||||
|
||||
import android.net.VpnService;
|
||||
|
||||
public class LokinetService extends VpnService
|
||||
{
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package network.loki.lokinet;
|
||||
|
||||
import android.util.Log;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
|
||||
public class NetworkStateChangeReceiver extends BroadcastReceiver {
|
||||
|
||||
private static final String TAG = "lokinet";
|
||||
|
||||
//api level 1
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
Log.d(TAG,"Network state change");
|
||||
try {
|
||||
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo();
|
||||
boolean isConnected = activeNetworkInfo!=null && activeNetworkInfo.isConnected();
|
||||
// https://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html?hl=ru
|
||||
// boolean isWiFi = activeNetworkInfo!=null && (activeNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI);
|
||||
} catch (Throwable tr) {
|
||||
Log.d(TAG,"",tr);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,173 @@
|
||||
package network.loki.lokinet;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
//dangerous perms, per https://developer.android.com/guide/topics/permissions/normal-permissions.html :
|
||||
//android.permission.WRITE_EXTERNAL_STORAGE
|
||||
public class PermsAskerActivity extends Activity {
|
||||
|
||||
private static final int PERMISSION_VPN = 0;
|
||||
|
||||
private Button button_request_write_ext_storage_perms;
|
||||
private TextView textview_retry;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
startMainActivity();
|
||||
/*
|
||||
//if less than Android 6, no runtime perms req system present
|
||||
if (android.os.Build.VERSION.SDK_INT < 23) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
setContentView(R.layout.activity_perms_asker);
|
||||
button_request_write_ext_storage_perms = (Button) findViewById(R.id.button_request_write_ext_storage_perms);
|
||||
textview_retry = (TextView) findViewById(R.id.textview_retry);
|
||||
|
||||
button_request_write_ext_storage_perms.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
request_write_ext_storage_perms();
|
||||
}
|
||||
});
|
||||
request_write_ext_storage_perms();
|
||||
*/
|
||||
}
|
||||
|
||||
private void request_write_ext_storage_perms() {
|
||||
|
||||
textview_retry.setVisibility(TextView.GONE);
|
||||
button_request_write_ext_storage_perms.setVisibility(Button.GONE);
|
||||
|
||||
Method methodCheckPermission;
|
||||
Method method_shouldShowRequestPermissionRationale;
|
||||
Method method_requestPermissions;
|
||||
try {
|
||||
methodCheckPermission = getClass().getMethod("checkSelfPermission", String.class);
|
||||
method_shouldShowRequestPermissionRationale =
|
||||
getClass().getMethod("shouldShowRequestPermissionRationale", String.class);
|
||||
method_requestPermissions =
|
||||
getClass().getMethod("requestPermissions", String[].class, int.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
Integer resultObj;
|
||||
try {
|
||||
resultObj = (Integer) methodCheckPermission.invoke(
|
||||
this, Manifest.permission.BIND_VPN_SERVICE);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
if (resultObj != PackageManager.PERMISSION_GRANTED) {
|
||||
|
||||
// Should we show an explanation?
|
||||
Boolean aBoolean;
|
||||
try {
|
||||
aBoolean = (Boolean) method_shouldShowRequestPermissionRationale.invoke(this,
|
||||
Manifest.permission.BIND_VPN_SERVICE);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (aBoolean) {
|
||||
|
||||
// Show an explanation to the user *asynchronously* -- don't block
|
||||
// this thread waiting for the user's response! After the user
|
||||
// sees the explanation, try again to request the permission.
|
||||
|
||||
showExplanation();
|
||||
|
||||
} else {
|
||||
|
||||
// No explanation needed, we can request the permission.
|
||||
|
||||
try {
|
||||
method_requestPermissions.invoke(this,
|
||||
new String[]{Manifest.permission.BIND_VPN_SERVICE},
|
||||
PERMISSION_VPN);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
} else startMainActivity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode,
|
||||
String permissions[], int[] grantResults) {
|
||||
switch (requestCode) {
|
||||
case PERMISSION_VPN: {
|
||||
// If request is cancelled, the result arrays are empty.
|
||||
if (grantResults.length > 0
|
||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
|
||||
// permission was granted, yay! Do the
|
||||
// contacts-related task you need to do.
|
||||
|
||||
startMainActivity();
|
||||
|
||||
} else {
|
||||
|
||||
// permission denied, boo! Disable the
|
||||
// functionality that depends on this permission.
|
||||
textview_retry.setText("you need to allow this to continue");
|
||||
textview_retry.setVisibility(TextView.VISIBLE);
|
||||
button_request_write_ext_storage_perms.setVisibility(Button.VISIBLE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// other 'case' lines to check for other
|
||||
// permissions this app might request.
|
||||
}
|
||||
}
|
||||
|
||||
private void startMainActivity() {
|
||||
startActivity(new Intent(this, LokiNetActivity.class));
|
||||
finish();
|
||||
}
|
||||
|
||||
private static final int SHOW_EXPLANATION_REQUEST = 1; // The request code
|
||||
private void showExplanation() {
|
||||
Intent intent = new Intent(this, PermsExplanationActivity.class);
|
||||
startActivityForResult(intent, SHOW_EXPLANATION_REQUEST);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
// Check which request we're responding to
|
||||
if (requestCode == SHOW_EXPLANATION_REQUEST) {
|
||||
// Make sure the request was successful
|
||||
if (resultCode == RESULT_OK) {
|
||||
// Request the permission
|
||||
Method method_requestPermissions;
|
||||
try {
|
||||
method_requestPermissions =
|
||||
getClass().getMethod("requestPermissions", String[].class, int.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
try {
|
||||
method_requestPermissions.invoke(this,
|
||||
new String[]{Manifest.permission.BIND_VPN_SERVICE},
|
||||
PERMISSION_VPN);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
finish(); //close the app
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package network.loki.lokinet;
|
||||
|
||||
import android.app.ActionBar;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.app.Activity;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
public class PermsExplanationActivity extends Activity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_perms_explanation);
|
||||
ActionBar actionBar = getActionBar();
|
||||
if(actionBar!=null)actionBar.setHomeButtonEnabled(false);
|
||||
Button button_ok = (Button) findViewById(R.id.button_ok);
|
||||
button_ok.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
returnFromActivity();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void returnFromActivity() {
|
||||
Intent data = new Intent();
|
||||
Activity parent = getParent();
|
||||
if (parent == null) {
|
||||
setResult(Activity.RESULT_OK, data);
|
||||
} else {
|
||||
parent.setResult(Activity.RESULT_OK, data);
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
|
||||
int
|
||||
main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[])
|
||||
{
|
||||
return 0;
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
set(LIBCURL_PREFIX ${CMAKE_BINARY_DIR}/libcurl)
|
||||
set(LIBCURL_URL https://github.com/curl/curl/releases/download/curl-7_67_0/curl-7.67.0.tar.xz)
|
||||
set(LIBCURL_HASH SHA256=f5d2e7320379338c3952dcc7566a140abb49edb575f9f99272455785c40e536c)
|
||||
|
||||
if(CURL_TARBALL_URL)
|
||||
# make a build time override of the tarball url so we can fetch it if the original link goes away
|
||||
set(LIBCURL_URL ${CURL_TARBALL_URL})
|
||||
endif()
|
||||
|
||||
|
||||
file(MAKE_DIRECTORY ${LIBCURL_PREFIX}/include)
|
||||
|
||||
include(ExternalProject)
|
||||
include(ProcessorCount)
|
||||
ProcessorCount(PROCESSOR_COUNT)
|
||||
if(PROCESSOR_COUNT EQUAL 0)
|
||||
set(PROCESSOR_COUNT 1)
|
||||
endif()
|
||||
|
||||
set(libcurl_cc ${CMAKE_C_COMPILER})
|
||||
if(CCACHE_PROGRAM)
|
||||
set(libcurl_cc "${CCACHE_PROGRAM} ${libcurl_cc}")
|
||||
endif()
|
||||
set(CURL_CONFIGURE ./configure --prefix=${LIBCURL_PREFIX}
|
||||
--without-ssl --without-nss --without-gnutls --without-mbedtls --without-wolfssl --without-mesalink
|
||||
--without-bearssl --without-ca-bundle --without-libidn2 --without-zlib --without-nghttp2 --without-nghttp3
|
||||
--without-quiche --without-zsh-functions-dir --without-fish-functions-dir
|
||||
--without-librtmp --without-ca-fallback --without-ca-path --without-brotli --without-libpsl
|
||||
--disable-manual --disable-dict --disable-file --disable-ftp --disable-gopher --disable-imap --disable-ldap --disable-ldaps
|
||||
--disable-pop3 --disable-rtsp --disable-smtp --disable-telnet --disable-tftp
|
||||
--enable-static --disable-shared CC=${libcurl_cc})
|
||||
|
||||
if (CMAKE_C_COMPILER_ARG1)
|
||||
set(CURL_CONFIGURE ${CURL_CONFIGURE} CPPFLAGS=${CMAKE_C_COMPILER_ARG1})
|
||||
endif()
|
||||
|
||||
if (CROSS_TARGET)
|
||||
set(CURL_CONFIGURE ${CURL_CONFIGURE} --target=${CROSS_TARGET} --host=${CROSS_TARGET})
|
||||
endif()
|
||||
|
||||
|
||||
ExternalProject_Add(libcurl_external
|
||||
BUILD_IN_SOURCE ON
|
||||
PREFIX ${LIBCURL_PREFIX}
|
||||
URL ${LIBCURL_URL}
|
||||
URL_HASH ${LIBCURL_HASH}
|
||||
CONFIGURE_COMMAND ${CURL_CONFIGURE}
|
||||
BUILD_COMMAND make -j${PROCESSOR_COUNT}
|
||||
BUILD_BYPRODUCTS ${LIBCURL_PREFIX}/lib/libcurl.a ${LIBCURL_PREFIX}/include
|
||||
)
|
||||
|
||||
add_library(curl_vendor STATIC IMPORTED GLOBAL)
|
||||
add_dependencies(curl_vendor curl_external)
|
||||
set_target_properties(curl_vendor PROPERTIES
|
||||
IMPORTED_LOCATION ${LIBCURL_PREFIX}/lib/libcurl.a
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${LIBCURL_PREFIX}/include
|
||||
)
|
@ -1,57 +0,0 @@
|
||||
#
|
||||
# Find the JEMALLOC client includes and library
|
||||
#
|
||||
|
||||
# This module defines
|
||||
# JEMALLOC_INCLUDE_DIR, where to find jemalloc.h
|
||||
# JEMALLOC_LIBRARIES, the libraries to link against
|
||||
# JEMALLOC_FOUND, if false, you cannot build anything that requires JEMALLOC
|
||||
|
||||
# also defined, but not for general use are
|
||||
# JEMALLOC_LIBRARY, where to find the JEMALLOC library.
|
||||
|
||||
set( JEMALLOC_FOUND 0 )
|
||||
|
||||
if ( UNIX )
|
||||
FIND_PATH( JEMALLOC_INCLUDE_DIR
|
||||
NAMES
|
||||
jemalloc/jemalloc.h
|
||||
PATHS
|
||||
/usr/include
|
||||
/usr/include/jemalloc
|
||||
/usr/local/include
|
||||
/usr/local/include/jemalloc
|
||||
$ENV{JEMALLOC_ROOT}
|
||||
$ENV{JEMALLOC_ROOT}/include
|
||||
DOC
|
||||
"Specify include-directories that might contain jemalloc.h here."
|
||||
)
|
||||
FIND_LIBRARY( JEMALLOC_LIBRARY
|
||||
NAMES
|
||||
jemalloc libjemalloc JEMALLOC
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/lib/jemalloc
|
||||
/usr/local/lib
|
||||
/usr/local/lib/jemalloc
|
||||
/usr/local/jemalloc/lib
|
||||
$ENV{JEMALLOC_ROOT}/lib
|
||||
$ENV{JEMALLOC_ROOT}
|
||||
DOC "Specify library-locations that might contain the jemalloc library here."
|
||||
)
|
||||
|
||||
if ( JEMALLOC_LIBRARY )
|
||||
if ( JEMALLOC_INCLUDE_DIR )
|
||||
set( JEMALLOC_FOUND 1 )
|
||||
message( STATUS "Found JEMALLOC library: ${JEMALLOC_LIBRARY}")
|
||||
message( STATUS "Found JEMALLOC headers: ${JEMALLOC_INCLUDE_DIR}")
|
||||
else ( JEMALLOC_INCLUDE_DIR )
|
||||
message(FATAL_ERROR "Could not find jemalloc headers! Please install jemalloc libraries and headers")
|
||||
endif ( JEMALLOC_INCLUDE_DIR )
|
||||
endif ( JEMALLOC_LIBRARY )
|
||||
add_library(jemalloc SHARED IMPORTED)
|
||||
set_target_properties(jemalloc PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${JEMALLOC_INCLUDE_DUR}"
|
||||
IMPORTED_LOCATION "${JEMALLOC_LIBRARY}")
|
||||
mark_as_advanced( JEMALLOC_FOUND JEMALLOC_LIBRARY JEMALLOC_EXTRA_LIBRARIES JEMALLOC_INCLUDE_DIR )
|
||||
endif (UNIX)
|
@ -0,0 +1,288 @@
|
||||
# Written in 2016 by Henrik Steffen Gaßmann <henrik@gassmann.onl>
|
||||
#
|
||||
# To the extent possible under law, the author(s) have dedicated all
|
||||
# copyright and related and neighboring rights to this software to the
|
||||
# public domain worldwide. This software is distributed without any warranty.
|
||||
#
|
||||
# You should have received a copy of the CC0 Public Domain Dedication
|
||||
# along with this software. If not, see
|
||||
#
|
||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
||||
#
|
||||
########################################################################
|
||||
# Tries to find the local libsodium installation.
|
||||
#
|
||||
# On Windows the sodium_DIR environment variable is used as a default
|
||||
# hint which can be overridden by setting the corresponding cmake variable.
|
||||
#
|
||||
# Once done the following variables will be defined:
|
||||
#
|
||||
# sodium_FOUND
|
||||
# sodium_INCLUDE_DIR
|
||||
# sodium_LIBRARY_DEBUG
|
||||
# sodium_LIBRARY_RELEASE
|
||||
#
|
||||
#
|
||||
# Furthermore an imported "sodium" target is created.
|
||||
#
|
||||
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU"
|
||||
OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
set(_GCC_COMPATIBLE 1)
|
||||
endif()
|
||||
|
||||
# static library option
|
||||
if (NOT DEFINED sodium_USE_STATIC_LIBS)
|
||||
option(sodium_USE_STATIC_LIBS "enable to statically link against sodium" OFF)
|
||||
endif()
|
||||
if(NOT (sodium_USE_STATIC_LIBS EQUAL sodium_USE_STATIC_LIBS_LAST))
|
||||
unset(sodium_LIBRARY CACHE)
|
||||
unset(sodium_LIBRARY_DEBUG CACHE)
|
||||
unset(sodium_LIBRARY_RELEASE CACHE)
|
||||
unset(sodium_DLL_DEBUG CACHE)
|
||||
unset(sodium_DLL_RELEASE CACHE)
|
||||
set(sodium_USE_STATIC_LIBS_LAST ${sodium_USE_STATIC_LIBS} CACHE INTERNAL "internal change tracking variable")
|
||||
endif()
|
||||
|
||||
|
||||
########################################################################
|
||||
# UNIX
|
||||
if (UNIX)
|
||||
# import pkg-config
|
||||
find_package(PkgConfig QUIET)
|
||||
if (PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(sodium_PKG QUIET libsodium>=${Sodium_FIND_VERSION})
|
||||
endif()
|
||||
|
||||
if(sodium_USE_STATIC_LIBS)
|
||||
foreach(_libname ${sodium_PKG_STATIC_LIBRARIES})
|
||||
if (NOT _libname MATCHES "^lib.*\\.a$") # ignore strings already ending with .a
|
||||
list(INSERT sodium_PKG_STATIC_LIBRARIES 0 "lib${_libname}.a")
|
||||
endif()
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES sodium_PKG_STATIC_LIBRARIES)
|
||||
|
||||
# if pkgconfig for libsodium doesn't provide
|
||||
# static lib info, then override PKG_STATIC here..
|
||||
if (sodium_PKG_STATIC_LIBRARIES STREQUAL "")
|
||||
set(sodium_PKG_STATIC_LIBRARIES libsodium.a)
|
||||
endif()
|
||||
|
||||
set(XPREFIX sodium_PKG_STATIC)
|
||||
else()
|
||||
if (sodium_PKG_LIBRARIES STREQUAL "")
|
||||
set(sodium_PKG_LIBRARIES sodium)
|
||||
endif()
|
||||
|
||||
set(XPREFIX sodium_PKG)
|
||||
endif()
|
||||
|
||||
find_path(sodium_INCLUDE_DIR sodium.h
|
||||
HINTS ${${XPREFIX}_INCLUDE_DIRS} /usr/local/include
|
||||
)
|
||||
find_library(sodium_LIBRARY_DEBUG NAMES ${${XPREFIX}_LIBRARIES}
|
||||
HINTS ${${XPREFIX}_LIBRARY_DIRS} /usr/local/lib
|
||||
)
|
||||
find_library(sodium_LIBRARY_RELEASE NAMES ${${XPREFIX}_LIBRARIES}
|
||||
HINTS ${${XPREFIX}_LIBRARY_DIRS} /usr/local/lib
|
||||
)
|
||||
|
||||
|
||||
########################################################################
|
||||
# Windows
|
||||
elseif (WIN32)
|
||||
set(sodium_DIR "$ENV{sodium_DIR}" CACHE FILEPATH "sodium install directory")
|
||||
mark_as_advanced(sodium_DIR)
|
||||
|
||||
find_path(sodium_INCLUDE_DIR sodium.h
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES include
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
# detect target architecture
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/arch.c" [=[
|
||||
#if defined _M_IX86
|
||||
#error ARCH_VALUE x86_32
|
||||
#elif defined _M_X64
|
||||
#error ARCH_VALUE x86_64
|
||||
#endif
|
||||
#error ARCH_VALUE unknown
|
||||
]=])
|
||||
try_compile(_UNUSED_VAR "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/arch.c"
|
||||
OUTPUT_VARIABLE _COMPILATION_LOG
|
||||
)
|
||||
string(REGEX REPLACE ".*ARCH_VALUE ([a-zA-Z0-9_]+).*" "\\1" _TARGET_ARCH "${_COMPILATION_LOG}")
|
||||
|
||||
# construct library path
|
||||
if (_TARGET_ARCH STREQUAL "x86_32")
|
||||
string(APPEND _PLATFORM_PATH "Win32")
|
||||
elseif(_TARGET_ARCH STREQUAL "x86_64")
|
||||
string(APPEND _PLATFORM_PATH "x64")
|
||||
else()
|
||||
message(FATAL_ERROR "the ${_TARGET_ARCH} architecture is not supported by Findsodium.cmake.")
|
||||
endif()
|
||||
string(APPEND _PLATFORM_PATH "/$$CONFIG$$")
|
||||
|
||||
if (MSVC_VERSION LESS 1900)
|
||||
math(EXPR _VS_VERSION "${MSVC_VERSION} / 10 - 60")
|
||||
else()
|
||||
math(EXPR _VS_VERSION "${MSVC_VERSION} / 10 - 50")
|
||||
endif()
|
||||
string(APPEND _PLATFORM_PATH "/v${_VS_VERSION}")
|
||||
|
||||
if (sodium_USE_STATIC_LIBS)
|
||||
string(APPEND _PLATFORM_PATH "/static")
|
||||
else()
|
||||
string(APPEND _PLATFORM_PATH "/dynamic")
|
||||
endif()
|
||||
|
||||
string(REPLACE "$$CONFIG$$" "Debug" _DEBUG_PATH_SUFFIX "${_PLATFORM_PATH}")
|
||||
string(REPLACE "$$CONFIG$$" "Release" _RELEASE_PATH_SUFFIX "${_PLATFORM_PATH}")
|
||||
|
||||
find_library(sodium_LIBRARY_DEBUG libsodium.lib
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES ${_DEBUG_PATH_SUFFIX}
|
||||
)
|
||||
find_library(sodium_LIBRARY_RELEASE libsodium.lib
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES ${_RELEASE_PATH_SUFFIX}
|
||||
)
|
||||
if (NOT sodium_USE_STATIC_LIBS)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES_BCK ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll")
|
||||
find_library(sodium_DLL_DEBUG libsodium
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES ${_DEBUG_PATH_SUFFIX}
|
||||
)
|
||||
find_library(sodium_DLL_RELEASE libsodium
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES ${_RELEASE_PATH_SUFFIX}
|
||||
)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_BCK})
|
||||
endif()
|
||||
|
||||
elseif(_GCC_COMPATIBLE)
|
||||
if (sodium_USE_STATIC_LIBS)
|
||||
find_library(sodium_LIBRARY_DEBUG libsodium.a
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES lib
|
||||
)
|
||||
find_library(sodium_LIBRARY_RELEASE libsodium.a
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES lib
|
||||
)
|
||||
else()
|
||||
find_library(sodium_LIBRARY_DEBUG libsodium.dll.a
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES lib
|
||||
)
|
||||
find_library(sodium_LIBRARY_RELEASE libsodium.dll.a
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES lib
|
||||
)
|
||||
|
||||
file(GLOB _DLL
|
||||
LIST_DIRECTORIES false
|
||||
RELATIVE "${sodium_DIR}/bin"
|
||||
"${sodium_DIR}/bin/libsodium*.dll"
|
||||
)
|
||||
find_library(sodium_DLL_DEBUG ${_DLL} libsodium
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES bin
|
||||
)
|
||||
find_library(sodium_DLL_RELEASE ${_DLL} libsodium
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES bin
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "this platform is not supported by FindSodium.cmake")
|
||||
endif()
|
||||
|
||||
|
||||
########################################################################
|
||||
# unsupported
|
||||
else()
|
||||
message(FATAL_ERROR "this platform is not supported by FindSodium.cmake")
|
||||
endif()
|
||||
|
||||
|
||||
########################################################################
|
||||
# common stuff
|
||||
|
||||
# extract sodium version
|
||||
if (sodium_INCLUDE_DIR)
|
||||
set(_VERSION_HEADER "${sodium_INCLUDE_DIR}/sodium/version.h")
|
||||
if (EXISTS "${_VERSION_HEADER}")
|
||||
file(READ "${_VERSION_HEADER}" _VERSION_HEADER_CONTENT)
|
||||
string(REGEX REPLACE ".*#[ \t]*define[ \t]*SODIUM_VERSION_STRING[ \t]*\"([^\n]*)\".*" "\\1"
|
||||
sodium_VERSION "${_VERSION_HEADER_CONTENT}")
|
||||
set(sodium_VERSION "${sodium_VERSION}" PARENT_SCOPE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# communicate results
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(sodium
|
||||
REQUIRED_VARS
|
||||
sodium_LIBRARY_RELEASE
|
||||
sodium_LIBRARY_DEBUG
|
||||
sodium_INCLUDE_DIR
|
||||
VERSION_VAR
|
||||
sodium_VERSION
|
||||
)
|
||||
|
||||
# mark file paths as advanced
|
||||
mark_as_advanced(sodium_INCLUDE_DIR)
|
||||
mark_as_advanced(sodium_LIBRARY_DEBUG)
|
||||
mark_as_advanced(sodium_LIBRARY_RELEASE)
|
||||
if (WIN32)
|
||||
mark_as_advanced(sodium_DLL_DEBUG)
|
||||
mark_as_advanced(sodium_DLL_RELEASE)
|
||||
endif()
|
||||
|
||||
# create imported target
|
||||
if(sodium_USE_STATIC_LIBS)
|
||||
set(_LIB_TYPE STATIC)
|
||||
else()
|
||||
set(_LIB_TYPE SHARED)
|
||||
endif()
|
||||
add_library(sodium ${_LIB_TYPE} IMPORTED)
|
||||
|
||||
set_target_properties(sodium PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${sodium_INCLUDE_DIR}"
|
||||
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
|
||||
)
|
||||
|
||||
if (sodium_USE_STATIC_LIBS)
|
||||
set_target_properties(sodium PROPERTIES
|
||||
INTERFACE_COMPILE_DEFINITIONS "SODIUM_STATIC"
|
||||
IMPORTED_LOCATION "${sodium_LIBRARY_RELEASE}"
|
||||
IMPORTED_LOCATION_DEBUG "${sodium_LIBRARY_DEBUG}"
|
||||
)
|
||||
else()
|
||||
if (UNIX)
|
||||
set_target_properties(sodium PROPERTIES
|
||||
IMPORTED_LOCATION "${sodium_LIBRARY_RELEASE}"
|
||||
IMPORTED_LOCATION_DEBUG "${sodium_LIBRARY_DEBUG}"
|
||||
)
|
||||
elseif (WIN32)
|
||||
set_target_properties(sodium PROPERTIES
|
||||
IMPORTED_IMPLIB "${sodium_LIBRARY_RELEASE}"
|
||||
IMPORTED_IMPLIB_DEBUG "${sodium_LIBRARY_DEBUG}"
|
||||
)
|
||||
if (NOT (sodium_DLL_DEBUG MATCHES ".*-NOTFOUND"))
|
||||
set_target_properties(sodium PROPERTIES
|
||||
IMPORTED_LOCATION_DEBUG "${sodium_DLL_DEBUG}"
|
||||
)
|
||||
endif()
|
||||
if (NOT (sodium_DLL_RELEASE MATCHES ".*-NOTFOUND"))
|
||||
set_target_properties(sodium PROPERTIES
|
||||
IMPORTED_LOCATION_RELWITHDEBINFO "${sodium_DLL_RELEASE}"
|
||||
IMPORTED_LOCATION_MINSIZEREL "${sodium_DLL_RELEASE}"
|
||||
IMPORTED_LOCATION_RELEASE "${sodium_DLL_RELEASE}"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
@ -1,482 +0,0 @@
|
||||
# cmake bits to do a full static build, downloading and building all dependencies.
|
||||
|
||||
# Most of these are CACHE STRINGs so that you can override them using -DWHATEVER during cmake
|
||||
# invocation to override.
|
||||
|
||||
set(LOCAL_MIRROR "" CACHE STRING "local mirror path/URL for lib downloads")
|
||||
|
||||
set(OPENSSL_VERSION 3.0.7 CACHE STRING "openssl version")
|
||||
set(OPENSSL_MIRROR ${LOCAL_MIRROR} https://www.openssl.org/source CACHE STRING "openssl download mirror(s)")
|
||||
set(OPENSSL_SOURCE openssl-${OPENSSL_VERSION}.tar.gz)
|
||||
set(OPENSSL_HASH SHA256=83049d042a260e696f62406ac5c08bf706fd84383f945cf21bd61e9ed95c396e
|
||||
CACHE STRING "openssl source hash")
|
||||
|
||||
set(EXPAT_VERSION 2.5.0 CACHE STRING "expat version")
|
||||
string(REPLACE "." "_" EXPAT_TAG "R_${EXPAT_VERSION}")
|
||||
set(EXPAT_MIRROR ${LOCAL_MIRROR} https://github.com/libexpat/libexpat/releases/download/${EXPAT_TAG}
|
||||
CACHE STRING "expat download mirror(s)")
|
||||
set(EXPAT_SOURCE expat-${EXPAT_VERSION}.tar.xz)
|
||||
set(EXPAT_HASH SHA512=2da73b991b7c0c54440485c787e5edeb3567230204e31b3cac1c3a6713ec6f9f1554d3afffc0f8336168dfd5df02db4a69bcf21b4d959723d14162d13ab87516
|
||||
CACHE STRING "expat source hash")
|
||||
|
||||
set(UNBOUND_VERSION 1.17.0 CACHE STRING "unbound version")
|
||||
set(UNBOUND_MIRROR ${LOCAL_MIRROR} https://nlnetlabs.nl/downloads/unbound CACHE STRING "unbound download mirror(s)")
|
||||
set(UNBOUND_SOURCE unbound-${UNBOUND_VERSION}.tar.gz)
|
||||
set(UNBOUND_HASH SHA512=f6b9f279330fb19b5feca09524959940aad8c4e064528aa82b369c726d77e9e8e5ca23f366f6e9edcf2c061b96f482ed7a2c26ac70fc15ae5762b3d7e36a5284
|
||||
CACHE STRING "unbound source hash")
|
||||
|
||||
set(SQLITE3_VERSION 3400000 CACHE STRING "sqlite3 version")
|
||||
set(SQLITE3_MIRROR ${LOCAL_MIRROR} https://www.sqlite.org/2022
|
||||
CACHE STRING "sqlite3 download mirror(s)")
|
||||
set(SQLITE3_SOURCE sqlite-autoconf-${SQLITE3_VERSION}.tar.gz)
|
||||
set(SQLITE3_HASH SHA3_256=7ee8f02b21edb4489df5082b5cf5b7ef47bcebcdb0e209bf14240db69633c878
|
||||
CACHE STRING "sqlite3 source hash")
|
||||
|
||||
set(SODIUM_VERSION 1.0.18 CACHE STRING "libsodium version")
|
||||
set(SODIUM_MIRROR ${LOCAL_MIRROR}
|
||||
https://download.libsodium.org/libsodium/releases
|
||||
https://github.com/jedisct1/libsodium/releases/download/${SODIUM_VERSION}-RELEASE
|
||||
CACHE STRING "libsodium mirror(s)")
|
||||
set(SODIUM_SOURCE libsodium-${SODIUM_VERSION}.tar.gz)
|
||||
set(SODIUM_HASH SHA512=17e8638e46d8f6f7d024fe5559eccf2b8baf23e143fadd472a7d29d228b186d86686a5e6920385fe2020729119a5f12f989c3a782afbd05a8db4819bb18666ef
|
||||
CACHE STRING "libsodium source hash")
|
||||
|
||||
set(ZMQ_VERSION 4.3.4 CACHE STRING "libzmq version")
|
||||
set(ZMQ_MIRROR ${LOCAL_MIRROR} https://github.com/zeromq/libzmq/releases/download/v${ZMQ_VERSION}
|
||||
CACHE STRING "libzmq mirror(s)")
|
||||
set(ZMQ_SOURCE zeromq-${ZMQ_VERSION}.tar.gz)
|
||||
set(ZMQ_HASH SHA512=e198ef9f82d392754caadd547537666d4fba0afd7d027749b3adae450516bcf284d241d4616cad3cb4ad9af8c10373d456de92dc6d115b037941659f141e7c0e
|
||||
CACHE STRING "libzmq source hash")
|
||||
|
||||
set(LIBUV_VERSION 1.44.2 CACHE STRING "libuv version")
|
||||
set(LIBUV_MIRROR ${LOCAL_MIRROR} https://dist.libuv.org/dist/v${LIBUV_VERSION}
|
||||
CACHE STRING "libuv mirror(s)")
|
||||
set(LIBUV_SOURCE libuv-v${LIBUV_VERSION}.tar.gz)
|
||||
set(LIBUV_HASH SHA512=91197ff9303112567bbb915bbb88058050e2ad1c048815a3b57c054635d5dc7df458b956089d785475290132236cb0edcfae830f5d749de29a9a3213eeaf0b20
|
||||
CACHE STRING "libuv source hash")
|
||||
|
||||
set(ZLIB_VERSION 1.2.13 CACHE STRING "zlib version")
|
||||
set(ZLIB_MIRROR ${LOCAL_MIRROR} https://zlib.net
|
||||
CACHE STRING "zlib mirror(s)")
|
||||
set(ZLIB_SOURCE zlib-${ZLIB_VERSION}.tar.xz)
|
||||
set(ZLIB_HASH SHA256=d14c38e313afc35a9a8760dadf26042f51ea0f5d154b0630a31da0540107fb98
|
||||
CACHE STRING "zlib source hash")
|
||||
|
||||
set(CURL_VERSION 7.86.0 CACHE STRING "curl version")
|
||||
set(CURL_MIRROR ${LOCAL_MIRROR} https://curl.haxx.se/download https://curl.askapache.com
|
||||
CACHE STRING "curl mirror(s)")
|
||||
set(CURL_SOURCE curl-${CURL_VERSION}.tar.xz)
|
||||
set(CURL_HASH SHA512=18e03a3c00f22125e07bddb18becbf5acdca22baeb7b29f45ef189a5c56f95b2d51247813f7a9a90f04eb051739e9aa7d3a1c5be397bae75d763a2b918d1b656
|
||||
CACHE STRING "curl source hash")
|
||||
|
||||
include(ExternalProject)
|
||||
|
||||
set(DEPS_DESTDIR ${CMAKE_BINARY_DIR}/static-deps)
|
||||
set(DEPS_SOURCEDIR ${CMAKE_BINARY_DIR}/static-deps-sources)
|
||||
|
||||
include_directories(BEFORE SYSTEM ${DEPS_DESTDIR}/include)
|
||||
|
||||
file(MAKE_DIRECTORY ${DEPS_DESTDIR}/include)
|
||||
|
||||
set(deps_cc "${CMAKE_C_COMPILER}")
|
||||
set(deps_cxx "${CMAKE_CXX_COMPILER}")
|
||||
if(CMAKE_C_COMPILER_LAUNCHER)
|
||||
set(deps_cc "${CMAKE_C_COMPILER_LAUNCHER} ${deps_cc}")
|
||||
endif()
|
||||
if(CMAKE_CXX_COMPILER_LAUNCHER)
|
||||
set(deps_cxx "${CMAKE_CXX_COMPILER_LAUNCHER} ${deps_cxx}")
|
||||
endif()
|
||||
|
||||
|
||||
function(expand_urls output source_file)
|
||||
set(expanded)
|
||||
foreach(mirror ${ARGN})
|
||||
list(APPEND expanded "${mirror}/${source_file}")
|
||||
endforeach()
|
||||
set(${output} "${expanded}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(add_static_target target ext_target libname)
|
||||
add_library(${target} STATIC IMPORTED GLOBAL)
|
||||
add_dependencies(${target} ${ext_target})
|
||||
set_target_properties(${target} PROPERTIES
|
||||
IMPORTED_LOCATION ${DEPS_DESTDIR}/lib/${libname}
|
||||
)
|
||||
endfunction()
|
||||
|
||||
|
||||
|
||||
set(cross_host "")
|
||||
set(cross_rc "")
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
set(cross_host "--host=${ARCH_TRIPLET}")
|
||||
if (ARCH_TRIPLET MATCHES mingw AND CMAKE_RC_COMPILER)
|
||||
set(cross_rc "WINDRES=${CMAKE_RC_COMPILER}")
|
||||
endif()
|
||||
endif()
|
||||
if(ANDROID)
|
||||
set(android_toolchain_suffix linux-android)
|
||||
set(android_compiler_suffix linux-android23)
|
||||
if(CMAKE_ANDROID_ARCH_ABI MATCHES x86_64)
|
||||
set(android_machine x86_64)
|
||||
set(cross_host "--host=x86_64-linux-android")
|
||||
set(android_compiler_prefix x86_64)
|
||||
set(android_compiler_suffix linux-android23)
|
||||
set(android_toolchain_prefix x86_64)
|
||||
set(android_toolchain_suffix linux-android)
|
||||
elseif(CMAKE_ANDROID_ARCH_ABI MATCHES x86)
|
||||
set(android_machine x86)
|
||||
set(cross_host "--host=i686-linux-android")
|
||||
set(android_compiler_prefix i686)
|
||||
set(android_compiler_suffix linux-android23)
|
||||
set(android_toolchain_prefix i686)
|
||||
set(android_toolchain_suffix linux-android)
|
||||
elseif(CMAKE_ANDROID_ARCH_ABI MATCHES armeabi-v7a)
|
||||
set(android_machine arm)
|
||||
set(cross_host "--host=armv7a-linux-androideabi")
|
||||
set(android_compiler_prefix armv7a)
|
||||
set(android_compiler_suffix linux-androideabi23)
|
||||
set(android_toolchain_prefix arm)
|
||||
set(android_toolchain_suffix linux-androideabi)
|
||||
elseif(CMAKE_ANDROID_ARCH_ABI MATCHES arm64-v8a)
|
||||
set(android_machine arm64)
|
||||
set(cross_host "--host=aarch64-linux-android")
|
||||
set(android_compiler_prefix aarch64)
|
||||
set(android_compiler_suffix linux-android23)
|
||||
set(android_toolchain_prefix aarch64)
|
||||
set(android_toolchain_suffix linux-android)
|
||||
else()
|
||||
message(FATAL_ERROR "unknown android arch: ${CMAKE_ANDROID_ARCH_ABI}")
|
||||
endif()
|
||||
set(deps_cc "${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/${android_compiler_prefix}-${android_compiler_suffix}-clang")
|
||||
set(deps_cxx "${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/${android_compiler_prefix}-${android_compiler_suffix}-clang++")
|
||||
set(deps_ld "${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/${android_compiler_prefix}-${android_toolchain_suffix}-ld")
|
||||
set(deps_ranlib "${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/${android_toolchain_prefix}-${android_toolchain_suffix}-ranlib")
|
||||
set(deps_ar "${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/${android_toolchain_prefix}-${android_toolchain_suffix}-ar")
|
||||
endif()
|
||||
|
||||
set(deps_CFLAGS "-O2")
|
||||
set(deps_CXXFLAGS "-O2")
|
||||
|
||||
if(WITH_LTO)
|
||||
set(deps_CFLAGS "${deps_CFLAGS} -flto")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set(deps_CFLAGS "${deps_CFLAGS} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
|
||||
set(deps_CXXFLAGS "${deps_CXXFLAGS} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
|
||||
endif()
|
||||
|
||||
if(_winver)
|
||||
set(deps_CFLAGS "${deps_CFLAGS} -D_WIN32_WINNT=${_winver}")
|
||||
set(deps_CXXFLAGS "${deps_CXXFLAGS} -D_WIN32_WINNT=${_winver}")
|
||||
endif()
|
||||
|
||||
|
||||
if("${CMAKE_GENERATOR}" STREQUAL "Unix Makefiles")
|
||||
set(_make $(MAKE))
|
||||
else()
|
||||
set(_make make)
|
||||
endif()
|
||||
|
||||
|
||||
# Builds a target; takes the target name (e.g. "readline") and builds it in an external project with
|
||||
# target name suffixed with `_external`. Its upper-case value is used to get the download details
|
||||
# (from the variables set above). The following options are supported and passed through to
|
||||
# ExternalProject_Add if specified. If omitted, these defaults are used:
|
||||
set(build_def_DEPENDS "")
|
||||
set(build_def_PATCH_COMMAND "")
|
||||
set(build_def_CONFIGURE_COMMAND ./configure ${cross_host} --disable-shared --prefix=${DEPS_DESTDIR} --with-pic
|
||||
"CC=${deps_cc}" "CXX=${deps_cxx}" "CFLAGS=${deps_CFLAGS}" "CXXFLAGS=${deps_CXXFLAGS}" ${cross_rc})
|
||||
set(build_def_BUILD_COMMAND ${_make})
|
||||
set(build_def_INSTALL_COMMAND ${_make} install)
|
||||
set(build_def_BUILD_BYPRODUCTS ${DEPS_DESTDIR}/lib/lib___TARGET___.a ${DEPS_DESTDIR}/include/___TARGET___.h)
|
||||
|
||||
function(build_external target)
|
||||
set(options DEPENDS PATCH_COMMAND CONFIGURE_COMMAND BUILD_COMMAND INSTALL_COMMAND BUILD_BYPRODUCTS)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "" "" "${options}")
|
||||
foreach(o ${options})
|
||||
if(NOT DEFINED arg_${o})
|
||||
set(arg_${o} ${build_def_${o}})
|
||||
endif()
|
||||
endforeach()
|
||||
string(REPLACE ___TARGET___ ${target} arg_BUILD_BYPRODUCTS "${arg_BUILD_BYPRODUCTS}")
|
||||
|
||||
string(TOUPPER "${target}" prefix)
|
||||
expand_urls(urls ${${prefix}_SOURCE} ${${prefix}_MIRROR})
|
||||
ExternalProject_Add("${target}_external"
|
||||
DEPENDS ${arg_DEPENDS}
|
||||
BUILD_IN_SOURCE ON
|
||||
PREFIX ${DEPS_SOURCEDIR}
|
||||
URL ${urls}
|
||||
URL_HASH ${${prefix}_HASH}
|
||||
DOWNLOAD_NO_PROGRESS ON
|
||||
PATCH_COMMAND ${arg_PATCH_COMMAND}
|
||||
CONFIGURE_COMMAND ${arg_CONFIGURE_COMMAND}
|
||||
BUILD_COMMAND ${arg_BUILD_COMMAND}
|
||||
INSTALL_COMMAND ${arg_INSTALL_COMMAND}
|
||||
BUILD_BYPRODUCTS ${arg_BUILD_BYPRODUCTS}
|
||||
)
|
||||
endfunction()
|
||||
|
||||
build_external(libuv
|
||||
CONFIGURE_COMMAND ./autogen.sh && ./configure ${cross_host} ${cross_rc} --prefix=${DEPS_DESTDIR} --with-pic --disable-shared --enable-static "CC=${deps_cc}" "CFLAGS=${deps_CFLAGS}"
|
||||
BUILD_BYPRODUCTS
|
||||
${DEPS_DESTDIR}/lib/libuv.a
|
||||
${DEPS_DESTDIR}/include/uv.h
|
||||
)
|
||||
add_static_target(libuv libuv_external libuv.a)
|
||||
target_link_libraries(libuv INTERFACE ${CMAKE_DL_LIBS})
|
||||
|
||||
|
||||
build_external(zlib
|
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env "CC=${deps_cc}" "CFLAGS=${deps_CFLAGS} -fPIC" ${cross_extra} ./configure --prefix=${DEPS_DESTDIR} --static
|
||||
BUILD_BYPRODUCTS
|
||||
${DEPS_DESTDIR}/lib/libz.a
|
||||
${DEPS_DESTDIR}/include/zlib.h
|
||||
)
|
||||
add_static_target(zlib zlib_external libz.a)
|
||||
|
||||
|
||||
set(openssl_system_env "")
|
||||
set(openssl_arch "")
|
||||
set(openssl_configure_command ./config)
|
||||
set(openssl_flags "CFLAGS=${deps_CFLAGS}")
|
||||
set(unbound_ldflags "")
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
if(ARCH_TRIPLET STREQUAL x86_64-w64-mingw32)
|
||||
set(openssl_arch mingw64)
|
||||
set(openssl_system_env RC=${CMAKE_RC_COMPILER} AR=${ARCH_TRIPLET}-ar RANLIB=${ARCH_TRIPLET}-ranlib)
|
||||
elseif(ARCH_TRIPLET STREQUAL i686-w64-mingw32)
|
||||
set(openssl_arch mingw)
|
||||
set(openssl_system_env RC=${CMAKE_RC_COMPILER} AR=${ARCH_TRIPLET}-ar RANLIB=${ARCH_TRIPLET}-ranlib)
|
||||
elseif(ANDROID)
|
||||
set(openssl_arch android-${android_machine})
|
||||
set(openssl_system_env LD=${deps_ld} RANLIB=${deps_ranlib} AR=${deps_ar} ANDROID_NDK_ROOT=${CMAKE_ANDROID_NDK} "PATH=${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin:$ENV{PATH}")
|
||||
list(APPEND openssl_flags "CPPFLAGS=-D__ANDROID_API__=${ANDROID_API}")
|
||||
set(openssl_extra_opts no-asm)
|
||||
elseif(ARCH_TRIPLET STREQUAL mips64-linux-gnuabi64)
|
||||
set(openssl_arch linux-mips64)
|
||||
elseif(ARCH_TRIPLET STREQUAL mips-linux-gnu)
|
||||
set(openssl_arch linux-mips32)
|
||||
elseif(ARCH_TRIPLET STREQUAL mips-openwrt-linux)
|
||||
set(unbound_ldflags "-latomic")
|
||||
set(openssl_arch linux-mips32)
|
||||
elseif(ARCH_TRIPLET STREQUAL mipsel-linux-gnu)
|
||||
set(openssl_arch linux-mips)
|
||||
elseif(ARCH_TRIPLET STREQUAL aarch64-linux-gnu OR ARCH_TRIPLET STREQUAL aarch64-openwrt-linux-musl)
|
||||
# cross compile arm64
|
||||
set(openssl_arch linux-aarch64)
|
||||
elseif(ARCH_TRIPLET MATCHES arm-linux)
|
||||
# cross compile armhf
|
||||
set(openssl_arch linux-armv4)
|
||||
elseif(ARCH_TRIPLET MATCHES powerpc64le)
|
||||
# cross compile ppc64le
|
||||
set(openssl_arch linux-ppc64le)
|
||||
endif()
|
||||
elseif(CMAKE_C_FLAGS MATCHES "-march=armv7")
|
||||
# Help openssl figure out that we're building from armv7 even if on armv8 hardware:
|
||||
set(openssl_arch linux-armv4)
|
||||
endif()
|
||||
|
||||
|
||||
build_external(openssl
|
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env CC=${deps_cc} ${openssl_system_env} ${openssl_configure_command}
|
||||
--prefix=${DEPS_DESTDIR} --libdir=lib ${openssl_extra_opts}
|
||||
no-shared no-capieng no-dso no-dtls1 no-ec_nistp_64_gcc_128 no-gost
|
||||
no-md2 no-rc5 no-rdrand no-rfc3779 no-sctp no-ssl-trace no-ssl3
|
||||
no-static-engine no-tests no-weak-ssl-ciphers no-zlib no-zlib-dynamic ${openssl_flags}
|
||||
${openssl_arch}
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} -E env ${openssl_system_env} ${_make}
|
||||
INSTALL_COMMAND ${_make} install_sw
|
||||
BUILD_BYPRODUCTS
|
||||
${DEPS_DESTDIR}/lib/libssl.a ${DEPS_DESTDIR}/lib/libcrypto.a
|
||||
${DEPS_DESTDIR}/include/openssl/ssl.h ${DEPS_DESTDIR}/include/openssl/crypto.h
|
||||
)
|
||||
add_static_target(OpenSSL::SSL openssl_external libssl.a)
|
||||
add_static_target(OpenSSL::Crypto openssl_external libcrypto.a)
|
||||
if(WIN32)
|
||||
target_link_libraries(OpenSSL::Crypto INTERFACE "ws2_32;crypt32;iphlpapi")
|
||||
endif()
|
||||
|
||||
set(OPENSSL_INCLUDE_DIR ${DEPS_DESTDIR}/include)
|
||||
set(OPENSSL_CRYPTO_LIBRARY ${DEPS_DESTDIR}/lib/libcrypto.a ${DEPS_DESTDIR}/lib/libssl.a)
|
||||
set(OPENSSL_ROOT_DIR ${DEPS_DESTDIR})
|
||||
|
||||
build_external(expat
|
||||
CONFIGURE_COMMAND ./configure ${cross_host} --prefix=${DEPS_DESTDIR} --enable-static
|
||||
--disable-shared --with-pic --without-examples --without-tests --without-docbook --without-xmlwf
|
||||
"CC=${deps_cc}" "CFLAGS=${deps_CFLAGS}"
|
||||
)
|
||||
add_static_target(expat expat_external libexpat.a)
|
||||
|
||||
|
||||
if(WIN32)
|
||||
set(unbound_patch
|
||||
PATCH_COMMAND ${PROJECT_SOURCE_DIR}/contrib/apply-patches.sh
|
||||
${PROJECT_SOURCE_DIR}/contrib/patches/unbound-delete-crash-fix.patch)
|
||||
endif()
|
||||
build_external(unbound
|
||||
DEPENDS openssl_external expat_external
|
||||
${unbound_patch}
|
||||
CONFIGURE_COMMAND ./configure ${cross_host} ${cross_rc} --prefix=${DEPS_DESTDIR} --disable-shared
|
||||
--enable-static --with-libunbound-only --with-pic
|
||||
--$<IF:$<BOOL:${WITH_LTO}>,enable,disable>-flto --with-ssl=${DEPS_DESTDIR}
|
||||
--with-libexpat=${DEPS_DESTDIR}
|
||||
"CC=${deps_cc}" "CFLAGS=${deps_CFLAGS}" "LDFLAGS=${unbound_ldflags}"
|
||||
)
|
||||
add_static_target(libunbound unbound_external libunbound.a)
|
||||
if(NOT WIN32)
|
||||
set_target_properties(libunbound PROPERTIES INTERFACE_LINK_LIBRARIES "OpenSSL::SSL;OpenSSL::Crypto")
|
||||
else()
|
||||
set_target_properties(libunbound PROPERTIES INTERFACE_LINK_LIBRARIES "OpenSSL::SSL;OpenSSL::Crypto;ws2_32;crypt32;iphlpapi")
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
build_external(sodium CONFIGURE_COMMAND ./configure ${cross_host} ${cross_rc} --prefix=${DEPS_DESTDIR} --disable-shared
|
||||
--enable-static --with-pic "CC=${deps_cc}" "CFLAGS=${deps_CFLAGS}")
|
||||
add_static_target(sodium sodium_external libsodium.a)
|
||||
|
||||
|
||||
if(WITH_PEERSTATS_BACKEND)
|
||||
build_external(sqlite3)
|
||||
add_static_target(sqlite3 sqlite3_external libsqlite3.a)
|
||||
endif()
|
||||
|
||||
|
||||
if(ARCH_TRIPLET MATCHES mingw)
|
||||
option(WITH_WEPOLL "use wepoll zmq poller (crashy)" OFF)
|
||||
if(WITH_WEPOLL)
|
||||
set(zmq_extra --with-poller=wepoll)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_CROSSCOMPILING AND ARCH_TRIPLET MATCHES mingw)
|
||||
set(zmq_patch
|
||||
PATCH_COMMAND ${PROJECT_SOURCE_DIR}/contrib/apply-patches.sh
|
||||
${PROJECT_SOURCE_DIR}/contrib/patches/libzmq-mingw-wepoll.patch
|
||||
${PROJECT_SOURCE_DIR}/contrib/patches/libzmq-mingw-unistd.patch)
|
||||
endif()
|
||||
|
||||
build_external(zmq
|
||||
DEPENDS sodium_external
|
||||
${zmq_patch}
|
||||
CONFIGURE_COMMAND ./configure ${cross_host} --prefix=${DEPS_DESTDIR} --enable-static --disable-shared
|
||||
--disable-curve-keygen --enable-curve --disable-drafts --disable-libunwind --with-libsodium
|
||||
--without-pgm --without-norm --without-vmci --without-docs --with-pic --disable-Werror --disable-libbsd ${zmq_extra}
|
||||
"CC=${deps_cc}" "CXX=${deps_cxx}" "CFLAGS=${deps_CFLAGS} -fstack-protector" "CXXFLAGS=${deps_CXXFLAGS} -fstack-protector"
|
||||
"sodium_CFLAGS=-I${DEPS_DESTDIR}/include" "sodium_LIBS=-L${DEPS_DESTDIR}/lib -lsodium"
|
||||
)
|
||||
add_static_target(libzmq zmq_external libzmq.a)
|
||||
|
||||
set(libzmq_link_libs "sodium")
|
||||
if(CMAKE_CROSSCOMPILING AND ARCH_TRIPLET MATCHES mingw)
|
||||
list(APPEND libzmq_link_libs iphlpapi)
|
||||
endif()
|
||||
|
||||
set_target_properties(libzmq PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES "${libzmq_link_libs}"
|
||||
INTERFACE_COMPILE_DEFINITIONS "ZMQ_STATIC")
|
||||
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
# Everything that follows is *only* for lokinet-bootstrap (i.e. if adding new deps put them *above*
|
||||
# this).
|
||||
#
|
||||
#
|
||||
#
|
||||
if(NOT WITH_BOOTSTRAP)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(curl_extra)
|
||||
if(WIN32)
|
||||
set(curl_ssl_opts --without-ssl --with-schannel)
|
||||
elseif(APPLE)
|
||||
set(curl_ssl_opts --without-ssl --with-secure-transport)
|
||||
if(IOS)
|
||||
# This CPP crap shouldn't be necessary but is because Apple's toolchain is trash
|
||||
set(curl_extra "LDFLAGS=-L${DEPS_DESTDIR}/lib -isysroot ${CMAKE_OSX_SYSROOT}" CPP=cpp)
|
||||
endif()
|
||||
else()
|
||||
set(curl_ssl_opts --with-ssl=${DEPS_DESTDIR})
|
||||
set(curl_extra "LIBS=-pthread")
|
||||
endif()
|
||||
|
||||
set(curl_arches default)
|
||||
set(curl_lib_outputs)
|
||||
if(IOS)
|
||||
# On iOS things get a little messy: curl won't build a multi-arch library (with `clang -arch arch1
|
||||
# -arch arch2`) so we have to build them separately then glue them together if we're building
|
||||
# multiple.
|
||||
set(curl_arches ${CMAKE_OSX_ARCHITECTURES})
|
||||
list(GET curl_arches 0 curl_arch0)
|
||||
list(LENGTH CMAKE_OSX_ARCHITECTURES num_arches)
|
||||
endif()
|
||||
|
||||
foreach(curl_arch ${curl_arches})
|
||||
set(curl_target_suffix "")
|
||||
set(curl_prefix "${DEPS_DESTDIR}")
|
||||
if(curl_arch STREQUAL "default")
|
||||
set(curl_cflags_extra "")
|
||||
elseif(IOS)
|
||||
set(cflags_extra " -arch ${curl_arch}")
|
||||
if(num_arches GREATER 1)
|
||||
set(curl_target_suffix "-${curl_arch}")
|
||||
set(curl_prefix "${DEPS_DESTDIR}/tmp/${curl_arch}")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "unexpected curl_arch=${curl_arch}")
|
||||
endif()
|
||||
|
||||
build_external(curl
|
||||
TARGET_SUFFIX ${curl_target_suffix}
|
||||
DEPENDS openssl_external zlib_external
|
||||
CONFIGURE_COMMAND ./configure ${cross_host} ${cross_extra} --prefix=${curl_prefix} --disable-shared
|
||||
--enable-static --disable-ares --disable-ftp --disable-ldap --disable-laps --disable-rtsp
|
||||
--disable-dict --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smb
|
||||
--disable-smtp --disable-gopher --disable-manual --disable-libcurl-option --enable-http
|
||||
--enable-ipv6 --disable-threaded-resolver --disable-pthreads --disable-verbose --disable-sspi
|
||||
--enable-crypto-auth --disable-ntlm-wb --disable-tls-srp --disable-unix-sockets --disable-cookies
|
||||
--enable-http-auth --enable-doh --disable-mime --enable-dateparse --disable-netrc --without-libidn2
|
||||
--disable-progress-meter --without-brotli --with-zlib=${DEPS_DESTDIR} ${curl_ssl_opts}
|
||||
--without-librtmp --disable-versioned-symbols --enable-hidden-symbols
|
||||
--without-zsh-functions-dir --without-fish-functions-dir
|
||||
--without-nghttp3 --without-zstd
|
||||
"CC=${deps_cc}" "CFLAGS=${deps_noarch_CFLAGS}${cflags_extra}" ${curl_extra}
|
||||
BUILD_COMMAND true
|
||||
INSTALL_COMMAND ${_make} -C lib install && ${_make} -C include install
|
||||
BUILD_BYPRODUCTS
|
||||
${curl_prefix}/lib/libcurl.a
|
||||
${curl_prefix}/include/curl/curl.h
|
||||
)
|
||||
list(APPEND curl_lib_targets curl${curl_target_suffix}_external)
|
||||
list(APPEND curl_lib_outputs ${curl_prefix}/lib/libcurl.a)
|
||||
endforeach()
|
||||
|
||||
|
||||
|
||||
if(IOS AND num_arches GREATER 1)
|
||||
# We are building multiple architectures for different iOS devices, so we need to glue the
|
||||
# separate libraries into one. (Normally multiple -arch values passed to clang does this for us,
|
||||
# but curl refuses to build that way).
|
||||
add_custom_target(curl_external
|
||||
COMMAND lipo ${curl_lib_outputs} -create -output ${DEPS_DESTDIR}/libcurl.a
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPS_DESTDIR}/tmp/${curl_arch0}/include/curl ${DEPS_DESTDIR}/include/curl
|
||||
BYPRODUCTS ${DEPS_DESTDIR}/lib/libcurl.a ${DEPS_DESTDIR}/include/curl/curl.h
|
||||
DEPENDS ${curl_lib_targets})
|
||||
endif()
|
||||
|
||||
add_static_target(CURL::libcurl curl_external libcurl.a)
|
||||
set(libcurl_link_libs zlib)
|
||||
if(CMAKE_CROSSCOMPILING AND ARCH_TRIPLET MATCHES mingw)
|
||||
list(APPEND libcurl_link_libs crypt32)
|
||||
elseif(APPLE)
|
||||
list(APPEND libcurl_link_libs "-framework Security -framework CoreFoundation")
|
||||
endif()
|
||||
set_target_properties(CURL::libcurl PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES "${libcurl_link_libs}"
|
||||
INTERFACE_COMPILE_DEFINITIONS "CURL_STATICLIB")
|
@ -1,46 +1,22 @@
|
||||
# We do this via a custom command that re-invokes a cmake script because we need the DEPENDS on .git/index so that we will re-run it (to regenerate the commit tag in the version) whenever the current commit changes. If we used a configure_file directly here, it would only re-run when something else causes cmake to re-run.
|
||||
|
||||
if(LOKINET_VERSIONTAG)
|
||||
set(VERSIONTAG "${LOKINET_VERSIONTAG}")
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/constants/version.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/constants/version.cpp" @ONLY)
|
||||
else()
|
||||
set(VERSIONTAG "${GIT_VERSION}")
|
||||
set(GIT_INDEX_FILE "${PROJECT_SOURCE_DIR}/.git/index")
|
||||
find_package(Git)
|
||||
if(EXISTS "${GIT_INDEX_FILE}" AND ( GIT_FOUND OR Git_FOUND) )
|
||||
message(STATUS "Found Git: ${GIT_EXECUTABLE}")
|
||||
set(genversion_args "-DGIT=${GIT_EXECUTABLE}")
|
||||
foreach(v lokinet_VERSION lokinet_VERSION_MAJOR lokinet_VERSION_MINOR lokinet_VERSION_PATCH RELEASE_MOTTO)
|
||||
list(APPEND genversion_args "-D${v}=${${v}}")
|
||||
endforeach()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/constants/version.cpp"
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
${genversion_args}
|
||||
"-D" "SRC=${CMAKE_CURRENT_SOURCE_DIR}/constants/version.cpp.in"
|
||||
"-D" "DEST=${CMAKE_CURRENT_BINARY_DIR}/constants/version.cpp"
|
||||
"-P" "${CMAKE_CURRENT_LIST_DIR}/GenVersion.cmake"
|
||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/constants/version.cpp.in"
|
||||
"${GIT_INDEX_FILE}")
|
||||
else()
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/constants/version.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/constants/version.cpp" @ONLY)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(Git QUIET)
|
||||
set(GIT_INDEX_FILE "${PROJECT_SOURCE_DIR}/.git/index")
|
||||
if(EXISTS ${GIT_INDEX_FILE} AND ( GIT_FOUND OR Git_FOUND) )
|
||||
message(STATUS "Found Git: ${GIT_EXECUTABLE}")
|
||||
|
||||
if(WIN32)
|
||||
foreach(exe IN ITEMS lokinet lokinet-vpn lokinet-bootstrap)
|
||||
set(lokinet_EXE_NAME "${exe}.exe")
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/win32/version.rc.in" "${CMAKE_BINARY_DIR}/${exe}.rc" @ONLY)
|
||||
set_property(SOURCE "${CMAKE_BINARY_DIR}/${exe}.rc" PROPERTY GENERATED 1)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
add_custom_target(genversion_cpp DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/constants/version.cpp")
|
||||
if(WIN32)
|
||||
add_custom_target(genversion_rc DEPENDS "${CMAKE_BINARY_DIR}/lokinet.rc" "${CMAKE_BINARY_DIR}/lokinet-vpn.rc" "${CMAKE_BINARY_DIR}/lokinet-bootstrap.rc")
|
||||
add_custom_command(
|
||||
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/constants/version.cpp"
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
"-D" "GIT=${GIT_EXECUTABLE}"
|
||||
"-D" "SRC=${CMAKE_CURRENT_SOURCE_DIR}/constants/version.cpp.in"
|
||||
"-D" "DEST=${CMAKE_CURRENT_BINARY_DIR}/constants/version.cpp"
|
||||
"-P" "${CMAKE_CURRENT_LIST_DIR}/GenVersion.cmake"
|
||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/constants/version.cpp.in"
|
||||
"${GIT_INDEX_FILE}")
|
||||
else()
|
||||
add_custom_target(genversion_rc)
|
||||
message(STATUS "Git was not found! Setting version to to nogit")
|
||||
set(VERSIONTAG "nogit")
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/constants/version.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/constants/version.cpp")
|
||||
endif()
|
||||
add_custom_target(genversion DEPENDS genversion_cpp genversion_rc)
|
||||
|
||||
add_custom_target(genversion DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/constants/version.cpp")
|
||||
|
@ -0,0 +1,8 @@
|
||||
function(add_log_tag target)
|
||||
if(TARGET ${target})
|
||||
get_target_property(TARGET_SRCS ${target} SOURCES)
|
||||
foreach(F ${TARGET_SRCS})
|
||||
set_source_files_properties(${F} PROPERTIES COMPILE_FLAGS -DLOG_TAG=\\\"${F}\\\")
|
||||
endforeach(F)
|
||||
endif()
|
||||
endfunction()
|
@ -0,0 +1,20 @@
|
||||
# Basic definitions
|
||||
set(LIB lokinet)
|
||||
set(SHARED_LIB ${LIB}-shared)
|
||||
set(STATIC_LIB ${LIB}-static)
|
||||
set(CRYPTOGRAPHY_LIB ${LIB}-cryptography)
|
||||
set(UTIL_LIB ${LIB}-util)
|
||||
set(PLATFORM_LIB ${LIB}-platform)
|
||||
set(ANDROID_LIB ${LIB}android)
|
||||
set(ABYSS libabyss)
|
||||
set(ABYSS_LIB abyss)
|
||||
set(ABYSS_EXE ${ABYSS_LIB}-main)
|
||||
get_filename_component(TT_ROOT "${CMAKE_CURRENT_LIST_DIR}/../vendor/libtuntap-master" ABSOLUTE)
|
||||
add_definitions(-D${CMAKE_SYSTEM_NAME})
|
||||
|
||||
get_filename_component(CORE_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/include" ABSOLUTE)
|
||||
get_filename_component(ABYSS_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/${ABYSS}/include" ABSOLUTE)
|
||||
|
||||
set(LIBTUNTAP_SRC
|
||||
${TT_ROOT}/tuntap.cpp
|
||||
${TT_ROOT}/tuntap_log.cpp)
|
@ -1,51 +0,0 @@
|
||||
# Figure out if we need -lstdc++fs or -lc++fs and add it to the `filesystem` interface, if needed
|
||||
# (otherwise just leave it an empty interface library; linking to it will do nothing). The former
|
||||
# is needed for gcc before v9, and the latter with libc++ before llvm v9. But this gets more
|
||||
# complicated than just using the compiler, because clang on linux by default uses libstdc++, so
|
||||
# we'll just give up and see what works.
|
||||
|
||||
add_library(filesystem INTERFACE)
|
||||
|
||||
set(filesystem_code [[
|
||||
#include <filesystem>
|
||||
|
||||
int main() {
|
||||
auto cwd = std::filesystem::current_path();
|
||||
return !cwd.string().empty();
|
||||
}
|
||||
]])
|
||||
|
||||
if(CMAKE_CXX_COMPILER STREQUAL "AppleClang" AND CMAKE_OSX_DEPLOYMENT_TARGET)
|
||||
# It seems that check_cxx_source_compiles doesn't respect the CMAKE_OSX_DEPLOYMENT_TARGET, so this
|
||||
# check would pass on Catalina (10.15) and then later compilation would fail because you aren't
|
||||
# allowed to use <filesystem> when the deployment target is anything before 10.15.
|
||||
set(CMAKE_REQUIRED_FLAGS -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET})
|
||||
endif()
|
||||
|
||||
check_cxx_source_compiles("${filesystem_code}" filesystem_compiled)
|
||||
if(filesystem_compiled)
|
||||
message(STATUS "No extra link flag needed for std::filesystem")
|
||||
set(filesystem_is_good 1)
|
||||
else()
|
||||
foreach(fslib stdc++fs c++fs)
|
||||
set(CMAKE_REQUIRED_LIBRARIES -l${fslib})
|
||||
check_cxx_source_compiles("${filesystem_code}" filesystem_compiled_${fslib})
|
||||
if (filesystem_compiled_${fslib})
|
||||
message(STATUS "Using -l${fslib} for std::filesystem support")
|
||||
target_link_libraries(filesystem INTERFACE ${fslib})
|
||||
set(filesystem_is_good 1)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
||||
if(filesystem_is_good EQUAL 1)
|
||||
message(STATUS "we have std::filesystem")
|
||||
else()
|
||||
# Probably broken AF macos
|
||||
message(STATUS "std::filesystem is not available, apparently this compiler isn't C++17 compliant; falling back to ghc::filesystem")
|
||||
set(GHC_FILESYSTEM_WITH_INSTALL OFF CACHE INTERNAL "")
|
||||
add_subdirectory(external/ghc-filesystem)
|
||||
target_link_libraries(filesystem INTERFACE ghc_filesystem)
|
||||
target_compile_definitions(filesystem INTERFACE USE_GHC_FILESYSTEM CLI11_HAS_FILESYSTEM=0)
|
||||
endif()
|
@ -1,18 +0,0 @@
|
||||
# check for std::optional because macos is broke af sometimes
|
||||
|
||||
set(std_optional_code [[
|
||||
#include <optional>
|
||||
|
||||
int main() {
|
||||
std::optional<int> maybe;
|
||||
maybe = 1;
|
||||
return *maybe == 1;
|
||||
}
|
||||
]])
|
||||
|
||||
check_cxx_source_compiles("${std_optional_code}" was_compiled)
|
||||
if(was_compiled)
|
||||
message(STATUS "we have std::optional")
|
||||
else()
|
||||
message(FATAL_ERROR "we dont have std::optional your compiler is broke af")
|
||||
endif()
|
@ -1,21 +0,0 @@
|
||||
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
endif()
|
||||
|
||||
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
foreach(file ${files})
|
||||
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
||||
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
exec_program(
|
||||
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RETURN_VALUE rm_retval
|
||||
)
|
||||
if(NOT "${rm_retval}" STREQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
||||
endif()
|
||||
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
||||
endif()
|
||||
endforeach()
|
@ -1,23 +0,0 @@
|
||||
# -flto
|
||||
include(CheckIPOSupported)
|
||||
option(WITH_LTO "enable lto on compile time" ON)
|
||||
if(WITH_LTO)
|
||||
if(WIN32)
|
||||
message(FATAL_ERROR "LTO not supported on win32 targets, please set -DWITH_LTO=OFF")
|
||||
endif()
|
||||
check_ipo_supported(RESULT IPO_ENABLED OUTPUT ipo_error)
|
||||
if(IPO_ENABLED)
|
||||
message(STATUS "LTO enabled")
|
||||
else()
|
||||
message(WARNING "LTO not supported by compiler: ${ipo_error}")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "LTO disabled")
|
||||
set(IPO_ENABLED OFF)
|
||||
endif()
|
||||
|
||||
function(enable_lto)
|
||||
if(IPO_ENABLED)
|
||||
set_target_properties(${ARGN} PROPERTIES INTERPROCEDURAL_OPTIMIZATION ON)
|
||||
endif()
|
||||
endfunction()
|
@ -1,17 +0,0 @@
|
||||
set(default_build_gui OFF)
|
||||
if(APPLE OR WIN32)
|
||||
set(default_build_gui ON)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(GUI_EXE "" CACHE FILEPATH "path to a pre-built Windows GUI .exe to use (implies -DBUILD_GUI=OFF)")
|
||||
if(GUI_EXE)
|
||||
set(default_build_gui OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(BUILD_GUI "build electron gui from 'gui' submodule source" ${default_build_gui})
|
||||
|
||||
if(BUILD_GUI AND GUI_EXE)
|
||||
message(FATAL_ERROR "-DGUI_EXE=... and -DBUILD_GUI=ON are mutually exclusive")
|
||||
endif()
|
@ -1,67 +0,0 @@
|
||||
|
||||
if(WIN32 AND GUI_EXE)
|
||||
message(STATUS "using pre-built lokinet gui executable: ${GUI_EXE}")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${GUI_EXE}" "${PROJECT_BINARY_DIR}/gui/lokinet-gui.exe")
|
||||
elseif(BUILD_GUI)
|
||||
message(STATUS "Building lokinet-gui from source")
|
||||
|
||||
set(default_gui_target pack)
|
||||
if(APPLE)
|
||||
set(default_gui_target macos:raw)
|
||||
elseif(WIN32)
|
||||
set(default_gui_target win32)
|
||||
endif()
|
||||
|
||||
set(GUI_YARN_TARGET "${default_gui_target}" CACHE STRING "yarn target for building the GUI")
|
||||
set(GUI_YARN_EXTRA_OPTS "" CACHE STRING "extra options to pass into the yarn build command")
|
||||
|
||||
# allow manually specifying yarn with -DYARN=
|
||||
if(NOT YARN)
|
||||
find_program(YARN NAMES yarnpkg yarn REQUIRED)
|
||||
endif()
|
||||
message(STATUS "Building lokinet-gui with yarn ${YARN}, target ${GUI_YARN_TARGET}")
|
||||
|
||||
if(NOT WIN32)
|
||||
add_custom_target(lokinet-gui
|
||||
COMMAND ${YARN} install --frozen-lockfile &&
|
||||
${YARN} ${GUI_YARN_EXTRA_OPTS} ${GUI_YARN_TARGET}
|
||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/gui")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
add_custom_target(assemble_gui ALL
|
||||
DEPENDS assemble lokinet-gui
|
||||
COMMAND mkdir "${lokinet_app}/Contents/Helpers"
|
||||
COMMAND cp -a "${PROJECT_SOURCE_DIR}/gui/release/mac/Lokinet-GUI.app" "${lokinet_app}/Contents/Helpers/"
|
||||
COMMAND mkdir -p "${lokinet_app}/Contents/Resources/en.lproj"
|
||||
COMMAND cp "${PROJECT_SOURCE_DIR}/contrib/macos/InfoPlist.strings" "${lokinet_app}/Contents/Resources/en.lproj/"
|
||||
COMMAND cp "${lokinet_app}/Contents/Resources/icon.icns" "${lokinet_app}/Contents/Helpers/Lokinet-GUI.app/Contents/Resources/icon.icns"
|
||||
COMMAND cp "${PROJECT_SOURCE_DIR}/contrib/macos/InfoPlist.strings" "${lokinet_app}/Contents/Helpers/Lokinet-GUI.app/Contents/Resources/en.lproj/"
|
||||
COMMAND /usr/libexec/PlistBuddy
|
||||
-c "Delete :CFBundleDisplayName"
|
||||
-c "Add :LSHasLocalizedDisplayName bool true"
|
||||
-c "Add :CFBundleDevelopmentRegion string en"
|
||||
-c "Set :CFBundleShortVersionString ${lokinet_VERSION}"
|
||||
-c "Set :CFBundleVersion ${lokinet_VERSION}.${LOKINET_APPLE_BUILD}"
|
||||
"${lokinet_app}/Contents/Helpers/Lokinet-GUI.app/Contents/Info.plist"
|
||||
)
|
||||
elseif(WIN32)
|
||||
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/gui")
|
||||
add_custom_command(OUTPUT "${PROJECT_BINARY_DIR}/gui/lokinet-gui.exe"
|
||||
COMMAND ${YARN} install --frozen-lockfile &&
|
||||
USE_SYSTEM_7ZA=true DISPLAY= WINEDEBUG=-all WINEPREFIX="${PROJECT_BINARY_DIR}/wineprefix" ${YARN} ${GUI_YARN_EXTRA_OPTS} ${GUI_YARN_TARGET}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${PROJECT_SOURCE_DIR}/gui/release/Lokinet-GUI_portable.exe"
|
||||
"${PROJECT_BINARY_DIR}/gui/lokinet-gui.exe"
|
||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/gui")
|
||||
add_custom_target(assemble_gui ALL COMMAND "true" DEPENDS "${PROJECT_BINARY_DIR}/gui/lokinet-gui.exe")
|
||||
else()
|
||||
message(FATAL_ERROR "Building/bundling the GUI from this repository is not supported on this platform")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "not building gui")
|
||||
endif()
|
||||
|
||||
if(NOT TARGET assemble_gui)
|
||||
add_custom_target(assemble_gui COMMAND "true")
|
||||
endif()
|
@ -1,46 +0,0 @@
|
||||
set(CPACK_PACKAGE_VENDOR "lokinet.org")
|
||||
set(CPACK_PACKAGE_HOMEPAGE_URL "https://lokinet.org/")
|
||||
set(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/contrib/readme-installer.txt")
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
|
||||
|
||||
if(WIN32)
|
||||
include(cmake/win32_installer_deps.cmake)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/contrib/configs/00-exit.ini DESTINATION share/conf.d COMPONENT exit_configs)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/contrib/configs/00-keyfile.ini DESTINATION share/conf.d COMPONENT keyfile_configs)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/contrib/configs/00-debug-log.ini DESTINATION share/conf.d COMPONENT debug_configs)
|
||||
get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS)
|
||||
list(REMOVE_ITEM CPACK_COMPONENTS_ALL "Unspecified" "lokinet" "gui" "exit_configs" "keyfile_configs" "debug_configs")
|
||||
list(APPEND CPACK_COMPONENTS_ALL "lokinet" "gui" "exit_configs" "keyfile_configs" "debug_configs")
|
||||
elseif(APPLE)
|
||||
set(CPACK_GENERATOR DragNDrop;ZIP)
|
||||
get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS)
|
||||
list(REMOVE_ITEM CPACK_COMPONENTS_ALL "Unspecified")
|
||||
endif()
|
||||
|
||||
include(CPack)
|
||||
|
||||
if(WIN32)
|
||||
cpack_add_component(lokinet
|
||||
DISPLAY_NAME "lokinet"
|
||||
DESCRIPTION "core required lokinet files"
|
||||
REQUIRED)
|
||||
|
||||
cpack_add_component(gui
|
||||
DISPLAY_NAME "lokinet gui"
|
||||
DESCRIPTION "electron based control panel for lokinet")
|
||||
|
||||
cpack_add_component(exit_configs
|
||||
DISPLAY_NAME "auto-enable exit"
|
||||
DESCRIPTION "automatically enable usage of exit.loki as an exit node\n"
|
||||
DISABLED)
|
||||
|
||||
cpack_add_component(keyfile_configs
|
||||
DISPLAY_NAME "persist address"
|
||||
DESCRIPTION "persist .loki address across restarts of lokinet\nnot recommended when enabling exit nodes"
|
||||
DISABLED)
|
||||
|
||||
cpack_add_component(debug_configs
|
||||
DISPLAY_NAME "debug logging"
|
||||
DESCRIPTION "enable debug spew log level by default"
|
||||
DISABLED)
|
||||
endif()
|
@ -1,49 +1,49 @@
|
||||
function(check_working_cxx_atomics64 varname)
|
||||
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
||||
if (EMBEDDED_CFG)
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -m32 -march=i486")
|
||||
elseif(MSVC OR MSVC_VERSION)
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -arch:IA32 -std:c++14")
|
||||
else()
|
||||
# CMAKE_CXX_STANDARD does not propagate to cmake compile tests
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++14")
|
||||
endif()
|
||||
check_cxx_source_compiles("
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
std::atomic<uint64_t> x (0);
|
||||
int main() {
|
||||
uint64_t i = x.load(std::memory_order_relaxed);
|
||||
return 0;
|
||||
}
|
||||
" ${varname})
|
||||
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
|
||||
endfunction()
|
||||
|
||||
function(link_libatomic)
|
||||
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
|
||||
|
||||
if(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
|
||||
message(STATUS "Have working 64bit atomics")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (NOT MSVC AND NOT MSVC_VERSION)
|
||||
check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
|
||||
if (HAVE_CXX_LIBATOMICS64)
|
||||
message(STATUS "Have 64bit atomics via library")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
|
||||
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
|
||||
if (HAVE_CXX_ATOMICS64_WITH_LIB)
|
||||
message(STATUS "Can link with libatomic")
|
||||
link_libraries(-latomic)
|
||||
return()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if (MSVC OR MSVC_VERSION)
|
||||
message(FATAL_ERROR "Host compiler must support 64-bit std::atomic! (What does MSVC do to inline atomics?)")
|
||||
else()
|
||||
message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!")
|
||||
endif()
|
||||
endfunction()
|
||||
function(check_working_cxx_atomics64 varname)
|
||||
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
||||
if (EMBEDDED_CFG)
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -m32 -march=i486")
|
||||
elseif(MSVC OR MSVC_VERSION)
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -arch:IA32 -std:c++14")
|
||||
else()
|
||||
# CMAKE_CXX_STANDARD does not propagate to cmake compile tests
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++14")
|
||||
endif()
|
||||
check_cxx_source_compiles("
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
std::atomic<uint64_t> x (0);
|
||||
int main() {
|
||||
uint64_t i = x.load(std::memory_order_relaxed);
|
||||
return 0;
|
||||
}
|
||||
" ${varname})
|
||||
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
|
||||
endfunction()
|
||||
|
||||
function(link_libatomic)
|
||||
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
|
||||
|
||||
if(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
|
||||
message(STATUS "Have working 64bit atomics")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (NOT MSVC AND NOT MSVC_VERSION)
|
||||
check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
|
||||
if (HAVE_CXX_LIBATOMICS64)
|
||||
message(STATUS "Have 64bit atomics via library")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
|
||||
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
|
||||
if (HAVE_CXX_ATOMICS64_WITH_LIB)
|
||||
message(STATUS "Can link with libatomic")
|
||||
link_libraries(-latomic)
|
||||
return()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if (MSVC OR MSVC_VERSION)
|
||||
message(FATAL_ERROR "Host compiler must support 64-bit std::atomic! (What does MSVC do to inline atomics?)")
|
||||
else()
|
||||
message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!")
|
||||
endif()
|
||||
endfunction()
|
@ -1,214 +0,0 @@
|
||||
if(NOT APPLE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
|
||||
option(MACOS_SYSTEM_EXTENSION
|
||||
"Build the network extension as a system extension rather than a plugin. This must be ON for non-app store release builds, and must be OFF for dev builds and Mac App Store distribution builds"
|
||||
OFF)
|
||||
option(CODESIGN "codesign the resulting app and extension" ON)
|
||||
set(CODESIGN_ID "" CACHE STRING "codesign the macos app using this key identity; if empty we'll try to guess")
|
||||
set(default_profile_type "dev")
|
||||
if(MACOS_SYSTEM_EXTENSION)
|
||||
set(default_profile_type "release")
|
||||
endif()
|
||||
set(CODESIGN_PROFILE "${PROJECT_SOURCE_DIR}/contrib/macos/lokinet.${default_profile_type}.provisionprofile" CACHE FILEPATH
|
||||
"Path to a .provisionprofile to use for the main app")
|
||||
set(CODESIGN_EXT_PROFILE "${PROJECT_SOURCE_DIR}/contrib/macos/lokinet-extension.${default_profile_type}.provisionprofile" CACHE FILEPATH
|
||||
"Path to a .provisionprofile to use for the lokinet extension")
|
||||
|
||||
if(CODESIGN AND NOT CODESIGN_ID)
|
||||
if(MACOS_SYSTEM_EXTENSION)
|
||||
set(codesign_cert_pattern "Developer ID Application")
|
||||
else()
|
||||
set(codesign_cert_pattern "Apple Development")
|
||||
endif()
|
||||
execute_process(
|
||||
COMMAND security find-identity -v -p codesigning
|
||||
COMMAND sed -n "s/^ *[0-9][0-9]*) *\\([A-F0-9]\\{40\\}\\) *\"\\(${codesign_cert_pattern}.*\\)\"\$/\\1 \\2/p"
|
||||
RESULT_VARIABLE find_id_exit_code
|
||||
OUTPUT_VARIABLE find_id_output)
|
||||
if(NOT find_id_exit_code EQUAL 0)
|
||||
message(FATAL_ERROR "Finding signing identities with security find-identity failed; try specifying an id using -DCODESIGN_ID=...")
|
||||
endif()
|
||||
|
||||
string(REGEX MATCHALL "(^|\n)[0-9A-F]+" find_id_sign_id "${find_id_output}")
|
||||
if(NOT find_id_sign_id)
|
||||
message(FATAL_ERROR "Did not find any \"${codesign_cert_pattern}\" identity; try specifying an id using -DCODESIGN_ID=...")
|
||||
endif()
|
||||
if (find_id_sign_id MATCHES ";")
|
||||
message(FATAL_ERROR "Found multiple \"${codesign_cert_pattern}\" identities:\n${find_id_output}\nSpecify an identify using -DCODESIGN_ID=...")
|
||||
endif()
|
||||
set(CODESIGN_ID "${find_id_sign_id}" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
|
||||
if(CODESIGN)
|
||||
message(STATUS "Codesigning using ${CODESIGN_ID}")
|
||||
|
||||
if (NOT MACOS_NOTARIZE_USER AND NOT MACOS_NOTARIZE_PASS AND NOT MACOS_NOTARIZE_ASC AND EXISTS "$ENV{HOME}/.notarization.cmake")
|
||||
message(STATUS "Loading notarization info from ~/.notarization.cmake")
|
||||
include("$ENV{HOME}/.notarization.cmake")
|
||||
endif()
|
||||
|
||||
if (MACOS_NOTARIZE_USER AND MACOS_NOTARIZE_PASS AND MACOS_NOTARIZE_ASC)
|
||||
message(STATUS "Enabling notarization with account ${MACOS_NOTARIZE_ASC}/${MACOS_NOTARIZE_USER}")
|
||||
else()
|
||||
message(WARNING "You have not set one or more of MACOS_NOTARIZE_USER, MACOS_NOTARIZE_PASS, MACOS_NOTARIZE_ASC: notarization will fail; see contrib/macos/README.txt")
|
||||
endif()
|
||||
|
||||
else()
|
||||
message(WARNING "Codesigning disabled; the resulting build will not run on most macOS systems")
|
||||
endif()
|
||||
|
||||
|
||||
foreach(prof IN ITEMS CODESIGN_PROFILE CODESIGN_EXT_PROFILE)
|
||||
if(NOT ${prof})
|
||||
message(WARNING "Missing a ${prof} provisioning profile: Apple will most likely log an uninformative error message to the system log and then kill harmless kittens if you try to run the result")
|
||||
elseif(NOT EXISTS "${${prof}}")
|
||||
message(FATAL_ERROR "Provisioning profile ${${prof}} does not exist; fix your -D${prof} path")
|
||||
endif()
|
||||
endforeach()
|
||||
message(STATUS "Using ${CODESIGN_PROFILE} app provisioning profile")
|
||||
message(STATUS "Using ${CODESIGN_EXT_PROFILE} extension provisioning profile")
|
||||
|
||||
|
||||
|
||||
set(lokinet_installer "${PROJECT_BINARY_DIR}/Lokinet ${PROJECT_VERSION}")
|
||||
if(NOT CODESIGN)
|
||||
set(lokinet_installer "${lokinet_installer}-UNSIGNED")
|
||||
endif()
|
||||
set(lokinet_app "${lokinet_installer}/Lokinet.app")
|
||||
|
||||
|
||||
if(MACOS_SYSTEM_EXTENSION)
|
||||
set(lokinet_ext_dir Contents/Library/SystemExtensions)
|
||||
else()
|
||||
set(lokinet_ext_dir Contents/PlugIns)
|
||||
endif()
|
||||
|
||||
if(CODESIGN)
|
||||
if(MACOS_SYSTEM_EXTENSION)
|
||||
set(LOKINET_ENTITLEMENTS_TYPE sysext)
|
||||
set(notarize_py_is_sysext True)
|
||||
else()
|
||||
set(LOKINET_ENTITLEMENTS_TYPE plugin)
|
||||
set(notarize_py_is_sysext False)
|
||||
endif()
|
||||
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/contrib/macos/sign.sh.in"
|
||||
"${PROJECT_BINARY_DIR}/sign.sh"
|
||||
@ONLY)
|
||||
|
||||
add_custom_target(
|
||||
sign
|
||||
DEPENDS "${PROJECT_BINARY_DIR}/sign.sh"
|
||||
COMMAND "${PROJECT_BINARY_DIR}/sign.sh"
|
||||
)
|
||||
|
||||
if(MACOS_NOTARIZE_USER AND MACOS_NOTARIZE_PASS AND MACOS_NOTARIZE_ASC)
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/contrib/macos/notarize.py.in"
|
||||
"${PROJECT_BINARY_DIR}/notarize.py"
|
||||
@ONLY)
|
||||
add_custom_target(
|
||||
notarize
|
||||
DEPENDS "${PROJECT_BINARY_DIR}/notarize.py" sign
|
||||
COMMAND "${PROJECT_BINARY_DIR}/notarize.py"
|
||||
)
|
||||
else()
|
||||
message(WARNING "You have not set one or more of MACOS_NOTARIZE_USER, MACOS_NOTARIZE_PASS, MACOS_NOTARIZE_ASC: notarization disabled")
|
||||
endif()
|
||||
else()
|
||||
add_custom_target(sign COMMAND "true")
|
||||
add_custom_target(notarize DEPENDS sign COMMAND "true")
|
||||
endif()
|
||||
|
||||
set(mac_icon "${PROJECT_BINARY_DIR}/lokinet.icns")
|
||||
add_custom_command(OUTPUT "${mac_icon}"
|
||||
COMMAND ${PROJECT_SOURCE_DIR}/contrib/macos/mk-icns.sh ${PROJECT_SOURCE_DIR}/contrib/lokinet-mac.svg "${mac_icon}"
|
||||
DEPENDS ${PROJECT_SOURCE_DIR}/contrib/lokinet-mac.svg ${PROJECT_SOURCE_DIR}/contrib/macos/mk-icns.sh)
|
||||
add_custom_target(icon DEPENDS "${mac_icon}")
|
||||
|
||||
if(BUILD_PACKAGE)
|
||||
add_executable(seticon "${PROJECT_SOURCE_DIR}/contrib/macos/seticon.swift")
|
||||
add_custom_command(OUTPUT "${lokinet_installer}.dmg"
|
||||
DEPENDS notarize seticon
|
||||
COMMAND create-dmg
|
||||
--volname "Lokinet ${PROJECT_VERSION}"
|
||||
--volicon lokinet.icns
|
||||
--background "${PROJECT_SOURCE_DIR}/contrib/macos/installer.tiff"
|
||||
--text-size 16
|
||||
--icon-size 128
|
||||
--window-size 555 440
|
||||
--icon Lokinet.app 151 196
|
||||
--hide-extension Lokinet.app
|
||||
--app-drop-link 403 196
|
||||
--eula "${PROJECT_SOURCE_DIR}/LICENSE"
|
||||
--no-internet-enable
|
||||
"${lokinet_installer}.dmg"
|
||||
"${lokinet_installer}"
|
||||
COMMAND ./seticon lokinet.icns "${lokinet_installer}.dmg"
|
||||
)
|
||||
add_custom_target(dmg DEPENDS "${lokinet_installer}.dmg")
|
||||
endif()
|
||||
|
||||
|
||||
# Called later to set things up, after the main lokinet targets are set up
|
||||
function(macos_target_setup)
|
||||
|
||||
if(MACOS_SYSTEM_EXTENSION)
|
||||
target_compile_definitions(lokinet PRIVATE MACOS_SYSTEM_EXTENSION)
|
||||
endif()
|
||||
|
||||
set_target_properties(lokinet
|
||||
PROPERTIES
|
||||
OUTPUT_NAME Lokinet
|
||||
MACOSX_BUNDLE TRUE
|
||||
MACOSX_BUNDLE_INFO_STRING "Lokinet IP Packet Onion Router"
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "Lokinet"
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION "${lokinet_VERSION}"
|
||||
MACOSX_BUNDLE_LONG_VERSION_STRING "${lokinet_VERSION}"
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${lokinet_VERSION_MAJOR}.${lokinet_VERSION_MINOR}"
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER "org.lokinet"
|
||||
MACOSX_BUNDLE_INFO_PLIST "${PROJECT_SOURCE_DIR}/contrib/macos/lokinet.Info.plist.in"
|
||||
MACOSX_BUNDLE_COPYRIGHT "© 2022, The Oxen Project"
|
||||
)
|
||||
|
||||
add_custom_target(copy_bootstrap
|
||||
DEPENDS lokinet-extension
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECT_SOURCE_DIR}/contrib/bootstrap/mainnet.signed
|
||||
$<TARGET_BUNDLE_DIR:lokinet-extension>/Contents/Resources/bootstrap.signed
|
||||
)
|
||||
|
||||
|
||||
add_dependencies(lokinet lokinet-extension icon)
|
||||
|
||||
|
||||
if(CODESIGN_PROFILE)
|
||||
add_custom_target(copy_prov_prof
|
||||
DEPENDS lokinet
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CODESIGN_PROFILE}
|
||||
$<TARGET_BUNDLE_DIR:lokinet>/Contents/embedded.provisionprofile
|
||||
)
|
||||
else()
|
||||
add_custom_target(copy_prov_prof COMMAND true)
|
||||
endif()
|
||||
|
||||
add_custom_target(assemble ALL
|
||||
DEPENDS lokinet lokinet-extension icon copy_prov_prof copy_bootstrap
|
||||
COMMAND rm -rf "${lokinet_app}"
|
||||
COMMAND mkdir -p "${lokinet_installer}"
|
||||
COMMAND cp -a $<TARGET_BUNDLE_DIR:lokinet> "${lokinet_app}"
|
||||
COMMAND mkdir -p "${lokinet_app}/${lokinet_ext_dir}"
|
||||
COMMAND cp -a $<TARGET_BUNDLE_DIR:lokinet-extension> "${lokinet_app}/${lokinet_ext_dir}/"
|
||||
COMMAND mkdir -p "${lokinet_app}/Contents/Resources"
|
||||
COMMAND cp -a "${mac_icon}" "${lokinet_app}/Contents/Resources/icon.icns"
|
||||
)
|
||||
|
||||
if(BUILD_GUI)
|
||||
add_dependencies(sign assemble_gui)
|
||||
else()
|
||||
add_dependencies(sign assemble)
|
||||
endif()
|
||||
endfunction()
|
@ -1,53 +0,0 @@
|
||||
# ngtcp2's top-level CMakeLists.txt loads a bunch of crap we don't want (examples, a conflicting
|
||||
# 'check' target, etc.); instead we directly include it's lib subdirectory to build just the
|
||||
# library, but we have to set up a couple things to make that work:
|
||||
function(add_ngtcp2_lib)
|
||||
file(STRINGS ngtcp2/CMakeLists.txt ngtcp2_project_line REGEX "^project\\(ngtcp2 ")
|
||||
if(NOT ngtcp2_project_line MATCHES "^project\\(ngtcp2 VERSION ([0-9]+)\\.([0-9]+)\\.([0-9]+)\\)$")
|
||||
message(FATAL_ERROR "Unable to extract ngtcp2 version from ngtcp2/CMakeLists.txt (found '${ngtcp2_project_line}')")
|
||||
endif()
|
||||
|
||||
set(PACKAGE_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
|
||||
include(ngtcp2/cmake/Version.cmake)
|
||||
HexVersion(PACKAGE_VERSION_NUM ${CMAKE_MATCH_1} ${CMAKE_MATCH_2} ${CMAKE_MATCH_3})
|
||||
configure_file("ngtcp2/lib/includes/ngtcp2/version.h.in" "ngtcp2/lib/includes/ngtcp2/version.h" @ONLY)
|
||||
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
|
||||
# Checks for header files.
|
||||
include(CheckIncludeFile)
|
||||
check_include_file("arpa/inet.h" HAVE_ARPA_INET_H)
|
||||
check_include_file("netinet/in.h" HAVE_NETINET_IN_H)
|
||||
check_include_file("stddef.h" HAVE_STDDEF_H)
|
||||
check_include_file("stdint.h" HAVE_STDINT_H)
|
||||
check_include_file("stdlib.h" HAVE_STDLIB_H)
|
||||
check_include_file("string.h" HAVE_STRING_H)
|
||||
check_include_file("unistd.h" HAVE_UNISTD_H)
|
||||
check_include_file("sys/endian.h" HAVE_SYS_ENDIAN_H)
|
||||
check_include_file("endian.h" HAVE_ENDIAN_H)
|
||||
check_include_file("byteswap.h" HAVE_BYTESWAP_H)
|
||||
|
||||
include(CheckTypeSize)
|
||||
check_type_size("ssize_t" SIZEOF_SSIZE_T)
|
||||
if(SIZEOF_SSIZE_T STREQUAL "")
|
||||
set(ssize_t ptrdiff_t)
|
||||
endif()
|
||||
|
||||
include(CheckSymbolExists)
|
||||
if(HAVE_ENDIAN_H)
|
||||
check_symbol_exists(be64toh "endian.h" HAVE_BE64TOH)
|
||||
endif()
|
||||
if(NOT HAVE_BE64TO AND HAVE_SYS_ENDIAN_H)
|
||||
check_symbol_exists(be64toh "sys/endian.h" HAVE_BE64TOH)
|
||||
endif()
|
||||
|
||||
check_symbol_exists(bswap_64 "byteswap.h" HAVE_BSWAP_64)
|
||||
|
||||
configure_file(ngtcp2/cmakeconfig.h.in ngtcp2/config.h)
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}/ngtcp2") # for config.h
|
||||
set(ENABLE_STATIC_LIB ON FORCE BOOL)
|
||||
set(ENABLE_SHARED_LIB OFF FORCE BOOL)
|
||||
add_subdirectory(ngtcp2/lib EXCLUDE_FROM_ALL)
|
||||
|
||||
target_compile_definitions(ngtcp2_static PRIVATE -DHAVE_CONFIG_H -D_GNU_SOURCE)
|
||||
endfunction()
|
@ -0,0 +1,18 @@
|
||||
set(WITH_STATIC OFF)
|
||||
set(WITH_SHARED ON)
|
||||
if("${SHADOW_ROOT}" STREQUAL "")
|
||||
set(SHADOW_ROOT "$ENV{HOME}/.shadow")
|
||||
endif("${SHADOW_ROOT}" STREQUAL "")
|
||||
if(EXISTS "${SHADOW_ROOT}")
|
||||
message(STATUS "SHADOW_ROOT = ${SHADOW_ROOT}")
|
||||
else()
|
||||
message(FATAL_ERROR "SHADOW_ROOT path does not exist: '${SHADOW_ROOT}'")
|
||||
endif(EXISTS "${SHADOW_ROOT}")
|
||||
|
||||
set(CMAKE_MODULE_PATH "${SHADOW_ROOT}/share/cmake/Modules")
|
||||
include_directories(${CMAKE_MODULE_PATH})
|
||||
include(ShadowTools)
|
||||
add_compile_options(-fno-inline -fno-strict-aliasing )
|
||||
add_definitions(-DTESTNET=1)
|
||||
add_definitions(-DLOKINET_SHADOW)
|
||||
include_directories(${SHADOW_ROOT}/include)
|
@ -1,7 +1,38 @@
|
||||
if(STATIC_LINK)
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
link_libraries( -static-libstdc++ )
|
||||
if(NOT STATIC_LINK)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# not supported on Solaris - system libraries are not available as archives
|
||||
# LTO is supported only for native builds
|
||||
if(SOLARIS)
|
||||
link_libraries( -static-libstdc++ -static-libgcc )
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_CROSSCOMPILING)
|
||||
add_compile_options(-static -flto)
|
||||
else()
|
||||
add_compile_options(-static)
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
if(APPLE)
|
||||
link_libraries( -flto)
|
||||
else()
|
||||
link_libraries( -static-libstdc++ -static-libgcc )
|
||||
link_libraries( -static -static-libstdc++ -pthread -flto )
|
||||
endif()
|
||||
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_CROSSCOMPILING)
|
||||
set(CMAKE_AR "gcc-ar")
|
||||
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_C_ARCHIVE_FINISH "true")
|
||||
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_CXX_ARCHIVE_FINISH "true")
|
||||
link_libraries( -flto -static-libstdc++ -static-libgcc -static ${CMAKE_CXX_FLAGS} ${CRYPTO_FLAGS} )
|
||||
else()
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc -static" )
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
|
||||
endif()
|
||||
|
@ -1,21 +1,83 @@
|
||||
if(NOT ANDROID)
|
||||
if(NOT UNIX)
|
||||
return()
|
||||
endif()
|
||||
if(NOT UNIX)
|
||||
return()
|
||||
endif()
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
include(CheckLibraryExists)
|
||||
|
||||
# can't have UNIX defined
|
||||
# can't have the include paths for libuv either?
|
||||
if(NOT IOS AND NOT ANDROID AND NOT WIN32)
|
||||
if(LIBCURL_ROOT)
|
||||
option(HTTP_ONLY "" ON)
|
||||
option(SSL_ENABLED "" OFF)
|
||||
option(BUILD_SHARED_LIBS "" OFF)
|
||||
option(ENABLE_IPV6 "" OFF)
|
||||
option(CMAKE_USE_OPENSSL "" OFF)
|
||||
option(CURL_CA_PATH "" OFF)
|
||||
set(CURL_CA_PATH none)
|
||||
message(STATUS "using local curl: ${LIBCURL_ROOT}")
|
||||
add_subdirectory(${LIBCURL_ROOT})
|
||||
set(CURL_INCLUDE_DIRS ${LIBCURL_ROOT}/include)
|
||||
set(CURL_LIBRARIES libcurl)
|
||||
set(CURL_FOUND TRUE)
|
||||
else()
|
||||
include(FindCURL)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_definitions(-DUNIX)
|
||||
add_definitions(-DPOSIX)
|
||||
list(APPEND LIBTUNTAP_SRC ${TT_ROOT}/tuntap-unix.c)
|
||||
|
||||
if (STATIC_LINK_RUNTIME OR STATIC_LINK)
|
||||
set(LIBUV_USE_STATIC ON)
|
||||
endif()
|
||||
|
||||
if(LIBUV_ROOT)
|
||||
add_subdirectory(${LIBUV_ROOT})
|
||||
set(LIBUV_INCLUDE_DIRS ${LIBUV_ROOT}/include)
|
||||
set(LIBUV_LIBRARY uv_a)
|
||||
add_definitions(-D_LARGEFILE_SOURCE)
|
||||
add_definitions(-D_FILE_OFFSET_BITS=64)
|
||||
elseif(NOT LIBUV_IN_SOURCE)
|
||||
find_package(LibUV 1.28.0 REQUIRED)
|
||||
endif()
|
||||
|
||||
include_directories(${LIBUV_INCLUDE_DIRS})
|
||||
|
||||
if(EMBEDDED_CFG OR ${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
link_libatomic()
|
||||
endif()
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD")
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
list(APPEND LIBTUNTAP_SRC ${TT_ROOT}/tuntap-unix-linux.c)
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Android")
|
||||
list(APPEND LIBTUNTAP_SRC ${TT_ROOT}/tuntap-unix-linux.c)
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD")
|
||||
add_definitions(-D_BSD_SOURCE)
|
||||
add_definitions(-D_GNU_SOURCE)
|
||||
add_definitions(-D_XOPEN_SOURCE=700)
|
||||
list(APPEND LIBTUNTAP_SRC ${TT_ROOT}/tuntap-unix-openbsd.c ${TT_ROOT}/tuntap-unix-bsd.c)
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "NetBSD")
|
||||
list(APPEND LIBTUNTAP_SRC ${TT_ROOT}/tuntap-unix-netbsd.c ${TT_ROOT}/tuntap-unix-bsd.c)
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD" OR ${CMAKE_SYSTEM_NAME} MATCHES "DragonFly")
|
||||
list(APPEND LIBTUNTAP_SRC ${TT_ROOT}/tuntap-unix-freebsd.c ${TT_ROOT}/tuntap-unix-bsd.c)
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" OR ${CMAKE_SYSTEM_NAME} MATCHES "iOS")
|
||||
list(APPEND LIBTUNTAP_SRC ${TT_ROOT}/tuntap-unix-darwin.c ${TT_ROOT}/tuntap-unix-bsd.c)
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
|
||||
list(APPEND LIBTUNTAP_SRC ${TT_ROOT}/tuntap-unix-sunos.c)
|
||||
# Apple C++ screws up name decorations in stdc++fs, causing link to fail
|
||||
# Samsung does not build c++experimental or c++fs in their Apple libc++ pkgsrc build
|
||||
if (LIBUV_USE_STATIC)
|
||||
link_libraries(-lkstat -lsendfile)
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "Your operating system - ${CMAKE_SYSTEM_NAME} is not supported yet")
|
||||
endif()
|
||||
|
||||
set(EXE_LIBS ${STATIC_LIB})
|
||||
|
||||
if(RELEASE_MOTTO)
|
||||
add_definitions(-DLLARP_RELEASE_MOTTO="${RELEASE_MOTTO}")
|
||||
endif()
|
||||
|
@ -1,49 +1,62 @@
|
||||
if(NOT WIN32)
|
||||
return()
|
||||
endif()
|
||||
if (NOT STATIC_LINK)
|
||||
message(FATAL_ERROR "windows requires static builds (thanks balmer)")
|
||||
endif()
|
||||
|
||||
enable_language(RC)
|
||||
|
||||
option(WITH_WINDOWS_32 "build 32 bit windows" OFF)
|
||||
|
||||
# unlike unix where you get a *single* compiler ID string in .comment
|
||||
# GNU ld sees fit to merge *all* the .ident sections in object files
|
||||
# to .r[o]data section one after the other!
|
||||
add_compile_options(-fno-ident -Wa,-mbig-obj)
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
|
||||
if(NOT MSVC_VERSION)
|
||||
add_compile_options($<$<COMPILE_LANGUAGE:C>:-Wno-bad-function-cast>)
|
||||
add_compile_options($<$<COMPILE_LANGUAGE:C>:-Wno-cast-function-type>)
|
||||
# unlike unix where you get a *single* compiler ID string in .comment
|
||||
# GNU ld sees fit to merge *all* the .ident sections in object files
|
||||
# to .r[o]data section one after the other!
|
||||
add_compile_options(-fno-ident -Wa,-mbig-obj)
|
||||
link_libraries( -lws2_32 -lshlwapi -ldbghelp -luser32 -liphlpapi -lpsapi -luserenv )
|
||||
add_definitions(-DWINVER=0x0500 -D_WIN32_WINNT=0x0500)
|
||||
if (CMAKE_C_COMPILER_AR AND STATIC_LINK_RUNTIME)
|
||||
add_compile_options(-flto)
|
||||
set(CMAKE_AR ${CMAKE_C_COMPILER_AR})
|
||||
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_C_ARCHIVE_FINISH "true")
|
||||
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_CXX_ARCHIVE_FINISH "true")
|
||||
link_libraries( -flto -static-libstdc++ -static-libgcc -static ${CMAKE_CXX_FLAGS} ${CRYPTO_FLAGS} )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(EMBEDDED_CFG)
|
||||
link_libatomic()
|
||||
endif()
|
||||
|
||||
set(WINTUN_VERSION 0.14.1 CACHE STRING "wintun version")
|
||||
set(WINTUN_MIRROR https://www.wintun.net/builds
|
||||
CACHE STRING "wintun mirror(s)")
|
||||
set(WINTUN_SOURCE wintun-${WINTUN_VERSION}.zip)
|
||||
set(WINTUN_HASH SHA256=07c256185d6ee3652e09fa55c0b673e2624b565e02c4b9091c79ca7d2f24ef51
|
||||
CACHE STRING "wintun source hash")
|
||||
|
||||
set(WINDIVERT_VERSION 2.2.0-A CACHE STRING "windivert version")
|
||||
set(WINDIVERT_MIRROR https://reqrypt.org/download
|
||||
CACHE STRING "windivert mirror(s)")
|
||||
set(WINDIVERT_SOURCE WinDivert-${WINDIVERT_VERSION}.zip)
|
||||
set(WINDIVERT_HASH SHA256=2a7630aac0914746fbc565ac862fa096e3e54233883ac52d17c83107496b7a7f
|
||||
CACHE STRING "windivert source hash")
|
||||
|
||||
set(WINTUN_URL ${WINTUN_MIRROR}/${WINTUN_SOURCE}
|
||||
CACHE STRING "wintun download url")
|
||||
set(WINDIVERT_URL ${WINDIVERT_MIRROR}/${WINDIVERT_SOURCE}
|
||||
CACHE STRING "windivert download url")
|
||||
|
||||
message(STATUS "Downloading wintun from ${WINTUN_URL}")
|
||||
file(DOWNLOAD ${WINTUN_URL} ${CMAKE_BINARY_DIR}/wintun.zip EXPECTED_HASH ${WINTUN_HASH})
|
||||
message(STATUS "Downloading windivert from ${WINDIVERT_URL}")
|
||||
file(DOWNLOAD ${WINDIVERT_URL} ${CMAKE_BINARY_DIR}/windivert.zip EXPECTED_HASH ${WINDIVERT_HASH})
|
||||
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E tar x ${CMAKE_BINARY_DIR}/wintun.zip
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E tar x ${CMAKE_BINARY_DIR}/windivert.zip
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
list(APPEND LIBTUNTAP_SRC ${TT_ROOT}/tuntap-windows.c)
|
||||
get_filename_component(EV_SRC "llarp/ev/ev_libuv.cpp" ABSOLUTE)
|
||||
add_definitions(-DWIN32_LEAN_AND_MEAN -DWIN32)
|
||||
set(EXE_LIBS ${STATIC_LIB} ws2_32 iphlpapi)
|
||||
|
||||
if(RELEASE_MOTTO)
|
||||
add_definitions(-DLLARP_RELEASE_MOTTO="${RELEASE_MOTTO}")
|
||||
add_definitions(-DRELEASE_MOTTO=${RELEASE_MOTTO})
|
||||
endif()
|
||||
|
||||
if (NOT STATIC_LINK_RUNTIME AND NOT MSVC)
|
||||
message("must ship compiler runtime libraries with this build: libwinpthread-1.dll, libgcc_s_dw2-1.dll, and libstdc++-6.dll")
|
||||
message("for release builds, turn on STATIC_LINK_RUNTIME in cmake options")
|
||||
endif()
|
||||
|
||||
if (STATIC_LINK_RUNTIME)
|
||||
set(LIBUV_USE_STATIC ON)
|
||||
endif()
|
||||
|
||||
if(LIBUV_ROOT)
|
||||
add_subdirectory(${LIBUV_ROOT})
|
||||
set(LIBUV_INCLUDE_DIRS ${LIBUV_ROOT}/include)
|
||||
set(LIBUV_LIBRARY uv_a)
|
||||
add_definitions(-D_LARGEFILE_SOURCE)
|
||||
add_definitions(-D_FILE_OFFSET_BITS=64)
|
||||
elseif(NOT LIBUV_IN_SOURCE)
|
||||
find_package(LibUV 1.28.0 REQUIRED)
|
||||
endif()
|
||||
|
||||
include_directories(${LIBUV_INCLUDE_DIRS})
|
||||
|
@ -1,46 +0,0 @@
|
||||
install(DIRECTORY ${CMAKE_BINARY_DIR}/gui DESTINATION share COMPONENT gui)
|
||||
|
||||
if(WITH_WINDOWS_32)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/wintun/bin/x86/wintun.dll DESTINATION bin COMPONENT lokinet)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/WinDivert-${WINDIVERT_VERSION}/x86/WinDivert.sys DESTINATION lib COMPONENT lokinet)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/WinDivert-${WINDIVERT_VERSION}/x86/WinDivert.dll DESTINATION bin COMPONENT lokinet)
|
||||
else()
|
||||
install(FILES ${CMAKE_BINARY_DIR}/wintun/bin/amd64/wintun.dll DESTINATION bin COMPONENT lokinet)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/WinDivert-${WINDIVERT_VERSION}/x64/WinDivert64.sys DESTINATION lib COMPONENT lokinet)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/WinDivert-${WINDIVERT_VERSION}/x64/WinDivert.dll DESTINATION bin COMPONENT lokinet)
|
||||
endif()
|
||||
|
||||
set(BOOTSTRAP_FILE "${PROJECT_SOURCE_DIR}/contrib/bootstrap/mainnet.signed")
|
||||
install(FILES ${BOOTSTRAP_FILE} DESTINATION share COMPONENT lokinet RENAME bootstrap.signed)
|
||||
|
||||
set(win_ico "${PROJECT_BINARY_DIR}/lokinet.ico")
|
||||
add_custom_command(OUTPUT "${win_ico}"
|
||||
COMMAND ${PROJECT_SOURCE_DIR}/contrib/make-ico.sh ${PROJECT_SOURCE_DIR}/contrib/lokinet.svg "${win_ico}"
|
||||
DEPENDS ${PROJECT_SOURCE_DIR}/contrib/lokinet.svg ${PROJECT_SOURCE_DIR}/contrib/make-ico.sh)
|
||||
add_custom_target(icon ALL DEPENDS "${win_ico}")
|
||||
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "Lokinet")
|
||||
set(CPACK_NSIS_MUI_ICON "${PROJECT_BINARY_DIR}/lokinet.ico")
|
||||
set(CPACK_NSIS_DEFINES "RequestExecutionLevel admin")
|
||||
set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
|
||||
|
||||
function(read_nsis_file filename outvar)
|
||||
file(STRINGS "${filename}" _outvar)
|
||||
list(TRANSFORM _outvar REPLACE "\\\\" "\\\\\\\\")
|
||||
list(JOIN _outvar "\\n" out)
|
||||
set(${outvar} ${out} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
read_nsis_file("${CMAKE_SOURCE_DIR}/win32-setup/extra_preinstall.nsis" _extra_preinstall)
|
||||
read_nsis_file("${CMAKE_SOURCE_DIR}/win32-setup/extra_install.nsis" _extra_install)
|
||||
read_nsis_file("${CMAKE_SOURCE_DIR}/win32-setup/extra_uninstall.nsis" _extra_uninstall)
|
||||
read_nsis_file("${CMAKE_SOURCE_DIR}/win32-setup/extra_create_icons.nsis" _extra_create_icons)
|
||||
read_nsis_file("${CMAKE_SOURCE_DIR}/win32-setup/extra_delete_icons.nsis" _extra_delete_icons)
|
||||
|
||||
set(CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS "${_extra_preinstall}")
|
||||
set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "${_extra_install}")
|
||||
set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "${_extra_uninstall}")
|
||||
set(CPACK_NSIS_CREATE_ICONS_EXTRA "${_extra_create_icons}")
|
||||
set(CPACK_NSIS_DELETE_ICONS_EXTRA "${_extra_delete_icons}")
|
||||
|
||||
set(CPACK_NSIS_COMPRESSOR "/SOLID lzma")
|
@ -1,13 +0,0 @@
|
||||
Place in `/etc/NetworkManager/dnsmasq.d/lokinet.conf`.
|
||||
|
||||
To make use of this, first install dnsmasq.
|
||||
|
||||
Then enable NetworkManager dnsmasq backend by editing `/etc/NetworkManager/NetworkManager.conf` to something like:
|
||||
```
|
||||
[main]
|
||||
dns=dnsmasq
|
||||
```
|
||||
If NetworkManager is currently running, restart it for changes to take effect:
|
||||
```
|
||||
sudo systemctl restart NetworkManager
|
||||
```
|
@ -1 +0,0 @@
|
||||
server=/loki/snode/127.3.2.1
|
@ -1,67 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
default_abis="armeabi-v7a arm64-v8a x86_64"
|
||||
build_abis=${ABIS:-$default_abis}
|
||||
|
||||
test x$NDK = x && test -e /usr/lib/android-ndk && export NDK=/usr/lib/android-ndk
|
||||
test x$NDK = x && exit 1
|
||||
|
||||
echo "building abis: $build_abis"
|
||||
|
||||
root=$(readlink -f "$1")
|
||||
shift
|
||||
build=$(readlink -f "$1")
|
||||
shift
|
||||
mkdir -p $build
|
||||
cd $build
|
||||
|
||||
for abi in $build_abis; do
|
||||
mkdir -p build-$abi
|
||||
cd build-$abi
|
||||
cmake \
|
||||
-S "$root" -B . \
|
||||
-G 'Unix Makefiles' \
|
||||
-DANDROID=ON \
|
||||
-DANDROID_ABI=$abi \
|
||||
-DANDROID_ARM_MODE=arm \
|
||||
-DANDROID_PLATFORM=android-23 \
|
||||
-DANDROID_API=23 \
|
||||
-DANDROID_STL=c++_static \
|
||||
-DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \
|
||||
-DBUILD_STATIC_DEPS=ON \
|
||||
-DBUILD_PACKAGE=ON \
|
||||
-DBUILD_SHARED_LIBS=OFF \
|
||||
-DBUILD_TESTING=OFF \
|
||||
-DWITH_TESTS=OFF \
|
||||
-DWITH_BOOTSTRAP=OFF \
|
||||
-DNATIVE_BUILD=OFF \
|
||||
-DSTATIC_LINK=ON \
|
||||
-DWITH_SYSTEMD=OFF \
|
||||
-DFORCE_OXENMQ_SUBMODULE=ON \
|
||||
-DFORCE_OXENC_SUBMODULE=ON \
|
||||
-DFORCE_FMT_SUBMODULE=ON \
|
||||
-DFORCE_SPDLOG_SUBMODULE=ON \
|
||||
-DFORCE_NLOHMANN_SUBMODULE=ON \
|
||||
-DSUBMODULE_CHECK=OFF \
|
||||
-DWITH_LTO=OFF \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
"$@"
|
||||
cd -
|
||||
done
|
||||
rm -f $build/Makefile
|
||||
echo "# generated makefile" >> $build/Makefile
|
||||
echo "all: $build_abis" >> $build/Makefile
|
||||
for abi in $build_abis; do
|
||||
echo -ne "$abi:\n\t" >> $build/Makefile
|
||||
echo -ne '$(MAKE) -C ' >> $build/Makefile
|
||||
echo "build-$abi lokinet-android" >> $build/Makefile
|
||||
echo -ne "\tmkdir -p out/$abi && cp build-$abi/jni/liblokinet-android.so out/$abi/liblokinet-android.so\n\n" >> $build/Makefile
|
||||
echo -ne "clean-$abi:\n\t" >> $build/Makefile
|
||||
echo -ne '$(MAKE) -C ' >> $build/Makefile
|
||||
echo "build-$abi clean" >> $build/Makefile
|
||||
done
|
||||
|
||||
echo -ne "clean:" >> $build/Makefile
|
||||
for targ in $build_abis ; do echo -ne " clean-$targ" >> $build/Makefile ; done
|
||||
echo "" >> $build/Makefile
|
@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
set +x
|
||||
|
||||
root="$(readlink -f $(dirname $0)/../)"
|
||||
cd "$root"
|
||||
./contrib/android-configure.sh . build-android "$@"
|
||||
make -C build-android -j ${JOBS:-$(nproc)}
|
@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
for f in "$@" ; do
|
||||
patch -p1 -i "$f"
|
||||
done
|
@ -1,109 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import pprint
|
||||
|
||||
if len(sys.argv) == 1 or (len(sys.argv) == 2 and sys.argv[1] == '-'):
|
||||
f = sys.stdin.buffer
|
||||
elif len(sys.argv) != 2 or sys.argv[1].startswith('-'):
|
||||
print("Usage: {} FILE -- dumps a bencoded file".format(sys.argv[0]), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
else:
|
||||
f = open(sys.argv[1], 'rb')
|
||||
|
||||
|
||||
initial = f.peek(2)
|
||||
is_hex = False
|
||||
if initial.startswith(b'64') or initial.startswith(b'6c'):
|
||||
print("Input looks like hex bencoded data; parsing as hex input", file=sys.stderr)
|
||||
is_hex = True
|
||||
|
||||
class HexPrinter():
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
|
||||
def __repr__(self):
|
||||
return "hex({} bytes):'{}'".format(len(self.data), self.data.hex())
|
||||
|
||||
|
||||
def next_byte():
|
||||
if is_hex:
|
||||
pair = f.read(2)
|
||||
assert pair is not None and len(pair) == 2
|
||||
b = int(pair, 16).to_bytes(1, 'big')
|
||||
else:
|
||||
b = f.read(1)
|
||||
assert b is not None and len(b) == 1
|
||||
return b
|
||||
|
||||
|
||||
def parse_int():
|
||||
s = b''
|
||||
x = next_byte()
|
||||
while x in b"0123456789-":
|
||||
s += x
|
||||
x = next_byte()
|
||||
assert x == b'e' and len(s) > 0, "Invalid integer encoding"
|
||||
return int(s)
|
||||
|
||||
|
||||
def parse_string(s):
|
||||
x = next_byte()
|
||||
while x in b"0123456789":
|
||||
s += x
|
||||
x = next_byte()
|
||||
assert x == b':', "Invalid string encoding"
|
||||
s = int(s)
|
||||
if is_hex:
|
||||
data = bytes.fromhex(f.read(2*s).decode('ascii'))
|
||||
else:
|
||||
data = f.read(s)
|
||||
assert len(data) == s, "Truncated string data"
|
||||
# If the string is ascii then convert to string:
|
||||
if all(0x20 <= b <= 0x7e for b in data):
|
||||
return data.decode()
|
||||
# Otherwise display as hex:
|
||||
return HexPrinter(data)
|
||||
|
||||
|
||||
def parse_dict():
|
||||
d = {}
|
||||
last_key = None
|
||||
while True:
|
||||
t = next_byte()
|
||||
if t == b'e':
|
||||
return d
|
||||
assert t in b"0123456789", "Invalid dict: dict keys must be strings"
|
||||
key = parse_string(t)
|
||||
raw_key = key.data if isinstance(key, HexPrinter) else key.encode()
|
||||
if last_key is not None and raw_key <= last_key:
|
||||
print("Warning: found out-of-order dict keys ({} after {})".format(raw_key, last_key), file=sys.stderr)
|
||||
last_key = raw_key
|
||||
t = next_byte()
|
||||
d[key] = parse_thing(t)
|
||||
|
||||
|
||||
def parse_list():
|
||||
l = []
|
||||
while True:
|
||||
t = next_byte()
|
||||
if t == b'e':
|
||||
return l
|
||||
l.append(parse_thing(t))
|
||||
|
||||
|
||||
def parse_thing(t):
|
||||
if t == b'd':
|
||||
return parse_dict()
|
||||
if t == b'l':
|
||||
return parse_list()
|
||||
if t == b'i':
|
||||
return parse_int()
|
||||
if t in b"0123456789":
|
||||
return parse_string(t)
|
||||
assert False, "Parsing error: encountered invalid type '{}'".format(t)
|
||||
|
||||
|
||||
pprint.PrettyPrinter(
|
||||
indent=2
|
||||
).pprint(parse_thing(next_byte()))
|
@ -0,0 +1 @@
|
||||
lokinet-bootserv
|
@ -0,0 +1,29 @@
|
||||
# replace your.server.tld with your server's fqdn
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name your.server.tld;
|
||||
location / {
|
||||
return 302 https://your.server.tld$request_uri;
|
||||
}
|
||||
location /.well-known/acme-challenge {
|
||||
root /var/www/letsencrypt;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name your.server.tld;
|
||||
ssl_certificate /etc/letsencrypt/live/your.server.tld/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/your.server.tld/privkey.pem;
|
||||
|
||||
location / {
|
||||
root /var/www/lokinet-bootserv;
|
||||
}
|
||||
|
||||
location /bootstrap.signed {
|
||||
include /etc/nginx/fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME /usr/local/bin/lokinet-bootserv;
|
||||
fastcgi_pass unix://tmp/cgi.sock;
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
|
||||
# set me to where the nodedb is for lokinet
|
||||
#[nodedb]
|
||||
#dir=/path/to/nodedb/
|
@ -0,0 +1,20 @@
|
||||
|
||||
SRC = $(sort $(wildcard src/*.cpp))
|
||||
OBJS = $(SRC:.cpp=.cpp.o)
|
||||
|
||||
CGI_EXE = lokinet-bootserv
|
||||
|
||||
CXX = clang++
|
||||
|
||||
all: build
|
||||
|
||||
build: $(CGI_EXE)
|
||||
|
||||
%.cpp.o: %.cpp
|
||||
$(CXX) -g -std=c++17 -c -Wall -Werror -Wpedantic $^ -o $^.o
|
||||
|
||||
$(CGI_EXE): $(OBJS)
|
||||
$(CXX) -o $(CGI_EXE) $^
|
||||
|
||||
clean:
|
||||
rm -f $(CGI_EXE) $(OBJS)
|
@ -0,0 +1,35 @@
|
||||
# lokinet-bootserv
|
||||
|
||||
cgi executable for serving a random RC for bootstrap from a nodedb
|
||||
|
||||
## configuring
|
||||
|
||||
copy the example config (privileged)
|
||||
|
||||
# cp configs/lokinet-bootserv.ini /usr/local/etc/lokinet-bootserv.ini
|
||||
|
||||
edit config to have proper values,
|
||||
specifically make sure the `[nodedb]` section has a `dir` value that points to a static copy of a healthy nodedb
|
||||
|
||||
## building
|
||||
|
||||
to build:
|
||||
|
||||
$ make
|
||||
|
||||
## installing (priviledged)
|
||||
|
||||
install cgi binary:
|
||||
|
||||
# cp lokinet-bootserv /usr/local/bin/lokinet-bootserv
|
||||
|
||||
set up with nginx cgi:
|
||||
|
||||
# cp configs/lokinet-bootserv-nginx.conf /etc/nginx/sites-available/lokinet-bootserv.conf
|
||||
# ln -s /etc/nginx/sites-available/lokinet-bootserv.conf /etc/nginx/sites-enabled/
|
||||
|
||||
## maintainence
|
||||
|
||||
add the following to crontab
|
||||
|
||||
0 0 * * * /usr/local/bin/lokinet-bootserv --cron
|
@ -0,0 +1,171 @@
|
||||
#include "lokinet-cgi.hpp"
|
||||
#include <fstream>
|
||||
#include <dirent.h>
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
|
||||
namespace lokinet
|
||||
{
|
||||
namespace bootserv
|
||||
{
|
||||
CGIHandler::CGIHandler(std::ostream& o) : Handler(o)
|
||||
{
|
||||
}
|
||||
|
||||
CGIHandler::~CGIHandler()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
CGIHandler::Exec(const Config& conf)
|
||||
{
|
||||
const char* e = getenv("REQUEST_METHOD");
|
||||
if(e == nullptr)
|
||||
return ReportError("$REQUEST_METHOD not set");
|
||||
std::string_view method(e);
|
||||
|
||||
if(method != "GET")
|
||||
{
|
||||
out << "Content-Type: text/plain" << std::endl;
|
||||
out << "Status: 405 Method Not Allowed" << std::endl << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string fname;
|
||||
if(!conf.VisitSection(
|
||||
"nodedb", [&](const Config::Section_t& sect) -> bool {
|
||||
auto itr = sect.find("dir");
|
||||
if(itr == sect.end())
|
||||
return false;
|
||||
fname = PickRandomFileInDir(
|
||||
std::string(itr->second.data(), itr->second.size()));
|
||||
return true;
|
||||
}))
|
||||
|
||||
return ReportError("bad values in nodedb section of config");
|
||||
if(fname.empty())
|
||||
{
|
||||
// no files in nodedb
|
||||
out << "Content-Type: text/plain" << std::endl;
|
||||
out << "Status: 404 Not Found" << std::endl << std::endl;
|
||||
return 0;
|
||||
}
|
||||
return ServeFile(fname.c_str(), "application/octect-stream");
|
||||
}
|
||||
|
||||
std::string
|
||||
CGIHandler::PickRandomFileInDir(std::string dirname) const
|
||||
{
|
||||
// collect files
|
||||
std::list< std::string > files;
|
||||
{
|
||||
DIR* d = opendir(dirname.c_str());
|
||||
if(d == nullptr)
|
||||
{
|
||||
return "";
|
||||
};
|
||||
std::list< std::string > subdirs;
|
||||
dirent* ent = nullptr;
|
||||
while((ent = readdir(d)))
|
||||
{
|
||||
std::string_view f = ent->d_name;
|
||||
if(f != "." && f != "..")
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << dirname;
|
||||
ss << '/';
|
||||
ss << f;
|
||||
subdirs.emplace_back(ss.str());
|
||||
}
|
||||
}
|
||||
closedir(d);
|
||||
for(const auto& subdir : subdirs)
|
||||
{
|
||||
d = opendir(subdir.c_str());
|
||||
if(d)
|
||||
{
|
||||
while((ent = readdir(d)))
|
||||
{
|
||||
std::string_view f;
|
||||
f = ent->d_name;
|
||||
if(f != "." && f != ".."
|
||||
&& f.find_last_of(".signed") != std::string_view::npos)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << subdir << "/" << f;
|
||||
files.emplace_back(ss.str());
|
||||
}
|
||||
}
|
||||
closedir(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
uint32_t randint;
|
||||
{
|
||||
std::basic_ifstream< uint32_t > randf("/dev/urandom");
|
||||
if(!randf.is_open())
|
||||
return "";
|
||||
randf.read(&randint, 1);
|
||||
}
|
||||
auto itr = files.begin();
|
||||
if(files.size() > 1)
|
||||
std::advance(itr, randint % files.size());
|
||||
return *itr;
|
||||
}
|
||||
|
||||
int
|
||||
CGIHandler::ServeFile(const char* fname, const char* contentType) const
|
||||
{
|
||||
std::ifstream f(fname);
|
||||
if(f.is_open())
|
||||
{
|
||||
f.seekg(0, std::ios::end);
|
||||
auto sz = f.tellg();
|
||||
f.seekg(0, std::ios::beg);
|
||||
if(sz)
|
||||
{
|
||||
out << "Content-Type: " << contentType << std::endl;
|
||||
out << "Status: 200 OK" << std::endl;
|
||||
out << "Content-Length: " << std::to_string(sz) << std::endl
|
||||
<< std::endl;
|
||||
char buf[512] = {0};
|
||||
size_t r = 0;
|
||||
while((r = f.readsome(buf, sizeof(buf))) > 0)
|
||||
out.write(buf, r);
|
||||
out << std::flush;
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "Content-Type: text/plain" << std::endl;
|
||||
out << "Status: 500 Internal Server Error" << std::endl << std::endl;
|
||||
out << "could not serve '" << fname << "' as it is an empty file"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "Content-Type: text/plain" << std::endl;
|
||||
out << "Status: 404 Not Found" << std::endl << std::endl;
|
||||
out << "could not serve '" << fname
|
||||
<< "' as it does not exist on the filesystem" << std::endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
CGIHandler::ReportError(const char* err)
|
||||
{
|
||||
out << "Content-Type: text/plain" << std::endl;
|
||||
out << "Status: 500 Internal Server Error" << std::endl << std::endl;
|
||||
out << err << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Handler_ptr
|
||||
NewCGIHandler(std::ostream& out)
|
||||
{
|
||||
return std::make_unique< CGIHandler >(out);
|
||||
}
|
||||
|
||||
} // namespace bootserv
|
||||
} // namespace lokinet
|
@ -0,0 +1,43 @@
|
||||
#ifndef LOKINET_BOOTSERV_HANDLER_HPP
|
||||
#define LOKINET_BOOTSERV_HANDLER_HPP
|
||||
#include <iostream>
|
||||
#include "lokinet-config.hpp"
|
||||
|
||||
namespace lokinet
|
||||
{
|
||||
namespace bootserv
|
||||
{
|
||||
struct Handler
|
||||
{
|
||||
Handler(std::ostream& o) : out(o){};
|
||||
|
||||
virtual ~Handler(){};
|
||||
|
||||
/// handle command
|
||||
/// return exit code
|
||||
virtual int
|
||||
Exec(const Config& conf) = 0;
|
||||
|
||||
/// report an error to system however that is done
|
||||
/// return exit code
|
||||
virtual int
|
||||
ReportError(const char* err) = 0;
|
||||
|
||||
protected:
|
||||
std::ostream& out;
|
||||
};
|
||||
|
||||
using Handler_ptr = std::unique_ptr< Handler >;
|
||||
|
||||
/// create cgi handler
|
||||
Handler_ptr
|
||||
NewCGIHandler(std::ostream& out);
|
||||
|
||||
/// create cron handler
|
||||
Handler_ptr
|
||||
NewCronHandler(std::ostream& out);
|
||||
|
||||
} // namespace bootserv
|
||||
} // namespace lokinet
|
||||
|
||||
#endif
|
@ -0,0 +1,31 @@
|
||||
#ifndef BOOTSERV_LOKINET_CRON_HPP
|
||||
#define BOOTSERV_LOKINET_CRON_HPP
|
||||
|
||||
#include "handler.hpp"
|
||||
|
||||
namespace lokinet
|
||||
{
|
||||
namespace bootserv
|
||||
{
|
||||
struct CGIHandler final : public Handler
|
||||
{
|
||||
CGIHandler(std::ostream& o);
|
||||
~CGIHandler();
|
||||
|
||||
int
|
||||
Exec(const Config& conf) override;
|
||||
|
||||
int
|
||||
ReportError(const char* err) override;
|
||||
|
||||
int
|
||||
ServeFile(const char* fname, const char* mime) const;
|
||||
|
||||
std::string
|
||||
PickRandomFileInDir(std::string dirname) const;
|
||||
};
|
||||
|
||||
} // namespace bootserv
|
||||
} // namespace lokinet
|
||||
|
||||
#endif
|
@ -0,0 +1,132 @@
|
||||
#include "lokinet-config.hpp"
|
||||
#include <fstream>
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
|
||||
namespace lokinet
|
||||
{
|
||||
namespace bootserv
|
||||
{
|
||||
const char* Config::DefaultPath = "/usr/local/etc/lokinet-bootserv.ini";
|
||||
|
||||
bool
|
||||
Config::LoadFile(const char* fname)
|
||||
{
|
||||
{
|
||||
std::ifstream f(fname);
|
||||
if(!f.is_open())
|
||||
return false;
|
||||
f.seekg(0, std::ios::end);
|
||||
m_Data.resize(f.tellg());
|
||||
f.seekg(0, std::ios::beg);
|
||||
if(m_Data.size() == 0)
|
||||
return false;
|
||||
f.read(m_Data.data(), m_Data.size());
|
||||
}
|
||||
return Parse();
|
||||
}
|
||||
|
||||
void
|
||||
Config::Clear()
|
||||
{
|
||||
m_Config.clear();
|
||||
m_Data.clear();
|
||||
}
|
||||
|
||||
bool
|
||||
Config::Parse()
|
||||
{
|
||||
std::list< String_t > lines;
|
||||
{
|
||||
auto itr = m_Data.begin();
|
||||
// split into lines
|
||||
while(itr != m_Data.end())
|
||||
{
|
||||
auto beg = itr;
|
||||
while(itr != m_Data.end() && *itr != '\n' && *itr != '\r')
|
||||
++itr;
|
||||
lines.emplace_back(std::addressof(*beg), (itr - beg));
|
||||
if(itr == m_Data.end())
|
||||
break;
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
String_t sectName;
|
||||
|
||||
for(const auto& line : lines)
|
||||
{
|
||||
String_t realLine;
|
||||
auto comment = line.find_first_of(';');
|
||||
if(comment == String_t::npos)
|
||||
comment = line.find_first_of('#');
|
||||
if(comment == String_t::npos)
|
||||
realLine = line;
|
||||
else
|
||||
realLine = line.substr(0, comment);
|
||||
// blank or commented line?
|
||||
if(realLine.size() == 0)
|
||||
continue;
|
||||
// find delimiters
|
||||
auto sectOpenPos = realLine.find_first_of('[');
|
||||
auto sectClosPos = realLine.find_first_of(']');
|
||||
auto kvDelim = realLine.find_first_of('=');
|
||||
if(sectOpenPos != String_t::npos && sectClosPos != String_t::npos
|
||||
&& kvDelim == String_t::npos)
|
||||
{
|
||||
// section header
|
||||
|
||||
// clamp whitespaces
|
||||
++sectOpenPos;
|
||||
while(std::isspace(realLine[sectOpenPos])
|
||||
&& sectOpenPos != sectClosPos)
|
||||
++sectOpenPos;
|
||||
--sectClosPos;
|
||||
while(std::isspace(realLine[sectClosPos])
|
||||
&& sectClosPos != sectOpenPos)
|
||||
--sectClosPos;
|
||||
// set section name
|
||||
sectName = realLine.substr(sectOpenPos, sectClosPos);
|
||||
}
|
||||
else if(kvDelim != String_t::npos)
|
||||
{
|
||||
// key value pair
|
||||
String_t::size_type k_start = 0;
|
||||
String_t::size_type k_end = kvDelim;
|
||||
String_t::size_type v_start = kvDelim + 1;
|
||||
String_t::size_type v_end = realLine.size() - 1;
|
||||
// clamp whitespaces
|
||||
while(std::isspace(realLine[k_start]) && k_start != kvDelim)
|
||||
++k_start;
|
||||
while(std::isspace(realLine[k_end]) && k_end != k_start)
|
||||
--k_end;
|
||||
while(std::isspace(realLine[v_start]) && v_start != v_end)
|
||||
++v_start;
|
||||
while(std::isspace(realLine[v_end]))
|
||||
--v_end;
|
||||
|
||||
// sect.k = v
|
||||
String_t k = realLine.substr(k_start, k_end);
|
||||
String_t v = realLine.substr(v_start, v_end);
|
||||
Section_t& sect = m_Config[sectName];
|
||||
sect[k] = v;
|
||||
}
|
||||
else // malformed?
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Config::VisitSection(
|
||||
const char* name,
|
||||
std::function< bool(const Section_t& sect) > visit) const
|
||||
{
|
||||
auto itr = m_Config.find(name);
|
||||
if(itr == m_Config.end())
|
||||
return false;
|
||||
return visit(itr->second);
|
||||
}
|
||||
|
||||
} // namespace bootserv
|
||||
} // namespace lokinet
|
@ -0,0 +1,47 @@
|
||||
#ifndef LOKINET_BOOTSERV_CONFIG_HPP
|
||||
#define LOKINET_BOOTSERV_CONFIG_HPP
|
||||
#include <unordered_map>
|
||||
#include <string_view>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace lokinet
|
||||
{
|
||||
namespace bootserv
|
||||
{
|
||||
struct Config
|
||||
{
|
||||
using String_t = std::string_view;
|
||||
using Section_t = std::unordered_map< String_t, String_t >;
|
||||
using Config_impl_t = std::unordered_map< String_t, Section_t >;
|
||||
|
||||
static const char* DefaultPath;
|
||||
|
||||
/// clear config
|
||||
void
|
||||
Clear();
|
||||
|
||||
/// load config file for bootserv
|
||||
/// return true on success
|
||||
/// return false on error
|
||||
bool
|
||||
LoadFile(const char* fname);
|
||||
|
||||
/// visit a section in config read only by name
|
||||
/// return false if no section or value propagated from visitor
|
||||
bool
|
||||
VisitSection(const char* name,
|
||||
std::function< bool(const Section_t&) > visit) const;
|
||||
|
||||
private:
|
||||
bool
|
||||
Parse();
|
||||
|
||||
std::vector< char > m_Data;
|
||||
Config_impl_t m_Config;
|
||||
};
|
||||
} // namespace bootserv
|
||||
} // namespace lokinet
|
||||
|
||||
#endif
|
@ -0,0 +1,37 @@
|
||||
#include "lokinet-cron.hpp"
|
||||
|
||||
namespace lokinet
|
||||
{
|
||||
namespace bootserv
|
||||
{
|
||||
CronHandler::CronHandler(std::ostream& o) : Handler(o)
|
||||
{
|
||||
}
|
||||
|
||||
CronHandler::~CronHandler()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
CronHandler::Exec(const Config& conf)
|
||||
{
|
||||
// this runs the cron tasks
|
||||
// TODO: implement me
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
CronHandler::ReportError(const char* err)
|
||||
{
|
||||
out << "error: " << err << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Handler_ptr
|
||||
NewCronHandler(std::ostream& out)
|
||||
{
|
||||
return std::make_unique< CronHandler >(out);
|
||||
}
|
||||
|
||||
} // namespace bootserv
|
||||
} // namespace lokinet
|
@ -0,0 +1,25 @@
|
||||
#ifndef BOOTSERV_LOKINET_CRON_HPP
|
||||
#define BOOTSERV_LOKINET_CRON_HPP
|
||||
|
||||
#include "handler.hpp"
|
||||
|
||||
namespace lokinet
|
||||
{
|
||||
namespace bootserv
|
||||
{
|
||||
struct CronHandler final : public Handler
|
||||
{
|
||||
CronHandler(std::ostream& o);
|
||||
~CronHandler();
|
||||
|
||||
int
|
||||
Exec(const Config& conf) override;
|
||||
|
||||
int
|
||||
ReportError(const char* err) override;
|
||||
};
|
||||
|
||||
} // namespace bootserv
|
||||
} // namespace lokinet
|
||||
|
||||
#endif
|
@ -0,0 +1,60 @@
|
||||
#include "handler.hpp"
|
||||
#include "lokinet-config.hpp"
|
||||
|
||||
#include <getopt.h>
|
||||
#include <string_view>
|
||||
#include <sstream>
|
||||
|
||||
static int
|
||||
printhelp(const char* exe)
|
||||
{
|
||||
std::cout << "usage: " << exe << " [--cron] [--conf /path/to/alt/config.ini]"
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
bool RunCron = false;
|
||||
|
||||
const char* confFile = lokinet::bootserv::Config::DefaultPath;
|
||||
lokinet::bootserv::Config config;
|
||||
|
||||
lokinet::bootserv::Handler_ptr handler;
|
||||
|
||||
option longopts[] = {{"cron", no_argument, 0, 'C'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"conf", required_argument, 0, 'c'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
int c = 0;
|
||||
int index = 0;
|
||||
while((c = getopt_long(argc, argv, "hCc:", longopts, &index)) != -1)
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
case 'h':
|
||||
return printhelp(argv[0]);
|
||||
case 'C':
|
||||
RunCron = true;
|
||||
break;
|
||||
case 'c':
|
||||
confFile = optarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(RunCron)
|
||||
handler = lokinet::bootserv::NewCronHandler(std::cout);
|
||||
else
|
||||
handler = lokinet::bootserv::NewCGIHandler(std::cout);
|
||||
|
||||
if(!config.LoadFile(confFile))
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "failed to load " << confFile;
|
||||
return handler->ReportError(ss.str().c_str());
|
||||
}
|
||||
else
|
||||
return handler->Exec(config);
|
||||
}
|
Binary file not shown.
@ -1,9 +0,0 @@
|
||||
## drone-ci docker jizz
|
||||
|
||||
To rebuild all ci images and push them to the oxen registry server do:
|
||||
|
||||
$ docker login registry.oxen.rocks
|
||||
$ ./rebuild-docker-images.py
|
||||
|
||||
If you aren't part of the Oxen team, you'll likely need to set up your own registry and change
|
||||
registry.oxen.rocks to your own domain name in order to do anything useful with this.
|
@ -1,350 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import subprocess
|
||||
import tempfile
|
||||
import optparse
|
||||
import sys
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
import threading
|
||||
|
||||
parser = optparse.OptionParser()
|
||||
parser.add_option("--no-cache", action="store_true",
|
||||
help="Run `docker build` with the `--no-cache` option to ignore existing images")
|
||||
parser.add_option("--parallel", "-j", type="int", default=1,
|
||||
help="Run up to this many builds in parallel")
|
||||
parser.add_option("--distro", type="string", default="",
|
||||
help="Build only this distro; should be DISTRO-CODE or DISTRO-CODE/ARCH, "
|
||||
"e.g. debian-sid/amd64")
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
registry_base = 'registry.oxen.rocks/lokinet-ci-'
|
||||
|
||||
distros = [*(('debian', x) for x in ('sid', 'stable', 'testing', 'bullseye', 'buster')),
|
||||
*(('ubuntu', x) for x in ('rolling', 'lts', 'impish', 'hirsute', 'focal', 'bionic'))]
|
||||
|
||||
if options.distro:
|
||||
d = options.distro.split('-')
|
||||
if len(d) != 2 or d[0] not in ('debian', 'ubuntu') or not d[1]:
|
||||
print("Bad --distro value '{}'".format(options.distro), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
distros = [(d[0], d[1].split('/')[0])]
|
||||
|
||||
|
||||
manifests = {} # "image:latest": ["image/amd64", "image/arm64v8", ...]
|
||||
manifestlock = threading.Lock()
|
||||
|
||||
|
||||
def arches(distro):
|
||||
if options.distro and '/' in options.distro:
|
||||
arch = options.distro.split('/')
|
||||
if arch not in ('amd64', 'i386', 'arm64v8', 'arm32v7'):
|
||||
print("Bad --distro value '{}'".format(options.distro), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
return [arch]
|
||||
|
||||
a = ['amd64', 'arm64v8', 'arm32v7']
|
||||
if distro[0] == 'debian' or distro == ('ubuntu', 'bionic'):
|
||||
a.append('i386') # i386 builds don't work on later ubuntu
|
||||
return a
|
||||
|
||||
|
||||
hacks = {
|
||||
registry_base + 'ubuntu-bionic-builder': """g++-8 \
|
||||
&& mkdir -p /usr/lib/x86_64-linux-gnu/pgm-5.2/include""",
|
||||
}
|
||||
|
||||
|
||||
failure = False
|
||||
|
||||
lineno = 0
|
||||
linelock = threading.Lock()
|
||||
|
||||
|
||||
def print_line(myline, value):
|
||||
linelock.acquire()
|
||||
global lineno
|
||||
if sys.__stdout__.isatty():
|
||||
jump = lineno - myline
|
||||
print("\033[{jump}A\r\033[K{value}\033[{jump}B\r".format(jump=jump, value=value), end='')
|
||||
sys.stdout.flush()
|
||||
else:
|
||||
print(value)
|
||||
linelock.release()
|
||||
|
||||
|
||||
def run_or_report(*args, myline):
|
||||
try:
|
||||
subprocess.run(
|
||||
args, check=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding='utf8')
|
||||
except subprocess.CalledProcessError as e:
|
||||
with tempfile.NamedTemporaryFile(suffix=".log", delete=False) as log:
|
||||
log.write("Error running {}: {}\n\nOutput:\n\n".format(' '.join(args), e).encode())
|
||||
log.write(e.output.encode())
|
||||
global failure
|
||||
failure = True
|
||||
print_line(myline, "\033[31;1mError! See {} for details".format(log.name))
|
||||
raise e
|
||||
|
||||
|
||||
def build_tag(tag_base, arch, contents):
|
||||
if failure:
|
||||
raise ChildProcessError()
|
||||
|
||||
linelock.acquire()
|
||||
global lineno
|
||||
myline = lineno
|
||||
lineno += 1
|
||||
print()
|
||||
linelock.release()
|
||||
|
||||
with tempfile.NamedTemporaryFile() as dockerfile:
|
||||
dockerfile.write(contents.encode())
|
||||
dockerfile.flush()
|
||||
|
||||
tag = '{}/{}'.format(tag_base, arch)
|
||||
print_line(myline, "\033[33;1mRebuilding \033[35;1m{}\033[0m".format(tag))
|
||||
run_or_report('docker', 'build', '--pull', '-f', dockerfile.name, '-t', tag,
|
||||
*(('--no-cache',) if options.no_cache else ()), '.', myline=myline)
|
||||
print_line(myline, "\033[33;1mPushing \033[35;1m{}\033[0m".format(tag))
|
||||
run_or_report('docker', 'push', tag, myline=myline)
|
||||
print_line(myline, "\033[32;1mFinished build \033[35;1m{}\033[0m".format(tag))
|
||||
|
||||
latest = tag_base + ':latest'
|
||||
global manifests
|
||||
manifestlock.acquire()
|
||||
if latest in manifests:
|
||||
manifests[latest].append(tag)
|
||||
else:
|
||||
manifests[latest] = [tag]
|
||||
manifestlock.release()
|
||||
|
||||
|
||||
def base_distro_build(distro, arch):
|
||||
tag = '{r}{distro[0]}-{distro[1]}-base'.format(r=registry_base, distro=distro)
|
||||
codename = 'latest' if distro == ('ubuntu', 'lts') else distro[1]
|
||||
build_tag(tag, arch, """
|
||||
FROM {}/{}:{}
|
||||
RUN /bin/bash -c 'echo "man-db man-db/auto-update boolean false" | debconf-set-selections'
|
||||
RUN apt-get -o=Dpkg::Use-Pty=0 -q update \
|
||||
&& apt-get -o=Dpkg::Use-Pty=0 -q dist-upgrade -y \
|
||||
&& apt-get -o=Dpkg::Use-Pty=0 -q autoremove -y \
|
||||
{hacks}
|
||||
""".format(arch, distro[0], codename, hacks=hacks.get(tag, '')))
|
||||
|
||||
|
||||
def distro_build(distro, arch):
|
||||
prefix = '{r}{distro[0]}-{distro[1]}'.format(r=registry_base, distro=distro)
|
||||
fmtargs = dict(arch=arch, distro=distro, prefix=prefix)
|
||||
|
||||
# (distro)-(codename)-base: Base image from upstream: we sync the repos, but do nothing else.
|
||||
if (distro, arch) != (('debian', 'stable'), 'amd64'): # debian-stable-base/amd64 already built
|
||||
base_distro_build(distro, arch)
|
||||
|
||||
# (distro)-(codename)-builder: Deb builder image used for building debs; we add the basic tools
|
||||
# we use to build debs, not including things that should come from the dependencies in the
|
||||
# debian/control file.
|
||||
build_tag(prefix + '-builder', arch, """
|
||||
FROM {prefix}-base/{arch}
|
||||
RUN apt-get -o=Dpkg::Use-Pty=0 -q update \
|
||||
&& apt-get -o=Dpkg::Use-Pty=0 -q dist-upgrade -y \
|
||||
&& apt-get -o=Dpkg::Use-Pty=0 --no-install-recommends -q install -y \
|
||||
ccache \
|
||||
devscripts \
|
||||
equivs \
|
||||
g++ \
|
||||
git \
|
||||
git-buildpackage \
|
||||
openssh-client \
|
||||
{hacks}
|
||||
""".format(**fmtargs, hacks=hacks.get(prefix + '-builder', '')))
|
||||
|
||||
# (distro)-(codename): Basic image we use for most builds. This takes the -builder and adds
|
||||
# most dependencies found in our packages.
|
||||
build_tag(prefix, arch, """
|
||||
FROM {prefix}-builder/{arch}
|
||||
RUN apt-get -o=Dpkg::Use-Pty=0 -q update \
|
||||
&& apt-get -o=Dpkg::Use-Pty=0 -q dist-upgrade -y \
|
||||
&& apt-get -o=Dpkg::Use-Pty=0 --no-install-recommends -q install -y \
|
||||
automake \
|
||||
ccache \
|
||||
cmake \
|
||||
eatmydata \
|
||||
g++ \
|
||||
gdb \
|
||||
git \
|
||||
libboost-program-options-dev \
|
||||
libboost-serialization-dev \
|
||||
libboost-thread-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libevent-dev \
|
||||
libgtest-dev \
|
||||
libhidapi-dev \
|
||||
libjemalloc-dev \
|
||||
libminiupnpc-dev \
|
||||
libreadline-dev \
|
||||
libsodium-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libsystemd-dev \
|
||||
libtool \
|
||||
libunbound-dev \
|
||||
libunwind8-dev \
|
||||
libusb-1.0.0-dev \
|
||||
libuv1-dev \
|
||||
libzmq3-dev \
|
||||
lsb-release \
|
||||
make \
|
||||
nettle-dev \
|
||||
ninja-build \
|
||||
openssh-client \
|
||||
patch \
|
||||
pkg-config \
|
||||
pybind11-dev \
|
||||
python3-dev \
|
||||
python3-pip \
|
||||
python3-pybind11 \
|
||||
python3-pytest \
|
||||
python3-setuptools \
|
||||
qttools5-dev \
|
||||
{hacks}
|
||||
""".format(**fmtargs, hacks=hacks.get(prefix, '')))
|
||||
|
||||
|
||||
# Android and flutter builds on top of debian-stable-base and adds a ton of android crap; we
|
||||
# schedule this job as soon as the debian-sid-base/amd64 build finishes, because they easily take
|
||||
# the longest and are by far the biggest images.
|
||||
def android_builds():
|
||||
build_tag(registry_base + 'android', 'amd64', """
|
||||
FROM {r}debian-stable-base
|
||||
RUN /bin/bash -c 'sed -i "s/main/main contrib/g" /etc/apt/sources.list'
|
||||
RUN apt-get -o=Dpkg::Use-Pty=0 -q update \
|
||||
&& apt-get -o=Dpkg::Use-Pty=0 -q dist-upgrade -y \
|
||||
&& apt-get -o=Dpkg::Use-Pty=0 -q install --no-install-recommends -y \
|
||||
android-sdk \
|
||||
automake \
|
||||
ccache \
|
||||
cmake \
|
||||
curl \
|
||||
git \
|
||||
google-android-ndk-installer \
|
||||
libtool \
|
||||
make \
|
||||
openssh-client \
|
||||
patch \
|
||||
pkg-config \
|
||||
wget \
|
||||
xz-utils \
|
||||
zip \
|
||||
&& git clone https://github.com/Shadowstyler/android-sdk-licenses.git /tmp/android-sdk-licenses \
|
||||
&& cp -a /tmp/android-sdk-licenses/*-license /usr/lib/android-sdk/licenses \
|
||||
&& rm -rf /tmp/android-sdk-licenses
|
||||
""".format(r=registry_base))
|
||||
|
||||
build_tag(registry_base + 'flutter', 'amd64', """
|
||||
FROM {r}android
|
||||
RUN cd /opt \
|
||||
&& curl https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_2.2.2-stable.tar.xz \
|
||||
| tar xJv \
|
||||
&& ln -s /opt/flutter/bin/flutter /usr/local/bin/ \
|
||||
&& flutter precache
|
||||
""".format(r=registry_base))
|
||||
|
||||
|
||||
# lint is a tiny build (on top of debian-stable-base) with just formatting checking tools
|
||||
def lint_build():
|
||||
build_tag(registry_base + 'lint', 'amd64', """
|
||||
FROM {r}debian-stable-base
|
||||
RUN apt-get -o=Dpkg::Use-Pty=0 -q install --no-install-recommends -y \
|
||||
clang-format-11 \
|
||||
eatmydata \
|
||||
git \
|
||||
jsonnet
|
||||
""".format(r=registry_base))
|
||||
|
||||
|
||||
def nodejs_build():
|
||||
build_tag(registry_base + 'nodejs', 'amd64', """
|
||||
FROM node:14.16.1
|
||||
RUN /bin/bash -c 'echo "man-db man-db/auto-update boolean false" | debconf-set-selections'
|
||||
RUN apt-get -o=Dpkg::Use-Pty=0 -q update \
|
||||
&& apt-get -o=Dpkg::Use-Pty=0 -q dist-upgrade -y \
|
||||
&& apt-get -o=Dpkg::Use-Pty=0 -q install --no-install-recommends -y \
|
||||
ccache \
|
||||
cmake \
|
||||
eatmydata \
|
||||
g++ \
|
||||
gdb \
|
||||
git \
|
||||
make \
|
||||
ninja-build \
|
||||
openssh-client \
|
||||
patch \
|
||||
pkg-config \
|
||||
wine
|
||||
""")
|
||||
|
||||
|
||||
# Start debian-stable-base/amd64 on its own, because other builds depend on it and we want to get
|
||||
# those (especially android/flutter) fired off as soon as possible (because it's slow and huge).
|
||||
if ('debian', 'stable') in distros:
|
||||
base_distro_build(['debian', 'stable'], 'amd64')
|
||||
|
||||
executor = ThreadPoolExecutor(max_workers=max(options.parallel, 1))
|
||||
|
||||
if options.distro:
|
||||
jobs = []
|
||||
else:
|
||||
jobs = [executor.submit(b) for b in (android_builds, lint_build, nodejs_build)]
|
||||
|
||||
for d in distros:
|
||||
for a in arches(d):
|
||||
jobs.append(executor.submit(distro_build, d, a))
|
||||
while len(jobs):
|
||||
j = jobs.pop(0)
|
||||
try:
|
||||
j.result()
|
||||
except (ChildProcessError, subprocess.CalledProcessError):
|
||||
for k in jobs:
|
||||
k.cancel()
|
||||
|
||||
|
||||
if failure:
|
||||
print("Error(s) occured, aborting!", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
print("\n\n\033[32;1mAll builds finished successfully; pushing manifests...\033[0m\n")
|
||||
|
||||
|
||||
def push_manifest(latest, tags):
|
||||
if failure:
|
||||
raise ChildProcessError()
|
||||
|
||||
linelock.acquire()
|
||||
global lineno
|
||||
myline = lineno
|
||||
lineno += 1
|
||||
print()
|
||||
linelock.release()
|
||||
|
||||
subprocess.run(['docker', 'manifest', 'rm', latest], stderr=subprocess.DEVNULL, check=False)
|
||||
print_line(myline, "\033[33;1mCreating manifest \033[35;1m{}\033[0m".format(latest))
|
||||
run_or_report('docker', 'manifest', 'create', latest, *tags, myline=myline)
|
||||
print_line(myline, "\033[33;1mPushing manifest \033[35;1m{}\033[0m".format(latest))
|
||||
run_or_report('docker', 'manifest', 'push', latest, myline=myline)
|
||||
print_line(myline, "\033[32;1mFinished manifest \033[35;1m{}\033[0m".format(latest))
|
||||
|
||||
|
||||
for latest, tags in manifests.items():
|
||||
jobs.append(executor.submit(push_manifest, latest, tags))
|
||||
|
||||
while len(jobs):
|
||||
j = jobs.pop(0)
|
||||
try:
|
||||
j.result()
|
||||
except (ChildProcessError, subprocess.CalledProcessError):
|
||||
for k in jobs:
|
||||
k.cancel()
|
||||
|
||||
|
||||
print("\n\n\033[32;1mAll done!\n")
|
@ -1,28 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Script used with Drone CI to check that a statically build lokinet only links against the expected
|
||||
# base system libraries. Expects to be run with pwd of the build directory.
|
||||
|
||||
set -o errexit
|
||||
|
||||
bad=
|
||||
if [ "$DRONE_STAGE_OS" == "darwin" ]; then
|
||||
if otool -L llarp/apple/org.lokinet.network-extension.systemextension/Contents/MacOS/org.lokinet.network-extension | \
|
||||
grep -Ev '^llarp/apple:|^\t(/usr/lib/lib(System\.|c\+\+|objc))|/System/Library/Frameworks/(CoreFoundation|NetworkExtension|Foundation|Network)\.framework'; then
|
||||
bad=1
|
||||
fi
|
||||
elif [ "$DRONE_STAGE_OS" == "linux" ]; then
|
||||
if ldd daemon/lokinet | grep -Ev '(linux-vdso|ld-linux-(x86-64|armhf|aarch64)|lib(pthread|dl|rt|stdc\+\+|gcc_s|c|m))\.so'; then
|
||||
bad=1
|
||||
fi
|
||||
else
|
||||
echo -e "\n\n\n\n\e[31;1mDon't know how to check linked libs on $DRONE_STAGE_OS\e[0m\n\n\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "$bad" ]; then
|
||||
echo -e "\n\n\n\n\e[31;1mlokinet links to unexpected libraries\e[0m\n\n\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "\n\n\n\n\e[32;1mNo unexpected linked libraries found\e[0m\n\n\n"
|
@ -1,50 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script used with Drone CI to upload debs from the deb building pipelines (because specifying all
|
||||
# this in .drone.jsonnet is too painful). This is expected to run from the base project dir after
|
||||
# having build with debuild (which will leave the debs in ..).
|
||||
|
||||
set -o errexit
|
||||
|
||||
distro="$1"
|
||||
|
||||
if [ -z "$distro" ]; then
|
||||
echo "Bad usage: need distro name as first argument"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$SSH_KEY" ]; then
|
||||
echo -e "\n\n\n\e[31;1mUnable to upload debs: SSH_KEY not set\e[0m"
|
||||
# Just warn but don't fail, so that this doesn't trigger a build failure for untrusted builds
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "$SSH_KEY" >~/ssh_key
|
||||
|
||||
set -o xtrace # Don't start tracing until *after* we write the ssh key
|
||||
|
||||
chmod 600 ~/ssh_key
|
||||
|
||||
upload_to="oxen.rocks/debs/${DRONE_REPO// /_}@${DRONE_BRANCH// /_}/$(date --date=@$DRONE_BUILD_CREATED +%Y%m%dT%H%M%SZ)-${DRONE_COMMIT:0:9}/$distro/$DRONE_STAGE_ARCH"
|
||||
|
||||
# sftp doesn't have any equivalent to mkdir -p, so we have to split the above up into a chain of
|
||||
# -mkdir a/, -mkdir a/b/, -mkdir a/b/c/, ... commands. The leading `-` allows the command to fail
|
||||
# without error.
|
||||
upload_dirs=(${upload_to//\// })
|
||||
mkdirs=
|
||||
dir_tmp=""
|
||||
for p in "${upload_dirs[@]}"; do
|
||||
dir_tmp="$dir_tmp$p/"
|
||||
mkdirs="$mkdirs
|
||||
-mkdir $dir_tmp"
|
||||
done
|
||||
|
||||
sftp -i ~/ssh_key -b - -o StrictHostKeyChecking=off drone@oxen.rocks <<SFTP
|
||||
$mkdirs
|
||||
put ../*.*deb $upload_to
|
||||
SFTP
|
||||
|
||||
set +o xtrace
|
||||
|
||||
echo -e "\n\n\n\n\e[32;1mUploaded debs to https://${upload_to}/\e[0m\n\n\n"
|
||||
|
@ -1,9 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
test "x$IGNORE" != "x" && exit 0
|
||||
|
||||
. $(dirname $0)/../format-version.sh
|
||||
|
||||
repo=$(readlink -e $(dirname $0)/../../)
|
||||
$CLANG_FORMAT -i $(find $repo/jni $repo/daemon $repo/llarp $repo/include $repo/pybind | grep -E '\.[hc](pp)?$')
|
||||
jsonnetfmt -i $repo/.drone.jsonnet
|
||||
git --no-pager diff --exit-code --color || (echo -ne '\n\n\e[31;1mLint check failed; please run ./contrib/format.sh\e[0m\n\n' ; exit 1)
|
@ -1,5 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
rm -f crash.out.txt exit.out.txt
|
||||
gdb -q -x $(readlink -e $(dirname $0))/gdb-filter.py --args $@
|
||||
test -e crash.out.txt && cat crash.out.txt
|
||||
exit $(cat exit.out.txt)
|
@ -1,6 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
export PYTHONPATH=pybind
|
||||
rm -f crash.out.txt exit.out.txt
|
||||
gdb -q -x $(readlink -e $(dirname $0))/gdb-filter.py --args /usr/bin/python3 -m pytest ../test/
|
||||
test -e crash.out.txt && cat crash.out.txt
|
||||
exit $(cat exit.out.txt)
|
@ -1,96 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Script used with Drone CI to upload build artifacts (because specifying all this in
|
||||
# .drone.jsonnet is too painful).
|
||||
|
||||
|
||||
|
||||
set -o errexit
|
||||
|
||||
if [ -z "$SSH_KEY" ]; then
|
||||
echo -e "\n\n\n\e[31;1mUnable to upload artifact: SSH_KEY not set\e[0m"
|
||||
# Just warn but don't fail, so that this doesn't trigger a build failure for untrusted builds
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "$SSH_KEY" >ssh_key
|
||||
|
||||
set -o xtrace # Don't start tracing until *after* we write the ssh key
|
||||
|
||||
chmod 600 ssh_key
|
||||
|
||||
os="$UPLOAD_OS"
|
||||
if [ -z "$os" ]; then
|
||||
if [ "$DRONE_STAGE_OS" == "darwin" ]; then
|
||||
os="macos-$DRONE_STAGE_ARCH"
|
||||
elif [ -n "$WINDOWS_BUILD_NAME" ]; then
|
||||
os="windows-$WINDOWS_BUILD_NAME"
|
||||
else
|
||||
os="$DRONE_STAGE_OS-$DRONE_STAGE_ARCH"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$DRONE_TAG" ]; then
|
||||
# For a tag build use something like `lokinet-linux-amd64-v1.2.3`
|
||||
base="lokinet-$os-$DRONE_TAG"
|
||||
else
|
||||
# Otherwise build a length name from the datetime and commit hash, such as:
|
||||
# lokinet-linux-amd64-20200522T212342Z-04d7dcc54
|
||||
base="lokinet-$os-$(date --date=@$DRONE_BUILD_CREATED +%Y%m%dT%H%M%SZ)-${DRONE_COMMIT:0:9}"
|
||||
fi
|
||||
|
||||
mkdir -v "$base"
|
||||
if [ -e build/win32 ]; then
|
||||
# save debug symbols
|
||||
cp -av build/win32/daemon/debug-symbols.tar.xz "$base-debug-symbols.tar.xz"
|
||||
# save installer
|
||||
cp -av build/win32/*.exe "$base"
|
||||
# zipit up yo
|
||||
archive="$base.zip"
|
||||
zip -r "$archive" "$base"
|
||||
elif [ -e lokinet.apk ] ; then
|
||||
# android af ngl
|
||||
archive="$base.apk"
|
||||
cp -av lokinet.apk "$archive"
|
||||
elif [ -e build-docs ]; then
|
||||
archive="$base.tar.xz"
|
||||
cp -av build-docs/docs/mkdocs.yml build-docs/docs/markdown "$base"
|
||||
tar cJvf "$archive" "$base"
|
||||
elif [ -e build-mac ]; then
|
||||
archive="$base.tar.xz"
|
||||
mv build-mac/Lokinet*/ "$base"
|
||||
tar cJvf "$archive" "$base"
|
||||
else
|
||||
cp -av build/daemon/lokinet{,-vpn} "$base"
|
||||
cp -av contrib/bootstrap/mainnet.signed "$base/bootstrap.signed"
|
||||
# tar dat shiz up yo
|
||||
archive="$base.tar.xz"
|
||||
tar cJvf "$archive" "$base"
|
||||
fi
|
||||
|
||||
upload_to="oxen.rocks/${DRONE_REPO// /_}/${DRONE_BRANCH// /_}"
|
||||
|
||||
# sftp doesn't have any equivalent to mkdir -p, so we have to split the above up into a chain of
|
||||
# -mkdir a/, -mkdir a/b/, -mkdir a/b/c/, ... commands. The leading `-` allows the command to fail
|
||||
# without error.
|
||||
upload_dirs=(${upload_to//\// })
|
||||
put_debug=
|
||||
mkdirs=
|
||||
dir_tmp=""
|
||||
for p in "${upload_dirs[@]}"; do
|
||||
dir_tmp="$dir_tmp$p/"
|
||||
mkdirs="$mkdirs
|
||||
-mkdir $dir_tmp"
|
||||
done
|
||||
if [ -e "$base-debug-symbols.tar.xz" ] ; then
|
||||
put_debug="put $base-debug-symbols.tar.xz $upload_to"
|
||||
fi
|
||||
sftp -i ssh_key -b - -o StrictHostKeyChecking=off drone@oxen.rocks <<SFTP
|
||||
$mkdirs
|
||||
put $archive $upload_to
|
||||
$put_debug
|
||||
SFTP
|
||||
|
||||
set +o xtrace
|
||||
|
||||
echo -e "\n\n\n\n\e[32;1mUploaded to https://${upload_to}/${archive}\e[0m\n\n\n"
|
@ -1,36 +0,0 @@
|
||||
def exit_handler (event):
|
||||
"""
|
||||
write exit code of the program running in gdb to a file called exit.out.txt
|
||||
"""
|
||||
code = 1
|
||||
if hasattr(event, "exit_code"):
|
||||
code = event.exit_code
|
||||
with open("exit.out.txt", 'w') as f:
|
||||
f.write("{}".format(code))
|
||||
|
||||
def gdb_execmany(*cmds):
|
||||
"""
|
||||
run multiple gdb commands
|
||||
"""
|
||||
for cmd in cmds:
|
||||
gdb.execute(cmd)
|
||||
|
||||
def crash_handler (event):
|
||||
"""
|
||||
handle a crash from the program running in gdb
|
||||
"""
|
||||
if isinstance(event, gdb.SignalEvent):
|
||||
log_file_name = "crash.out.txt"
|
||||
# poop out log file for stack trace of all threads
|
||||
gdb_execmany("set logging file {}".format(log_file_name), "set logging on", "set logging redirect on", "thread apply all bt full")
|
||||
# quit gdb
|
||||
gdb.execute("q")
|
||||
|
||||
# set up event handlers to catch shit
|
||||
gdb.events.stop.connect(crash_handler)
|
||||
gdb.events.exited.connect(exit_handler)
|
||||
|
||||
# run settings setup
|
||||
gdb_execmany("set confirm off", "set pagination off", "set print thread-events off")
|
||||
# run program and exit
|
||||
gdb_execmany("r", "q")
|
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
rm -fr loki*/tmp-nodes
|
||||
rm loki*/profile.dat
|
@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
# copy a lokinet binary into this cluster
|
||||
cp ../../lokinet .
|
||||
# generate default config file
|
||||
./lokinet -g -r lokinet.ini
|
||||
# make seed node
|
||||
./makenode.sh 1
|
||||
# establish bootstrap
|
||||
ln -s loki1/self.signed bootstrap.signed
|
@ -0,0 +1,7 @@
|
||||
mkdir loki$1
|
||||
cd loki$1
|
||||
ln -s ../lokinet lokinet$1
|
||||
cp ../lokinet.ini .
|
||||
nano lokinet.ini
|
||||
cd ..
|
||||
echo "killall -9 lokinet$1" >> ../stop.sh
|
@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
set +x
|
||||
cd loki1
|
||||
nohup ./lokinet1 $PWD/lokinet.ini &
|
||||
# seed node needs some time to write RC to make sure it's not expired on load for the rest
|
||||
sleep 1
|
||||
cd ../loki2
|
||||
nohup ./lokinet2 $PWD/lokinet.ini &
|
||||
cd ../loki3
|
||||
nohup ./lokinet3 $PWD/lokinet.ini &
|
||||
cd ../loki4
|
||||
nohup ./lokinet4 $PWD/lokinet.ini &
|
||||
cd ../loki5
|
||||
nohup ./lokinet5 $PWD/lokinet.ini &
|
||||
cd ..
|
||||
tail -f loki*/nohup.out
|
@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
killall -9 lokinet1
|
||||
killall -9 lokinet2
|
||||
killall -9 lokinet3
|
||||
killall -9 lokinet4
|
||||
killall -9 lokinet5
|
||||
killall -9 lokinet6
|
@ -1,2 +0,0 @@
|
||||
[logging]
|
||||
level=debug
|
@ -1,5 +0,0 @@
|
||||
#
|
||||
# "suggested" default exit node config
|
||||
#
|
||||
[network]
|
||||
exit-node=exit.loki
|
@ -1,5 +0,0 @@
|
||||
#
|
||||
# persist .loki address in a private key file in the data dir
|
||||
#
|
||||
[network]
|
||||
keyfile=lokinet-addr.privkey
|
@ -1,65 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# helper script for me for when i cross compile
|
||||
# t. jeff
|
||||
#
|
||||
set -e
|
||||
|
||||
die() {
|
||||
echo $@
|
||||
exit 1
|
||||
}
|
||||
|
||||
platform=${PLATFORM:-Linux}
|
||||
root="$(readlink -e $(dirname $0)/../)"
|
||||
cd $root
|
||||
mkdir -p build-cross
|
||||
|
||||
targets=()
|
||||
cmake_extra=()
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
if [ "$1" = "--" ]; then
|
||||
shift
|
||||
cmake_extra=("$@")
|
||||
break
|
||||
fi
|
||||
targets+=("$1")
|
||||
shift
|
||||
done
|
||||
test ${#targets[@]} = 0 && die no targets provided
|
||||
|
||||
archs="${targets[@]}"
|
||||
echo "all: $archs" > build-cross/Makefile
|
||||
for arch in $archs ; do
|
||||
mkdir -p $root/build-cross/build-$arch
|
||||
cd $root/build-cross/build-$arch
|
||||
cmake \
|
||||
-G 'Unix Makefiles' \
|
||||
-DCROSS_PLATFORM=$platform \
|
||||
-DCROSS_PREFIX=$arch \
|
||||
-DCMAKE_EXE_LINKER_FLAGS=-fstack-protector \
|
||||
-DCMAKE_CXX_FLAGS=-fdiagnostics-color=always \
|
||||
-DCMAKE_TOOLCHAIN_FILE=$root/contrib/cross/cross.toolchain.cmake \
|
||||
-DBUILD_STATIC_DEPS=ON \
|
||||
-DSTATIC_LINK=ON \
|
||||
-DBUILD_SHARED_LIBS=OFF \
|
||||
-DBUILD_TESTING=OFF \
|
||||
-DBUILD_LIBLOKINET=OFF \
|
||||
-DWITH_TESTS=OFF \
|
||||
-DNATIVE_BUILD=OFF \
|
||||
-DSTATIC_LINK=ON \
|
||||
-DWITH_SYSTEMD=OFF \
|
||||
-DFORCE_OXENMQ_SUBMODULE=ON \
|
||||
-DSUBMODULE_CHECK=OFF \
|
||||
-DWITH_LTO=OFF \
|
||||
-DWITH_BOOTSTRAP=OFF \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDeb \
|
||||
"${cmake_extra[@]}" \
|
||||
$root
|
||||
cd $root/build-cross
|
||||
echo -ne "$arch:\n\t\$(MAKE) -C build-$arch\n" >> $root/build-cross/Makefile
|
||||
|
||||
done
|
||||
cd $root
|
||||
make -j${JOBS:-$(nproc)} -C build-cross
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue