diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4cffdb6..e3f1532 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,6 +29,7 @@ jobs: fail-fast: false matrix: arch: [x86-64] + family: [x86-64] compiler: [gcc, clang] container: - archlinux:latest @@ -47,34 +48,39 @@ jobs: - ubuntu:jammy - ubuntu:focal - ubuntu:bionic - - ubuntu:xenial + # Meson version on Ubuntu Xenial is really too old + #- ubuntu:xenial cross_compile: [""] variant: [""] include: # Debian 32-bit builds - container: "debian:testing" arch: i386 - compiler: gcc -m32 + family: x86 + compiler: gcc cross_compile: i686-linux-gnu pkg_config_path: /usr/lib/i386-linux-gnu/pkgconfig variant: i386 - container: "debian:stable" arch: i386 - compiler: gcc -m32 + family: x86 + compiler: gcc cross_compile: i686-linux-gnu pkg_config_path: /usr/lib/i386-linux-gnu/pkgconfig variant: i386 - container: "debian:bookworm" arch: i386 - compiler: gcc -m32 + family: x86 + compiler: gcc cross_compile: i686-linux-gnu pkg_config_path: /usr/lib/i386-linux-gnu/pkgconfig variant: i386 - container: "debian:buster" arch: i386 + family: x86 compiler: gcc -m32 cross_compile: i686-linux-gnu pkg_config_path: /usr/lib/i386-linux-gnu/pkgconfig @@ -83,6 +89,7 @@ jobs: # Debian cross compilation builds - container: "debian:testing" arch: armhf + family: arm compiler: arm-linux-gnueabihf-gcc cross_compile: arm-linux-gnueabihf pkg_config_path: /usr/lib/arm-linux-gnueabihf/pkgconfig @@ -90,6 +97,7 @@ jobs: - container: "debian:testing" arch: arm64 + family: aarch64 compiler: aarch64-linux-gnu-gcc cross_compile: aarch64-linux-gnu pkg_config_path: /usr/lib/aarch64-linux-gnu/pkgconfig @@ -97,6 +105,7 @@ jobs: - container: "debian:testing" arch: ppc64el + family: ppc64 compiler: powerpc64le-linux-gnu-gcc cross_compile: powerpc64le-linux-gnu pkg_config_path: /usr/lib/powerpc64le-linux-gnu/pkgconfig @@ -104,6 +113,7 @@ jobs: - container: "debian:testing" arch: s390x + family: s390x compiler: s390x-linux-gnu-gcc cross_compile: s390x-linux-gnu pkg_config_path: /usr/lib/s390x-linux-gnu/pkgconfig @@ -111,6 +121,7 @@ jobs: - container: "debian:stable" arch: armhf + family: arm compiler: arm-linux-gnueabihf-gcc cross_compile: arm-linux-gnueabihf pkg_config_path: /usr/lib/arm-linux-gnueabihf/pkgconfig @@ -118,6 +129,7 @@ jobs: - container: "debian:stable" arch: arm64 + family: aarch64 compiler: aarch64-linux-gnu-gcc cross_compile: aarch64-linux-gnu pkg_config_path: /usr/lib/aarch64-linux-gnu/pkgconfig @@ -125,6 +137,7 @@ jobs: - container: "debian:stable" arch: ppc64el + family: ppc64 compiler: powerpc64le-linux-gnu-gcc cross_compile: powerpc64le-linux-gnu pkg_config_path: /usr/lib/powerpc64le-linux-gnu/pkgconfig @@ -132,6 +145,7 @@ jobs: - container: "debian:stable" arch: s390x + family: s390x compiler: s390x-linux-gnu-gcc cross_compile: s390x-linux-gnu pkg_config_path: /usr/lib/s390x-linux-gnu/pkgconfig @@ -141,9 +155,9 @@ jobs: image: ${{ matrix.container }} env: ARCH: ${{ matrix.arch }} + FAMILY: ${{ matrix.family }} CC: ${{ matrix.compiler }} CROSS_COMPILE: ${{ matrix.cross_compile }} - MODE: ${{ matrix.mode }} PKG_CONFIG_PATH: ${{ matrix.pkg_config_path }} VARIANT: ${{ matrix.variant }} @@ -154,10 +168,11 @@ jobs: - name: Show env (matrix settings) run: | echo "ARCH: $ARCH" + echo "FAMILY: $FAMILY" echo "CC: $CC" echo "CROSS_COMPILE: $CROSS_COMPILE" - echo "MODE: $MODE" echo "VARIANT: $VARIANT" + echo "PKG_CONFIG_PATH: $PKG_CONFIG_PATH" - name: Git checkout uses: actions/checkout@v3 @@ -187,8 +202,41 @@ jobs: echo "############################################" printenv + # i386 build on x86_64 only requires passing -m32 to CFLAGS & LDFLAGS + - name: Meson init for i386 + if: ${{ matrix.variant == 'i386' }} + run: | + mkdir build + CFLAGS="-m32" LDFLAGS="-m32" meson setup . build + + - name: Meson init with cross compile + if: ${{ matrix.variant == 'cross-compile' }} + run: | + # Generate cross compile file (see https://mesonbuild.com/Cross-compilation.html#cross-compilation) + echo "[binaries]" > cross.txt + echo "c = '${CROSS_COMPILE}-gcc'" >> cross.txt + echo "strip = '${CROSS_COMPILE}-strip'" >> cross.txt + # Forcing pkgconfig binary to 'pkg-config' is required for cross build to work + echo "pkgconfig = 'pkg-config'" >> cross.txt + echo "[host_machine]" >> cross.txt + echo "system = 'linux'" >> cross.txt + echo "cpu_family = '${FAMILY}'" >> cross.txt + echo "cpu = '${ARCH}'" >> cross.txt + echo "endian = 'little'" >> cross.txt + echo "[properties]" >> cross.txt + echo "pkg_config_libdir = '${PKG_CONFIG_PATH}'" >> cross.txt + cat cross.txt + mkdir build + meson setup --cross-file cross.txt . build + + - name: Meson init + if: ${{ matrix.variant == '' }} + run: | + mkdir build + meson setup . build + - name: Compile - run: make -j$(nproc) + run: ninja -C build - name: Install - run: make install + run: ninja -C build install diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index b424b83..92f7cd0 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -34,9 +34,8 @@ jobs: - name: Install additional packages run: sudo ./ci/ubuntu.sh - - name: Compile - run: | - make -j$(nproc) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v2 diff --git a/Makefile b/Makefile deleted file mode 100644 index ec8d1cb..0000000 --- a/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -CLIENT := cdba -SERVER := cdba-server - -.PHONY: all - -all: $(CLIENT) $(SERVER) - -CFLAGS := -Wall -g -O2 -# Wextra without few warnings -CFLAGS := $(CFLAGS) -Wextra -Wno-unused-parameter -Wno-unused-result -Wno-missing-field-initializers -Wno-sign-compare - -# Few clang version still have warnings so fail only on GCC -GCC_CFLAGS := -Werror -GCC_CFLAGS += -Wformat-signedness -Wnull-dereference -Wduplicated-cond -Wduplicated-branches -Wvla-larger-than=1 -GCC_CFLAGS += -Walloc-zero -Wstringop-truncation -Wdouble-promotion -Wshadow -Wunsafe-loop-optimizations -GCC_CFLAGS += -Wpointer-arith -Wcast-align -Wwrite-strings -Wlogical-op -Wstrict-overflow=4 -Wundef -Wjump-misses-init -CLANG_CFLAGS := -Wnull-dereference -Wdouble-promotion -Wshadow -Wpointer-arith -Wwrite-strings -Wstrict-overflow=4 -Wundef -# TODO: -# GCC_CFLAGS += -Wcast-qual -# CLANG_CFLAGS += -Wcast-qual -Wcast-align -ifeq ($(CC),cc) - CFLAGS += $(GCC_CFLAGS) -else ifeq ($(CC),clang) - CFLAGS += $(CLANG_CFLAGS) -else - $(info No compiler flags for: $(CC)) -endif - -LIBFTDI := $(shell pkg-config --exists libftdi1 && echo libftdi1 || echo libftdi) - -CPPFLAGS := $(shell pkg-config --cflags yaml-0.1 $(LIBFTDI) libudev) -LDFLAGS := $(shell pkg-config --libs yaml-0.1 $(LIBFTDI) libudev) - -CLIENT_SRCS := cdba.c circ_buf.c -CLIENT_OBJS := $(CLIENT_SRCS:.c=.o) - -SERVER_SRCS := cdba-server.c cdb_assist.c circ_buf.c conmux.c device.c device_parser.c fastboot.c alpaca.c ftdi-gpio.c console.c qcomlt_dbg.c ppps.c -SERVER_OBJS := $(SERVER_SRCS:.c=.o) - -$(CLIENT): $(CLIENT_OBJS) - $(CC) $(LDFLAGS) -o $@ $^ - -$(SERVER): $(SERVER_OBJS) - $(CC) -o $@ $^ $(LDFLAGS) - -clean: - rm -f $(CLIENT) $(CLIENT_OBJS) $(SERVER) $(SERVER_OBJS) - -install: $(CLIENT) $(SERVER) - install -D -m 755 $(CLIENT) $(DESTDIR)$(prefix)/bin/$(CLIENT) - install -D -m 755 $(SERVER) $(DESTDIR)$(prefix)/bin/$(SERVER) diff --git a/README b/README index 9930a09..0f0f4cc 100644 --- a/README +++ b/README @@ -3,13 +3,18 @@ The CDBA control tool is used for remotely booting images on development boards attached using a CDB Assist [https://github.com/sonyxperiadev/CDB-Assist] or Conmux. = Dependencies -sudo apt-get install libudev-dev libyaml-dev for debian systems -dnf install systemd-devel libyaml-devel for fedora systems +sudo apt-get install libudev-dev libyaml-dev libftdi1-dev pkg-config meson for debian systems +dnf install systemd-devel libyaml-devel libftdi1-devel pkg-config meson for fedora systems = Device side On the host with the CDB Assist or Conmux attached the "cdba-server" executable is run from sandbox/cdba/cdba-server. Available devices are read from $HOME/.cdba += Build instructions + +# meson . build +# ninja -C build + = Client side The client is invoked as: diff --git a/ci/archlinux.sh b/ci/archlinux.sh index d128922..037794a 100755 --- a/ci/archlinux.sh +++ b/ci/archlinux.sh @@ -20,8 +20,8 @@ pacman -Syu --noconfirm \ libftdi-compat \ libyaml \ systemd-libs \ - make \ pkgconf \ + meson \ $PKGS_CC echo "Install finished: $0" diff --git a/ci/debian.sh b/ci/debian.sh index 58ebdff..8683ab9 100755 --- a/ci/debian.sh +++ b/ci/debian.sh @@ -32,7 +32,7 @@ apt install -y --no-install-recommends \ libftdi-dev \ libudev-dev \ libyaml-dev \ - make \ + meson \ $PKGS_CC echo "Install finished: $0" diff --git a/ci/fedora.sh b/ci/fedora.sh index d6292bc..720c88a 100755 --- a/ci/fedora.sh +++ b/ci/fedora.sh @@ -20,7 +20,7 @@ dnf -y install \ libftdi-devel \ libudev-devel \ libyaml-devel \ - make \ + meson \ $PKGS_CC echo "Install finished: $0" diff --git a/conmux.c b/conmux.c index 4b0b670..ef0e914 100644 --- a/conmux.c +++ b/conmux.c @@ -51,7 +51,7 @@ struct conmux { struct conmux_lookup { char *host; - int port; + char *port; }; struct conmux_response { @@ -193,7 +193,7 @@ static int registry_lookup(const char *service, struct conmux_lookup *result) *p++ = '\0'; result->host = strdup(resp.result); - result->port = strtol(p, NULL, 10); + result->port = strdup(p); ret = strcmp(resp.status, "OK") ? -1 : 0; @@ -226,17 +226,16 @@ static int conmux_data(int fd, void *data) void *conmux_open(struct device *dev) { + struct addrinfo hints = {0}, *addrs, *addr; struct conmux_response resp = {}; struct conmux_lookup lookup; - struct sockaddr_in saddr; struct conmux *conmux; - struct hostent *hent; const char *service = dev->control_dev; const char *user; ssize_t n; char req[256]; int ret; - int fd; + int fd = -1; user = getenv("USER"); if (!user) @@ -246,27 +245,31 @@ void *conmux_open(struct device *dev) if (ret) exit(1); - fprintf(stderr, "conmux device at %s:%d\n", lookup.host, lookup.port); + fprintf(stderr, "conmux device at %s:%s\n", lookup.host, lookup.port); - fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd < 0) - err(1, "failed to create registry socket"); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; - memset(&saddr, 0, sizeof(saddr)); - saddr.sin_family = AF_INET; - saddr.sin_port = htons(lookup.port); + ret = getaddrinfo(lookup.host, lookup.port, &hints, &addrs); + if (ret != 0) + errx(1, "failed resolve \"%s\": %s", lookup.host, gai_strerror(ret)); - hent = gethostbyname(lookup.host); - if (!hent) { - errno = h_errno; - err(1, "failed resolve \"%s\"", lookup.host); - } + for (addr = addrs; addr; addr = addr->ai_next) { + fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); + if (fd < 0) + err(1, "failed to create registry socket"); - saddr.sin_addr = *(struct in_addr *)hent->h_addr_list[0]; + ret = connect(fd, addr->ai_addr, addr->ai_addrlen); + if (ret < 0) { + warn("failed to connect to conmux instance"); + close(fd); + fd = -1; + } + } - ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)); - if (ret < 0) - err(1, "failed to connect to conmux instance"); + if (fd == -1) + errx(1, "failed to connect to conmux instance"); ret = snprintf(req, sizeof(req), "CONNECT id=cdba:%s to=console\n", user); if (ret >= (int)sizeof(req)) diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..0392b0e --- /dev/null +++ b/meson.build @@ -0,0 +1,73 @@ +# SPDX-License-Identifier: GPL-2.0 + +project('cdba', + 'c', + license : [ 'BSD-3-Clause'], + meson_version : '>= 0.43.0', # for compiler.get_supported_arguments() + default_options: [ + 'warning_level=2', # sets -Wextra + 'buildtype=release', + ]) + +# Set advanced compiler flags +compiler = meson.get_compiler('c') + +compiler_cflags = ['-Wno-unused-parameter', + '-Wno-unused-result', + '-Wno-missing-field-initializers', + '-Wno-sign-compare', + '-Wundef', + '-Wnull-dereference', + '-Wdouble-promotion', + '-Wshadow', + '-Wpointer-arith', + '-Wwrite-strings', + '-Wstrict-overflow=4'] + +# TODO add clang specific options +if compiler.get_id() == 'gcc' + compiler_cflags += ['-Werror', # Only set it on GCC + '-Wformat-signedness', + '-Wduplicated-cond', + '-Wduplicated-branches', + '-Wvla-larger-than=1', + '-Walloc-zero', + '-Wunsafe-loop-optimizations', + '-Wcast-align', + '-Wlogical-op', + '-Wjump-misses-init'] +endif + +add_global_arguments(compiler.get_supported_arguments(compiler_cflags), + language: 'c') + +client_srcs = ['cdba.c', + 'circ_buf.c'] +executable('cdba', + client_srcs, + install : true) + +ftdi_dep = dependency('libftdi1', required: false) +if not ftdi_dep.found() + ftdi_dep = dependency('libftdi') +endif + +server_deps = [dependency('libudev'), + dependency('yaml-0.1'), + ftdi_dep] +server_srcs = ['cdba-server.c', + 'cdb_assist.c', + 'circ_buf.c', + 'conmux.c', + 'device.c', + 'device_parser.c', + 'fastboot.c', + 'alpaca.c', + 'ftdi-gpio.c', + 'console.c', + 'qcomlt_dbg.c', + 'ppps.c'] +executable('cdba-server', + server_srcs, + dependencies : server_deps, + install : true)