code:
cmake_minimum_required (VERSION 3.19)
project (syncspirit VERSION 0.4.0)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)

cmake_policy(SET CMP0063 NEW)
cmake_policy(SET CMP0077 NEW)
cmake_policy(SET CMP0091 NEW)
cmake_policy(SET CMP0135 NEW)

include(GenerateExportHeader)
include (FetchContent)

if (WIN32)
    # set(CMAKE_CROSSCOMPILING on)
    # set(CMAKE_CROSSCOMPILING_EMULATOR "/usr/bin/wine")
endif()

set(CMAKE_POSITION_INDEPENDENT_CODE True)

#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
#set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")

find_package(
    Boost
    COMPONENTS
        nowide
        program_options
        system
        url
    REQUIRED
)
find_package(OpenSSL REQUIRED)
find_package(protopuf REQUIRED)
find_package(ZLIB REQUIRED)
find_package(rotor COMPONENTS asio thread REQUIRED)
find_package(lz4 REQUIRED)
find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)
find_package(protopuf REQUIRED)
find_package(pugixml REQUIRED)
find_package(tomlplusplus REQUIRED)
find_package(nlohmann_json REQUIRED)
#find_package(c-ares REQUIRED)

set(SYNCSPIRIT_VERSION "v${CMAKE_PROJECT_VERSION}")

option(SYNCSPIRIT_BUILD_TESTS "Enable building tests [default: OFF]"  OFF)

