热门角色不仅是灵感来源,更是你的效率助手。通过精挑细选的角色提示词,你可以快速生成高质量内容、提升创作灵感,并找到最契合你需求的解决方案。让创作更轻松,让价值更直接!
我们根据不同用户需求,持续更新角色库,让你总能找到合适的灵感入口。
指导在特定项目类型中配置构建工具,实现目标效果如优化打包和部署流程,并确保配置可扩展、可维护,提升项目开发效率与质量。
下面给出一套可直接落地的 Webpack 5 配置方案,面向 TypeScript + React 的单页应用(SPA),满足以下目标:
一、目录结构建议
二、依赖(精简清单)
三、package.json(摘取关键) { "scripts": { "start": "cross-env NODE_ENV=development webpack serve --config webpack/webpack.dev.js", "build": "cross-env NODE_ENV=production webpack --config webpack/webpack.prod.js", "build:stats": "cross-env NODE_ENV=production webpack --config webpack/webpack.prod.js --profile --json > build/stats.json", "typecheck": "tsc -p tsconfig.json --noEmit", "analyze": "cross-env ANALYZE=true npm run build" }, "sideEffects": [".css", ".scss"], "browserslist": [ "defaults", "not IE 11", "maintained node versions" ] }
说明:
四、tsconfig.json(确保支持 Tree Shaking 与路径别名) { "compilerOptions": { "target": "ES2018", "lib": ["ES2018", "DOM"], "module": "ESNext", "moduleResolution": "Bundler", "jsx": "react-jsx", "strict": true, "noEmit": true, "baseUrl": ".", "paths": { "@/": ["src/"] }, "resolveJsonModule": true, "isolatedModules": true, "skipLibCheck": true }, "include": ["src"] }
五、babel.config.js(React + TS + 按需 polyfill) module.exports = function (api) { const isProd = api.env('production'); const isTest = api.env('test');
return { presets: [ ["@babel/preset-env", { targets: ">0.2%, not dead, not op_mini all", useBuiltIns: "usage", corejs: 3 }], ["@babel/preset-react", { runtime: "automatic", development: !isProd }], ["@babel/preset-typescript", { allowDeclareFields: true }] ], plugins: [ !isProd && "react-refresh/babel" ].filter(Boolean), assumptions: { setPublicClassFields: true } }; };
六、postcss.config.js module.exports = { plugins: [ require("postcss-preset-env")({ stage: 3 }), require("autoprefixer") ] };
七、.browserslistrc(可与 package.json 中 browserslist 二选一)
0.2% not dead not op_mini all
八、环境变量约定
九、webpack/utils/env.js(统一加载并筛选环境变量) const fs = require("fs"); const path = require("path"); const dotenv = require("dotenv"); const dotenvExpand = require("dotenv-expand");
function loadEnv(mode) {
const base = path.resolve(process.cwd(), ".env");
const modeFile = ${base}.${mode};
const files = [base, modeFile].filter(fs.existsSync);
let env = {}; files.forEach((file) => { const result = dotenv.config({ path: file }); dotenvExpand.expand(result); Object.assign(env, result.parsed || {}); });
// 从 process.env 合并,CI 中常用 Object.keys(process.env).forEach((k) => { if (!(k in env)) env[k] = process.env[k]; });
// 仅暴露 PUBLIC_ 开头的键 const raw = Object.keys(env) .filter((k) => /^PUBLIC_/i.test(k)) .reduce((acc, k) => ((acc[k] = env[k]), acc), {});
// 供 DefinePlugin 使用
const stringified = Object.keys(raw).reduce((acc, k) => {
acc[process.env.${k}] = JSON.stringify(raw[k]);
return acc;
}, { "process.env.NODE_ENV": JSON.stringify(mode) });
return { raw, stringified }; }
module.exports = { loadEnv };
十、webpack/webpack.common.js(基础配置) const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const { DefinePlugin } = require("webpack"); const { loadEnv } = require("./utils/env"); const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin"); const { WebpackManifestPlugin } = require("webpack-manifest-plugin");
module.exports = (env, argv) => { const mode = argv.mode || process.env.NODE_ENV || "development"; const isProd = mode === "production"; const { stringified } = loadEnv(mode);
return { mode, entry: path.resolve(__dirname, "../src/index.tsx"), output: { path: path.resolve(__dirname, "../dist"), filename: isProd ? "js/[name].[contenthash:8].js" : "js/[name].js", chunkFilename: isProd ? "js/[name].[contenthash:8].chunk.js" : "js/[name].chunk.js", assetModuleFilename: "assets/[name].[contenthash:8][ext]", publicPath: "/", clean: true }, resolve: { extensions: [".tsx", ".ts", ".jsx", ".js", ".json"], plugins: [new TsconfigPathsPlugin()] }, cache: { type: "filesystem", buildDependencies: { config: [__filename] } }, module: { rules: [ { test: /.[jt]sx?$/, include: path.resolve(dirname, "../src"), use: [ { loader: "babel-loader", options: { cacheDirectory: true, cacheCompression: false } } ] }, // CSS Modules { test: /.module.css$/, use: [ isProd ? require("mini-css-extract-plugin").loader : "style-loader", { loader: "css-loader", options: { modules: { localIdentName: isProd ? "[hash:base64:8]" : "[path][name][local]" }, importLoaders: 1 } }, "postcss-loader" ] }, // 全局 CSS { test: /.css$/, exclude: /.module.css$/, use: [ isProd ? require("mini-css-extract-plugin").loader : "style-loader", "css-loader", "postcss-loader" ] }, // 资源模块 { test: /.(png|jpe?g|gif|svg|webp|avif)$/i, type: "asset", parser: { dataUrlCondition: { maxSize: 8 * 1024 } } }, { test: /.(woff2?|ttf|eot|otf)$/i, type: "asset/resource" } ] }, plugins: [ new HtmlWebpackPlugin({ template: path.resolve(__dirname, "../public/index.html"), favicon: path.resolve(__dirname, "../public/favicon.ico"), inject: "body" }), new DefinePlugin(stringified), new ForkTsCheckerWebpackPlugin({ async: !isProd }), new WebpackManifestPlugin({ fileName: "asset-manifest.json", publicPath: "/" }) ] }; };
十一、webpack/webpack.dev.js(开发配置) const { merge } = require("webpack-merge"); const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin"); const common = require("./webpack.common");
module.exports = (env, argv) => merge(common(env, argv), { mode: "development", devtool: "cheap-module-source-map", devServer: { port: 3000, open: true, hot: true, historyApiFallback: true, compress: true, client: { overlay: { errors: true, warnings: false } }, static: { directory: "public", watch: true } }, plugins: [new ReactRefreshWebpackPlugin()], optimization: { runtimeChunk: "single" } });
十二、webpack/webpack.prod.js(生产配置:长期缓存、分包、压缩与 SourceMap) const { merge } = require("webpack-merge"); const common = require("./webpack.common"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); const TerserPlugin = require("terser-webpack-plugin"); // 可选 gzip/brotli 压缩 // const CompressionPlugin = require("compression-webpack-plugin");
const isAnalyze = process.env.ANALYZE === "true";
module.exports = (env, argv) => merge(common(env, argv), { mode: "production", devtool: process.env.SOURCE_MAP === "hidden" ? "hidden-source-map" : "source-map", output: { filename: "js/[name].[contenthash:8].js", chunkFilename: "js/[name].[contenthash:8].chunk.js" }, plugins: [ new MiniCssExtractPlugin({ filename: "css/[name].[contenthash:8].css", chunkFilename: "css/[name].[contenthash:8].chunk.css" }) // new CompressionPlugin({ algorithm: "brotliCompress", filename: "[path][base].br" }), // new CompressionPlugin({ algorithm: "gzip", filename: "[path][base].gz" }) ], optimization: { minimize: true, minimizer: [ new TerserPlugin({ extractComments: false, terserOptions: { safari10: true, compress: { passes: 2, pure_getters: true, drop_console: !!process.env.DROP_CONSOLE } } }), new CssMinimizerPlugin() ], moduleIds: "deterministic", chunkIds: "deterministic", runtimeChunk: "single", splitChunks: { chunks: "all", minSize: 20_000, cacheGroups: { // 将第三方依赖抽到 vendor vendor: { test: /[\/]node_modules[\/]/, name: "vendors", priority: -10, reuseExistingChunk: true }, // 可选:单独拆出 React 生态,保持更稳定的缓存 react: { test: /[\/]node_modules\/[\/]/, name: "react-vendor", priority: 10, enforce: true } } } }, performance: { hints: false } });
说明:
十三、public/index.html(模板要有根节点)
十四、src/index.tsx(示例:动态 import 触发代码分包) import React, { Suspense } from "react"; import { createRoot } from "react-dom/client";
const App = React.lazy(() => import("./App"));
createRoot(document.getElementById("root")!).render( <Suspense fallback={
十五、关键点解释与落地建议
十六、常见拓展(可选)
至此,该配置即满足:
下面给出一套在 Gradle Kotlin DSL 下可复用的工程化配置思路与示例,覆盖:多模块构建、版本对齐与依赖约束、统一格式化与静态检查、按环境打包、可插拔插件与缓存加速,并兼顾扩展性与可维护性。示例以 Java 21 为主、Gradle 8.10+、Kotlin DSL(.kts)为基准,可适配纯 Java 或 Spring Boot 服务。
一、推荐目录结构
二、settings.gradle.kts(集中式管理与加速)
示例(要点): file: settings.gradle.kts pluginManagement { repositories { gradlePluginPortal() mavenCentral() } } dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { mavenCentral() } versionCatalogs { create("libs") { from(files("gradle/libs.versions.toml")) } } } includeBuild("build-logic") rootProject.name = "my-company-services"
enableFeaturePreview("STABLE_CONFIGURATION_CACHE") // 如使用的Gradle需要 buildCache { local { isEnabled = true } // 可选远程缓存(含鉴权): // remote(HttpBuildCache::class) { // url = uri(System.getenv("GRADLE_REMOTE_CACHE_URL") ?: "") // isPush = (System.getenv("CI") == "true") // credentials { username = System.getenv("CACHE_USER"); password = System.getenv("CACHE_PASS") } // } }
// 开启 typesafe project accessors(Gradle 8+ 中已稳定,可不写) enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
// 依赖锁定(可选,建议在CI稳定后启用) dependencyResolutionManagement { components { // 也可在这里做元数据规则、漏洞拒绝等 } }
include( "platform", "common:core", "common:web", "services:user-service", "services:order-service" )
三、gradle.properties(全局默认) file: gradle.properties org.gradle.jvmargs=-Xmx2g -XX:ReservedCodeCacheSize=512m -Dfile.encoding=UTF-8 org.gradle.caching=true org.gradle.parallel=true org.gradle.configuration-cache=true org.gradle.daemon=true org.gradle.warning.mode=all
env=dev
javaVersion=21
四、版本目录 gradle/libs.versions.toml(版本对齐与集中管理) 要点:
示例(片段): file: gradle/libs.versions.toml [versions] java = "21" junit = "5.10.2" slf4j = "2.0.13" logback = "1.5.6" jackson = "2.17.1" guava = "33.2.0-jre" spotless = "6.25.0" errorpronePlugin = "3.1.0" errorprone = "2.27.2" nullaway = "0.10.20" spotbugsPlugin = "6.0.17" versionsPlugin = "0.51.0" shadow = "8.1.1" jib = "3.4.2"
[libraries] junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" } slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" } logback-classic = { module = "ch.qos.logback:logback-classic", version.ref = "logback" } jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" } jackson-annotations = { module = "com.fasterxml.jackson.core:jackson-annotations", version.ref = "jackson" } jackson-core = { module = "com.fasterxml.jackson.core:jackson-core", version.ref = "jackson" } guava = { module = "com.google.guava:guava", version.ref = "guava" }
[bundles] logging = ["slf4j-api", "logback-classic"] jackson = ["jackson-databind", "jackson-annotations", "jackson-core"]
[plugins] spotless = { id = "com.diffplug.spotless", version.ref = "spotless" } errorprone = { id = "net.ltgt.errorprone", version.ref = "errorpronePlugin" } spotbugs = { id = "com.github.spotbugs", version.ref = "spotbugsPlugin" } versions = { id = "com.github.ben-manes.versions", version.ref = "versionsPlugin" } shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } jib = { id = "com.google.cloud.tools.jib", version.ref = "jib" }
五、约定式插件(build-logic,提升可维护性、可插拔)
build-logic/settings.gradle.kts pluginManagement { repositories { gradlePluginPortal(); mavenCentral() } } rootProject.name = "build-logic"
build-logic/build.gradle.kts
plugins { kotlin-dsl }
repositories { mavenCentral() }
dependencies {
// 访问根工程的 version catalog
implementation(files(locateOrCreate("gradle/libs.versions.toml")))
}
fun locateOrCreate(path: String) = path
Java库约定插件(工具链、测试、基本依赖、缓存友好)
file: build-logic/src/main/kotlin/my.company.java-library-conventions.gradle.kts
plugins {
java-library
jacoco
}
val libs = extensions.getByType
Java应用约定插件(应用打包、环境资源、Shadow/Jib可插拔)
file: build-logic/src/main/kotlin/my.company.java-application-conventions.gradle.kts
plugins {
application
alias(libs.plugins.shadow) apply false
alias(libs.plugins.jib) apply false
}
val env = providers.gradleProperty("env").orElse("dev").get()
application {
mainClass.set(providers.gradleProperty("appMainClass"))
}
java {
toolchain { languageVersion.set(JavaLanguageVersion.of(providers.gradleProperty("javaVersion").get().toInt())) }
}
sourceSets {
named("main") {
resources.srcDir("src/$env/resources")
}
}
tasks.processResources {
// 可按需过滤占位符,如 ${env}
inputs.property("env", env)
}
tasks.withType
质量约定插件(Spotless、Checkstyle/PMD可选、Error Prone/NullAway、SpotBugs)
file: build-logic/src/main/kotlin/my.company.quality-conventions.gradle.kts
plugins {
alias(libs.plugins.spotless)
alias(libs.plugins.errorprone)
// alias(libs.plugins.spotbugs) // 可选
}
spotless {
java {
target("**/*.java")
googleJavaFormat()
// 或者 palantirFormatter()/eclipse().editorConfigFile("$rootDir/config/spotless/.editorconfig")
// 可统一licenseHeaderFile
}
}
tasks.withType
发布约定插件(可选:统一 maven-publish、签名、仓库)
file: build-logic/src/main/kotlin/my.company.publishing-conventions.gradle.kts
plugins { maven-publish }
publishing {
repositories {
// 配置企业Nexus/Artifactory
// maven { url = uri("..."); credentials { ... } }
}
}
Spring Boot 应用约定插件(可选) file: build-logic/src/main/kotlin/my.company.spring-boot-application-conventions.gradle.kts plugins { id("org.springframework.boot") version "3.3.5" apply true id("io.spring.dependency-management") version "1.1.6" } java { toolchain { languageVersion.set(JavaLanguageVersion.of(providers.gradleProperty("javaVersion").get().toInt())) } } tasks.named<org.springframework.boot.gradle.tasks.bundling.BootJar>("bootJar") { isReproducibleFileOrder = true isPreserveFileTimestamps = false }
六、平台模块(platform)做统一依赖约束与版本对齐
file: platform/build.gradle.kts
plugins {
java-platform
maven-publish
}
javaPlatform { allowDependencies() }
dependencies {
constraints {
api("com.fasterxml.jackson.core:jackson-databind:${libs.versions.jackson.get()}")
api("com.fasterxml.jackson.core:jackson-core:${libs.versions.jackson.get()}")
api("com.fasterxml.jackson.core:jackson-annotations:${libs.versions.jackson.get()}")
api("org.slf4j:slf4j-api:${libs.versions.slf4j.get()}")
api("ch.qos.logback:logback-classic:${libs.versions.logback.get()}")
api("com.google.guava:guava:${libs.versions.guava.get()}")
// 可引入第三方BOM以强制对齐:
api(platform("org.apache.logging.log4j:log4j-bom:2.23.1"))
// Spring Boot(可选):api(platform("org.springframework.boot:spring-boot-dependencies:3.3.5"))
}
}
七、根 build.gradle.kts(尽量精简) file: build.gradle.kts plugins { alias(libs.plugins.versions) apply true // 依赖更新检查 } allprojects { group = "my.company" version = "1.0.0" repositories { mavenCentral() } } subprojects { // 只在需要的模块应用约定插件,保持可插拔 // 例如:所有模块都应用质量检查 apply(plugin = "my.company.quality-conventions") }
tasks.register("checkAll") { dependsOn(gradle.includedBuild("build-logic")) dependsOn(subprojects.map { it.tasks.matching { t -> t.name == "check" } }) }
八、子模块示例(库与应用)
库模块(common/core) file: common/core/build.gradle.kts plugins { id("my.company.java-library-conventions") } dependencies { api(platform(project(":platform"))) api(libs.slf4j.api) implementation(libs.guava) testImplementation(libs.junit.jupiter) }
应用模块(services/user-service) file: services/user-service/gradle.properties appMainClass=my.company.user.Main
file: services/user-service/build.gradle.kts plugins { id("my.company.java-application-conventions") // 可按需选择 Shadow/Jib/Spring Boot // alias(libs.plugins.shadow) // alias(libs.plugins.jib) } dependencies { implementation(platform(project(":platform"))) implementation(projects.common.core) implementation(projects.common.web) implementation(libs.bundles.logging) implementation(libs.bundles.jackson) testImplementation(libs.junit.jupiter) }
// 如使用 Shadow 打包 fat jar: /* tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") { archiveClassifier.set("all-${providers.gradleProperty("env").orElse("dev").get()}") mergeServiceFiles() } tasks.named("build") { dependsOn("shadowJar") } */
// 如使用 Jib 生成镜像(推荐无需Docker守护进程): /* plugins { alias(libs.plugins.jib) } jib { from { image = "eclipse-temurin:21-jre" } to { image = "registry.example.com/my-company/user-service" tags = setOf(providers.gradleProperty("env").orElse("dev").get()) // auth from env/CI secret } container { jvmFlags = listOf("-Xms256m","-Xmx512m") ports = listOf("8080") environment = mapOf("APP_ENV" to providers.gradleProperty("env").orElse("dev").get()) } } */
九、统一代码格式化与静态检查
十、按环境打包与配置
十一、构建性能与缓存加速
十二、可插拔插件策略
十三、版本锁定与升级策略
十四、常见扩展点
十五、常用命令与 CI 建议
总结
下面给出一套“现代 CMake”做法与可直接落地的示例,覆盖跨平台库与示例程序的构建、Debug/Release 配置、FetchContent 拉依赖、按平台编译选项、启用 CTest 与覆盖率、安装与打包目标,并兼顾可扩展与可维护性。
一、项目结构建议
二、顶层 CMakeLists.txt(可直接使用的最小可扩展示例) 以下示例涵盖:多配置生成器兼容、FetchContent、平台编译选项、CTest/覆盖率、安装导出与CPack打包。可按需裁剪。
cmake_minimum_required(VERSION 3.22)
if(POLICY CMP0135) cmake_policy(SET CMP0135 NEW) # FetchContent 下载结果采用最近 mtime endif()
project(MyProj VERSION 1.2.0 DESCRIPTION "A cross-platform C++ library with examples" LANGUAGES CXX)
option(BUILD_SHARED_LIBS "Build shared libraries" ON) option(BUILD_EXAMPLES "Build examples" ON) option(ENABLE_COVERAGE "Enable code coverage flags" OFF) option(ENABLE_SANITIZERS "Enable sanitizers in Debug builds (where supported)" OFF) option(USE_SYSTEM_FMT "Use system fmt package instead of FetchContent" OFF)
if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug;Release;RelWithDebInfo;MinSizeRel") endif()
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF)
include(GNUInstallDirs) include(CMakePackageConfigHelpers) include(FetchContent) include(CTest) # 定义 BUILD_TESTING 选项并启用 ctest
add_library(project_options INTERFACE) add_library(project_warnings INTERFACE)
target_compile_features(project_options INTERFACE cxx_std_20)
set_property(TARGET project_options PROPERTY POSITION_INDEPENDENT_CODE ON)
if(MSVC) target_compile_options(project_warnings INTERFACE /W4 /permissive- /EHsc /Zc:__cplusplus /MP /utf-8)
target_compile_definitions(project_options INTERFACE WIN32_LEAN_AND_MEAN NOMINMAX _CRT_SECURE_NO_WARNINGS) else() target_compile_options(project_warnings INTERFACE -Wall -Wextra -Wpedantic $<$<COMPILE_LANG_AND_ID:CXX,Clang,GNU>:-Wconversion -Wshadow -Wnon-virtual-dtor>)
target_compile_options(project_options INTERFACE -fvisibility=hidden)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux") target_compile_definitions(project_options INTERFACE $<$CONFIG:Debug:_GLIBCXX_ASSERTIONS>) endif() endif()
if(ENABLE_SANITIZERS AND NOT MSVC) target_compile_options(project_options INTERFACE $<$CONFIG:Debug:-fsanitize=address,undefined>) target_link_options(project_options INTERFACE $<$CONFIG:Debug:-fsanitize=address,undefined>) endif()
if(USE_SYSTEM_FMT) find_package(fmt 11 CONFIG REQUIRED) else() FetchContent_Declare( fmt GIT_REPOSITORY https://github.com/fmtlib/fmt.git GIT_TAG 11.0.2 GIT_SHALLOW ON ) FetchContent_MakeAvailable(fmt) endif()
find_package(Threads REQUIRED)
add_library(mylib src/mylib.cpp )
target_include_directories(mylib PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include> $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include> # 导出宏头文件会生成到这 $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> ) target_link_libraries(mylib PUBLIC project_options project_warnings fmt::fmt Threads::Threads )
include(GenerateExportHeader) file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/include/mylib) generate_export_header(mylib EXPORT_FILE_NAME ${PROJECT_BINARY_DIR}/include/mylib/mylib_export.hpp ) target_compile_definitions(mylib PUBLIC $<TARGET_PROPERTY:mylib,DEFINE_SYMBOL>)
if(BUILD_EXAMPLES) add_executable(example_hello examples/hello.cpp) target_link_libraries(example_hello PRIVATE mylib) endif()
if(BUILD_TESTING)
FetchContent_Declare( googletest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG v1.14.0 GIT_SHALLOW ON )
set(INSTALL_GTEST OFF CACHE BOOL "" FORCE) FetchContent_MakeAvailable(googletest)
add_executable(mylib_tests tests/mylib_tests.cpp) target_link_libraries(mylib_tests PRIVATE mylib GTest::gtest_main) add_test(NAME mylib.tests COMMAND mylib_tests) endif()
if(ENABLE_COVERAGE AND NOT MSVC) include(cmake/CodeCoverage.cmake) # 见下文 enable_coverage_for_target(mylib) if(TARGET mylib_tests) enable_coverage_for_target(mylib_tests) endif() add_coverage_target(NAME coverage EXECUTABLE ctest -j ${PROCESSOR_COUNT} --output-on-failure) endif()
install(TARGETS mylib EXPORT MyProjTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(EXPORT MyProjTargets NAMESPACE MyProj:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyProj )
write_basic_package_version_file( ${PROJECT_BINARY_DIR}/MyProjConfigVersion.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion ) configure_package_config_file( ${PROJECT_SOURCE_DIR}/cmake/MyProjConfig.cmake.in ${PROJECT_BINARY_DIR}/MyProjConfig.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyProj ) install(FILES ${PROJECT_BINARY_DIR}/MyProjConfig.cmake ${PROJECT_BINARY_DIR}/MyProjConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyProj )
export(EXPORT MyProjTargets NAMESPACE MyProj:: FILE ${PROJECT_BINARY_DIR}/MyProjTargets.cmake )
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CPACK_PACKAGE_NAME "MyProj") set(CPACK_PACKAGE_VENDOR "Your Org") set(CPACK_PACKAGE_CONTACT "you@example.com") set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
if(WIN32) set(CPACK_GENERATOR "ZIP") else() set(CPACK_GENERATOR "TGZ") endif() include(CPack)
三、cmake/CodeCoverage.cmake(最小化,基于 gcovr 或 llvm-cov) 说明:ENABLE_COVERAGE=ON 时使用;仅对 GCC/Clang。要求系统安装 gcovr 或使用 llvm-cov + llvm-profdata。推荐 Debug 配置执行测试。
function(enable_coverage_for_target tgt) if(MSVC) message(WARNING "Coverage is not supported on MSVC by this helper.") return() endif() if(NOT TARGET ${tgt}) message(FATAL_ERROR "Target ${tgt} not found for coverage.") endif() target_compile_options(${tgt} PRIVATE $<$CONFIG:Debug:--coverage -O0 -g>) target_link_options(${tgt} PRIVATE $<$CONFIG:Debug:--coverage>) endfunction()
function(add_coverage_target) set(options) set(oneValueArgs NAME EXECUTABLE) set(multiValueArgs) cmake_parse_arguments(COV "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if(NOT COV_NAME) set(COV_NAME coverage) endif()
find_program(GCOVR_BIN gcovr) if(GCOVR_BIN) add_custom_target(${COV_NAME} COMMAND ${COV_EXECUTABLE} COMMAND ${GCOVR_BIN} --root ${PROJECT_SOURCE_DIR} --filter ${PROJECT_SOURCE_DIR}/src --xml --output ${PROJECT_BINARY_DIR}/coverage.xml --html --html-details --output ${PROJECT_BINARY_DIR}/coverage.html WORKING_DIRECTORY ${PROJECT_BINARY_DIR} COMMENT "Run tests and generate coverage (gcovr)" USES_TERMINAL ) else() # llvm-cov 回退(要求 clang/llvm-profdata 可用) find_program(LLVM_PROFDATA llvm-profdata) find_program(LLVM_COV llvm-cov) if(LLVM_COV AND LLVM_PROFDATA) add_custom_target(${COV_NAME} COMMAND ${COV_EXECUTABLE} # 这里根据项目二进制与 .profraw/.profdata 的生成策略补充命令 COMMENT "Run tests and generate coverage via llvm-cov (customize as needed)" USES_TERMINAL ) else() message(WARNING "No gcovr or llvm-cov found; coverage target will be dummy.") add_custom_target(${COV_NAME} COMMENT "Coverage tools not found") endif() endif() endfunction()
四、cmake/CompilerWarnings.cmake(可选:若需要更细粒度警告集)
五、cmake/Sanitizers.cmake(可选)
六、包配置模板 cmake/MyProjConfig.cmake.in @PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/MyProjTargets.cmake")
check_required_components(MyProj)
七、示例源码提示
include/mylib/mylib.hpp
examples/hello.cpp
tests/mylib_tests.cpp
八、CMakePresets.json(建议)
九、关键实践与可维护性要点
这套配置可在小项目“即插即用”,又能平滑扩展到中大型工程(多库、多示例、多测试、更多依赖与平台)。将通用策略沉淀为 cmake/ 模块,保持 CMakeLists.txt 简洁清晰,便于维护与团队协作。
帮助用户快速掌握用于项目构建工具配置的最佳实践,通过提供清晰、可操作的指导,解决项目配置的复杂性问题,同时提升配置的可扩展性和可维护性,最终实现高效开发与项目管理。
帮助初级开发者快速上手复杂的构建工具配置,实现项目构建所需的基础目标,减少因经验不足带来的配置错误。
为高级工程师提供高效的配置优化指导,帮助他们在复杂项目中实现更优构建性能并确保良好扩展性。
提供规范化和结构化的构建流程建议,帮助项目经理提升团队开发效率,确保持续交付质量。
将模板生成的提示词复制粘贴到您常用的 Chat 应用(如 ChatGPT、Claude 等),即可直接对话使用,无需额外开发。适合个人快速体验和轻量使用场景。
把提示词模板转化为 API,您的程序可任意修改模板参数,通过接口直接调用,轻松实现自动化与批量处理。适合开发者集成与业务系统嵌入。
在 MCP client 中配置对应的 server 地址,让您的 AI 应用自动调用提示词模板。适合高级用户和团队协作,让提示词在不同 AI 工具间无缝衔接。
半价获取高级提示词-优惠即将到期