diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index f7aa45f..ec5d5e1 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -11,16 +11,18 @@ on: jobs: checks: - name: Build for Linux (${{ matrix.libsignal }} libsignal) + name: Build for Linux (shared=${{ matrix.BUILD_SHARED_LIBS }}, pthreads=${{ matrix.AXC_WITH_PTHREADS }}) runs-on: ubuntu-20.04 strategy: + fail-fast: false matrix: - libsignal: ['system', 'bundled'] + BUILD_SHARED_LIBS: ['ON', 'OFF'] + AXC_WITH_PTHREADS: ['ON', 'OFF'] steps: - uses: actions/checkout@v2.4.0 - - name: Install build dependencies (all but libsignal-protocol-c) + - name: Install build dependencies run: |- set -x sudo apt-get update @@ -29,37 +31,41 @@ jobs: libcmocka-dev \ libgcrypt20-dev \ libglib2.0-dev \ - libsqlite3-dev + libsignal-protocol-c-dev \ + libsqlite3-dev \ + ninja-build - - name: Install build dependency libsignal-protocol-c - if: ${{ matrix.libsignal == 'system' }} + - name: Configure run: |- - sudo apt-get install --yes --no-install-recommends -V \ - libsignal-protocol-c-dev - - - name: Fetch Git submodule for build dependency libsignal-protocol-c - if: ${{ matrix.libsignal == 'bundled' }} - run: |- - git submodule update --init --recursive + set -x + cmake \ + -B build \ + -G Ninja \ + -DAXC_WITH_PTHREADS=${{ matrix.AXC_WITH_PTHREADS }} \ + -DBUILD_SHARED_LIBS=${{ matrix.BUILD_SHARED_LIBS }} \ + -D_AXC_WITH_COVERAGE=ON - name: Build run: |- set -x - make -j $(nproc) all build/libaxc-nt.a + ninja -v -C build all + cat build/libaxc.pc - name: Test run: |- - make coverage # includes tests + set -x + CTEST_OUTPUT_ON_FAILURE=1 ninja -C build test + ninja -C build coverage - name: Install run: |- set -x -o pipefail - make DESTDIR="${PWD}"/ROOT install + DESTDIR="${PWD}"/ROOT ninja -v -C build install find ROOT/ -not -type d | sort | xargs ls -l - name: Store coverage HTML report uses: actions/upload-artifact@v2.3.1 with: - name: coverage_${{ matrix.libsignal }} - path: coverage/ + name: axc_coverage_shared_${{ matrix.BUILD_SHARED_LIBS }}_pthreads_${{ matrix.AXC_WITH_PTHREADS }} + path: build/coverage*.html if-no-files-found: error diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml new file mode 100644 index 0000000..21447ff --- /dev/null +++ b/.github/workflows/windows.yml @@ -0,0 +1,80 @@ +# Copyright (c) 2022 Sebastian Pipping +# Licensed under the GPL v2 or later + +name: Build for Windows + +on: + pull_request: + push: + schedule: + - cron: '0 2 * * 5' # Every Friday at 2am + +jobs: + checks: + name: Build for Windows (shared=${{ matrix.BUILD_SHARED_LIBS }}, pthreads=${{ matrix.AXC_WITH_PTHREADS }}) + runs-on: windows-2019 + defaults: + run: + shell: msys2 {0} + strategy: + fail-fast: false + matrix: + BUILD_SHARED_LIBS: ['ON', 'OFF'] + AXC_WITH_PTHREADS: ['ON', 'OFF'] + steps: + + - uses: actions/checkout@v2.4.0 + + - name: Install build dependencies + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW32 + install: | + cmake + mingw-w64-i686-cmocka + mingw-w64-i686-glib2 + mingw-w64-i686-libgcrypt + mingw-w64-i686-libsignal-protocol-c + mingw-w64-i686-sqlite3 + mingw-w64-i686-toolchain + ninja + + - name: Configure + run: |- + set -x + cmake \ + -B build \ + -G Ninja \ + -DCMAKE_C_COMPILER=i686-w64-mingw32-gcc -DCMAKE_SYSTEM_NAME=Windows -DWIN32=ON -DMINGW=ON \ + -DAXC_WITH_PTHREADS=${{ matrix.AXC_WITH_PTHREADS }} \ + -DBUILD_SHARED_LIBS=${{ matrix.BUILD_SHARED_LIBS }} \ + -D_AXC_WITH_COVERAGE=ON + + - name: Build + run: |- + set -x + ninja -v -C build all + cat build/libaxc.pc + + - name: Test (KNOWN TO FAIL) + run: |- + set -x + CTEST_OUTPUT_ON_FAILURE=1 ninja -C build test || true # TODO fix tests + # Note: msys2 does not come with a package for gcovr, yet(?) + # ninja -C build coverage + + - name: Install + run: |- + set -x -o pipefail + DESTDIR="${PWD}"/ROOT ninja -v -C build install + find ROOT/ -not -type d | sort | xargs ls -l + + - name: Store Windows binaries + uses: actions/upload-artifact@v2.3.1 + with: + name: axc_win32bin_shared_${{ matrix.BUILD_SHARED_LIBS }}_pthreads_${{ matrix.AXC_WITH_PTHREADS }} + path: | + build/*.a + build/*.dll + build/*.exe + if-no-files-found: error diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 006008c..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "lib/libsignal-protocol-c"] - path = lib/libsignal-protocol-c - url = https://github.com/WhisperSystems/libsignal-protocol-c.git diff --git a/CHANGELOG.md b/CHANGELOG.md index 6057ceb..c6e958b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,14 @@ - Fix the build for users without libsignal-protocol-c installed system-wide ([#31](https://github.com/gkdr/axc/pull/31)) (thanks, [@hartwork](https://github.com/hartwork)!) - The example code is runnable again, and some memory leaks ([#14](https://github.com/gkdr/axc/pull/14)) (thanks, [@fbrausse](https://github.com/fbrausse)!) - Compiler warnings for test files. +- Add missing field `Requires.private:` to auto-generated pkg-config file `libaxc.pc` ([#32](https://github.com/gkdr/axc/pull/32)) (thanks, [@hartwork](https://github.com/hartwork)!) + +### Changed +- Migrate build system from a Makefile to CMake ([#32](https://github.com/gkdr/axc/pull/32)) (thanks, [@hartwork](https://github.com/hartwork)!) ### Infrastructure - Cover Linux build by GitHub Actions CI ([#31](https://github.com/gkdr/axc/pull/31)) (thanks, [@hartwork](https://github.com/hartwork)!) +- Cover Windows build by GitHub Actions CI using msys2 ([#32](https://github.com/gkdr/axc/pull/32)) (thanks, [@hartwork](https://github.com/hartwork)!) ## [0.3.6] - 2021-09-06 ### Fixed diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..0955a6e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,248 @@ +# Copyright (c) 2022 Sebastian Pipping +# Licensed under the GPL v2 or later + +cmake_minimum_required(VERSION 3.16.3) + +project(axc + VERSION + 0.3.7 + # NOTE: Because this^^ version affects shared library filenames, + # it needs a major version bump to 1.0.0 already at + # the _first ever ABI break_ despite semver rule 4 + # (https://semver.org/#spec-item-4). + LANGUAGES + C +) + +include(FindPkgConfig) +include(FindThreads) +include(GNUInstallDirs) + + +# +# Public configuration +# +option(BUILD_SHARED_LIBS "Build shared libraries (rather than static ones)" ON) +option(AXC_INSTALL "Install build artifacts" ON) +option(AXC_WITH_PTHREADS "Build with pthreads support" ON) +option(AXC_WITH_TESTS "Build test suite (depends on cmocka)" ON) +if(NOT _AXC_HELP) # hide from "cmake -D_AXC_HELP=ON -LH ." output + option(_AXC_WARNINGS_AS_ERRORS "(Unofficial!) Turn warnings into errors" OFF) + option(_AXC_WITH_COVERAGE "(Unofficial!) Build with coverage" OFF) +endif() + +if(NOT BUILD_SHARED_LIBS) + # NOTE: If we don't enforce -fPIC for static(!) libraries, we may run into + # "[..] relocation R_X86_64_PC32 against symbol [..]" link errors + # in dependent projects trying to link a shared library based on + # our static library. + set(CMAKE_POSITION_INDEPENDENT_CODE ON) +endif() + + +# +# Global CPPFLAGS and CFLAGS +# +add_compile_definitions( + _XOPEN_SOURCE=700 + _BSD_SOURCE + _POSIX_SOURCE + _GNU_SOURCE + _DEFAULT_SOURCE +) +add_compile_options( + -std=c99 + -Wall + -Wextra + -Wpedantic + -Wstrict-overflow + -fno-strict-aliasing + -funsigned-char + -fno-builtin-memset + -Wformat + -Werror=format-security +) + +if(NOT WIN32) + # Note: This would give link error "undefined reference to `__stack_chk_guard'" + # with MinGW + add_compile_options(-fstack-protector-strong) +endif() + +if(_AXC_WARNINGS_AS_ERRORS) + add_compile_options(-Werror) +endif() + +if(_AXC_WITH_COVERAGE) + set(_AXC_COVERAGE_FLAGS -g -O0 --coverage) + add_compile_options(${_AXC_COVERAGE_FLAGS}) + link_libraries(${_AXC_COVERAGE_FLAGS}) +endif() + + +# +# Build dependencies +# +if(AXC_WITH_PTHREADS) + set(THREADS_PREFER_PTHREAD_FLAG ON) + find_package(Threads REQUIRED) +endif() + +# NOTE: We cannot use "pkg_check_modules([..] IMPORTED_TARGET [..])" +# because we'd run into a (false positive) CMake error +# "contains relative path in its INTERFACE_INCLUDE_DIRECTORIES" +# when using "target_link_libraries([..] PkgConfig::[..])" with msys2. +if(AXC_WITH_TESTS) + pkg_check_modules(CMOCKA REQUIRED "cmocka") +endif() +pkg_check_modules(GLIB REQUIRED "glib-2.0") +pkg_check_modules(GCRYPT REQUIRED "libgcrypt") +pkg_check_modules(SIGNAL REQUIRED "libsignal-protocol-c") +pkg_check_modules(SQLITE REQUIRED "sqlite3") + + +# +# C library +# +file(GLOB _AXC_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/axc*.[ch]) +add_library(axc ${_AXC_SOURCES}) +target_include_directories(axc PUBLIC $) + +if(NOT AXC_WITH_PTHREADS) + # TODO Use target-specific function "target_compile_definitions" instead + # once the tests are no longer including libaxc's .c(!) files + add_compile_definitions(NO_THREADS) +endif() + +if(AXC_INSTALL) + file(GLOB _AXC_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/axc*.h) + target_include_directories(axc PUBLIC $) + install(FILES ${_AXC_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/axc) + install(TARGETS axc EXPORT axc + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) +endif() + +if(NOT WIN32) + set_property(TARGET axc PROPERTY VERSION ${PROJECT_VERSION}) + set_property(TARGET axc PROPERTY SOVERSION ${PROJECT_VERSION_MAJOR}) + set_property(TARGET axc PROPERTY NO_SONAME ${NO_SONAME}) +endif() + + +# +# pkg-config/pkgconf file +# +set(_AXC_PKGCONF_EXEC_PREFIX ${CMAKE_INSTALL_PREFIX}) +set(_AXC_PKGCONF_LIBDIR ${CMAKE_INSTALL_FULL_LIBDIR}) +set(_AXC_PKGCONF_INCLUDEDIR ${CMAKE_INSTALL_FULL_INCLUDEDIR}) +set(_AXC_PKGCONF_PREFIX ${CMAKE_INSTALL_PREFIX}) +string(REPLACE ${CMAKE_INSTALL_PREFIX} \${exec_prefix} _AXC_PKGCONF_LIBDIR ${_AXC_PKGCONF_LIBDIR}) +string(REPLACE ${CMAKE_INSTALL_PREFIX} \${prefix} _AXC_PKGCONF_EXEC_PREFIX ${_AXC_PKGCONF_EXEC_PREFIX}) +string(REPLACE ${CMAKE_INSTALL_PREFIX} \${prefix} _AXC_PKGCONF_INCLUDEDIR ${_AXC_PKGCONF_INCLUDEDIR}) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libaxc.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libaxc.pc @ONLY) +set_target_properties(axc PROPERTIES ADDITIONAL_CLEAN_FILES ${CMAKE_CURRENT_BINARY_DIR}/libaxc.pc) + +if(AXC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libaxc.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig + ) +endif() + + +# +# C example app +# +if(NOT WIN32) + # NOTE: The message client uses funtion "getline" + # which MinGW doesn't have out of the box. + set(_AXC_EXAMPLE_TARGETS message_client) + add_executable(message_client ${CMAKE_CURRENT_SOURCE_DIR}/src/message_client.c) + target_link_libraries(message_client PRIVATE axc) +endif() + + +# +# C test suite +# +if(AXC_WITH_TESTS) + set(_AXC_TEST_TARGETS test_client test_store) + + enable_testing() + + foreach(_target ${_AXC_TEST_TARGETS}) + add_executable(${_target} ${CMAKE_CURRENT_SOURCE_DIR}/test/${_target}.c) + target_link_libraries(${_target} PRIVATE axc) + add_test(NAME ${_target} COMMAND ${_target}) + + if(BUILD_SHARED_LIBS) + target_compile_options(${_target} PRIVATE ${CMOCKA_CFLAGS}) + target_link_libraries(${_target} PRIVATE ${CMOCKA_LIBRARIES}) + else() + target_compile_options(${_target} PRIVATE ${CMOCKA_STATIC_CFLAGS}) + target_link_libraries(${_target} PRIVATE ${CMOCKA_STATIC_LIBRARIES}) + endif() + endforeach() +endif() + + +# +# External build dependencies +# +foreach(_target axc ${_AXC_EXAMPLE_TARGETS} ${_AXC_TEST_TARGETS}) + if(BUILD_SHARED_LIBS) + target_compile_options(${_target} PUBLIC ${SIGNAL_CFLAGS}) + target_link_libraries(${_target} PUBLIC ${SIGNAL_LIBRARIES}) + else() + target_compile_options(${_target} PUBLIC ${SIGNAL_STATIC_CFLAGS}) + target_link_libraries(${_target} PUBLIC ${SIGNAL_STATIC_LIBRARIES}) + endif() + + if(AXC_WITH_PTHREADS) + target_link_libraries(${_target} PRIVATE Threads::Threads) + endif() +endforeach() + +foreach(_target axc ${_AXC_TEST_TARGETS}) + if(BUILD_SHARED_LIBS) + # TODO: Tests should stop depending on gcrypt + # once the tests stop including libaxc's .c(!) files + target_compile_options(${_target} PRIVATE ${GCRYPT_CFLAGS}) + target_link_libraries(${_target} PRIVATE ${GCRYPT_LIBRARIES}) + + # TODO: Tests should stop depending on glib + # once the tests stop including libaxc's .c(!) files + target_compile_options(${_target} PRIVATE ${GLIB_CFLAGS}) + target_link_libraries(${_target} PRIVATE ${GLIB_LIBRARIES}) + + target_compile_options(${_target} PRIVATE ${SQLITE_CFLAGS}) + target_link_libraries(${_target} PRIVATE ${SQLITE_LIBRARIES}) + else() + # TODO: Tests should stop depending on gcrypt + # once the tests stop including libaxc's .c(!) files + target_compile_options(${_target} PRIVATE ${GCRYPT_STATIC_CFLAGS}) + target_link_libraries(${_target} PRIVATE ${GCRYPT_STATIC_LIBRARIES}) + + # TODO: Tests should stop depending on glib + # once the tests stop including libaxc's .c(!) files + target_compile_options(${_target} PRIVATE ${GLIB_STATIC_CFLAGS}) + target_link_libraries(${_target} PRIVATE ${GLIB_STATIC_LIBRARIES}) + + target_compile_options(${_target} PRIVATE ${SQLITE_STATIC_CFLAGS}) + target_link_libraries(${_target} PRIVATE ${SQLITE_STATIC_LIBRARIES}) + endif() +endforeach() + + +# +# Coverage reporting +# +if(_AXC_WITH_COVERAGE) + add_custom_target(coverage + COMMAND gcovr -r ${CMAKE_CURRENT_SOURCE_DIR} --html --html-details -o coverage.html + COMMAND gcovr -r ${CMAKE_CURRENT_SOURCE_DIR} -s + ) +endif() diff --git a/Makefile b/Makefile deleted file mode 100644 index ddcb6bb..0000000 --- a/Makefile +++ /dev/null @@ -1,172 +0,0 @@ -### toolchain -# -CC ?= gcc -AR ?= ar -MKDIR = mkdir -MKDIR_P = mkdir -p -CMAKE ?= cmake -CMAKE_FLAGS = -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_FLAGS=-fPIC -ARCH := $(shell $(CC) -print-multiarch) -VER_MAJ = 0 -VERSION = 0.3.7 - -AX_DIR=./lib/libsignal-protocol-c -AX_BDIR=$(AX_DIR)/build -AX_PATH=$(AX_BDIR)/src/libsignal-protocol-c.a - -PKG_CONFIG ?= pkg-config -GLIB_CFLAGS ?= $(shell $(PKG_CONFIG) --cflags glib-2.0) -GLIB_LDFLAGS ?= $(shell $(PKG_CONFIG) --libs glib-2.0) - -SQLITE3_CFLAGS ?= $(shell $(PKG_CONFIG) --cflags sqlite3) -SQLITE3_LDFLAGS ?= $(shell $(PKG_CONFIG) --libs sqlite3) - -SIGNAL_CFLAGS ?= $(shell $(PKG_CONFIG) --cflags libsignal-protocol-c) -SIGNAL_LDFLAGS ?= $(shell $(PKG_CONFIG) --libs libsignal-protocol-c) - -LIBGCRYPT_CONFIG ?= libgcrypt-config -LIBGCRYPT_LDFLAGS ?= $(shell $(LIBGCRYPT_CONFIG) --libs) - - -SDIR = src -LDIR = lib -BDIR = build -TDIR = test -TFN = test_all -CDIR = coverage - -PKGCFG_C=$(GLIB_CFLAGS) \ - $(SQLITE3_CFLAGS) \ - $(LIBGCRYPT_CFLAGS) - -PKGCFG_L=$(GLIB_LDFLAGS) \ - $(SQLITE3_LDFLAGS) \ - $(LIBGCRYPT_LDFLAGS) - -REQPKG=libsignal-protocol-c -REQPKG:=$(shell $(PKG_CONFIG) --exists $(REQPKG) && echo '$(REQPKG)') -ifneq ($(REQPKG),) - AX_PATH_AS_NEEDED = - PKGCFG_C += $(SIGNAL_CFLAGS) - PKGCFG_L += $(SIGNAL_LDFLAGS) -else - AX_PATH_AS_NEEDED = $(AX_PATH) - HEADERS=-I$(AX_DIR)/src - PKGCFG_C +=$(HEADERS) - PKGCFG_L +=$(AX_PATH) -endif - -ifeq ($(PREFIX),) - PREFIX := /usr/local -endif - -CPPFLAGS += -D_XOPEN_SOURCE=700 -D_BSD_SOURCE -D_POSIX_SOURCE -D_GNU_SOURCE -D_DEFAULT_SOURCE -CFLAGS += $(PKGCFG_C) -std=c11 -g -Wall -Wextra -Wpedantic \ - -Wstrict-overflow -fno-strict-aliasing -funsigned-char \ - -fno-builtin-memset -fstack-protector-strong -Wformat -Werror=format-security -TESTFLAGS=$(PKGCFG_C) -g -O0 --coverage -Wall -Wextra -Wpedantic -Wstrict-overflow -fstack-protector-strong -Wformat -Werror=format-security -LDFLAGS += -pthread -ldl $(PKGCFG_L) -lm -LDFLAGS_T= -lcmocka $(LDFLAGS) -PICFLAGS=-fPIC $(CFLAGS) - - -all: $(BDIR)/libaxc.a shared - -$(BDIR): - $(MKDIR_P) $@ - -client: $(SDIR)/message_client.c $(BDIR)/axc_store.o $(BDIR)/axc_crypto.o $(BDIR)/axc.o $(AX_PATH_AS_NEEDED) - $(MKDIR_P) $@ - $(CC) $(CPPFLAGS) $(CFLAGS) $^ -o $@/$@.o $(LDFLAGS) - -$(BDIR)/axc.o: $(SDIR)/axc.c $(AX_PATH_AS_NEEDED) | $(BDIR) - $(CC) $(PICFLAGS) $(CPPFLAGS) -c $< -o $@ - -$(BDIR)/axc-nt.o: $(SDIR)/axc.c $(AX_PATH_AS_NEEDED) | $(BDIR) - $(CC) $(PICFLAGS) $(CPPFLAGS) -DNO_THREADS -c $< -o $@ - -$(BDIR)/axc_crypto.o: $(SDIR)/axc_crypto.c $(AX_PATH_AS_NEEDED) | $(BDIR) - $(CC) $(PICFLAGS) $(CPPFLAGS) -c $< -o $@ - -$(BDIR)/axc_store.o: $(SDIR)/axc_store.c $(AX_PATH_AS_NEEDED) | $(BDIR) - $(CC) $(PICFLAGS) $(CPPFLAGS) -c $< -o $@ - -$(BDIR)/libaxc.a: $(BDIR)/axc.o $(BDIR)/axc_crypto.o $(BDIR)/axc_store.o - $(AR) rcs $@ $^ - -$(BDIR)/libaxc-nt.a: $(BDIR)/axc-nt.o $(BDIR)/axc_crypto.o $(BDIR)/axc_store.o - $(AR) rcs $@ $^ - -$(BDIR)/libaxc.so: $(AX_PATH_AS_NEEDED) | $(BDIR) - $(CC) -shared -Wl,-soname,libaxc.so.$(VER_MAJ) -o $@ $(PICFLAGS) $(SDIR)/axc.c $(SDIR)/axc_crypto.c $(SDIR)/axc_store.c $(LDFLAGS) $(CPPFLAGS) - -$(BDIR)/libaxc.pc: $(BDIR) - echo 'prefix='$(PREFIX) > $@ - echo 'exec_prefix=$${prefix}' >> $@ - echo 'libdir=$${prefix}/lib/$(ARCH)' >> $@ - echo 'includedir=$${prefix}/include' >> $@ - echo 'Name: libaxc' >> $@ - echo 'Version: ${VERSION}' >> $@ - echo 'Description: client library for libsignal-protocol-c' >> $@ - echo 'Requires: libsignal-protocol-c' >> $@ - echo 'Cflags: -I$${includedir}/axc' >> $@ - echo 'Libs: -L$${libdir} -laxc' >> $@ - -$(AX_DIR): - @echo "ERROR: Git submodules are not initialized, please run e.g. 'git submodule update --init --recursive' first" >&2 ; false - -$(AX_BDIR): | $(AX_DIR) - $(MKDIR_P) $@ - -$(AX_PATH): | $(AX_BDIR) - cd $(AX_BDIR) && $(CMAKE) $(CMAKE_FLAGS) .. - $(MAKE) -C $(AX_BDIR) - -shared: $(BDIR)/libaxc.so $(BDIR)/libaxc.pc - - -install: $(BDIR) - install -d $(DESTDIR)/$(PREFIX)/lib/$(ARCH)/pkgconfig/ - install -m 644 $(BDIR)/libaxc.a $(DESTDIR)/$(PREFIX)/lib/$(ARCH)/libaxc.a - install -m 644 $(BDIR)/libaxc.so $(DESTDIR)/$(PREFIX)/lib/$(ARCH)/libaxc.so.$(VERSION) - ln -s libaxc.so.$(VERSION) $(DESTDIR)/$(PREFIX)/lib/$(ARCH)/libaxc.so.$(VER_MAJ) - ln -s libaxc.so.$(VERSION) $(DESTDIR)/$(PREFIX)/lib/$(ARCH)/libaxc.so - install -m 644 $(BDIR)/libaxc.pc $(DESTDIR)/$(PREFIX)/lib/$(ARCH)/pkgconfig/ - install -d $(DESTDIR)/$(PREFIX)/include/axc/ - install -m 644 $(SDIR)/axc.h $(DESTDIR)/$(PREFIX)/include/axc/ - install -m 644 $(SDIR)/axc_crypto.h $(DESTDIR)/$(PREFIX)/include/axc/ - install -m 644 $(SDIR)/axc_store.h $(DESTDIR)/$(PREFIX)/include/axc/ - - -.PHONY: test -test: test_store test_client - -.PHONY: test_store -test_store: $(SDIR)/axc_store.c $(SDIR)/axc_crypto.c $(TDIR)/test_store.c $(AX_PATH_AS_NEEDED) - $(CC) $(TESTFLAGS) -o $(TDIR)/$@.o $(TDIR)/test_store.c $(SDIR)/axc_crypto.c $(LDFLAGS_T) - -$(TDIR)/$@.o - find . -maxdepth 1 -iname 'test*.g*' -exec mv {} $(TDIR) \; - -.PHONY: test_client -test_client: $(SDIR)/axc.c $(SDIR)/axc_crypto.c $(SDIR)/axc_store.c $(TDIR)/test_client.c $(AX_PATH_AS_NEEDED) - $(CC) $(TESTFLAGS) -o $(TDIR)/$@.o $(SDIR)/axc_crypto.c $(TDIR)/test_client.c $(LDFLAGS_T) - -$(TDIR)/$@.o - find . -maxdepth 1 -iname 'test*.g*' -exec mv {} $(TDIR) \; - -.PHONY: coverage -coverage: test - gcovr -r . --html --html-details -o $@.html - gcovr -r . -s - $(MKDIR_P) $@ - mv $@.* $@ - -.PHONY: clean -clean: - rm -f $(TDIR)/*.o - rm -f $(TDIR)/*.gcno $(TDIR)/*.gcda $(TDIR)/*.sqlite - -.PHONY: clean-all -clean-all: clean - rm -rf client $(BDIR) $(CDIR) $(AX_BDIR) - - diff --git a/README.md b/README.md index e85444f..1a97079 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,61 @@ # axc 0.3.7 -Client lib for [libsignal-c](https://github.com/WhisperSystems/libsignal-protocol-c), implementing the needed database and crypto interfaces using SQLite and gcrypt. -Initially, the library's name was _libaxolotl_, hence the name. +Client lib for [libsignal-protocol-c](https://github.com/WhisperSystems/libsignal-protocol-c), implementing the needed database and crypto interfaces using SQLite and gcrypt. +Initially, the libsignal-protocol-c project was named _libaxolotl_, hence the name `axc`. -Additionally it provides utility functions for common use cases like encrypting and decrypting, ultimately making direct use of libsignal unnecessary. +Additionally it provides utility functions for common use cases like encrypting and decrypting, ultimately making direct use of libsignal-protocol-c unnecessary. ## Dependencies +* CMake (`cmake`) +* pkg-config (`pkg-config`) or pkgconf (`pkgconf`) +* glib2 (`libglib2.0-dev`) +* libsignal-protocol-c (`libsignal-protocol-c-dev`) * gcrypt for the crypto (`libgcrypt20-dev`) * SQLite for the stores (`libsqlite3-dev`) +* GNU make (`make`) or Ninja (`ninja-build`) Optional: -* [cmocka](https://cmocka.org/) for testing (`make test`) -* [gcovr](http://gcovr.com/) for a coverage report (`make coverage`) +* [cmocka](https://cmocka.org/) (`libcmocka-dev`) for testing (`make test`) +* [gcovr](http://gcovr.com/) (`gcovr`) for a coverage report (`make coverage`) ## Installation -First, you should pull the _libsignal_ submodule using `git submodule update --init`. -If you are using this as a submodule in another project, you should lso append `--recursive` so it gets pulled as well. +axc uses CMake as a build system. It can be used with either GNU make or Ninja. For example: +``` +mkdir build +cd build -Since you will need to link _libsignal_ also anyway, it is included here instead of just the headers, and the makefile provides an example of how to compile it as a static library with position independent code. -In theory there is also the possibility to install it as a shared lib by typing `cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=ON ..` instead and then type `sudo make install` after the `make`. +cmake -G Ninja .. # for options see below +ninja -v all +ninja -v test # potentially with CTEST_OUTPUT_ON_FAILURE=1 in the environment +ninja -v install +``` -The standard makefile target creates a static library with position independent code. -There is also a target for creating a static library without the code for threading support, as it is implemented using `pthread` and will not work on Windows, and is not necessary for the functioning. +The following configuration options are supported: +```console +# rm -f CMakeCache.txt ; cmake -D_AXC_HELP=ON -LH . | grep -B1 ':.*=' | sed 's,^--$,,' +// Install build artifacts +AXC_INSTALL:BOOL=ON -The `client` make target is a little demo that should explain the usage a bit, and if that is not enough there is also the testcases and the documentation. -Unfortunately it is currently broken as the synchronous code was removed. +// Build with pthreads support +AXC_WITH_PTHREADS:BOOL=ON + +// Build test suite (depends on cmocka) +AXC_WITH_TESTS:BOOL=ON + +// Build shared libraries (rather than static ones) +BUILD_SHARED_LIBS:BOOL=ON + +// Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel ... +CMAKE_BUILD_TYPE:STRING= + +// Install path prefix, prepended onto install directories. +CMAKE_INSTALL_PREFIX:PATH=/usr/local +``` + +They can be passed to CMake as `-D=`, e.g. `-DBUILD_SHARED_LIBS=OFF`. ## Usage The basic idea is to create the `axc_context`, set what is needed (e.g. path to the database or logging function), init it, and then pass it to every function as it contains all necessary data. -As said before, In theory you should not have to directly communicate with _libsignal_. +As said before, In theory you should not have to directly communicate with _libsignal-protocol-c_. diff --git a/lib/libsignal-protocol-c b/lib/libsignal-protocol-c deleted file mode 160000 index 3a83a4f..0000000 --- a/lib/libsignal-protocol-c +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 3a83a4f4ed2302ff6e68ab569c88793b50c22d28 diff --git a/libaxc.pc.cmake b/libaxc.pc.cmake new file mode 100644 index 0000000..07e5e73 --- /dev/null +++ b/libaxc.pc.cmake @@ -0,0 +1,13 @@ +prefix=@_AXC_PKGCONF_PREFIX@ +exec_prefix=@_AXC_PKGCONF_EXEC_PREFIX@ +libdir=@_AXC_PKGCONF_LIBDIR@ +includedir=@_AXC_PKGCONF_INCLUDEDIR@ + +Name: libaxc +Version: @PROJECT_VERSION@ +Description: client library for libsignal-protocol-c +URL: https://github.com/gkdr/axc +Requires: libsignal-protocol-c +Requires.private: glib-2.0 libgcrypt sqlite3 +Cflags: -I${includedir}/axc +Libs: -L${libdir} -laxc diff --git a/test/test_client.c b/test/test_client.c index d0e8045..e1fdd22 100644 --- a/test/test_client.c +++ b/test/test_client.c @@ -15,9 +15,9 @@ #include "../src/axc.c" #include "../src/axc_store.c" -char * test_fn = "test/test.sqlite"; -char * a_fn = "test/a.sqlite"; -char * b_fn = "test/b.sqlite"; +char * test_fn = "test.sqlite"; +char * a_fn = "a.sqlite"; +char * b_fn = "b.sqlite"; signal_protocol_address addr_alice_42 = {.name = "alice", .name_len = 5, .device_id = 42}; signal_protocol_address addr_alice_21 = {.name = "alice", .name_len = 5, .device_id = 21}; diff --git a/test/test_store.c b/test/test_store.c index d2c2e73..b001877 100644 --- a/test/test_store.c +++ b/test/test_store.c @@ -20,7 +20,7 @@ sqlite3 * db_p; sqlite3_stmt * pstmt_p; -char * db_filename = "test/test.sqlite"; +char * db_filename = "test.sqlite"; axc_context * ctx_global_p; signal_protocol_address addr_alice_42 = {.name = "alice", .name_len = 5, .device_id = 42}; @@ -381,8 +381,8 @@ void test_db_session_get_sub_device_sessions_should_find_and_return_correct_numb void test_db_session_contains_should_return_correct_values(void ** state) { (void) state; - char * a_db_filename = "test/a.sqlite"; - char * b_db_filename = "test/b.sqlite"; + char * a_db_filename = "a.sqlite"; + char * b_db_filename = "b.sqlite"; axc_context * ctx_a_p = (void *) 0; axc_context * ctx_b_p = (void *) 0;