set(dist_dir "${syncspirit_BINARY_DIR}/dist")
add_custom_target("deploy")
if (WIN32)
    add_custom_target("deploy_deps"
        COMMAND
            python ${syncspirit_SOURCE_DIR}/misc/post-install-win32.py
                --binaries ${dist_dir}/*
                --dirs
                    `conan config home`
                    ${CMAKE_BINARY_DIR}
                    `dirname ${CMAKE_CXX_COMPILER}`/../../
        DEPENDS deploy
    )
endif()

function(install_executable target)
    install(TARGETS ${target} DESTINATION bin)
        add_custom_target("deploy_${target}")
        add_dependencies("deploy" "deploy_${target}")
        if (WIN32)
            get_target_property(target_type ${target} TYPE)
            if (target_type STREQUAL "EXECUTABLE")
                add_custom_command(TARGET deploy_${target} POST_BUILD
                    COMMAND ${CMAKE_COMMAND} -E
                        copy
                            $<TARGET_FILE:${target}>
                            "${dist_dir}/$<TARGET_FILE_NAME:${target}>"
                )
            endif ()
        else()
            add_custom_command(TARGET deploy_${target} POST_BUILD
                COMMAND
                   cd ${syncspirit_BINARY_DIR} && sh
                    ${syncspirit_SOURCE_DIR}/misc/make-appimage.sh
                        $<TARGET_FILE:${target}>
            )
        endif()
endfunction()

configure_file(misc/syncspirit-config.h.in include/syncspirit-config.h @ONLY)

add_library(syncspirit_core
    src/constants.cpp
    src/config/utils.cpp
    src/db/cursor.cpp
    src/db/error_code.cpp
    src/db/prefix.cpp
    src/db/transaction.cpp
    src/db/utils.cpp
    src/fs/chunk_iterator.cpp
    src/fs/file.cpp
    src/fs/file_actor.cpp
    src/fs/fs_supervisor.cpp
    src/fs/new_chunk_iterator.cpp
    src/fs/scan_actor.cpp
    src/fs/scan_scheduler.cpp
    src/fs/scan_task.cpp
    src/fs/utils.cpp
    src/hasher/hasher_actor.cpp
    src/hasher/hasher_proxy_actor.cpp
    src/hasher/hasher_supervisor.cpp
    src/model/diff/apply_controller.cpp
    src/model/diff/block_diff.cpp
    src/model/diff/cluster_diff.cpp
    src/model/diff/cluster_visitor.cpp
    src/model/diff/advance/advance.cpp
    src/model/diff/advance/local_update.cpp
    src/model/diff/advance/remote_copy.cpp
    src/model/diff/advance/remote_win.cpp
    src/model/diff/contact/connect_request.cpp
    src/model/diff/contact/dial_request.cpp
    src/model/diff/contact/ignored_connected.cpp
    src/model/diff/contact/relay_connect_request.cpp
    src/model/diff/contact/peer_state.cpp
    src/model/diff/contact/unknown_connected.cpp
    src/model/diff/contact/update_contact.cpp
    src/model/diff/load/blocks.cpp
    src/model/diff/load/devices.cpp
    src/model/diff/load/file_infos.cpp
    src/model/diff/load/folder_infos.cpp
    src/model/diff/load/folders.cpp
    src/model/diff/load/ignored_devices.cpp
    src/model/diff/load/ignored_folders.cpp
    src/model/diff/load/load_cluster.cpp
    src/model/diff/load/pending_devices.cpp
    src/model/diff/load/pending_folders.cpp
    src/model/diff/local/blocks_availability.cpp
    src/model/diff/local/custom.cpp
    src/model/diff/local/file_availability.cpp
    src/model/diff/local/io_failure.cpp
    src/model/diff/local/scan_finish.cpp
    src/model/diff/local/scan_request.cpp
    src/model/diff/local/scan_start.cpp
    src/model/diff/local/synchronization_finish.cpp
    src/model/diff/local/synchronization_start.cpp
    src/model/diff/modify/add_blocks.cpp
    src/model/diff/modify/add_remote_folder_infos.cpp
    src/model/diff/modify/add_ignored_device.cpp
    src/model/diff/modify/add_pending_device.cpp
    src/model/diff/modify/add_pending_folders.cpp
    src/model/diff/modify/append_block.cpp
    src/model/diff/modify/block_ack.cpp
    src/model/diff/modify/block_rej.cpp
    src/model/diff/modify/block_transaction.cpp
    src/model/diff/modify/clone_block.cpp
    src/model/diff/modify/finish_file.cpp
    src/model/diff/modify/generic_remove.cpp
    src/model/diff/modify/lock_file.cpp
    src/model/diff/modify/mark_reachable.cpp
    src/model/diff/modify/remove_blocks.cpp
    src/model/diff/modify/remove_files.cpp
    src/model/diff/modify/remove_folder.cpp
    src/model/diff/modify/remove_folder_infos.cpp
    src/model/diff/modify/remove_peer.cpp
    src/model/diff/modify/remove_ignored_device.cpp
    src/model/diff/modify/remove_pending_device.cpp
    src/model/diff/modify/remove_pending_folders.cpp
    src/model/diff/modify/reset_folder_infos.cpp
    src/model/diff/modify/share_folder.cpp
    src/model/diff/modify/suspend_folder.cpp
    src/model/diff/modify/unshare_folder.cpp
    src/model/diff/modify/update_peer.cpp
    src/model/diff/modify/upsert_folder.cpp
    src/model/diff/modify/upsert_folder_info.cpp
    src/model/diff/peer/cluster_update.cpp
    src/model/diff/peer/rx_tx.cpp
    src/model/diff/peer/update_folder.cpp
    src/model/misc/augmentation.cpp
    src/model/misc/block_iterator.cpp
    src/model/misc/error_code.cpp
    src/model/misc/file_block.cpp
    src/model/misc/file_iterator.cpp
    src/model/misc/orphaned_blocks.cpp
    src/model/misc/resolver.cpp
    src/model/misc/sequencer.cpp
    src/model/misc/updates_streamer.cpp
    src/model/misc/uuid.cpp
    src/model/block_info.cpp
    src/model/cluster.cpp
    src/model/device.cpp
    src/model/device_id.cpp
    src/model/file_info.cpp
    src/model/folder.cpp
    src/model/folder_data.cpp
    src/model/folder_info.cpp
    src/model/ignored_device.cpp
    src/model/ignored_folder.cpp
    src/model/pending_device.cpp
    src/model/pending_folder.cpp
    src/model/remote_folder_info.cpp
    src/model/some_device.cpp
    src/model/version.cpp
    src/net/acceptor_actor.cpp
    src/net/cluster_supervisor.cpp
    src/net/controller_actor.cpp
    src/net/db_actor.cpp
    src/net/dialer_actor.cpp
    src/net/global_discovery_actor.cpp
    src/net/http_actor.cpp
    src/net/initiator_actor.cpp
    src/net/local_discovery_actor.cpp
    src/net/messages.cpp
    src/net/net_supervisor.cpp
    src/net/peer_actor.cpp
    src/net/peer_supervisor.cpp
    src/net/relay_actor.cpp
    src/net/resolver_actor.cpp
    src/net/names.cpp
    src/net/sink_actor.cpp
    src/net/ssdp_actor.cpp
    src/net/upnp_actor.cpp
    src/presentation/entity.cpp
    src/presentation/cluster_file_presence.cpp
    src/presentation/file_entity.cpp
    src/presentation/folder_entity.cpp
    src/presentation/folder_presence.cpp
    src/presentation/local_file_presence.cpp
    src/presentation/missing_file_presence.cpp
    src/presentation/orphans.cpp
    src/presentation/path.cpp
    src/presentation/peer_file_presence.cpp
    src/presentation/presence.cpp
    src/proto/bep_support.cpp
    src/proto/discovery_support.cpp
    src/proto/luhn32.cpp
    src/proto/proto-helpers-bep.cpp
    src/proto/proto-helpers-db.cpp
    src/proto/relay_support.cpp
    src/proto/upnp_support.cpp
    src/transport/stream.cpp
    src/transport/http.cpp
    src/utils/base32.cpp
    src/utils/beast_support.cpp
    src/utils/bytes.cpp
    src/utils/dns.cpp
    src/utils/error_code.cpp
    src/utils/location.cpp
    src/utils/log.cpp
    src/utils/log-setup.cpp
    src/utils/network_interface.cpp
    src/utils/platform.cpp
    src/utils/time.cpp
    src/utils/tls.cpp
    src/utils/uri.cpp
)
generate_export_header(syncspirit_core
    EXPORT_MACRO_NAME SYNCSPIRIT_API
    EXPORT_FILE_NAME include/syncspirit-export.h
)
FetchContent_Declare(MDBX
    URL https://libmdbx.dqdkfa.ru/release/libmdbx-amalgamated-0.14.1.tar.xz
    URL_HASH SHA256=2edb8b59db5b2b021c7634010f8dbdbbf948eda609942dd300510c6e93bd5d25
    PATCH_COMMAND ${CMAKE_COMMAND} -E
        chdir ${CMAKE_CURRENT_BINARY_DIR}
        patch -u _deps/mdbx-src/mdbx.c -i ${CMAKE_CURRENT_SOURCE_DIR}/misc/mdbx-win32.patch
)
    if (WIN32)
        set(BUILD_SHARED_LIBS true CACHE BOOL "BUILD_SHARED_LIBS")
        set(MDBX_BUILD_SHARED_LIBRARY true CACHE BOOL "MDBX_BUILD_SHARED_LIBRARY")
    else()
        set(BUILD_SHARED_LIBS false CACHE BOOL "BUILD_SHARED_LIBS")
        set(MDBX_BUILD_SHARED_LIBRARY false CACHE BOOL "MDBX_BUILD_SHARED_LIBRARY")
    endif()
    set(MDBX_BUILD_TOOLS false  CACHE BOOL "MDBX_BUILD_TOOLS")
    set(MDBX_ENABLE_TESTS false CACHE BOOL "MDBX_ENABLE_TESTS")
    set(MDBX_BUILD_CXX false CACHE BOOL "MDBX_BUILD_CXX")
    set(MDBX_ALLOY_BUILD_DEFAULT true CACHE BOOL "MDBX_ALLOY_BUILD_DEFAULT")
    set(MDBX_ALLOY_BUILD true CACHE BOOL "MDBX_ALLOY_BUILD")
FetchContent_MakeAvailable(MDBX)

FetchContent_Declare(C_ARES
    URL https://github.com/c-ares/c-ares/releases/download/v1.34.5/c-ares-1.34.5.tar.gz
    URL_HASH SHA256=7d935790e9af081c25c495fd13c2cfcda4792983418e96358ef6e7320ee06346
)
    set(CARES_STATIC      true  CACHE BOOL "CARES_STATIC")
    set(CARES_SHARED      false CACHE BOOL "CARES_SHARED")
    set(CARES_STATIC_PIC  true  CACHE BOOL "CARES_STATIC_PIC")
    set(CARES_BUILD_TOOLS false CACHE BOOL "CARES_BUILD_TOOLS")
    set(CARES_THREADS     false CACHE BOOL "CARES_THREADS")
FetchContent_MakeAvailable(C_ARES)

target_include_directories(syncspirit_core PUBLIC
    ${OPENSSL_INCLUDE_DIR}
    ${CMAKE_CURRENT_BINARY_DIR}
    ${CMAKE_CURRENT_BINARY_DIR}/include
    ${CMAKE_CURRENT_SOURCE_DIR}/src
)

target_link_libraries(syncspirit_core
    PUBLIC
        protopuf::protopuf
        rotor::asio
        rotor::thread
        pugixml::pugixml
        Boost::nowide
        Boost::program_options
        Boost::system
        Boost::url
        OpenSSL::SSL
        fmt::fmt
        spdlog::spdlog
        tomlplusplus::tomlplusplus
        nlohmann_json::nlohmann_json
        lz4::lz4
        $<IF:$<PLATFORM_ID:Windows>,mdbx,mdbx-static>
        $<$<PLATFORM_ID:Windows>:iphlpapi>
        $<$<PLATFORM_ID:Windows>:ws2_32>
        $<$<PLATFORM_ID:Windows>:wsock32>
    PRIVATE
        ZLIB::ZLIB
        c-ares::cares
)
install_executable("syncspirit_core")

if (SYNCSPIRIT_BUILD_TESTS)
    enable_testing()
    add_subdirectory("tests")
endif()

add_subdirectory("src/ui-daemon")
add_subdirectory("src/ui-fltk")


code:
# syncspirit

Sites:
[github](https://github.com/basiliscos/syncspirit),
[notabug](https://notabug.org/basiliscos/syncspirit)
[gitflic](https://gitflic.ru/project/basiliscos/syncspirit)

`syncspirit` is a continuous file synchronization program, which synchronizes files between devices.
It is built using the C++ [rotor](https://github.com/basiliscos/cpp-rotor) actor framework. It implements
the [BEP-protocol](https://docs.syncthing.net/specs/bep-v1.html) for files synchronization, or,
simplistically speaking, it is a [syncthing](https://syncthing.net)-compatible synchronization
program at protocol level, which uses the [syncthing](https://syncthing.net) infrastructure (for global discovery
and relaying).

Despite being functional, `syncspirit` is much less feature-rich than [syncthing](https://syncthing.net)
and is still in heavy development

# front-ends (aka UIs)

![different UIs](docs/different-uis.gif)

- [fltk](https://www.fltk.org/)-based gui [app](docs/ui-fltk.md)

- headless [daemon](docs/ui-daemon.md)

All front-ends share the same configuration and database when running on same host.

# status

- [x] full-powered files synchronization (aka send and receive)

- [x] [global peer discovery](https://docs.syncthing.net/specs/globaldisco-v3.html)

- [x] [local (LAN) peer discovery](https://docs.syncthing.net/specs/localdisco-v4.html)

- [x] upnp & nat passthough

- [x] certificates generation

- [x] relay transport

- [x] conflict resolution

- [x] incoming and outcoming messages (de)compression using lz4

- [x] introducer support

- [x] send only/receive only dirs

# missing features

This list is probably incomplete. Here are the most important changes:

- [ ] inotify support (aka realtime files watching)

- [ ] ignoring pattern files

- [ ] [QUIC transport](https://en.wikipedia.org/wiki/QUIC)

- [ ] [untrusted devices encryption](https://docs.syncthing.net/specs/untrusted.html)

# run

(headless ui-daemon only, atm)

    syncspirit-daemon --log_level debug \
        --config_dir=/tmp/my_dir \
        --command add_peer:peer_label:KUEQE66-JJ7P6AD-BEHD4ZW-GPBNW6Q-Y4C3K4Y-X44WJWZ-DVPIDXS-UDRJMA7 \
        --command add_folder:label=my_label:id=nagkw-srrjz:path=/tmp/my_dir/data \
        --command share:folder=my_label:device=KUEQE66 \
        --command inactivate:120

the output should be like

[![asciicast](https://asciinema.org/a/474217.svg)](https://asciinema.org/a/474217)

i.e. it records some peer, adds a folder, then shares the folder with the peer device, connects to
the peer and downloads all files into `/tmp/my_dir/data` . The peer device currently can only be
[syncthing](https://syncthing.net). Then `syncspirit` either exits after 2 minutes of inactivity
or when you press `ctrl+c`. The output is successful, because I previously authorized this device
with the [syncthing](https://syncthing.net) web interface, and shared the folder with this device
(`syncspirit`).

I also assume some familiarity with [syncthing](https://syncthing.net), so you should understand
what's going on here.

For more details see [ui-daemon](docs/ui-daemon.md) docs and [configuration](docs/config.md) docs.

# design and ideas

[syncthing](https://syncthing.net) is implemented using [go](https://go.dev/) programming
language, which is a good fit for services. As a result, [syncthing](https://syncthing.net)
itself is written as a web-service, which exposes a REST-API for clients. So, yes, the end-user
software should also have a front-end, which is usually web-browser (or embeds web-browser),
which is written in different programming language (e.g. javascript or java).

I feel myself a bit uneasy with that design; maybe it's my personal nostalgia, but I like
the good old programs, where everything is "in memory" of one program. They are fast,
ecological, secure, manageable, have lower CPU and memory pressures.

The [actor model](https://en.wikipedia.org/wiki/Actor_model), blurs the boundaries between
classical desktop and client-server application models. I think,
[rotor](https://github.com/basiliscos/cpp-rotor) makes it possible to have (and embed) some
"core" into multiple different user interfaces (GUIs).

Currently, syncspirit has only a "daemon-ui", i.e. a simple non-interactive application,
which shows a synchronization log, and the only possibility is just to stop it. However, as soon
as the "core" is complete, there are plans to develop multiple `syncspirit` UIs:
[wx-widgets](https://www.wxwidgets.org/), qt, gtk, maybe native, maybe even native mobile UIs...

Another major idea is scripting support: it should be possible to expose the "core" to lua
scripts, and have some user-defined actions like synchronizing files with external folders including
flash-sticks, user-defined files ordering and filtering for synchronization, maybe even selective
sync, like in [resilio](https://www.resilio.com/). This, however, still needs to be researched,
after the core completion.

# platforms

- linux
- windows
- mac os x

# changes

## 0.4.1 (xx-xxx-xxxx)
 - [core] possibility to import directories outside of syncthing, including
         partial import, see [faq](faq.md)
 - [core, fltk] support merged cluster folder model
 - [core] support `folder_type` folder setting (send only, receive only, send & receive)
 - [core] support `pull_older` folder setting (alphabetic, by size, by modification date)
 - [core, bep] support `ignore_deletes` folder flag
 - [core, bep] support device `auto-accept` folder flag
 - [core, bep] support device `introducer` and `skip_introduction_removals` markers
 - [core, bep] support outgoing messages to be compressed using lz4
 - [impl] degoogle: use [protopuf](https://github.com/PragmaTwice/protopuf) instead of protobuf

## 0.4.0 (22-Feb-2025)
 - [feature] new [fltk-fronted](docs/ui-fltk.md)
 - major app refactoring

## 0.3.3 (12-May-2024)
- [bugfix, win32] governor actor, fix parsing folder path

## 0.3.2 (11-May-2024)
- [bugfix] folder scan isn't triggered on startup

## 0.3.1 (23-Apr-2024)
- [feature] added `syncspirit` binary fow windows xp
- [build, docs] improved build documentation

## 0.3.0 (14-Apr-2024)
- [feature] implemented complete files synchronization
- [feature] added local files watcher and updates streamer
- [build] switched from git submodules to [conan2](https://conan.io)
- [win32] better platform support

## 0.2.0 (22-May-2022)
- [feature] implement [relay transport](https://docs.syncthing.net/specs/relay-v1.html),
the relay is randomly chosen from the public relays [pool](https://relays.syncthing.net/endpoint)
- [feature] output binary is compressed via [upx](https://upx.github.io)
- [feature] small optimization, use thread less in overall program
- [bugfix] sometimes fs::scan_actor request timeout occurs, which is fatal
- [bugfix] global discovery sometimes skipped announcements

## 0.1.0 (18-Arp-2022)
 - initial release

# building from source

[see](docs/building.md)

# license

This software is licensed under the [GPLv3 license](https://www.gnu.org/licenses/gpl-3.0.en.html).

    Copyright (C) 2019-2022 Ivan Baidakou (aka basiliscos)

    This file is part of syncspirit.

    syncspirit 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.

    syncspirit 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 syncspirit.  If not, see <http://www.gnu.org/licenses/>.

[![GPL3 Logo](https://www.gnu.org/graphics/gplv3-127x51.png)](https://www.gnu.org/licenses/gpl-3.0.en.html)

repo_name: basiliscos/syncspirit

license: mit


code:
## core

 - add inotify-support
 - dynamically apply config changes

## fltk
 - fltk/core show % of availability
 - add localization support
 - put app into system tray somehow (win32, linux)


code:
from conan import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake, CMakeDeps, cmake_layout

class SyncspiritRecipe(ConanFile):
    settings = "os", "compiler", "build_type", "arch"
    options = {
        "shared": [True, False],
    }

    def requirements(self):
        # self.requires("c-ares/1.28.1")
        self.requires("fltk/1.3.9")
        self.requires("libqrencode/4.1.1")
        self.requires("lz4/1.10.0")
        self.requires("nlohmann_json/3.12.0")
        self.requires("openssl/3.4.1")
        self.requires("protopuf/3.0.0")
        self.requires("pugixml/1.15")
        self.requires("rotor/0.34")
        self.requires("spdlog/1.15.1")
        self.requires("tomlplusplus/3.4.0")
        self.requires("zlib/1.3.1")
#        self.requires("c-ares/1.34.5")
        self.requires("catch2/3.3.1")
        self.requires("boost/1.86.0", headers=True, libs=True, transitive_libs=True, force=True)

    def build_requirements(self):
        self.tool_requires("cmake/3.31.5")

    def generate(self):
        tc = CMakeToolchain(self)
        tc.variables["BUILD_SHARED_LIBS"] = self.options.shared
        tc.generate()
        tc = CMakeDeps(self)
        tc.generate()


code:
# building

## requirements

 - C++ 20 compatible compiler (tested with gcc-10 and clang-17)

 - [boost](https://www.boost.org/) (at least `v1.84.0`)
 - [openssl](https://www.openssl.org/)
 - [protobuf](https://github.com/PragmaTwice/protopuf), (at least `v3.0`)
 - [zlib](https://www.zlib.net/)
 - [rotor](https://github.com/basiliscos/cpp-rotor), (at least `v0.32`)
 - [lz4](https://github.com/lz4/lz4)
 - [libmbdx](https://github.com/erthink/libmdbx), (at least `v0.13.3`)
 - [spdlog](https://github.com/gabime/spdlog)
 - [json](https://github.com/nlohmann/json)
 - [pugixml](https://github.com/zeux/pugixml)
 - [tomlplusplus](https://github.com/marzer/tomlplusplus)
 - [c-ares](https://c-ares.org/)
 - [fltk](https://www.fltk.org/) (for fltk-ui)

The [conan](https://conan.io/) package manager (v2.0+) is used with
[cmake](https://cmake.org/) build system.

`syncspririt` can be build with [conan](https://conan.io/) or just with bare
[cmake](https://cmake.org/) build system. [conan](https://conan.io/) is
responsible for installing and building dependencies, with bare [cmake](https://cmake.org/)
it should be done manually (e.g. use system-provided libraries).

Please note, that [fltk](https://www.fltk.org/) library should be build as
shared library; otherwise applications will not work correctly.

## generic build

Make sure that the default conan profile has proper options:

```
cat ~/.conan2/profiles/default
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=20
compiler.libcxx=libstdc++11
compiler.version=11
os=Linux

[options]
*/*:shared=True
fltk/*:with_xft=True
fltk/*:with_gl=False
boost/*:magic_autolink=False
boost/*:visibility=hidden
boost/*:header_only=False
boost/*:without_serialization=True
boost/*:without_graph=True
boost/*:without_fiber=True
boost/*:without_log=True
boost/*:without_math=True
boost/*:without_process=True
boost/*:without_stacktrace=True
boost/*:without_test=True
boost/*:without_wave=True
pugixml/*:no_exceptions=True
rotor/*:enable_asio=True
rotor/*:enable_thread=True
rotor/*:enable_fltk=True
```

If static build is planned, than `*/*:shared=True` should be `False`.

If the defult conan profile is missing, than create it via:
```
conan profile detect
```

and modify accordingly.

```
mkdir build.release && cd build.release
conan install --build=missing --output-folder . -o '&:shared=True' -s build_type=Release ..
cmake .. -G "Unix Makefiles" \
  -DCMAKE_TOOLCHAIN_FILE=$PWD/conan_toolchain.cmake \
  -DCMAKE_BUILD_TYPE=Release
make -j`nproc`
```

(for shared build it should contain '&:shared=True' here too)

To have locally installed binaries with all dependencies `cmake` command
should be:

```
cmake .. -G "Unix Makefiles" \
  -DCMAKE_TOOLCHAIN_FILE=$PWD/conan_toolchain.cmake \
  -DCMAKE_POLICY_DEFAULT_CMP0091=NEW \
  -DCMAKE_BUILD_TYPE=Release
```

```
make -j`nproc`
```

For win32 to gater `dll`s it should be

```
make -j`nproc` deploy_deps
```

## cross building on linux for windows

Generally it the process is the same as above, with the addition, that
cross-compiler should be installed and conan profiles should be activated

### mingw

Install mingw on linux (something like `cross-x86_64-w64-mingw32`)

Make a conan profile for mingw:

```
cat ~/.conan2/profiles/mingw
[settings]
os=Windows
arch=x86_64
compiler=gcc
build_type=Release
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=12
[buildenv]
CC=x86_64-w64-mingw32-gcc
CXX=x86_64-w64-mingw32-g++
LD=ix86_64-w64-mingw32-ld
RC=x86_64-w64-mingw32-windres

[options]
*/*:shared=False
fltk/*:with_xft=True
fltk/*:with_gl=False
boost/*:magic_autolink=False
boost/*:visibility=hidden
boost/*:header_only=False
boost/*:without_serialization=True
boost/*:without_graph=True
boost/*:without_fiber=True
boost/*:without_log=True
boost/*:without_math=True
boost/*:without_process=True
boost/*:without_stacktrace=True
boost/*:without_test=True
boost/*:without_wave=True
pugixml/*:no_exceptions=True
rotor/*:enable_asio=True
rotor/*:enable_thread=True
rotor/*:enable_fltk=True
```

Then make a build

```
mkdir build.release && cd build.release
conan install --build=missing --output-folder . -s build_type=Release \
    --profile:build=default --profile:host=mingw -o '&:shared=False'  ..
source ./conanbuild.sh
cmake .. -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=$PWD/conan_toolchain.cmake \
   -DCMAKE_BUILD_TYPE=Release
make -j`nproc`
```

### mxe

Download [mxe](https://mxe.cc); make sure all requirements are met.

Your `settings.mk` should contain something like:

```
MXE_TARGETS := x86_64-w64-mingw32.shared
```

Validate, that everything is OK via typing in mxe dir something like

```
make zip
```

Add $mxe_dir/uer/bin to your `PATH`, and make sure something like that works:

```
export PATH=`pwd`/usr/bin:$PATH
x86_64-w64-mingw32.shared-g++ --version
x86_64-w64-mingw32.shared-g++ (GCC) 11.2.0
```

Make a conan profile for mingw:

```
cat ~/.conan2/profiles/mxe
[settings]
os=Windows
arch=x86_64
compiler=gcc
build_type=Release
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=11
[buildenv]
CC=x86_64-w64-mingw32.shared-gcc
CXX=x86_64-w64-mingw32.shared-g++
LD=x86_64-w64-mingw32.shared-ld
RC=x86_64-w64-mingw32.shared-windres

[options]
shared=False
*/*:shared=True
fltk/*:with_xft=True
fltk/*:with_gl=False
boost/*:magic_autolink=False
boost/*:visibility=hidden
boost/*:header_only=False
boost/*:without_serialization=True
boost/*:without_graph=True
boost/*:without_fiber=True
boost/*:without_log=True
boost/*:without_math=True
boost/*:without_process=True
boost/*:without_stacktrace=True
boost/*:without_test=True
boost/*:without_wave=True
protobuf/*:with_zlib=False
pugixml/*:no_exceptions=True
rotor/*:enable_asio=True
rotor/*:enable_thread=True
rotor/*:enable_fltk=True
```

Go to `syncspirit` dir and then make a build

```
cd syncspirit
mkdir build.release && cd build.release
conan install --build=missing --output-folder . -s build_type=Release \
    --profile:build=default --profile:host=mxe -o '&:shared=False' ..
source ./conanbuild.sh
cmake .. -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=$PWD/conan_toolchain.cmake \
  -DCMAKE_BUILD_TYPE=Release
make -j`nproc`
```

### mxe & windows xp

Download [mxe](https://mxe.cc); make sure all requirements are met.

Your `settings.mk` should contain something like:

```
MXE_TARGETS := i686-w64-mingw32.shared
MXE_PLUGIN_DIRS=plugins/windows-xp
```

Validate, that everything is OK via typing in mxe dir something like

```
make zip
```

Copy the resulting `zip.exe` to windows xp host and launch, i.e. make sure
everything is ok with the toolchain.

Add $mxe_dir/uer/bin to your `PATH`, and make sure something like that works:

```
export PATH=`pwd`/usr/bin:$PATH
i686-w64-mingw32.shared-g++ --version
i686-w64-mingw32.shared-g++ (GCC) 11.2.0
```

Make a conan profile for mingw:

```
cat ~/.conan2/profiles/xp
[settings]
os=Windows
arch=x86
compiler=gcc
build_type=Release
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=12
[buildenv]
CC=i686-w64-mingw32.shared-gcc
CXX=i686-w64-mingw32.shared-g++
LD=i686-w64-mingw32.shared-ld
RC=i686-w64-mingw32.shared-windres

[options]
*/*:shared=False
fltk/*:with_xft=True
fltk/*:with_gl=False
boost/*:magic_autolink=False
boost/*:visibility=hidden
boost/*:header_only=False
boost/*:without_serialization=True
boost/*:without_graph=True
boost/*:without_fiber=True
boost/*:without_log=True
boost/*:without_math=True
boost/*:without_process=True
boost/*:without_stacktrace=True
boost/*:without_test=True
boost/*:without_wave=True
protobuf/*:with_zlib=False
pugixml/*:no_exceptions=True
rotor/*:enable_asio=True
rotor/*:enable_thread=True
rotor/*:enable_fltk=True

[conf]
tools.build:cflags=["-D_WIN32_WINNT=0x0501"]
tools.build:cxxflags=["-D_WIN32_WINNT=0x0501", "-DBOOST_ASIO_ENABLE_CANCELIO=1"]
```

The supped libmbdx should be patched for windows xp support:

```
cd syncspirit/lib/mbdx
 patch -p1 < ../mdbx-xp-patch.diff
```

Go to `syncspirit` dir and then make a build

```
cd syncspirit
mkdir build.release && cd build.release
conan install --build=missing --output-folder . -s build_type=Release \
    --profile:build=default --profile:host=xp -o '&:shared=False' .. ..
source ./conanbuild.sh
cmake .. -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=$PWD/conan_toolchain.cmake \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_CXX_FLAGS="-DBOOST_ASIO_ENABLE_CANCELIO=1"
make -j`nproc` deploy_deps
```

## making appImage (ubuntu 20.04 etc.)

```
debootstrap --arch amd64 focal  ubuntu-root http://archive.ubuntu.com/ubuntu/

mount --bind /proc ubuntu-root/proc/
mount --rbind /dev ubuntu-root/dev/
chroot ubuntu-root

apt update
apt-get install -y software-properties-common
add-apt-repository universe -y
add-apt-repository ppa:ubuntu-toolchain-r/ppa -y
apt update
apt install -y g++-9 gcc-9

apt install -y g++-10 gcc-10
apt-get install -y wget libxft-dev build-essential python3-pip make cmake git fuse libfuse2 libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmuu-dev libxrandr-dev libxrender-dev libxres-dev libxss-dev libxtst-dev libxv-dev libxxf86vm-dev libxcb-glx0-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev libxcb-dri3-dev uuid-dev libxcb-cursor-dev libxcb-dri2-0-dev libxcb-dri3-dev libxcb-present-dev libxcb-composite0-dev libxcb-ewmh-dev libxcb-res0-dev libxcb-util0-dev libxcb-util-dev libglu1-mesa-dev pkgconf

adduser --quiet --disabled-password c

su c
export PATH=$HOME/.local/bin:$PATH
pip3 install --user conan
conan profile detect

cat << EOF > $HOME/.conan2/profiles/default
[settings]
arch=x86_64
build_type=Release
os=Linux
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=10
os=Linux
[buildenv]
CC=gcc-10
CXX=g++-10

[options]
shared=True
*/*:shared=True
fltk/*:with_xft=True
fltk/*:with_gl=False
boost/*:magic_autolink=False
boost/*:visibility=hidden
boost/*:header_only=False
boost/*:without_serialization=True
boost/*:without_graph=True
boost/*:without_fiber=True
boost/*:without_log=True
boost/*:without_math=True
boost/*:without_process=True
boost/*:without_stacktrace=True
boost/*:without_test=True
boost/*:without_wave=True
protobuf/*:with_zlib=False
pugixml/*:no_exceptions=True
rotor/*:enable_asio=True
rotor/*:enable_thread=True
rotor/*:enable_fltk=True
EOF

git clone https://notabug.org/basiliscos/syncspirit.git
cd syncspirit
git checkout v0.4.0-dev
git submodule update --init
mkdir build.chroot
cd build.chroot
conan install --build=missing --output-folder . -s build_type=Release  -o '&:shared=True' ..
source ./conanbuild.sh
cmake .. -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake  -DCMAKE_POLICY_DEFAULT_CMP0091=NEW -DCMAKE_BUILD_TYPE=Release
make -j`nproc`
make deploy_syncspirit-fltk
```

### Development build

conan install --build=missing --output-folder . -s build_type=Debug \
    -o '&:shared=True' ..

cmake  .. -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake \
    -DCMAKE_BUILD_TYPE=Debug -DSYNCSPIRIT_BUILD_TESTS=on \
    -DCMAKE_CXX_FLAGS="-fuse-ld=mold"


code:
# configuration

Configuration is generated by default should be OK in the most of cases,
however you might want to tune it.

```toml

# settings peer connection
[bep]
advances_per_iteration = 10         # maximum amount of file metadata advances per iteration
blocks_max_requested = 16           # maximum concurrent block read requests per peer
blocks_simultaneous_write = 16      # maximum concurrent block write requests to disk
connect_timeout = 5000              # maximum time for connection, milliseconds
request_timeout = 60000             # maximum time for request, milliseconds
rx_buff_size = 16777216             # preallocated receive buffer size
rx_timeout = 300000                 # maximum time for request, milliseconds
tx_buff_limit = 8388608             # preallocated transmit buffer size
tx_timeout = 90000                  # tx max time, milliseconds

# database settings
[db]
upper_limit = 0             # maximum amount of database, in bytes, 0 - for auto allocate
uncommitted_threshold = 150 # how often flush db to disk, i.e. how much operations
                            # might be not committed. Affects disk performance
max_blocks_per_diff = 8192  # maximum number of blocks per single diff (to display progress in UI)
max_files_per_diff = 1024   # maximum number of files per single diff (to display progress in UI)

# dialer settings
[dialer]
enabled = true
redial_timeout = 300000     # how often try to redial to connect offline peers, milliseconds
skip_discovers = 10         # when peer addresses are known, how many times skip rediscovering them

# filesystem settings
[fs]
temporally_timeout = 86400000           # remove incomplete file after this amount of seconds
mru_size = 128                          # maximum amount of cached/opened files
bytes_scan_iteration_limit = 1024*1024  # max number of bytes before emitting scan events
files_scan_iteration_limit = 128        # max number processed files before emitting scan events

[global_discovery]
enabled = true
debug = false
announce_url = 'https://discovery.syncthing.net/'   # url of syncthing/private global announce server
device_id = 'LYXKCHX-VI3NYZR-ALCJBHF-WMZYSPK-QG6QJA3-MPFYMSO-U56GTUK-NA2MIAW' # the device_id of global discovery server
cert_file = '/home/b/.config/syncthing/cert.pem'    # this device certificate location
key_file = '/home/b/.config/syncthing/key.pem'      # this device key location
rx_buff_size = 32768                                # preallocated receive buffer size, bytes
timeout = 4000                                      # max request/response time, milliseconds

[local_discovery]
enabled = true
frequency = 30000       # how often send announcements in LAN, in milliseconds
port = 21027            # upd port used for announcement (should be the same as in syncthing)

# default log settings
[[log]]
name = 'default'                            # possible values: trace, debug, info, warn, error, critical
level = 'trace'
sinks = ['stdout', 'file:/tmp/log.txt']     # where do output logs

[main]
default_location = '$HOME/.config/syncspirit/shared_data'    # where folders are created by default
device_name = 'this-device-name'                             # this device name
timeout = 5000                                               # main actors timeout, milliseconds
hasher_threads = 3                                           # the amount cpu cores used for hashing

[relay]
enabled = true
debug = false
discovery_url = 'https://relays.syncthing.net/endpoint'     # where pick the list of relay servers pool
rx_buff_size = 1048576                                      # preallocated receive buffer size, bytes

[upnp]
enabled = true
debug = false
external_port = 22001   # external (router) port for communication, opened on router
max_wait = 1            # router response max wait time, seconds
rx_buff_size = 65536    # preallocated receive buffer size, bytes

```


code:
#
# Automatically generated file; DO NOT EDIT.
# crosstool-NG 1.26.0 Configuration
#
CT_CONFIGURE_has_static_link=y
CT_CONFIGURE_has_cxx11=y
CT_CONFIGURE_has_wget=y
CT_CONFIGURE_has_curl=y
CT_CONFIGURE_has_rsync=y
CT_CONFIGURE_has_make_3_81_or_newer=y
CT_CONFIGURE_has_make_4_0_or_newer=y
CT_CONFIGURE_has_make_4_4_or_newer=y
CT_CONFIGURE_has_libtool_2_4_or_newer=y
CT_CONFIGURE_has_libtoolize_2_4_or_newer=y
CT_CONFIGURE_has_autoconf_2_65_or_newer=y
CT_CONFIGURE_has_autoreconf_2_65_or_newer=y
CT_CONFIGURE_has_automake_1_15_or_newer=y
CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y
CT_CONFIGURE_has_python_3_4_or_newer=y
CT_CONFIGURE_has_bison_2_7_or_newer=y
CT_CONFIGURE_has_bison_3_0_4_or_newer=y
CT_CONFIGURE_has_python=y
CT_CONFIGURE_has_git=y
CT_CONFIGURE_has_md5sum=y
CT_CONFIGURE_has_sha1sum=y
CT_CONFIGURE_has_sha256sum=y
CT_CONFIGURE_has_sha512sum=y
CT_CONFIGURE_has_install_with_strip_program=y
CT_VERSION="1.26.0"
CT_VCHECK=""
CT_CONFIG_VERSION_ENV="4"
CT_CONFIG_VERSION_CURRENT="4"
CT_CONFIG_VERSION="4"
CT_MODULES=y

#
# Paths and misc options
#

#
# crosstool-NG behavior
#
# CT_OBSOLETE is not set
# CT_EXPERIMENTAL is not set
# CT_DEBUG_CT is not set

#
# Paths
#
CT_LOCAL_TARBALLS_DIR="${HOME}/src"
CT_SAVE_TARBALLS=y
# CT_TARBALLS_BUILDROOT_LAYOUT is not set
CT_WORK_DIR="${CT_TOP_DIR}/.build"
CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}"
CT_BUILD_DIR="${CT_BUILD_TOP_DIR}/build"
CT_PREFIX_DIR="${CT_PREFIX:-${HOME}/x-tools}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}"
CT_RM_RF_PREFIX_DIR=y
CT_REMOVE_DOCS=y
CT_INSTALL_LICENSES=y
CT_PREFIX_DIR_RO=y
CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y
# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set

#
# Downloading
#
CT_DOWNLOAD_AGENT_WGET=y
# CT_DOWNLOAD_AGENT_CURL is not set
# CT_DOWNLOAD_AGENT_NONE is not set
# CT_FORBID_DOWNLOAD is not set
# CT_FORCE_DOWNLOAD is not set
CT_CONNECT_TIMEOUT=10
CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary"
# CT_ONLY_DOWNLOAD is not set
# CT_USE_MIRROR is not set
CT_VERIFY_DOWNLOAD_DIGEST=y
CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y
# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set
# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set
# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set
CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512"
# CT_VERIFY_DOWNLOAD_SIGNATURE is not set

#
# Extracting
#
# CT_FORCE_EXTRACT is not set
CT_OVERRIDE_CONFIG_GUESS_SUB=y
# CT_ONLY_EXTRACT is not set
CT_PATCH_BUNDLED=y
# CT_PATCH_BUNDLED_LOCAL is not set
CT_PATCH_ORDER="bundled"

#
# Build behavior
#
CT_PARALLEL_JOBS=0
CT_LOAD=""
CT_USE_PIPES=y
CT_EXTRA_CFLAGS_FOR_BUILD=""
CT_EXTRA_CXXFLAGS_FOR_BUILD=""
CT_EXTRA_LDFLAGS_FOR_BUILD=""
CT_EXTRA_CFLAGS_FOR_HOST=""
CT_EXTRA_LDFLAGS_FOR_HOST=""
# CT_CONFIG_SHELL_SH is not set
# CT_CONFIG_SHELL_ASH is not set
CT_CONFIG_SHELL_BASH=y
# CT_CONFIG_SHELL_CUSTOM is not set
CT_CONFIG_SHELL="${bash}"

#
# Logging
#
# CT_LOG_ERROR is not set
# CT_LOG_WARN is not set
# CT_LOG_INFO is not set
CT_LOG_EXTRA=y
# CT_LOG_ALL is not set
# CT_LOG_DEBUG is not set
CT_LOG_LEVEL_MAX="EXTRA"
# CT_LOG_SEE_TOOLS_WARN is not set
CT_LOG_PROGRESS_BAR=y
CT_LOG_TO_FILE=y
CT_LOG_FILE_COMPRESS=y
# end of Paths and misc options

#
# Target options
#
# CT_ARCH_ALPHA is not set
# CT_ARCH_ARC is not set
# CT_ARCH_ARM is not set
# CT_ARCH_AVR is not set
# CT_ARCH_BPF is not set
# CT_ARCH_M68K is not set
# CT_ARCH_MIPS is not set
# CT_ARCH_NIOS2 is not set
# CT_ARCH_POWERPC is not set
# CT_ARCH_PRU is not set
# CT_ARCH_S390 is not set
# CT_ARCH_SH is not set
# CT_ARCH_SPARC is not set
CT_ARCH_X86=y
# CT_ARCH_XTENSA is not set
CT_ARCH="x86"
CT_ARCH_CHOICE_KSYM="X86"
CT_ARCH_CPU=""
CT_ARCH_TUNE=""
CT_ARCH_X86_SHOW=y

#
# Options for x86
#
CT_ARCH_X86_PKG_KSYM=""
CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR BPF C6X LOONGARCH M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC PRU RISCV S390 SH SPARC X86 XTENSA"
CT_ARCH_SUFFIX=""
# CT_OMIT_TARGET_VENDOR is not set

#
# Generic target options
#
# CT_MULTILIB is not set
CT_DEMULTILIB=y
CT_ARCH_USE_MMU=y
CT_ARCH_SUPPORTS_LIBSANITIZER=y
CT_ARCH_SUPPORTS_32=y
CT_ARCH_SUPPORTS_64=y
CT_ARCH_DEFAULT_32=y
CT_ARCH_BITNESS=64
# CT_ARCH_32 is not set
CT_ARCH_64=y
CT_ARCH_SUPPORTS_WITH_32_64=y

#
# Target optimisations
#
CT_ARCH_SUPPORTS_WITH_ARCH=y
CT_ARCH_SUPPORTS_WITH_CPU=y
CT_ARCH_SUPPORTS_WITH_TUNE=y
CT_ARCH_ARCH=""
CT_TARGET_CFLAGS=""
CT_TARGET_LDFLAGS=""
# end of Target options

#
# Toolchain options
#

#
# General toolchain options
#
CT_FORCE_SYSROOT=y
CT_USE_SYSROOT=y
CT_SYSROOT_NAME="sysroot"
CT_SYSROOT_DIR_PREFIX=""
CT_WANTS_STATIC_LINK=y
CT_WANTS_STATIC_LINK_CXX=y
CT_STATIC_TOOLCHAIN=y
CT_SHOW_CT_VERSION=y
CT_TOOLCHAIN_PKGVERSION=""
CT_TOOLCHAIN_BUGURL=""

#
# Tuple completion and aliasing
#
CT_TARGET_VENDOR="syncspirit"
CT_TARGET_ALIAS_SED_EXPR=""
CT_TARGET_ALIAS=""

#
# Toolchain type
#
CT_CROSS=y
# CT_CANADIAN is not set
CT_TOOLCHAIN_TYPE="cross"

#
# Build system
#
CT_BUILD=""
CT_BUILD_PREFIX=""
CT_BUILD_SUFFIX=""

#
# Misc options
#
# CT_TOOLCHAIN_ENABLE_NLS is not set
# end of Toolchain options

#
# Operating System
#
CT_KERNEL_SUPPORTS_SHARED_LIBS=y
# CT_KERNEL_BARE_METAL is not set
CT_KERNEL_LINUX=y
CT_KERNEL="linux"
CT_KERNEL_CHOICE_KSYM="LINUX"
CT_KERNEL_LINUX_SHOW=y

#
# Options for linux
#
CT_KERNEL_LINUX_PKG_KSYM="LINUX"
CT_LINUX_DIR_NAME="linux"
CT_LINUX_USE_WWW_KERNEL_ORG=y
# CT_LINUX_USE_ORACLE is not set
CT_LINUX_USE="LINUX"
CT_LINUX_PKG_NAME="linux"
CT_LINUX_SRC_RELEASE=y
# CT_LINUX_SRC_DEVEL is not set
CT_LINUX_PATCH_ORDER="global"
# CT_LINUX_V_6_4 is not set
# CT_LINUX_V_6_3 is not set
# CT_LINUX_V_6_2 is not set
# CT_LINUX_V_6_1 is not set
# CT_LINUX_V_6_0 is not set
# CT_LINUX_V_5_19 is not set
# CT_LINUX_V_5_18 is not set
# CT_LINUX_V_5_17 is not set
# CT_LINUX_V_5_16 is not set
# CT_LINUX_V_5_15 is not set
# CT_LINUX_V_5_14 is not set
# CT_LINUX_V_5_13 is not set
# CT_LINUX_V_5_12 is not set
# CT_LINUX_V_5_11 is not set
# CT_LINUX_V_5_10 is not set
# CT_LINUX_V_5_9 is not set
# CT_LINUX_V_5_8 is not set
# CT_LINUX_V_5_7 is not set
# CT_LINUX_V_5_4 is not set
# CT_LINUX_V_5_3 is not set
# CT_LINUX_V_5_2 is not set
# CT_LINUX_V_5_1 is not set
# CT_LINUX_V_5_0 is not set
# CT_LINUX_V_4_20 is not set
# CT_LINUX_V_4_19 is not set
# CT_LINUX_V_4_18 is not set
# CT_LINUX_V_4_17 is not set
# CT_LINUX_V_4_16 is not set
# CT_LINUX_V_4_15 is not set
# CT_LINUX_V_4_14 is not set
# CT_LINUX_V_4_13 is not set
# CT_LINUX_V_4_12 is not set
# CT_LINUX_V_4_11 is not set
# CT_LINUX_V_4_10 is not set
# CT_LINUX_V_4_9 is not set
# CT_LINUX_V_4_4 is not set
# CT_LINUX_V_4_1 is not set
# CT_LINUX_V_3_16 is not set
# CT_LINUX_V_3_13 is not set
# CT_LINUX_V_3_12 is not set
# CT_LINUX_V_3_10 is not set
# CT_LINUX_V_3_4 is not set
CT_LINUX_V_3_2=y
# CT_LINUX_V_2_6_32 is not set
CT_LINUX_VERSION="3.2.101"
CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})"
CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz"
CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign"
CT_LINUX_5_19_or_older=y
CT_LINUX_older_than_5_19=y
CT_LINUX_5_12_or_older=y
CT_LINUX_older_than_5_12=y
CT_LINUX_5_5_or_older=y
CT_LINUX_older_than_5_5=y
CT_LINUX_5_3_or_older=y
CT_LINUX_older_than_5_3=y
CT_LINUX_4_8_or_older=y
CT_LINUX_older_than_4_8=y
CT_LINUX_3_7_or_older=y
CT_LINUX_older_than_3_7=y
CT_LINUX_later_than_3_2=y
CT_LINUX_3_2_or_later=y
CT_KERNEL_DEP_RSYNC=y
CT_KERNEL_LINUX_VERBOSITY_0=y
# CT_KERNEL_LINUX_VERBOSITY_1 is not set
# CT_KERNEL_LINUX_VERBOSITY_2 is not set
CT_KERNEL_LINUX_VERBOSE_LEVEL=0
CT_KERNEL_LINUX_INSTALL_CHECK=y
CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS"

#
# Common kernel options
#
CT_SHARED_LIBS=y
# end of Operating System

#
# Binary utilities
#
CT_ARCH_BINFMT_ELF=y
CT_BINUTILS_BINUTILS=y
CT_BINUTILS="binutils"
CT_BINUTILS_CHOICE_KSYM="BINUTILS"
CT_BINUTILS_BINUTILS_SHOW=y

#
# Options for binutils
#
CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS"
CT_BINUTILS_DIR_NAME="binutils"
CT_BINUTILS_USE_GNU=y
# CT_BINUTILS_USE_ORACLE is not set
CT_BINUTILS_USE="BINUTILS"
CT_BINUTILS_PKG_NAME="binutils"
CT_BINUTILS_SRC_RELEASE=y
# CT_BINUTILS_SRC_DEVEL is not set
CT_BINUTILS_PATCH_ORDER="global"
CT_BINUTILS_V_2_40=y
# CT_BINUTILS_V_2_39 is not set
# CT_BINUTILS_V_2_38 is not set
# CT_BINUTILS_V_2_37 is not set
# CT_BINUTILS_V_2_36 is not set
# CT_BINUTILS_V_2_35 is not set
# CT_BINUTILS_V_2_34 is not set
# CT_BINUTILS_V_2_33 is not set
# CT_BINUTILS_V_2_32 is not set
# CT_BINUTILS_V_2_31 is not set
# CT_BINUTILS_V_2_30 is not set
# CT_BINUTILS_V_2_29 is not set
# CT_BINUTILS_V_2_28 is not set
# CT_BINUTILS_V_2_27 is not set
# CT_BINUTILS_V_2_26 is not set
CT_BINUTILS_VERSION="2.40"
CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)"
CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig"
CT_BINUTILS_later_than_2_39=y
CT_BINUTILS_2_39_or_later=y
CT_BINUTILS_later_than_2_30=y
CT_BINUTILS_2_30_or_later=y
CT_BINUTILS_later_than_2_27=y
CT_BINUTILS_2_27_or_later=y
CT_BINUTILS_later_than_2_26=y
CT_BINUTILS_2_26_or_later=y

#
# GNU binutils
#
CT_BINUTILS_GOLD_SUPPORTS_ARCH=y
CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y
CT_BINUTILS_LINKER_LD=y
CT_BINUTILS_LINKERS_LIST="ld"
CT_BINUTILS_LINKER_DEFAULT="bfd"
CT_BINUTILS_RELRO=m
CT_BINUTILS_DETERMINISTIC_ARCHIVES=y
CT_BINUTILS_EXTRA_CONFIG_ARRAY=""
# CT_BINUTILS_FOR_TARGET is not set
CT_ALL_BINUTILS_CHOICES="BINUTILS"
# end of Binary utilities

#
# C-library
#
CT_LIBC_GLIBC=y
# CT_LIBC_UCLIBC_NG is not set
CT_LIBC="glibc"
CT_LIBC_CHOICE_KSYM="GLIBC"
CT_LIBC_GLIBC_SHOW=y

#
# Options for glibc
#
CT_LIBC_GLIBC_PKG_KSYM="GLIBC"
CT_GLIBC_DIR_NAME="glibc"
CT_GLIBC_USE_GNU=y
# CT_GLIBC_USE_ORACLE is not set
CT_GLIBC_USE="GLIBC"
CT_GLIBC_PKG_NAME="glibc"
CT_GLIBC_SRC_RELEASE=y
# CT_GLIBC_SRC_DEVEL is not set
CT_GLIBC_PATCH_ORDER="global"
# CT_GLIBC_V_2_38 is not set
# CT_GLIBC_V_2_37 is not set
# CT_GLIBC_V_2_36 is not set
# CT_GLIBC_V_2_35 is not set
# CT_GLIBC_V_2_34 is not set
# CT_GLIBC_V_2_33 is not set
# CT_GLIBC_V_2_32 is not set
# CT_GLIBC_V_2_31 is not set
# CT_GLIBC_V_2_30 is not set
# CT_GLIBC_V_2_29 is not set
# CT_GLIBC_V_2_28 is not set
# CT_GLIBC_V_2_27 is not set
# CT_GLIBC_V_2_26 is not set
# CT_GLIBC_V_2_25 is not set
# CT_GLIBC_V_2_24 is not set
# CT_GLIBC_V_2_23 is not set
# CT_GLIBC_V_2_19 is not set
CT_GLIBC_V_2_17=y
CT_GLIBC_VERSION="2.17"
CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)"
CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
CT_GLIBC_SIGNATURE_FORMAT="packed/.sig"
CT_GLIBC_2_38_or_older=y
CT_GLIBC_older_than_2_38=y
CT_GLIBC_2_37_or_older=y
CT_GLIBC_older_than_2_37=y
CT_GLIBC_2_36_or_older=y
CT_GLIBC_older_than_2_36=y
CT_GLIBC_2_34_or_older=y
CT_GLIBC_older_than_2_34=y
CT_GLIBC_2_32_or_older=y
CT_GLIBC_older_than_2_32=y
CT_GLIBC_2_31_or_older=y
CT_GLIBC_older_than_2_31=y
CT_GLIBC_2_30_or_older=y
CT_GLIBC_older_than_2_30=y
CT_GLIBC_2_29_or_older=y
CT_GLIBC_older_than_2_29=y
CT_GLIBC_2_28_or_older=y
CT_GLIBC_older_than_2_28=y
CT_GLIBC_2_27_or_older=y
CT_GLIBC_older_than_2_27=y
CT_GLIBC_2_26_or_older=y
CT_GLIBC_older_than_2_26=y
CT_GLIBC_2_25_or_older=y
CT_GLIBC_older_than_2_25=y
CT_GLIBC_2_24_or_older=y
CT_GLIBC_older_than_2_24=y
CT_GLIBC_2_23_or_older=y
CT_GLIBC_older_than_2_23=y
CT_GLIBC_2_20_or_older=y
CT_GLIBC_older_than_2_20=y
CT_GLIBC_2_17_or_later=y
CT_GLIBC_2_17_or_older=y
CT_GLIBC_later_than_2_14=y
CT_GLIBC_2_14_or_later=y
CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y
CT_GLIBC_DEP_BINUTILS=y
CT_GLIBC_DEP_GCC=y
CT_GLIBC_DEP_PYTHON=y
CT_GLIBC_DEP_MAKE_4_3=y
CT_GLIBC_SPARC_ALLOW_V7=y
CT_THREADS="nptl"
CT_GLIBC_HAS_NPTL_ADDON=y
CT_GLIBC_HAS_PORTS_ADDON=y
CT_GLIBC_HAS_LIBIDN_ADDON=y
CT_GLIBC_USE_NPTL_ADDON=y
# CT_GLIBC_USE_LIBIDN_ADDON is not set
CT_GLIBC_HAS_OBSOLETE_RPC=y
CT_GLIBC_EXTRA_CONFIG_ARRAY=""
CT_GLIBC_CONFIGPARMS=""
CT_GLIBC_ENABLE_DEBUG=y
CT_GLIBC_EXTRA_CFLAGS=""
CT_GLIBC_ENABLE_OBSOLETE_RPC=y
# CT_GLIBC_DISABLE_VERSIONING is not set
CT_GLIBC_OLDEST_ABI=""
CT_GLIBC_FORCE_UNWIND=y
# CT_GLIBC_LOCALES is not set
# CT_GLIBC_KERNEL_VERSION_NONE is not set
CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y
# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set
CT_GLIBC_MIN_KERNEL="3.2.101"
# CT_GLIBC_ENABLE_COMMON_FLAG is not set
CT_ALL_LIBC_CHOICES="AVR_LIBC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE PICOLIBC UCLIBC_NG"
CT_LIBC_SUPPORT_THREADS_ANY=y
CT_LIBC_SUPPORT_THREADS_NATIVE=y

#
# Common C library options
#
CT_THREADS_NATIVE=y
# CT_CREATE_LDSO_CONF is not set
CT_LIBC_XLDD=y
# end of C-library

#
# C compiler
#
CT_CC_CORE_NEEDED=y
CT_CC_SUPPORT_CXX=y
CT_CC_SUPPORT_FORTRAN=y
CT_CC_SUPPORT_ADA=y
CT_CC_SUPPORT_D=y
CT_CC_SUPPORT_JIT=y
CT_CC_SUPPORT_OBJC=y
CT_CC_SUPPORT_OBJCXX=y
CT_CC_SUPPORT_GOLANG=y
CT_CC_GCC=y
CT_CC="gcc"
CT_CC_CHOICE_KSYM="GCC"
CT_CC_GCC_SHOW=y

#
# Options for gcc
#
CT_CC_GCC_PKG_KSYM="GCC"
CT_GCC_DIR_NAME="gcc"
CT_GCC_USE_GNU=y
# CT_GCC_USE_ORACLE is not set
CT_GCC_USE="GCC"
CT_GCC_PKG_NAME="gcc"
CT_GCC_SRC_RELEASE=y
# CT_GCC_SRC_DEVEL is not set
CT_GCC_PATCH_ORDER="global"
# CT_GCC_V_13 is not set
# CT_GCC_V_12 is not set
# CT_GCC_V_11 is not set
# CT_GCC_V_10 is not set
# CT_GCC_V_9 is not set
CT_GCC_V_8=y
# CT_GCC_V_7 is not set
# CT_GCC_V_6 is not set
# CT_GCC_V_5 is not set
# CT_GCC_V_4_9 is not set
CT_GCC_VERSION="8.5.0"
CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})"
CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz"
CT_GCC_SIGNATURE_FORMAT=""
CT_GCC_13_or_older=y
CT_GCC_older_than_13=y
CT_GCC_12_or_older=y
CT_GCC_older_than_12=y
CT_GCC_11_or_older=y
CT_GCC_older_than_11=y
CT_GCC_10_or_older=y
CT_GCC_older_than_10=y
CT_GCC_9_or_older=y
CT_GCC_older_than_9=y
CT_GCC_later_than_8=y
CT_GCC_8_or_later=y
CT_GCC_later_than_7=y
CT_GCC_7_or_later=y
CT_GCC_later_than_6=y
CT_GCC_6_or_later=y
CT_GCC_later_than_5=y
CT_GCC_5_or_later=y
CT_GCC_later_than_4_9=y
CT_GCC_4_9_or_later=y
CT_CC_GCC_HAS_LIBMPX=y
CT_CC_GCC_ENABLE_CXX_FLAGS=""
CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY=""
CT_CC_GCC_EXTRA_CONFIG_ARRAY=""
CT_CC_GCC_STATIC_LIBSTDCXX=y
# CT_CC_GCC_SYSTEM_ZLIB is not set
CT_CC_GCC_CONFIG_TLS=m

#
# Optimisation features
#
CT_CC_GCC_USE_GRAPHITE=y

#
# Settings for libraries running on target
#
# CT_CC_GCC_ENABLE_DEFAULT_PIE is not set
CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y
# CT_CC_GCC_LIBMUDFLAP is not set
# CT_CC_GCC_LIBGOMP is not set
# CT_CC_GCC_LIBSSP is not set
# CT_CC_GCC_LIBQUADMATH is not set
# CT_CC_GCC_LIBSANITIZER is not set
CT_CC_GCC_LIBMPX=y
CT_CC_GCC_LIBSTDCXX_VERBOSE=m

#
# Misc. obscure options.
#
CT_CC_CXA_ATEXIT=y
# CT_CC_GCC_DISABLE_PCH is not set
CT_CC_GCC_SJLJ_EXCEPTIONS=m
CT_CC_GCC_LDBL_128=m
# CT_CC_GCC_BUILD_ID is not set
CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y
# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set
# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set
# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set
CT_CC_GCC_LNK_HASH_STYLE=""
CT_CC_GCC_DEC_FLOATS_AUTO=y
# CT_CC_GCC_DEC_FLOATS_BID is not set
# CT_CC_GCC_DEC_FLOATS_DPD is not set
# CT_CC_GCC_DEC_FLOATS_NO is not set
CT_CC_GCC_DEC_FLOATS=""
CT_ALL_CC_CHOICES="GCC"

#
# Additional supported languages:
#
CT_CC_LANG_CXX=y
# CT_CC_LANG_FORTRAN is not set
# end of C compiler

#
# Debug facilities
#
# CT_DEBUG_DUMA is not set
# CT_DEBUG_GDB is not set
# CT_DEBUG_LTRACE is not set
# CT_DEBUG_STRACE is not set
CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE"
# end of Debug facilities

#
# Companion libraries
#
# CT_COMPLIBS_CHECK is not set
# CT_COMP_LIBS_CLOOG is not set
# CT_COMP_LIBS_EXPAT is not set
CT_COMP_LIBS_GETTEXT=y
CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT"
CT_GETTEXT_DIR_NAME="gettext"
CT_GETTEXT_PKG_NAME="gettext"
CT_GETTEXT_SRC_RELEASE=y
# CT_GETTEXT_SRC_DEVEL is not set
CT_GETTEXT_PATCH_ORDER="global"
CT_GETTEXT_V_0_21=y
# CT_GETTEXT_V_0_20_1 is not set
# CT_GETTEXT_V_0_19_8_1 is not set
CT_GETTEXT_VERSION="0.21"
CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)"
CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.gz"
CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig"
CT_GETTEXT_0_21_or_later=y
CT_GETTEXT_0_21_or_older=y
CT_GETTEXT_INCOMPATIBLE_WITH_UCLIBC_NG=y

#
# This version of gettext is not compatible with uClibc-NG. Select
#

#
# a different version if uClibc-NG is used on the target or (in a
#

#
# Canadian cross build) on the host.
#
CT_COMP_LIBS_GMP=y
CT_COMP_LIBS_GMP_PKG_KSYM="GMP"
CT_GMP_DIR_NAME="gmp"
CT_GMP_PKG_NAME="gmp"
CT_GMP_SRC_RELEASE=y
# CT_GMP_SRC_DEVEL is not set
CT_GMP_PATCH_ORDER="global"
CT_GMP_V_6_2=y
# CT_GMP_V_6_1 is not set
CT_GMP_VERSION="6.2.1"
CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)"
CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2"
CT_GMP_SIGNATURE_FORMAT="packed/.sig"
CT_COMP_LIBS_ISL=y
CT_COMP_LIBS_ISL_PKG_KSYM="ISL"
CT_ISL_DIR_NAME="isl"
CT_ISL_PKG_NAME="isl"
CT_ISL_SRC_RELEASE=y
# CT_ISL_SRC_DEVEL is not set
CT_ISL_PATCH_ORDER="global"
CT_ISL_V_0_26=y
# CT_ISL_V_0_25 is not set
# CT_ISL_V_0_24 is not set
# CT_ISL_V_0_23 is not set
# CT_ISL_V_0_22 is not set
# CT_ISL_V_0_21 is not set
# CT_ISL_V_0_20 is not set
# CT_ISL_V_0_19 is not set
# CT_ISL_V_0_18 is not set
# CT_ISL_V_0_17 is not set
# CT_ISL_V_0_16 is not set
# CT_ISL_V_0_15 is not set
CT_ISL_VERSION="0.26"
CT_ISL_MIRRORS="https://libisl.sourceforge.io"
CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
CT_ISL_SIGNATURE_FORMAT=""
CT_ISL_later_than_0_18=y
CT_ISL_0_18_or_later=y
CT_ISL_later_than_0_15=y
CT_ISL_0_15_or_later=y
# CT_COMP_LIBS_LIBELF is not set
CT_COMP_LIBS_LIBICONV=y
CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV"
CT_LIBICONV_DIR_NAME="libiconv"
CT_LIBICONV_PKG_NAME="libiconv"
CT_LIBICONV_SRC_RELEASE=y
# CT_LIBICONV_SRC_DEVEL is not set
CT_LIBICONV_PATCH_ORDER="global"
CT_LIBICONV_V_1_16=y
# CT_LIBICONV_V_1_15 is not set
CT_LIBICONV_VERSION="1.16"
CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)"
CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz"
CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig"
CT_COMP_LIBS_MPC=y
CT_COMP_LIBS_MPC_PKG_KSYM="MPC"
CT_MPC_DIR_NAME="mpc"
CT_MPC_PKG_NAME="mpc"
CT_MPC_SRC_RELEASE=y
# CT_MPC_SRC_DEVEL is not set
CT_MPC_PATCH_ORDER="global"
CT_MPC_V_1_2=y
CT_MPC_VERSION="1.2.1"
CT_MPC_MIRRORS="https://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)"
CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
CT_MPC_ARCHIVE_FORMATS=".tar.gz"
CT_MPC_SIGNATURE_FORMAT="packed/.sig"
CT_MPC_later_than_1_1_0=y
CT_MPC_1_1_0_or_later=y
CT_COMP_LIBS_MPFR=y
CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR"
CT_MPFR_DIR_NAME="mpfr"
CT_MPFR_PKG_NAME="mpfr"
CT_MPFR_SRC_RELEASE=y
# CT_MPFR_SRC_DEVEL is not set
CT_MPFR_PATCH_ORDER="global"
CT_MPFR_V_4_2=y
CT_MPFR_VERSION="4.2.1"
CT_MPFR_MIRRORS="https://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)"
CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip"
CT_MPFR_SIGNATURE_FORMAT="packed/.asc"
CT_MPFR_later_than_4_0_0=y
CT_MPFR_4_0_0_or_later=y
CT_COMP_LIBS_NCURSES=y
CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES"
CT_NCURSES_DIR_NAME="ncurses"
CT_NCURSES_PKG_NAME="ncurses"
CT_NCURSES_SRC_RELEASE=y
# CT_NCURSES_SRC_DEVEL is not set
CT_NCURSES_PATCH_ORDER="global"
CT_NCURSES_V_6_4=y
# CT_NCURSES_V_6_2 is not set
# CT_NCURSES_V_6_1 is not set
# CT_NCURSES_V_6_0 is not set
CT_NCURSES_VERSION="6.4"
CT_NCURSES_MIRRORS="https://invisible-mirror.net/archives/ncurses $(CT_Mirrors GNU ncurses)"
CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
CT_NCURSES_ARCHIVE_FORMATS=".tar.gz"
CT_NCURSES_SIGNATURE_FORMAT="packed/.sig"
CT_NCURSES_NEW_ABI=y
CT_NCURSES_HOST_CONFIG_ARGS=""
CT_NCURSES_HOST_DISABLE_DB=y
CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100"
CT_NCURSES_TARGET_CONFIG_ARGS=""
# CT_NCURSES_TARGET_DISABLE_DB is not set
CT_NCURSES_TARGET_FALLBACKS=""
# CT_COMP_LIBS_ZLIB is not set
# CT_COMP_LIBS_ZSTD is not set
CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP GNUPRUMCU ISL LIBELF LIBICONV MPC MPFR NCURSES NEWLIB_NANO PICOLIBC ZLIB ZSTD"
CT_LIBICONV_NEEDED=y
CT_GETTEXT_NEEDED=y
CT_GMP_NEEDED=y
CT_MPFR_NEEDED=y
CT_ISL_NEEDED=y
CT_MPC_NEEDED=y
CT_NCURSES_NEEDED=y
# CT_ZLIB_NEEDED is not set
# CT_ZSTD_NEEDED is not set
CT_LIBICONV=y
CT_GETTEXT=y
CT_GMP=y
CT_MPFR=y
CT_ISL=y
CT_MPC=y
CT_NCURSES=y
# end of Companion libraries

#
# Companion tools
#
# CT_COMP_TOOLS_FOR_HOST is not set
# CT_COMP_TOOLS_AUTOCONF is not set
# CT_COMP_TOOLS_AUTOMAKE is not set
# CT_COMP_TOOLS_BISON is not set
# CT_COMP_TOOLS_DTC is not set
# CT_COMP_TOOLS_LIBTOOL is not set
# CT_COMP_TOOLS_M4 is not set
CT_COMP_TOOLS_MAKE=y
CT_COMP_TOOLS_MAKE_PKG_KSYM="MAKE"
CT_MAKE_DIR_NAME="make"
CT_MAKE_PKG_NAME="make"
CT_MAKE_SRC_RELEASE=y
# CT_MAKE_SRC_DEVEL is not set
CT_MAKE_PATCH_ORDER="global"
CT_MAKE_V_4_3=y
CT_MAKE_VERSION="4.3"
CT_MAKE_MIRRORS="$(CT_Mirrors GNU make)"
CT_MAKE_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
CT_MAKE_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
CT_MAKE_ARCHIVE_FORMATS=".tar.lz .tar.gz"
CT_MAKE_SIGNATURE_FORMAT="packed/.sig"
CT_MAKE_4_4_or_older=y
CT_MAKE_older_than_4_4=y
CT_MAKE_REQUIRE_older_than_4_4=y
CT_MAKE_4_3_or_later=y
CT_MAKE_4_3_or_older=y
# CT_MAKE_GMAKE_SYMLINK is not set
CT_MAKE_GNUMAKE_SYMLINK=y
CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE"
# end of Companion tools

path: docs/ct-ng-config


code:
// dot -Tpng -o /tmp/h.png < docs/hierarchy.dot
digraph D {
    "net::sup" -> "http::sup";
    "net::sup" -> "registry";
    "http::sup" -> "http::actor";
    "http::sup" -> "https::actor";
    "http::sup" -> "registry" [style = "dotted"];
    "net::sup" -> "local_announcer::actor";
    "net::sup" -> "global_announcer::sup";
    "net::sup" -> "acceptor::actor";
    "acceptor::actor" -> "registry" [style = "dotted"];
    "global_announcer::sup" -> "ssdp::actor";
    "global_announcer::sup" -> "registry" [style = "dotted"];
    "global_announcer::sup" -> "http::sup" [style = "dotted"];
    "global_announcer::sup" -> "acceptor::actor" [style = "dotted"];
    "local_announcer::actor" -> "registry" [style = "dotted"];
    "local_announcer::actor" -> "acceptor::actor" [style = "dotted"];
}


code:
[settings]
os=Windows
arch=x86_64
compiler=gcc
build_type=Release
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=12
[buildenv]
CC=x86_64-w64-mingw32-gcc
CXX=x86_64-w64-mingw32-g++
LD=ix86_64-w64-mingw32-ld
RC=x86_64-w64-mingw32-windres

[options]
boost/*:without_fiber=True
boost/*:without_graph=True
boost/*:without_log=True
boost/*:without_stacktrace=True
boost/*:without_test=True
boost/*:without_wave=True

path: docs/mingw


code:
[settings]
os=Linux
arch=x86_64
compiler=gcc
build_type=Release
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=8

[buildenv]
CC=x86_64-syncspirit-linux-gnu-gcc
CXX=x86_64-syncspirit-linux-gnu-g++
LD=x86_64-syncspirit-linux-gnu-ld

[options]
boost/*:without_fiber=True
boost/*:without_graph=True
boost/*:without_log=True
boost/*:without_stacktrace=True
boost/*:without_test=True
boost/*:without_wave=True


code:
# syncspirit-daemon

The program connects to peers (and listens incoming connections from peers)
and downloads files to local disk. The program stays always "online"
(similar to [syncthing](https://syncthing.net)), unless `inactivate`
command is defined.

`syncspirit-daemon` shares the same database, config folder and files with
other `syncspirit` programs, so it is possible to "setup" configuration
in one program and sync in other.

## generic command line options

 - `--log_level` log verbosity. Possible values are: `trace`, `debug`,
`info`, `warn`, `error`, `crit`, `off`

 - `--config_dir` path to directory with `syncspirit.toml`, ssh keys
and database

 - `--command` invoke a command within `syncspirit` core. It is possible
to specify several commands, the next command is executed after the
previous one is successfully applied.

## commands

 - `add_peer:$label:$device` record the target `$device` (locally name
it `$label`) into the `syncspirit` database, this allows to stay connected
with `$peer`.

 - `add_folder:label=$label:id=$id:path=$path` add the folder `$label`
with `$id` into the `syncspirit` database. All downloaded files will
be located under `$path`

 - `share:folder=$folder:device=$device` shares the specified folder with
the specified peer device. The `$folder` can refer folder label or
folder id; the `$device` can refer device either via full device id,
short device id or via device label.

 - `inactivate:$seconds` shutdown the programs after `$seconds` of
inactivity (i.e. no traffic between peers).

# launch example

```
syncspirit-daemon --log_level info \
    --config_dir=/tmp/my_dir \
    --command add_peer:peer_label:KUEQE66-JJ7P6AD-BEHD4ZW-GPBNW6Q-Y4C3K4Y-X44WJWZ-DVPIDXS-UDRJMA7 \
    --command add_folder:label=my_folder-label:id=nagkw-srrjz:path=/tmp/my_dir/data \
    --command share:folder=my_folder-label:device=KUEQE66 \
    --command inactivate:120
```


code:
# ui-fltk

## overview

`syncspirit` fltk-frontend (aka fltk-ui) is based on cross-platform
[fltk](https://www.fltk.org/) toolkit.

The source compiles for linux, windows and mac os X platforms, the binaries
are available for linux and windows only.

![main](fltk-01-main.png)

On the first launch the database is initialized, local device id is generated
(i.e. cryptographical keys). The local device id can be copied to clipboard
for sharing or it can be fetched from the generated QR-code.

![settings](fltk-02-settings.png)

The settings can be edited by expanding the local device (self) node
and selecting` settings` node. The settings have reasonable defaults applicable
for the most of uses.  The application restart is requite to let  the changed
settings take effect.

Alternatively, the settings can be edited via `$HOME/.config/syncspirit/syncspirit.toml`
file in toml-format.

The settings (aka `syncspirit.toml`) are shared across all `syncspirit` UIs
on the host.

![add new device](fltk-03-add-new-device.png)

To add peer device click on "devices" node and enter peer device id and its
label.

![add new device](fltk-04-add-pending-device.png)

Alternatively, if peer device already knows local device and tries to connect,
it will be disconnected but appear in "pending devices" list.

![edit peer device](fltk-05-peer-device-edit.png)

When peer device is connected (trusted), then some peer settings can be edited
(not all of them are implemented). When trusted peer connected to our device
at least once the shared with us folders appear on a tree (pending folders node).

![pending folder](fltk-06-pending-folders.png)

Click on a pending folder to be shared with peer. Edit its label and local
path where its files will be stored. There are other folder settings, not all
of them are implemented.

![scheduling folder](fltk-07-scheduled.png)

There is a special folder sharing option: "scheduled" . When this option is
enabled, the files from the folder are not downloaded from peer, instead
they (their metadata) just can be seen. This is implemented for asked
"selective sync" feature.

![remove folder browsing](fltk-08-remote-view.png)

Shared with peer folder can be browsed (actually metadata only, not content).
It does not depend whether the folder is "scheduled" or not. However if folder
is "paused", peer does not send folder updates, so it can be outdated.

Shared with peer folder can be browsed even if peer device is offline.

![synchronizing folder](fltk-09-sync.png)

When folder is synchronizing it is indicated by special icon. Some other folder
settings can be adjusted here.

![remove folder browsing](fltk-10-local-file.png)

Local files can be browsed, even when synchronization is in progress.

![view removed files](fltk-11-removed-files.png)

When browsing local and remote files the removed files can be also seen,
including the possibility to see the file history and determine the device
which deleted it.

![hide remove files](fltk-12-removed-files-hidden.png)

By default removed files are not displayed.

## bug reporting

1. launch the application with `--log_level trace`

2. the attach the log file `syncspirit-bootstrap.log` to bug description


code:
[settings]
os=Windows
arch=x86
compiler=gcc
build_type=Release
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=11
[buildenv]
CC=i686-w64-mingw32.shared-gcc
CXX=i686-w64-mingw32.shared-g++
LD=i686-w64-mingw32.shared-ld
RC=i686-w64-mingw32.shared-windres

[options]
boost/*:without_fiber=True
boost/*:without_graph=True
boost/*:without_log=True
boost/*:without_stacktrace=True
boost/*:without_test=True
boost/*:without_wave=True

[conf]
tools.build:cflags=["-DHAVE_NOTIFYIPINTERFACECHANGE=False", "-DHAVE_CONVERTINTERFACELUIDTONAMEA=False", "-DHAVE_CONVERTINTERFACEINDEXTOLUID=false"]
#tools.build:cflags=["-D_WIN32_WINNT=0x0501"]
#tools.build:cxxflags=["-D_WIN32_WINNT=0x0501"]

path: docs/xp


code:
# faq

## How to import existing directories into shared folder, i.e. to avoid  full
synchronization and transfer over network?

The [BEP-protocol](https://docs.syncthing.net/specs/bep-v1.html) tracks the
following information on a synchinized file:

1. Content, i.e. data blocks,

2. File metainformation, i.e. permissions and modification times

3. Syncrhonization information, i.e. file modification history from cluster point
of view.

Hence, simple file copying into the destination directory (1) is not enough.
Copying files full metainformation (i.e. (1) and (2)), can be done via the
following steps (on linux and mac-os):

- Create an archive with preserved permissions via (`p` is essential here):

```
tar -cjpf folder.tar.bz2 folder
```

- Unpack in the target location via

```
tar -xpf folder.tar.bz2
```

However, the synchronization information cannot be obtained outside of `syncspririt`,
to get it the following steps should be done:

1. Share folder with a peer, set the `scheduled` checkmark on the folder.

2. Wait until metainformation is fetched from a peer

3. Unpack the folder into the destination directory (`tar -xpf ...`)

4. Do "scan" on the folder.

You are not forced to import the whole folder. That way partial per-directory
import is also supported. The only requirement is tha the unpacked directories
should be located in the proper places.


code:
diff --git a/src/osal.c b/src/osal.c
index cdef5712..b54e91ce 100644
--- a/src/osal.c
+++ b/src/osal.c
@@ -1005,7 +1005,7 @@ MDBX_INTERNAL void osal_ioring_reset(osal_ioring_t *ior) {
     for (ior_item_t *item = ior->pool; item <= ior->last;) {
       if (!HasOverlappedIoCompleted(&item->ov)) {
         assert(ior->overlapped_fd);
-        CancelIoEx(ior->overlapped_fd, &item->ov);
+        CancelIo(ior->overlapped_fd);
       }
       if (item->ov.hEvent && item->ov.hEvent != ior)
         ior_put_event(ior, item->ov.hEvent);


code:
#!/usr/bin/sh

if [ -z "$1" ]; then
    echo "Usage: make-appimage.sh path/to/app/application"
    exit 1
fi

APP_PATH=$1
APP=$(basename $APP_PATH)
APP_DIR="AppDir-$APP/usr/bin"
WORK_DIR="AppDir/$APP_DIR"
echo $WORK_DIR

rm -rf "$WORK_DIR"
mkdir -p "$WORK_DIR"
strip --strip-all $APP_PATH
cp $APP_PATH "$WORK_DIR"

cd "AppDir"
if [ ! -e "./linuxdeploy-x86_64.AppImage" ]; then
    echo "going to download linux-deploy..."
    wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
    chmod +x linuxdeploy-x86_64.AppImage
fi

./linuxdeploy-x86_64.AppImage -v 2 --appdir "$APP_DIR" --output appimage -e "$APP_DIR/$APP" --icon-file "../../misc/$APP.png" -d "../../misc/$APP.desktop"
cd ..


code:
--- _deps/mdbx-src/mdbx.c	2025-03-07 09:32:49.342834537 +0300
+++ _deps/mdbx-src/mdbx.c.orig	2025-03-07 09:32:13.593479783 +0300
@@ -28490,7 +28490,7 @@
     for (ior_item_t *item = ior->pool; item <= ior->last;) {
       if (!HasOverlappedIoCompleted(&item->ov)) {
         assert(ior->overlapped_fd);
-        CancelIoEx(ior->overlapped_fd, &item->ov);
+        CancelIo(ior->overlapped_fd);
       }
       if (item->ov.hEvent && item->ov.hEvent != ior)
         ior_put_event(ior, item->ov.hEvent);


code:
#!/usr/bin/env perl
use strict;
use warnings;
use 5.30.0;

use File::Copy;
use File::Basename;

my ($original_bin, $tuned_bin) = ($ARGV[0], $ARGV[1]);
die("usage: $0 path/to/original/executable path/to/modified/executable")
    if (!$original_bin || !$tuned_bin);

# returns hash of ALL (recursively) resolved dependecies,
# i.e. {lib_1.so => /path/to/lib_1.so, ... }
my $resolve = sub {
    my $binary = shift;
    my $list = `ldd $binary 2>&1`;
    my %mapping =
        map  { m/(.*) => (.*)/; ($1, $2) }
        map  { s/\s*(lib.*) \(.*/$1/r }
        grep { /\s*lib.* => / }
        split /\n/, $list;
    return \%mapping;
};

