C++ Everywhere: How to Write Code for Windows, Linux, and macOS at Once

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Someday You'll Write Code That Runs Everywhere

\n

Imagine: you create a cool project in C++, everything works perfectly on Windows. Your friend asks you to build a version for Linux. You sigh, dive into the Makefile, change paths, compilers, stumble upon #ifdef _WIN32, and three hours later you get a binary that still crashes with a segmentation fault. Sound familiar?

\n

Cross-platform development in C++ is not magic, but a set of disciplines and tools. In this article, we'll break down how to write code that works on Windows, Linux, and macOS without tears, with real code examples and ready-made solutions. Let's go!

\n\n

Why C++ is Ideal for Cross-Platform (And Why It's a Pain)

\n

C++'s strengths — compilability, performance, and memory control — make it the king of system programming. But you have to pay for it: each OS has its own APIs, compilers (MSVC, GCC, Clang), and file system peculiarities.

\n

The main pitfalls:

\n
    \n
  • Different header files — windows.h vs unistd.h
  • \n
  • Different macros — _WIN32, __linux__, __APPLE__
  • \n
  • Different compilers — MSVC doesn't like GCC extensions
  • \n
  • Different libraries — dynamic loading (DLL vs .so)
  • \n
\n

But don't worry — all these problems are solvable. The main thing is to choose the right approach from the start.

\n\n

Tool #1: CMake — Your Universal Builder

\n

If you're writing a cross-platform application in C++, your best friend is CMake. It's not a build system like Make, but a build file generator: it creates Makefiles for Linux/macOS and .sln for Visual Studio on Windows.

\n

Here's a minimal CMakeLists.txt that works everywhere:

\n
cmake_minimum_required(VERSION 3.16)\nproject(CrossPlatformApp VERSION 1.0 LANGUAGES CXX)\n\nset(CMAKE_CXX_STANDARD 17)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\n# Add executable\nadd_executable(myapp main.cpp utils.cpp)\n\n# Cross-platform handling\nif(WIN32)\n    target_compile_definitions(myapp PRIVATE PLATFORM_WINDOWS)\n    target_link_libraries(myapp PRIVATE ws2_32)  # sockets on Windows\nelseif(APPLE)\n    target_compile_definitions(myapp PRIVATE PLATFORM_MACOS)\n    target_link_libraries(myapp PRIVATE "-framework CoreFoundation")\nelse()\n    target_compile_definitions(myapp PRIVATE PLATFORM_LINUX)\nendif()
\n

As you can see, target_compile_definitions allows you to set macros for each platform. In code, you use them like this:

\n
#ifdef PLATFORM_WINDOWS\n    #include <windows.h>\n    void sleep_ms(int ms) { Sleep(ms); }\n#else\n    #include <unistd.h>\n    void sleep_ms(int ms) { usleep(ms * 1000); }\n#endif
\n

CMake is the de facto standard. If your project doesn't use it, it's time to change your approach.

\n\n

Boost and Qt: Ready-Made Solutions for Complex Tasks

\n

Writing everything from scratch is for heroes and masochists. For cross-platform development in C++, there are mature libraries that hide OS differences.

\n

Boost — Swiss Army Knife

\n

Boost.Asio — for network programming (works on both Windows and Linux). Boost.Filesystem — for file operations (replaces std::filesystem if you have an old compiler). Example of cross-platform directory reading:

\n
#include <boost/filesystem.hpp>\nnamespace fs = boost::filesystem;\n\nvoid list_files(const std::string& path) {\n    for (const auto& entry : fs::directory_iterator(path)) {\n        std::cout << entry.path().string() << std::endl;\n    }\n}
\n

This code will compile on any OS without a single #ifdef.

\n\n

Qt — Full-Featured Framework

\n

If you need a GUI, networking, databases, or multithreading — Qt is your choice. It provides a unified API for all platforms. When

Blogs

Book Recommendations