# 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

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