# returns true if library should be skipped (i.e. it is a SYSTEM dependency)
my $skip = sub {
    my $path = shift;
    return scalar($path =~ m{^(/usr/|/lib/)});
};

my $dest_dir = dirname($tuned_bin);
my $copied = 0;
my $resolved = $resolve->($original_bin);

for my $lib  (keys $resolved->%*) {
    my $path = $resolved->{$lib};
    next if $skip->($path);
    my $target = "$dest_dir/$lib";
    next if (-e $target);
    if (File::Copy::syscopy($path, $target)) {
        say "[copied] $lib";
        ++$copied;
    } else {
        say "[error] cannot copy $lib ($path -> $target): $!";
    }
    say $lib;
}

say "totally copied $copied libs";

=x
my $info = $read_elf->($tuned_bin);
my $all_libs = $get_dynamic->($info);
my $dest_dir = $get_rpath->($info);
my $resolved = $resolve->($original_bin);
my $processed = {};
my $copied = 0;

say "dest_lib_dir = $dest_dir";
mkdir($dest_dir);

# try to copy each found dependecy
while (my $lib = shift($all_libs->@*)) {
    # skip already processed and not resolved dependency
    next if exists $processed->{$lib};
    say "zzz $lib";
    #if (exists $resolved->{$lib}) {
    #    my $r = $resolved->{$lib};
    #    next unless $r =~ m|/home/|;
    #}

    my $source_lib = $resolved->{$lib};
    my $dest_lib = "$dest_dir/$lib";

    # skip already existing (copied) dependency
    if (-e $dest_lib) {
        $processed->{$lib} = 1;
        next;
    }
    if ($skip->($source_lib)) {
        #say "[skip] $lib";
        next;
    }

    if (File::Copy::syscopy($source_lib, $dest_lib)) {
        say "[copy] $lib ($source_lib)";
        # $DB::single = 1 if ($lib eq 'libwx_gtk3u_richtext-3.2.so.0');
        ++$copied;
        # gather dependencies of the depndency
        my $lib_info = $read_elf->($source_lib);
        my $lib_libs = $get_dynamic->($lib_info);
        my $libs_resolved = $resolve->($source_lib);
        # append gathered dependencies if needed
        for my $l (@$lib_libs) {
            # $DB::single = 1 if ($l eq 'libwx_baseu_xml-3.2.so.0');
            next if exists $processed->{$l};
            next if not exists $libs_resolved->{$l};
            my $dep_path = $libs_resolved->{$l};
            next if $skip->($dep_path)  =~ m{/usr/|/lib/};
            $resolved->{$l} = $dep_path;
            push $all_libs->@*, $l;
        }

    } else {
        say "[error] $lib (from $source_lib): $!";
    }
    $processed->{$lib} = 1;
}

