توسعهٔ C++ مدرن.
محیطی مناسب استفادهٔ عملیاتی و با اولویت C++26 با ماژولهای متعلق به پروژه، قراردادهای خطای صریح، RAII، CMake مبتنی بر هدف، Ninja و زنجیرهابزارهای بومی پلتفرم. وقتی کامپایلر یا standard library لازم برای قابلیتهای انتخابی C++26 آماده نباشد، C++23 مسیر سازگاری است.
خط مبنای مهندسی.
| بخش | پیشفرض | قاعده |
|---|---|---|
| زبان | C++26 | مسیر زبان فعلی را ترجیح دهید؛ فقط وقتی پشتیبانی واقعی زنجیرهابزار ایجاب میکند از C++23 استفاده کنید. |
| مرزهای پروژه | C++ modules | مرزهای عملیاتی جدیدِ متعلق به پروژه از .cppm ماژولها بهصورت پیشفرض استفاده میکنند. |
| کتابخانهٔ استاندارد | فایلهای سرآیند حداقلی | فایلهای سرآیند استاندارد معمول را در سراسری ماژول fragment استفاده کنید و به قابلیت آزمایشی import std;. |
| خطاها | std::expected | خطاهای قابل بازیابی را بخشی از قرارداد API کنید، نه اینکه پشت مقادیر ویژه پنهان شوند. |
| خروجی کنسول | std::print / std::println | برای کد جدید، خروجی قالببندیشده مدرن را به زنجیرههای iostream ترجیح دهید. |
| مدل ساخت | Target-based CMake | compile قابلیتها، فایلهای منبع، definitionها و وابستگیها را به هدف مالک متصل نگه دارید. |
| Generator | Ninja | برای هر کامپایلر، پیکربندی و هدف از درخت ساخت جدا استفاده کنید. |
از ماژولها شروع کنید، نه فایل سرآیندها.
مرزهای متعلق به پروژه باید مسئولیت را مستقیم نشان دهند. اعلانها را از رابط ماژول صادر کنید، پیادهسازیهای غیرساده را در واحد پیادهسازی نگه دارید و کد پلتفرمی یا شخص ثالث را پشت سازگارکنندههای صریح ایزوله کنید.
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 مبتنی بر هدف با اسکن ماژولها.
استاندارد زبان، مجموعهفایلهای ماژول و نمودار وابستگی را روی هدف نگه دارید. برای شبیهسازی معماری کلاسیک فایل سرآیند به پرچمهای کامپایلر سراسری یا پوشههای include سراسری پروژه برنگردید.
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
Toolchainهای پلتفرمی.
معماری C++ قابلحمل میماند؛ کامپایلر، SDK، پیونددهنده، بستهبندی و محیط زمان اجرا مرزهای صریح پلتفرم هستند. بعد از عوض کردن کامپایلر یا SDK هدف، هرگز از درخت CMake پیکربندیشدهٔ قبلی دوباره استفاده نکنید.
macOS.
برای Apple SDK و ابزارهای پلتفرم، Xcode کامل را نصب کنید. Apple Clang کامپایلر بومی پیشفرض است؛ اگر قابلیت یا ابزارهای تشخیص خطا جدیدتر لازم است، بالادستی LLVM میتواند کنار آن نصب باشد.
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
در صورت نیاز بالادستی LLVM را برای همان ساخت انتخاب کنید؛ یکپارچگی Apple SDK و آزمایش قابلیتهای جدید زبان دو موضوع جدا هستند.
Linux.
وقتی قابلیت حمل مهم است GCC و Clang هر دو را در دسترس نگه دارید. برای هر کامپایلر یک پوشهٔ ساخت جداگانه پیکربندی کنید و پشتیبانی از ماژولها را با ترکیب واقعی CMake، کامپایلر و مولد ساخت بررسی کنید، نه صرفاً از روی شماره نسخه.
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.
برای Windows SDK و ABI مربوط به MSVC از Visual Studio Build Tools با workload سی++ استفاده کنید. وقتی به clang-cl ابزارهای تشخیص خطا نیاز دارید و میخواهید یکپارچگی سازگار با MSVC حفظ شود، LLVM را اضافه کنید.
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
پیش از پیکربندی CMake باید محیط MSVC کامپایلر، linker و Windows SDK initialize شده باشد.
Android.
برای Android از Clang زنجیرهابزار مربوط به NDK و فایل CMake زنجیرهابزار آن استفاده کنید؛ Android را یک ساخت معمولی Linux دسکتاپ فرض نکنید. برای پروژههایی که خط مبنا فعلی Qt را هم استفاده میکنند، compatibility فایل مشخصات نسخهٔ 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 و permission مخصوص Android را پشت سازگارکنندهها نگه دارید تا ماژولهای دامنه و برنامه همان 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
چندریسمانی مرورگر، SIMD، دسترسی سامانهٔ فایل و رفتار شبکه محدودیتهای زمان اجرا هستند، نه صرفاً گزینهٔ کامپایلر. آنها را بهعنوان قابلیت هدف مدل کنید و در مرورگر پیکربندی نهایی بررسی کنید.
Diagnostics بخشی از محیط توسعه است.
صحت زمان کامپایل فقط یک لایه است. ساختهای sanitizer و تحلیل ایستا را از ابتدا در دسترس نگه دارید، نه بعد از ظاهر شدن خطایی که بازتولیدش سخت است.
| ابزار | از | پیشنهاد |
|---|---|---|
ASan | خطاهای memory safety | Debug و CI در پلتفرمهای پشتیبانیشده |
UBSan | رفتار تعریفنشده | همراه ASan در یک diagnostic ساخت اختصاصی |
TSan | Data raceها | ساخت جدا، چون instrumentation رفتار زمان اجرا را تغییر میدهد |
clang-tidy | Static analysis و مدرنسازی | Editor بههمراه CI روی بخشهای عملیاتی تغییرکرده |
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 بخشی از زیرساخت بومی است.
هرجا کتابخانهٔ استاندارد C++ قابلیت موردنیاز را بهخوبی فراهم میکند، ابتدا همان را استفاده کنید؛ سپس برای قابلیتهایی که Boost هنوز در آنها گستردهتر یا قدرتمندتر است سراغ Boost بروید. وابستگیهای Boost را محدود به همان هدف نگه دارید، کتابخانههای کامپایلشده را برای هر معماری جدا بسازید و آنها را از طریق هدفهای واردشدهٔ CMake بهصورت شفاف متصل کنید.
برای برنامههای کاربرمحور، آگاهانه وارد Qt شوید.
برای یک برنامهٔ گرافیکی جدید به سبک Genyleap، پشته رابط پیشفرض Qt Quick، QML و Qt Quick Controls روی کد C++ مبتنی بر ماژول در لایههای برنامه/دامنه است. رابط کاربری یک سازگارکننده است و منطق کسبوکار تکراری را مالک نمیشود.