# Building Cross-Platform Softwares ###### tags: `C` `C++` `Linux` `GNU` `Make` `Software` `Software Packaging` `Open Source` `Shell Script` `Cross Platform` Explore cross-platform, cross-device build automation toolchains & discuss modern software packaging techniques for configuring, compiling, linking code, & runtime setup. ## Vcpkg *C/C++ package manager* - `vcpkg-configuration.json`: manage & install the third-party packages. [vcpkg-configuration.json Reference - Microsoft Learn](https://learn.microsoft.com/en-us/vcpkg/reference/vcpkg-configuration-json) ```json= { "registries": [ { "kind": "artifact", "location": "https://example.com/vcpkg-ce-registry.zip", "name": "arm" } ], "requires": { "arm:tools/kitware/cmake": "^3.25.2", "arm:tools/ninja-build/ninja": "^1.10.2", "arm:tools/open-cmsis-pack/cmsis-toolbox": "^2.0.0-0", "arm:compilers/arm/armclang": "^6.20.0", "arm:compilers/arm/arm-none-eabi-gcc": "^12.2.1-0" } } ``` ## CMake *A cross-platform build system tool, from dev environment setup to app install config* > All being configured & managed in `CMakeLists.txt`. - `CMakeLists.txt`: configure & generate the target build script ```Cmake= cmake_minimum_required(VERSION 3.16) project(MyProject) # Project Name set(CMAKE_CXX_STANDARD 11) # C++11/14/17... add_executable(MyApp myMainFunc main.cpp main.h pch.h) include_directories("path/to/include") target_link_libraries(MyApp "path/to/lib") target_precompile_headers(MyApp PRIVATE pch.h) ``` - usage: ```sh! mkdir ./build cd ./build cmake path/to/CMakeLists.txt # -D<var>=<value> # -DCMAKE_INSTALL_PREFIX=~/test/ # for "make install" use (e.g., ./include/ ./bin/ ./lib/ ./share/ ...) # --config Release # Debug, Release, RelWithDebInfo, MinSizeRel # -G Ninja # "Visual Studio 2022" # -A x64 ``` ## Autotools ![image](https://hackmd.io/_uploads/rJO28kV0C.png) ### autoconf *Like CMake but only for GNU/Linux platform to resolve build toolchains, dependencies, environment, install target path, ...* - usage: ```sh= ./configure # --prefix=/path/to/install ``` ### make A GNU/Linux-only software to create the target *program* from the configuration files & the source files. [Makefile 語法和示範 - jserv](https://hackmd.io/@sysprog/gnu-linux-dev/https%3A%2F%2Fhackmd.io%2Fs%2FSySTMXPvl) - `makefile`: compile the source. ```makefile= main: main.c cc main.c -o main \ -Wall -Wextra \ -I../include/ \ -L../lib/ -l:libmath.so # or -lmath clean: rm -f main ``` with variables: ```makefile= # Compiler command CC = gcc # Compiler flags CFLAGS = -Wall -g # Source files SRC = a.c b.c # Object files, transforms from *.c to *.o OBJ = $(SRC:.c=.o) # Executable name EXEC = prog # Default target all: $(EXEC) # $@: "target", same as the $(EXEC) in this context # $^: "prerequisites", same as the $(OBJ) in this context $(EXEC): $(OBJ) $(CC) $(CFLAGS) -o $@ $^ # Rule to compile each .c file into .o file (% is a wildcard, $< is the 1st $^) %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ # make clean clean: rm -f $(OBJ) $(EXEC) ``` advanced usages: ```makefile= CXX ?= g++ # if null => default value DEBUG ?= 1 ifeq ($(DEBUG), 1) CXXFLAGS += -g else CXXFLAGS += -O2 endif # target_file: dependencies # so determine whether recompile if file's changed # <tab> commands # for compiling target_file server: main.cpp a.cpp ./src/b.cpp ./src/c.cpp $(CXX) -o server $^ $(CXXFLAGS) -lpthread -lmysqlclient clean: rm -r server ``` - usage: ```sh! make # default build ``` ```sh! make install # install lib, bin, headers, data, ... on the system ``` ```sh! make clean ``` :::warning Config of `make <target>` in `makefile` may be set by the build system (e.g., *autoconf*, *CMake*, ...) ::: ## Cross-Platform Development Overview - **Build Tools:** version control, installation, system global environment settings, package management & configurations, ... e.g., using *CMake:* ```CMake= if (WIN32) target_compile_options(...) else if (LINUX) target_compile_options(...) endif() ``` ```CMake= cmake_minimum_required(VERSION 3.10) project(MyProject C) # Check if the compiler is GNU or Clang if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fstack-protector") endif() add_executable(executable_output main.c) ``` - **System Architectures:** protocols, bindings, portings, runtime deployment options, containers, VMs, resource orchestrators, ... - **Programming Development Environments:** pre-processors, compilers (frontend / backend), linkers, runtime, ... - **Source Code Level Control:** macros, syntax extensions, abstraction interfaces, ... ```cpp= #ifdef __cplusplus extern "C" { #endif void pure_c_function(); #ifdef __cplusplus } #endif ``` ```c= void __attribute__((stack_protect)) stack_canary_func(); int __attribute__((aligned(16))) aligned_var; ``` example: - [Porting My Hacking Toolkit From Windows To Linux - Nathan Baggs](https://www.youtube.com/watch?v=4614Hg7TEFc) - [blind_io - nathan-baggs - GitHub](https://github.com/nathan-baggs/blind_io)