say "totally copied $copied libs";
=cut


code:
#!/usr/bin/env python

import pefile
import sys
import os
import shutil
import subprocess
import argparse

from os.path import join

onerror = lambda err: print(err)
def gather(entry_dir, dlls, bitness):
    for root, dirs, files in os.walk(entry_dir, topdown=False, onerror = onerror, followlinks=True):
        for file in files:
            if (file.endswith(".dll")):
                full_path = join(root, file)
                #print(full_path)
                try:
                    pe = pefile.PE(full_path, fast_load = True)
                    pe_bitness = pe.OPTIONAL_HEADER.Magic
                    if (pe_bitness == bitness):
                        dlls[file.lower()] = full_path
                except Exception as e:
                    None;

def resolve(path):
    if (subprocess.check_output("uname").decode("utf-8").strip("\n") == "Linux"):
        # print(subprocess.check_output("uname").decode("utf-8").strip("\n"))
        return path
    else:
        # print(subprocess.check_output("uname"))
        return subprocess.check_output(["cygpath", "-w", path]).decode("utf-8").strip("\n")

parser = argparse.ArgumentParser(description='Gathers DLLs.')
parser.add_argument('--binaries', nargs='+', help='full paths to binaries for scaning')
parser.add_argument('--dirs', nargs='*', help='additional dirs for looking up dependencies')

