Skip to content

Commit

Permalink
Added|Changed|Fixed|Removed: Refactor termux-exec especially for ch…
Browse files Browse the repository at this point in the history
…anges in f261b26 for `system_linker_exec`

- The `src/exec-variants.c` has been moved to `src/exec/exec-variants.c` which handles hooks into the entire `exec()` family of functions except `execve()`. The handling of `execve` done by `src/exe/termux-exec.c` has been moved to `src/exec/exec.c`. The `src/exe/termux-exec.c` now exclusively only defines the functions intercepted by `libtermux-exec.so` and directs them to their hooks in respective source files.
- The `__attribute__((visibility("default")))` needs to be set for all the intercepted functions in `src/exe/termux-exec.c` as `libtermux-exec.so` is compiled with `-fvisibility=hidden`, so that no other function in the library other than ones explicitly labelled are exported. This can be confirmed by running `nm --demangle --dynamic --defined-only --extern-only /home/builder/.termux-build/termux-exec/src/build/usr/lib/libtermux-exec.so` after building the package.
- Revert order of functions in `src/exec/exec_variants.c` back to the one in AOSP and uncomment the `NULL` path checks for `execvpe()` and add its original license to file header. Log entries are also added to each variant to know which variant was originally hooked.

- Removed the singular `TERMUX_EXEC_OPTOUT` environment variable. Opt outs should be confined to specific hooks and logics.
- Added the `bool` environment variable `TERMUX_EXEC__INTERCEPT_EXECVE` for whether `execve` would be hooked for shebang fix or `system_linker_exec`. The default value is `true`. The other wrapper functions in the `exec()` family of functions declared in `unistd.h` are always intercepted to solve some other issues on older Android versions, check [`libc/bionic/exec.cpp`](https://cs.android.com/android/platform/superproject/+/android-14.0.0_r1:bionic/libc/bionic/exec.cpp) git history.
- Added the `string` `TERMUX_EXEC__SYSTEM_LINKER_EXEC` environment variable for whether to use `system_linker_exec` if `TERMUX_EXEC__INTERCEPT_EXECVE` is enabled. If set to `disable`, `system_linker_exec` will be disabled. If set to `enable`, then `system_linker_exec` will be enabled but only if required. If set to `force`, then `system_linker_exec` will be force enabled even if not required and is supported. The default value is `enable`. Check `should_system_linker_exec()` in `exec.h` and `exec.h` for more info and how its handled. Docs will be added in a later commit. The `system_linker_exec` will now engage for executable or interpreter paths that are under `TERMUX_APP__DATA_DIR` or `TERMUX_APP__LEGACY_DATA_DIR` instead of `TERMUX__ROOTFS` (`TERMUX_BASE_DIR`).
- Read `ANDROID__BUILD_VERSION_SDK` environment variable exported by Termux app to get Android build version sdk, and if its not set, then from the `android_get_device_api_level()` call provided by `<android/api-level.h>`, which gets it from the system properties, which should be slower.

- Port normalize and absolutize path functions from `portal-io` library and AOSP that has been tested on hundreds of test cases to handle all the required cases.
- Fix the order for normalize, absolutize and replacing termux bin prefix for both executable path and interpreter, check comment in `execve_intercept()`.
- Fix relative paths for interpreter path by absolutizing it. Previously, only prefix was being replaced.

- Fix `argv[0]` for executing shell scripts where it should be set to the original interpreter set in the file as is instead of the `argv[0]` to `execve()` being hooked for the executable.

- Increase buffer size for executable file shebang header from `256` to `340` defined by `FILE_HEADER__BUFFER_LEN` as per termux path limits, check comment in `exec.h` file and [Termux File Path Limits](https://github.com/termux/termux-packages/wiki/Termux-file-system-layout#file-path-limits) docs.
- Decrease max length of valid `TERMUX__ROOTFS` from `200` to `86` defined by `TERMUX__ROOTFS_DIR_MAX_LEN`, check `termux_files.h` file and [Termux File Path Limits](https://github.com/termux/termux-packages/wiki/Termux-file-system-layout#file-path-limits) docs.

- Add buffer overflow checks in `termux_prefix_path()` and return errors for it.
- Fix replacing prefix if termux rootfs is `/` or `/system` and executable equals the bin directory itself instead of a subfile.

- Fix `fexecve()` where executable path would be `/proc/self/fd/<n>` and checking if its under Termux app data directory directory would give wrong results. The `is_path_under_termux_app_data_dir()` function handles this by getting real path of file and ensuring that the real path is for the same file for which fd was open by comparing `stat.st_dev` and `stat.st_ino`.
- Fix checking if executable is under Termux directories, like Termux app data directory (previously rootfs/base). Previously, `strstr(executable_path, termux_base_dir)` was used, which would check first occurrence of the substring `termux_base_dir` in `executable_path`, and not whether `executable_path` is under `termux_base_dir`. This is now properly handled by `is_path_in_dir_path()` via `is_path_under_termux_app_data_dir()`.

- Do not use `TERMUX__PREFIX` to get Termux rootfs directory by getting its parent directory and use `TERMUX__ROOTFS` environment variable directly. There may also be cases where they `TERMUX__PREFIX` equals `TERMUX__ROOTFS`, and getting parent directory would result in wrong results. If environment variable is not set or is invalid as per `TERMUX__ROOTFS_DIR_MAX_LEN`, then we use the default Termux prefix for which package was compiled for as long as its executable and readable to ensure termux-exec was not compiled for a different package.

- Fix the environment `envp` being copied twice during `execve` for system bin paths, once for unsetting `LD_` variables and then to set `TERMUX_EXEC__PROC_SELF_EXE`. The `modify_exec_env()` function now handles all changes to environment with a single copy.
- Fix `TERMUX_EXEC__PROC_SELF_EXE` being set even if `system_linker_exec` is not being used on `targetSdkVersion <= 28`, etc, and also not being unset when going from `system_linker_exec` to direct execution like system binaries. Packages will be patched to detect if `system_linker_exec` is being used to modify their behaviour, which shouldn't be modified for direct execution.
- The `modify_exec_args()` function now handles all changes to the arguments.
- Fix issues where `errno` may already be set when `execve` is entered, check comment in `init()` function of `termux-exec.c` where it is set to `0`.

- Fix hardcoded `com.termux` values being used, all constants are replaced during building including the root scope of environment variables that are read and as per `TERMUX_ENV__S_ROOT` defined in `properties.sh` of `termux-pacakges` as `TERMUX_`.

- Fix `string_starts_with()` giving wrong results for `NULL` and empty strings.

- Added logger framework with multiple log levels with log entries for all the important variable states to track logic. The singular `TERMUX_EXEC_DEBUG` environment variable has been removed. The `int` `TERMUX_EXEC__LOG_LEVEL` environment variable controls the log level based on `(OFF=0, NORMAL=1, DEBUG=2, VERBOSE=3, VVERBOSE=4 and VVVERBOSE=5)`. The default value is `1`. Normally, `termux-exec` does not log anything at default log level `1` (`NORMAL`) for hooks even and will require setting log level to `>= 2` (`DEBUG`) to see log messages. To enable `VVERBOSE` logging for a command, you can run something like `TERMUX_EXEC__LOG_LEVEL=4 id -u`.

- Added `TERMUX_EXEC_PKG__VERSION` `Makefile` parameter that gets logged on hook for `termux-exec` package version currently installed.

- Create or move all build files under the `build/` directory. It's better to build a directory structure for the files to be added to prefix under the `build/usr` directory than have a mix of using files under both `src/` and `build/` during installation. This way `src/` directory also doesn't get modified and will not contain the files with replaced constants that were created from `*.in` files. This also makes it easier to clean and build the deb since all built files exist under the same directory, which `termux-create-package` can also use with `source_recurse`.

- Move unit tests from `termux-exec.c` to `tests/unit-tests.c` since tests shouldn't be in source files.
- Added testing framework via `tests/termux-exec-tests.in` that calls `tests/unit-tests.c` to run unit tests, and `runtime-binary-tests.c` and `tests/runtime-script-tests.in` for runtime tests. Old tests files in random places have been removed. The testing is done for `termux-exec` and other termux internal packages including `termux-core`, `termux-tools`, `termux-am`, `termux-api`, `tudo` and `sudo` to ensure a fully working termux environment. The entire `exec()` family of functions is also tested by `runtime-binary-tests.c`.  Currently, `termux-api` will not work in secondary users due to abstact namespace sockets being used. Docs will be added in a later commit. In future, tests can be moved to each package's own repo and a separate "tests caller" package can be added that runs tests for all packages that are installed. Tests can be run with `TERMUX_EXEC__LOG_LEVEL=1 "${TERMUX__PREFIX:-$PREFIX}/libexec/installed-tests/termux-exec/termux-exec-tests -vv all"`.

- The recursive replacement of termux constants is done with `find -exec sed` with `TERMUX_CONSTANTS_SED_ARGS` passed to it. Using `foreach` with the `call` function for `replace-termux-constants` does not work for some reason if multiple files exists, because somehow function definition itself like `@sed` gets passed to `sed` command as argument. So `replace-termux-constants` is only called for individual files. The sed replacements surround arguments with double quotes instead of single quotes, so it could potentially break on more cases during shell expansion, although regex variables weren't being escaped before either.

- The `termux-exec-package.json` will now have correct version and be consistent with `build.sh`, and also include tests files, which wasn't being done before.
- The `termux-exec-package.json` previously had hardcoded `aarch64` as architecture, now we find and replace it for the compiler based on which predefined architecture macro is defined.
  • Loading branch information
agnostic-apollo committed Jan 6, 2025
1 parent 29227a7 commit 5b5a1c7
Show file tree
Hide file tree
Showing 55 changed files with 9,469 additions and 926 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- run: brew install clang-format
- run: make
- run: make check
- run: make unit-test
- run: make test-unit

actionlint:
runs-on: ubuntu-latest
Expand Down
271 changes: 248 additions & 23 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,38 +1,263 @@
TERMUX_BASE_DIR ?= /data/data/com.termux/files
CFLAGS += -Wall -Wextra -Werror -Wshadow -O2
C_SOURCE := src/termux-exec.c src/exec-variants.c
export TERMUX_EXEC_PKG__VERSION ?= 1.0
export TERMUX_EXEC_PKG__ARCH
export TERMUX_EXEC__INSTALL_PREFIX

export TERMUX__NAME ?= Termux# Default value: `Termux`
export TERMUX__LNAME ?= termux# Default value: `termux`

export TERMUX_APP__PACKAGE_NAME ?= com.termux# Default value: `com.termux`
export TERMUX_APP__DATA_DIR ?= /data/data/$(TERMUX_APP__PACKAGE_NAME)# Default value: `/data/data/com.termux`

export TERMUX__ROOTFS ?= $(TERMUX_APP__DATA_DIR)/files# Default value: `/data/data/com.termux/files`
export TERMUX__PREFIX ?= $(TERMUX__ROOTFS)/usr# Default value: `/data/data/com.termux/files/usr`
export TERMUX__PREFIX__BIN_DIR ?= $(TERMUX__PREFIX)/bin# Default value: `/data/data/com.termux/files/usr/bin`
export TERMUX__PREFIX__TMP_DIR ?= $(TERMUX__PREFIX)/tmp# Default value: `/data/data/com.termux/files/usr/tmp`

export TERMUX_ENV__S_ROOT ?= TERMUX_# Default value: `TERMUX_`
export TERMUX_ENV__SS_TERMUX ?= _# Default value: `_`
export TERMUX_ENV__S_TERMUX ?= $(TERMUX_ENV__S_ROOT)$(TERMUX_ENV__SS_TERMUX)# Default value: `TERMUX__`
export TERMUX_ENV__SS_TERMUX_APP ?= APP__# Default value: `APP__`
export TERMUX_ENV__S_TERMUX_APP ?= $(TERMUX_ENV__S_ROOT)$(TERMUX_ENV__SS_TERMUX_APP)# Default value: `TERMUX_APP__`
export TERMUX_ENV__SS_TERMUX_API_APP ?= API_APP__# Default value: `API_APP__`
export TERMUX_ENV__S_TERMUX_API_APP ?= $(TERMUX_ENV__S_ROOT)$(TERMUX_ENV__SS_TERMUX_API_APP)# Default value: `TERMUX_API_APP__`
export TERMUX_ENV__SS_TERMUX_ROOTFS ?= ROOTFS__# Default value: `ROOTFS__`
export TERMUX_ENV__S_TERMUX_ROOTFS ?= $(TERMUX_ENV__S_ROOT)$(TERMUX_ENV__SS_TERMUX_ROOTFS)# Default value: `TERMUX_ROOTFS__`
export TERMUX_ENV__SS_TERMUX_CORE ?= CORE__# Default value: `CORE__`
export TERMUX_ENV__S_TERMUX_CORE ?= $(TERMUX_ENV__S_ROOT)$(TERMUX_ENV__SS_TERMUX_CORE)# Default value: `TERMUX_CORE__`
export TERMUX_ENV__SS_TERMUX_CORE__TESTS ?= CORE__TESTS__# Default value: `CORE__TESTS__`
export TERMUX_ENV__S_TERMUX_CORE__TESTS ?= $(TERMUX_ENV__S_ROOT)$(TERMUX_ENV__SS_TERMUX_CORE__TESTS)# Default value: `TERMUX_CORE__TESTS__`
export TERMUX_ENV__SS_TERMUX_EXEC ?= EXEC__# Default value: `EXEC__`
export TERMUX_ENV__S_TERMUX_EXEC ?= $(TERMUX_ENV__S_ROOT)$(TERMUX_ENV__SS_TERMUX_EXEC)# Default value: `TERMUX_EXEC__`
export TERMUX_ENV__SS_TERMUX_EXEC__TESTS ?= EXEC__TESTS__# Default value: `EXEC__TESTS__`
export TERMUX_ENV__S_TERMUX_EXEC__TESTS ?= $(TERMUX_ENV__S_ROOT)$(TERMUX_ENV__SS_TERMUX_EXEC__TESTS)# Default value: `TERMUX_EXEC__TESTS__`

export TERMUX_APP__NAMESPACE ?= $(TERMUX_APP__PACKAGE_NAME)# Default value: `com.termux`
export TERMUX_APP__SHELL_ACTIVITY__COMPONENT_NAME ?= $(TERMUX_APP__PACKAGE_NAME)/$(TERMUX_APP__NAMESPACE).app.TermuxActivity# Default value: `com.termux/com.termux.app.TermuxActivity`
export TERMUX_APP__SHELL_SERVICE__COMPONENT_NAME ?= $(TERMUX_APP__PACKAGE_NAME)/$(TERMUX_APP__NAMESPACE).app.TermuxService# Default value: `com.termux/com.termux.app.TermuxService`

TERMUX_EXEC__TESTS__API_LEVEL ?=


# If architecture not set, find it for the compiler based on which
# predefined architecture macro is defined. The `shell` function
# replaces newlines with a space and a literal space cannot be entered
# in a makefile as its used as a splitter, hence $(SPACE) variable is
# created and used for matching.
ifeq ($(TERMUX_EXEC_PKG__ARCH),)
export PREDEFINED_MACROS := $(shell $(CC) -x c /dev/null -dM -E)
EMPTY :=
SPACE := $(EMPTY) $(EMPTY)
ifneq (,$(findstring $(SPACE)#define __i686__ 1$(SPACE),$(SPACE)$(PREDEFINED_MACROS)$(SPACE)))
TERMUX_EXEC_PKG__ARCH := i686
else ifneq (,$(findstring $(SPACE)#define __x86_64__ 1$(SPACE),$(SPACE)$(PREDEFINED_MACROS)$(SPACE)))
TERMUX_EXEC_PKG__ARCH := x86_64
else ifneq (,$(findstring $(SPACE)#define __aarch64__ 1$(SPACE),$(SPACE)$(PREDEFINED_MACROS)$(SPACE)))
TERMUX_EXEC_PKG__ARCH := aarch64
else ifneq (,$(findstring $(SPACE)#define __arm__ 1$(SPACE),$(SPACE)$(PREDEFINED_MACROS)$(SPACE)))
TERMUX_EXEC_PKG__ARCH := arm
else
$(error Unsupported package arch)
endif
endif


ifeq ($(DESTDIR)$(PREFIX),)
TERMUX_EXEC__INSTALL_PREFIX := $(TERMUX__PREFIX)
else
TERMUX_EXEC__INSTALL_PREFIX := $(DESTDIR)$(PREFIX)
endif



BUILD_DIR := build
PREFIX_BUILD_DIR := $(BUILD_DIR)/usr
LIB_BUILD_DIR := $(PREFIX_BUILD_DIR)/lib
TESTS_BUILD_DIR := $(PREFIX_BUILD_DIR)/libexec/installed-tests/termux-exec


CFLAGS += -Wall -Wextra -Werror -Wshadow -O2 -D_FORTIFY_SOURCE=2 -fstack-protector-strong
FSANTIZE_FLAGS += -fsanitize=address -fsanitize-recover=address -fno-omit-frame-pointer
CLANG_FORMAT := clang-format --sort-includes --style="{ColumnLimit: 120}" $(C_SOURCE)
CLANG_TIDY ?= clang-tidy

libtermux-exec.so: $(C_SOURCE)
$(CC) $(CFLAGS) $(LDFLAGS) $(C_SOURCE) -DTERMUX_PREFIX=\"$(TERMUX_PREFIX)\" -DTERMUX_BASE_DIR=\"$(TERMUX_BASE_DIR)\" -shared -fPIC -o libtermux-exec.so
C_SOURCE := \
src/termux-exec-init.c \
src/data/assert_utils.c \
src/data/data_utils.c \
src/exec/exec.c \
src/exec/exec_variants.c \
src/file/file_utils.c \
src/logger/logger.c \
src/logger/file_logger_impl.c \
src/logger/standard_logger_impl.c \
src/os/safe_strerror.c \
src/os/selinux_utils.c \
src/termux/termux_env.c \
src/termux/termux_files.c

TERMUX_CONSTANTS_MACRO_FLAGS := \
-DTERMUX_EXEC_PKG__VERSION=\"$(TERMUX_EXEC_PKG__VERSION)\" \
-DTERMUX__NAME=\"$(TERMUX__NAME)\" \
-DTERMUX__LNAME=\"$(TERMUX__LNAME)\" \
-DTERMUX_APP__DATA_DIR=\"$(TERMUX_APP__DATA_DIR)\" \
-DTERMUX__ROOTFS=\"$(TERMUX__ROOTFS)\" \
-DTERMUX__PREFIX=\"$(TERMUX__PREFIX)\" \
-DTERMUX__PREFIX__BIN_DIR=\"$(TERMUX__PREFIX__BIN_DIR)\" \
-DTERMUX__PREFIX__TMP_DIR=\"$(TERMUX__PREFIX__TMP_DIR)\" \
-DTERMUX_ENV__S_TERMUX=\"$(TERMUX_ENV__S_TERMUX)\" \
-DTERMUX_ENV__S_TERMUX_APP=\"$(TERMUX_ENV__S_TERMUX_APP)\" \
-DTERMUX_ENV__S_TERMUX_ROOTFS=\"$(TERMUX_ENV__S_TERMUX_ROOTFS)\" \
-DTERMUX_ENV__S_TERMUX_EXEC=\"$(TERMUX_ENV__S_TERMUX_EXEC)\" \
-DTERMUX_ENV__S_TERMUX_EXEC__TESTS=\"$(TERMUX_ENV__S_TERMUX_EXEC__TESTS)\"

TERMUX_CONSTANTS_SED_ARGS := \
-e "s%[@]TERMUX_EXEC_PKG__VERSION[@]%$(TERMUX_EXEC_PKG__VERSION)%g" \
-e "s%[@]TERMUX_EXEC_PKG__ARCH[@]%$(TERMUX_EXEC_PKG__ARCH)%g" \
-e "s%[@]TERMUX__LNAME[@]%$(TERMUX__LNAME)%g" \
-e "s%[@]TERMUX_APP__PACKAGE_NAME[@]%$(TERMUX_APP__PACKAGE_NAME)%g" \
-e "s%[@]TERMUX__PREFIX[@]%$(TERMUX__PREFIX)%g" \
-e "s%[@]TERMUX_ENV__S_TERMUX[@]%$(TERMUX_ENV__S_TERMUX)%g" \
-e "s%[@]TERMUX_ENV__S_TERMUX_APP[@]%$(TERMUX_ENV__S_TERMUX_APP)%g" \
-e "s%[@]TERMUX_ENV__S_TERMUX_API_APP[@]%$(TERMUX_ENV__S_TERMUX_API_APP)%g" \
-e "s%[@]TERMUX_ENV__S_TERMUX_ROOTFS[@]%$(TERMUX_ENV__S_TERMUX_ROOTFS)%g" \
-e "s%[@]TERMUX_ENV__S_TERMUX_CORE[@]%$(TERMUX_ENV__S_TERMUX_CORE)%g" \
-e "s%[@]TERMUX_ENV__S_TERMUX_CORE__TESTS[@]%$(TERMUX_ENV__S_TERMUX_CORE__TESTS)%g" \
-e "s%[@]TERMUX_ENV__S_TERMUX_EXEC__TESTS[@]%$(TERMUX_ENV__S_TERMUX_EXEC__TESTS)%g" \
-e "s%[@]TERMUX_APP__NAMESPACE[@]%$(TERMUX_APP__NAMESPACE)%g" \
-e "s%[@]TERMUX_APP__SHELL_ACTIVITY__COMPONENT_NAME[@]%$(TERMUX_APP__SHELL_ACTIVITY__COMPONENT_NAME)%g" \
-e "s%[@]TERMUX_APP__SHELL_SERVICE__COMPONENT_NAME[@]%$(TERMUX_APP__SHELL_SERVICE__COMPONENT_NAME)%g"

define replace-termux-constants
sed $(TERMUX_CONSTANTS_SED_ARGS) "$1.in" > "$2/$$(basename "$1" | sed "s/\.in$$//")"
endef



all: | pre-build build-runtime-binary-tests
@echo "Building lib/libtermux-exec.so"
@mkdir -p $(LIB_BUILD_DIR)
$(CC) $(CFLAGS) $(LDFLAGS) src/termux-exec.c $(C_SOURCE) -shared -fPIC \
-fvisibility=hidden \
$(TERMUX_CONSTANTS_MACRO_FLAGS) \
-o $(LIB_BUILD_DIR)/libtermux-exec.so


@mkdir -p $(TESTS_BUILD_DIR)

@echo "Building tests/termux-exec-tests"
$(call replace-termux-constants,tests/termux-exec-tests,$(TESTS_BUILD_DIR))
chmod u+x $(TESTS_BUILD_DIR)/termux-exec-tests

@echo "Building tests/runtime-script-tests"
$(call replace-termux-constants,tests/runtime-script-tests,$(TESTS_BUILD_DIR))
chmod u+x $(TESTS_BUILD_DIR)/runtime-script-tests


@echo "Building tests/unit-tests"
@mkdir -p $(TESTS_BUILD_DIR)
$(CC) $(CFLAGS) $(LDFLAGS) -g tests/unit-tests.c $(C_SOURCE) \
$(FSANTIZE_FLAGS) \
$(TERMUX_CONSTANTS_MACRO_FLAGS) \
-DTERMUX_EXEC__RUNNING_TESTS=1 \
-o $(TESTS_BUILD_DIR)/unit-tests-fsanitize
$(CC) $(CFLAGS) $(LDFLAGS) -g tests/unit-tests.c $(C_SOURCE) \
$(TERMUX_CONSTANTS_MACRO_FLAGS) \
-DTERMUX_EXEC__RUNNING_TESTS=1 \
-o $(TESTS_BUILD_DIR)/unit-tests-nofsanitize


@mkdir -p $(TESTS_BUILD_DIR)/files


@echo "Building tests/files/exec/*"
@mkdir -p $(TESTS_BUILD_DIR)/files/exec
find tests/files/exec -maxdepth 1 -name '*.c' -exec sh -c '$(CC) $(CFLAGS) $(LDFLAGS) "$$1" -o $(TESTS_BUILD_DIR)/files/exec/"$$(basename "$$1" | sed "s/\.c$$//")"' sh "{}" \;
find tests/files/exec -maxdepth 1 \( -name '*.sh' -o -name '*.sym' \) -exec cp -a "{}" $(TESTS_BUILD_DIR)/files/exec/ \;
find tests/files/exec -maxdepth 1 -type f -name "*.in" -exec sh -c \
'sed $(TERMUX_CONSTANTS_SED_ARGS) "$$1" > $(TESTS_BUILD_DIR)/files/exec/"$$(basename "$$1" | sed "s/\.in$$//")"' sh "{}" \;
find $(TESTS_BUILD_DIR)/files/exec -maxdepth 1 -name '*.sh' -exec chmod u+x "{}" \;


@echo "Building termux-exec-package.json"
$(call replace-termux-constants,termux-exec-package.json,$(BUILD_DIR))

@echo "Build termux-exec-package successful"

build-runtime-binary-tests:
@echo "Building tests/runtime-binary-tests$(TERMUX_EXEC__TESTS__API_LEVEL)"
@mkdir -p $(TESTS_BUILD_DIR)
$(CC) $(CFLAGS) $(LDFLAGS) -g tests/runtime-binary-tests.c $(C_SOURCE) \
$(FSANTIZE_FLAGS) \
$(TERMUX_CONSTANTS_MACRO_FLAGS) \
-o $(TESTS_BUILD_DIR)/runtime-binary-tests-fsanitize$(TERMUX_EXEC__TESTS__API_LEVEL)
$(CC) $(CFLAGS) $(LDFLAGS) -g tests/runtime-binary-tests.c $(C_SOURCE) \
$(TERMUX_CONSTANTS_MACRO_FLAGS) \
-o $(TESTS_BUILD_DIR)/runtime-binary-tests-nofsanitize$(TERMUX_EXEC__TESTS__API_LEVEL)



pre-build: | clean
@echo "Building termux-exec-package"
@mkdir -p $(BUILD_DIR)

clean:
rm -f libtermux-exec.so tests/*-actual test-binary
rm -rf $(BUILD_DIR)

install:
@echo "Installing in $(TERMUX_EXEC__INSTALL_PREFIX)"

install -d $(TERMUX_EXEC__INSTALL_PREFIX)/lib
install $(LIB_BUILD_DIR)/libtermux-exec.so $(TERMUX_EXEC__INSTALL_PREFIX)/lib/libtermux-exec.so


install: libtermux-exec.so
install libtermux-exec.so $(DESTDIR)$(PREFIX)/lib/libtermux-exec.so
install -d $(TERMUX_EXEC__INSTALL_PREFIX)/libexec/installed-tests/termux-exec
find $(TESTS_BUILD_DIR) -maxdepth 1 -type f -exec install "{}" -t $(TERMUX_EXEC__INSTALL_PREFIX)/libexec/installed-tests/termux-exec/ \;


install -d $(TERMUX_EXEC__INSTALL_PREFIX)/libexec/installed-tests/termux-exec/files
install -d $(TERMUX_EXEC__INSTALL_PREFIX)/libexec/installed-tests/termux-exec/files/exec
find $(TESTS_BUILD_DIR)/files/exec -maxdepth 1 \( -type f -o -type l \) -exec cp -a "{}" $(TERMUX_EXEC__INSTALL_PREFIX)/libexec/installed-tests/termux-exec/files/exec/ \;

uninstall:
rm -f $(DESTDIR)$(PREFIX)/lib/libtermux-exec.so
@echo "Uninstalling from $(TERMUX_EXEC__INSTALL_PREFIX)"

on-device-tests: libtermux-exec.so
@LD_PRELOAD=${CURDIR}/libtermux-exec.so ./run-tests.sh
rm -f $(TERMUX_EXEC__INSTALL_PREFIX)/lib/libtermux-exec.so
rm -rf $(TERMUX_EXEC__INSTALL_PREFIX)/libexec/installed-tests/termux-exec

format:
$(CLANG_FORMAT) -i $(C_SOURCE)

check:
$(CLANG_FORMAT) --dry-run $(C_SOURCE)
$(CLANG_TIDY) -warnings-as-errors='*' $(C_SOURCE) -- -DTERMUX_BASE_DIR=\"$(TERMUX_BASE_DIR)\"

test-binary: $(C_SOURCE)
$(CC) $(CFLAGS) $(LDFLAGS) $(C_SOURCE) -g -fsanitize=address -fno-omit-frame-pointer -DUNIT_TEST=1 -DTERMUX_BASE_DIR=\"$(TERMUX_BASE_DIR)\" -o test-binary
deb: all
termux-create-package $(BUILD_DIR)/termux-exec-package.json



test: all
$(MAKE) TERMUX_EXEC__INSTALL_PREFIX=install install

@echo "Running tests"
install/libexec/installed-tests/termux-exec/termux-exec-tests --ld-preload="install/lib/libtermux-exec.so" --tests-path="install/libexec/installed-tests/termux-exec" -vvv all

test-unit: all
$(MAKE) TERMUX_EXEC__INSTALL_PREFIX=install install

@echo "Running unit tests"
bash install/libexec/installed-tests/termux-exec/termux-exec-tests --tests-path="install/libexec/installed-tests/termux-exec" -vvv unit

test-runtime: all
$(MAKE) TERMUX_EXEC__INSTALL_PREFIX=install install

@echo "Running runtime tests"
install/libexec/installed-tests/termux-exec/termux-exec-tests --ld-preload="install/lib/libtermux-exec.so" --tests-path="install/libexec/installed-tests/termux-exec" -vvv runtime



format:
$(CLANG_FORMAT) -i src/termux-exec.c $(C_SOURCE)
check:
$(CLANG_FORMAT) --dry-run src/termux-exec.c $(C_SOURCE)
$(CLANG_TIDY) -warnings-as-errors='*' src/termux-exec.c $(C_SOURCE) -- \
$(TERMUX_CONSTANTS_MACRO_FLAGS)

deb: libtermux-exec.so
termux-create-package termux-exec-debug.json

unit-test: test-binary
./test-binary

.PHONY: deb clean install uninstall test format check-format test
.PHONY: all pre-build build-runtime-binary-tests clean install uninstall deb test test-unit test-runtime format check
20 changes: 0 additions & 20 deletions run-tests.sh

This file was deleted.

Loading

0 comments on commit 5b5a1c7

Please sign in to comment.