---
# System prepended metadata

title: Building Cross-Platform Softwares
tags: [Cross Platform, Shell Script, GNU, C, C++, Linux, Open Source, Make, Software, Software Packaging]

---

# 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)