bitness = None
args = parser.parse_args()

scan_queue = []
for file_name in args.binaries.copy():
    file_ext = os.path.splitext(file_name)[1]
    if (file_ext == ".dll" or file_ext == ".exe"):
        scan_queue.append(file_name)

for file_name in scan_queue:
    file_ext = os.path.splitext(file_name)[1]
    if (file_ext == ".dll" or file_ext == ".exe"):
        pe = pefile.PE(file_name, fast_load = True)
        pe_bitness = pe.OPTIONAL_HEADER.Magic
        if bitness is None:
            bitness = pe_bitness
        elif bitness != pe_bitness:
            raise("binaries has different bitness")

available_dlls = dict()
for d in args.dirs:
    gather(resolve(d), available_dlls, bitness)

existing_dir = os.path.dirname(args.binaries[0])
existing_dlls = dict()
gather(existing_dir, existing_dlls, bitness)

visited = dict()
needed_dlls = dict()

while scan_queue:
    file_name =  scan_queue.pop(0)
    # print(f"checking '{file_name}'")
    visited[file_name] = True
    pe = pefile.PE(file_name)

    if pe_bitness == bitness:
        for item in pe.DIRECTORY_ENTRY_IMPORT:
            dll = item.dll.lower().decode("utf-8")
            # print(f"{dll}, bitness = {bitness} / {pe_bitness}")
            if (dll not in needed_dlls and dll in available_dlls and dll not in existing_dlls):
                full_path = available_dlls[dll]
                needed_dlls[dll] = full_path
                if (dll not in visited):
                    scan_queue.append(full_path)

