# Cross-Platform Compilation

Cross-platform compilation empowers you to build C/C++ applications that run on different operating systems without rewriting the entire codebase.

## The Challenge

* Compilers and linkers on different platforms have variations in syntax, standard libraries, and available functions. Code written for one platform might not compile or run correctly on another.
* Cross-platform compilation tackles this challenge by building the program for a target platform from a single codebase running on a development machine.

## Strategies for Cross-Platform

**Conditional Compilation:**

* Employ `#ifdef`, `#ifndef`, `#else`, and `#endif` directives to conditionally include code blocks based on pre-defined macros. You can define these macros based on the target platform during the build process.

```cpp
#ifdef WINDOWS
#include <windows.h>
#else
#include <unistd.h>
#endif

// Code using platform-specific headers
```

**Compiler and Linker Flags:**

* Different platforms might require specific compiler and linker flags for optimization or compatibility. CMake allows setting these flags based on the target platform.

{% code overflow="wrap" %}
```cmake
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
  target_compile_features(MyProgram PRIVATE cxx11)  # Enable C++11 for Linux
endif()

if(CMAKE_SYSTEM_NAME MATCHES "Windows")
  target_link_libraries(MyProgram PRIVATE user32 gdi32)  # Link with Windows UI libraries
endif()
```
{% endcode %}

CMake supports defining toolchain files that specify the compiler, linker, and their flags for various platforms. This provides a centralized location for platform-specific configurations.

#### CMake excels at streamlining cross-platform builds. It offers features like:

* **Platform Detection:** CMake can identify the current development platform.
* **Conditional Statements:** Use CMake's `if`, `else`, and `endif` statements to manage platform-specific configurations.
* **Target Properties:** Set compiler and linker flags for different platforms using target properties.
* **Toolchain Files:** Create reusable toolchain files for various platforms.

## Building a Simple Cross-Platform Application

**Scenario:**

You're developing a text processing application that needs to access the file system. You want to build it for both Linux and Windows.

#### The CMakeLists.txt:

```cmake
cmake_minimum_required(VERSION 3.0)

project(MyTextProcessor)

# Define a function to access the file system (implementation details omitted)
function(access_file FILENAME)
  if(CMAKE_SYSTEM_NAME MATCHES "Linux")
    # Use POSIX functions
    message("Using POSIX functions for file access")
  else()
    # Use Windows API functions
    message("Using Windows API functions for file access")
  endif()
  # Implement file access logic based on the platform
endfunction(access_file)

# Source files
add_executable(MyTextProcessor main.cpp)

# Call the access_file function during compilation
add_custom_command(TARGET MyTextProcessor PRE_BUILD
  COMMAND access_file
  COMMENT "Determine file access method based on platform"
)
```

#### **Explanation:**

* The `access_file` function uses conditional statements to determine the platform and choose the appropriate file access method (not shown here for brevity).
* A custom command is added to call the `access_file` function before building the executable. This ensures the platform-specific code is included based on the detected platform.
