تطوير C++ الحديثة.
بيئة موجهة للإنتاج تعتمد C++26 أولًا، مع modules مملوكة للمشروع وعقود أخطاء صريحة وRAII وCMake مبني على target وNinja وtoolchains أصلية للمنصة. تبقى C++23 مسار التوافق عندما لا يكون compiler أو standard library المطلوب جاهزًا لميزات C++26 المختارة.
الخط الأساسي الهندسي.
| Area | Default | Rule |
|---|---|---|
| Language | C++26 | فضّل مسار اللغة الحالي؛ استخدم C++23 عندما يفرض دعم toolchain الفعلي ذلك. |
| Project boundaries | C++ modules | New project-owned production boundaries use .cppm modules by default. |
| Standard library | Minimal headers | Use normal standard headers in the global module fragment; do not depend on experimental import std;. |
| الأخطاء | std::expected | اجعل الفشل القابل للاسترداد جزءًا من عقد API بدل إخفائه خلف sentinel values. |
| Console output | std::print / std::println | فضّل الإخراج المنسق الحديث على سلاسل iostream الجديدة. |
| Build model | Target-based CMake | أبقِ compile features والمصادر والتعريفات والاعتمادات مرتبطة بالtargets المالكة لها. |
| Generator | Ninja | استخدم أشجار build منفصلة لكل compiler وconfiguration وtarget. |
ابدأ بالـmodules، لا بالـheaders.
يجب أن توضّح حدود المشروع المسؤوليات مباشرة. صدّر declarations من واجهات modules، واحتفظ بالـimplementation غير البسيط داخل implementation units، واعزل كود المنصة أو الطرف الثالث خلف حدود adapters صريحة.
src/greeting/greeting.cppmmodule;
#include <expected>
#include <string>
#include <string_view>
export module genyleap.greeting;
export namespace genyleap::greeting {
enum class GreetingError {
EmptyName
};
[[nodiscard]] auto makeGreeting(std::string_view name)
-> std::expected<std::string, GreetingError>;
}
src/greeting/greeting.cppmodule;
#include <expected>
#include <format>
#include <string>
#include <string_view>
module genyleap.greeting;
namespace genyleap::greeting {
auto makeGreeting(std::string_view name)
-> std::expected<std::string, GreetingError>
{
if (name.empty()) {
return std::unexpected {GreetingError::EmptyName};
}
return std::format("Hello, {}.", name);
}
}
src/main.cpp#include <print>
import genyleap.greeting;
int main()
{
const auto greeting = genyleap::greeting::makeGreeting("Genyleap");
if (!greeting) {
std::println("Unable to create greeting.");
return 1;
}
std::println("{}", *greeting);
return 0;
}
CMake مبني على target مع module scanning.
أبقِ معيار اللغة وmodule file set ورسم الاعتمادات على الـtarget. لا تعد إلى compiler flags عامة أو include directories على مستوى المشروع لمحاكاة بنية headers التقليدية.
CMakeLists.txtcmake_minimum_required(VERSION 3.30)
project(GenyleapHello
VERSION 0.1.0
LANGUAGES CXX
)
add_library(genyleap_greeting)
target_compile_features(genyleap_greeting
PUBLIC
cxx_std_26
)
target_sources(genyleap_greeting
PUBLIC
FILE_SET CXX_MODULES
FILES
src/greeting/greeting.cppm
PRIVATE
src/greeting/greeting.cpp
)
set_property(
TARGET genyleap_greeting
PROPERTY CXX_SCAN_FOR_MODULES ON
)
add_executable(genyleap_hello
src/main.cpp
)
target_link_libraries(genyleap_hello
PRIVATE
genyleap_greeting
)
target_compile_features(genyleap_hello
PRIVATE
cxx_std_26
)
cmake -S . -B build/dev -G Ninja \
-DCMAKE_BUILD_TYPE=Debug
cmake --build build/dev --parallel
ctest --test-dir build/dev \
--output-on-failure \
--no-tests=error
Toolchains المنصات.
تبقى بنية C++ قابلة للنقل؛ compiler وSDK وlinker وpackaging وruntime حدود منصات صريحة. لا تعِد استخدام CMake tree مُهيأ بعد تغيير compiler أو target SDK.
macOS.
ثبّت Xcode الكامل من أجل Apple SDK وأدوات المنصة. Apple Clang هو الـcompiler الأصلي الافتراضي؛ ويمكن تثبيت LLVM upstream بجانبه عند الحاجة إلى ميزات أو diagnostics أحدث.
sudo xcode-select --switch /Applications/Xcode.app
sudo xcodebuild -license accept
brew install cmake ninja llvm
xcrun clang++ --version
cmake --version
ninja --version
xcrun --show-sdk-path
Select upstream LLVM per build when needed; Apple SDK integration and upstream language experimentation are separate concerns.
Linux.
احتفظ بـGCC وClang معًا عندما تكون portability مهمة. استخدم build directory منفصلًا لكل compiler وتحقق من دعم modules باستخدام تركيبة CMake/compiler/generator الفعلية بدل الاستنتاج من أرقام الإصدارات فقط.
sudo apt update
sudo apt install -y \
build-essential \
clang \
lld \
cmake \
ninja-build \
gdb
cmake -S . -B build/gcc -G Ninja \
-DCMAKE_CXX_COMPILER=g++
cmake -S . -B build/clang -G Ninja \
-DCMAKE_CXX_COMPILER=clang++
Windows.
Use Visual Studio Build Tools with the C++ workload for the Windows SDK and MSVC ABI. Add LLVM when you want clang-cl diagnostics while retaining MSVC-compatible platform integration.
winget install --id Microsoft.VisualStudio.2022.BuildTools `
--override "--wait --passive --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended"
winget install --id Kitware.CMake
winget install --id Ninja-build.Ninja
winget install --id LLVM.LLVM
يجب تهيئة بيئة MSVC compiler وlinker وWindows SDK قبل إعداد CMake.
Android.
Use the Android NDK's Clang toolchain and CMake toolchain file rather than treating Android as a normal Linux desktop build. For projects that also use the current Qt baseline, the compatibility manifest currently resolves NDK r27c (27.2.12479018).
cmake -S . -B build/android-arm64 -G Ninja \
-DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake" \
-DANDROID_ABI=arm64-v8a \
-DANDROID_PLATFORM=android-28
cmake --build build/android-arm64 --parallel
أبقِ كود JNI وlifecycle وstorage وpermissions الخاص بـAndroid خلف adapters حتى تبقى modules الخاصة بالـdomain وapplication عبارة عن C++ عادية.
iOS.
Use Xcode 16 or newer for the current Qt compatibility profile, and treat Apple frameworks, entitlements, signing and bundle resources as platform boundaries. Device and simulator builds are distinct targets even when they share application modules.
xcodebuild -version
xcrun --sdk iphoneos --show-sdk-path
xcrun --sdk iphonesimulator --show-sdk-path
xcrun --sdk iphoneos clang++ --version
WebAssembly.
Use Emscripten when the target runtime is the browser. For the current Qt compatibility profile, Emscripten 5.0.5 is pinned automatically from upstream Qt documentation; a standalone C++/WASM project may intentionally choose a newer SDK after its own verification.
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install 5.0.5./emsdk activate 5.0.5
source ./emsdk_env.sh
em++ --version
git clone https://github.com/emscripten-core/emsdk.git
Set-Location emsdk
.\emsdk.bat install 5.0.5.\emsdk.bat activate 5.0.5
.\emsdk_env.ps1
em++ --version
Threading المتصفح وSIMD والوصول إلى filesystem وسلوك الشبكة قيود runtime وليست مجرد compiler switches. اعتبرها capabilities للtarget وتحقق منها في إعداد المتصفح الذي ستدعمه.
Diagnostics جزء من بيئة التطوير.
الصحة وقت compile مجرد طبقة واحدة. أبقِ builds الخاصة بالـsanitizer وstatic analysis متاحة منذ البداية بدل إضافتها بعد ظهور عطل صعب إعادة إنتاجه.
| الأداة | الاستخدام | Recommendation |
|---|---|---|
ASan | Memory safety failures | Debug and CI where supported |
UBSan | Undefined behavior | Pair with ASan in a dedicated diagnostic build |
TSan | Data races | Separate build because instrumentation changes runtime behavior |
clang-tidy | Static analysis and modernization | Editor plus CI on changed production surfaces |
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
target_compile_options(genyleap_greeting PRIVATE
-fsanitize=address,undefined
-fno-omit-frame-pointer
)
target_link_options(genyleap_greeting PRIVATE
-fsanitize=address,undefined
)
endif()
Boost is part of the native foundation.
Use the C++ standard library first when it cleanly provides the required facility, then use Boost for capabilities that remain stronger or broader there. Keep Boost dependencies target-local, architecture-specific when compiled, and visible through modern CMake imported targets.
لتطبيقات المستخدم: انتقل إلى Qt بقرار واضح.
في تطبيق رسومي جديد بأسلوب Genyleap، تكون واجهة الاستخدام الافتراضية Qt Quick وQML وQt Quick Controls فوق كود C++ مبني على modules في application/domain. الـUI هو adapter ولا يملك business logic مكررة.