for dll, path in needed_dlls.items():
    print(f"{path}")
    shutil.copy(path, existing_dir)


code:
[Desktop Entry]
Name=syncspirit-fltk
Exec=syncspirit-fltk
Icon=syncspirit-fltk
Type=Application
Categories=Utility;


code:
set(TOOLCHAIN_HOME "/home/b/x-tools/x86_64-ubuntu14.04-linux-gnu")
set(CMAKE_C_COMPILER   ${TOOLCHAIN_HOME}/bin/x86_64-ubuntu14.04-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_HOME}/bin/x86_64-ubuntu14.04-linux-gnu-g++)
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
set(CMAKE_FIND_ROOT_PATH
    ${TOOLCHAIN_HOME}/x86_64-ubuntu14.04-linux-gnu/sysroot/
    /home/b/development/cpp/syncspirit-cross/sysroot
)


code:
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2019-2025 Ivan Baidakou

#pragma once

#include <cstdint>

namespace syncspirit::config {

struct bep_config_t {
    std::uint32_t rx_buff_size;
    std::uint32_t tx_buff_limit;
    std::uint32_t connect_timeout;
    std::uint32_t request_timeout;
    std::uint32_t tx_timeout;
    std::uint32_t rx_timeout;
    std::uint32_t blocks_max_requested;
    std::uint32_t blocks_simultaneous_write;
    std::uint32_t advances_per_iteration;
    std::uint32_t stats_interval;
};

} // namespace syncspirit::config


code:
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2019-2024 Ivan Baidakou

#pragma once

#pragma once
#include <cstdint>

namespace syncspirit::config {

struct db_config_t {
    std::int64_t upper_limit;
    std::uint32_t uncommitted_threshold;
    std::uint32_t max_blocks_per_diff;
    std::uint32_t max_files_per_diff;
};

} // namespace syncspirit::config


code:
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2019-2022 Ivan Baidakou

#pragma once

#include <cstdint>

namespace syncspirit::config {

struct dialer_config_t {
    bool enabled;
    std::uint32_t redial_timeout;
    std::uint32_t skip_discovers;
};

} // namespace syncspirit::config


code:
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2024 Ivan Baidakou

#pragma once
#include <spdlog/spdlog.h>

namespace syncspirit::config {

struct fltk_config_t {
    spdlog::level::level_enum level;
    bool display_deleted;
    bool display_missing;
    bool display_colorized;
    int main_window_width;
    int main_window_height;
    double left_panel_share;
    double bottom_panel_share;
    std::uint32_t log_records_buffer;
};

} // namespace syncspirit::config


code:
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2019-2024 Ivan Baidakou

#pragma once
#include <cstdint>

namespace syncspirit::config {

struct fs_config_t {
    std::uint32_t temporally_timeout;
    std::uint32_t mru_size;
    std::int64_t bytes_scan_iteration_limit;
    std::int64_t files_scan_iteration_limit;
};

} // namespace syncspirit::config


code:
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2019-2024 Ivan Baidakou

#pragma once
#include <cstdint>
#include <string>
#include "utils/uri.h"

namespace syncspirit::config {

struct global_announce_config_t {
    bool enabled;
    bool debug;
    utils::uri_ptr_t announce_url;
    std::string device_id;
    std::string cert_file;
    std::string key_file;
    std::uint32_t rx_buff_size;
    std::uint32_t timeout;
    std::uint32_t reannounce_after = 600;
};

} // namespace syncspirit::config


code:
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2019-2022 Ivan Baidakou

#pragma once
#include <cstdint>

namespace syncspirit::config {

struct local_announce_config_t {
    bool enabled;
    std::uint16_t port;
    std::uint32_t frequency;
};

} // namespace syncspirit::config


code:
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2019-2022 Ivan Baidakou

#pragma once
#include <spdlog/spdlog.h>
#include <vector>

namespace syncspirit::config {

struct log_config_t {
    using sinks_t = std::vector<std::string>;

    std::string name;
    spdlog::level::level_enum level;
    sinks_t sinks;
};

using log_configs_t = std::vector<log_config_t>;

} // namespace syncspirit::config


code:
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2019-2024 Ivan Baidakou

#pragma once
#include <cstdint>
#include "bep.h"
#include "db.h"
#include "dialer.h"
#include "fs.h"
#include "global_announce.h"
#include "local_announce.h"
#include "log.h"
#include "relay.h"
#include "upnp.h"
#include "fltk.h"
#include <filesystem>

namespace syncspirit::config {

namespace bfs = std::filesystem;

struct main_t {
    bfs::path config_path;
    bfs::path default_location;

    local_announce_config_t local_announce_config;
    log_configs_t log_configs;
    upnp_config_t upnp_config;
    global_announce_config_t global_announce_config;
    bep_config_t bep_config;
    dialer_config_t dialer_config;
    fs_config_t fs_config;
    db_config_t db_config;
    relay_config_t relay_config;
    fltk_config_t fltk_config;

    std::uint32_t timeout;
    std::string device_name;
    std::uint32_t hasher_threads;
};

} // namespace syncspirit::config


code:
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2019-2024 Ivan Baidakou

#pragma once

#include "utils/uri.h"

namespace syncspirit::config {

struct relay_config_t {
    bool enabled;
    bool debug;
    utils::uri_ptr_t discovery_url;
    std::uint32_t rx_buff_size;
};

} // namespace syncspirit::config


code:
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2019-2022 Ivan Baidakou

#pragma once
#include <cstdint>

namespace syncspirit::config {

struct upnp_config_t {
    bool enabled;
    bool debug;
    std::uint32_t max_wait;
    std::uint16_t external_port;
    std::uint32_t rx_buff_size;
};

} // namespace syncspirit::config