svharness 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +531 -0
- package/bin/cli.js +3 -0
- package/dist/adapters/_frontmatter.js +24 -0
- package/dist/adapters/claude-code.js +12 -0
- package/dist/adapters/codechat.js +12 -0
- package/dist/adapters/cursor.js +19 -0
- package/dist/adapters/generic.js +19 -0
- package/dist/adapters/index.js +26 -0
- package/dist/adapters/qoder.js +12 -0
- package/dist/commands/apply.js +272 -0
- package/dist/commands/init.js +420 -0
- package/dist/core/agent-injector.js +192 -0
- package/dist/core/next-steps.js +91 -0
- package/dist/core/render-meta.js +81 -0
- package/dist/core/repomix-pack.js +54 -0
- package/dist/core/scaffold.js +93 -0
- package/dist/core/state.js +80 -0
- package/dist/index.js +239 -0
- package/dist/types.js +5 -0
- package/dist/utils/baseline-copy.js +591 -0
- package/dist/utils/baseline-defaults.js +106 -0
- package/dist/utils/logger.js +56 -0
- package/dist/utils/validate-args.js +132 -0
- package/dist/utils/version.js +23 -0
- package/dist/wiki/abort.js +30 -0
- package/dist/wiki/config.js +79 -0
- package/dist/wiki/defaults.js +16 -0
- package/dist/wiki/envLoader.js +78 -0
- package/dist/wiki/index.js +29 -0
- package/dist/wiki/openaiCompat.js +219 -0
- package/dist/wiki/repowikiCanonicalSections.js +67 -0
- package/dist/wiki/repowikiCheckpoint.js +106 -0
- package/dist/wiki/repowikiConfig.js +9 -0
- package/dist/wiki/repowikiGit.js +73 -0
- package/dist/wiki/repowikiIndexer.js +824 -0
- package/dist/wiki/repowikiMarkdownPost.js +123 -0
- package/dist/wiki/repowikiMetadataContent.js +64 -0
- package/dist/wiki/repowikiMetadataJson.js +15 -0
- package/dist/wiki/repowikiScanner.js +156 -0
- package/dist/wiki/repowikiStructureNav.js +286 -0
- package/dist/wiki/repowikiStructureNormalize.js +218 -0
- package/dist/wiki/wikiStructureXml.js +316 -0
- package/dist/wiki/wikiTasksWriter.js +127 -0
- package/package.json +57 -0
- package/templates/_shared/apply-skills/harness-apply-skills-main.md +91 -0
- package/templates/_shared/build-rules/harness-build-rule-agent-agnostic.md +35 -0
- package/templates/_shared/build-rules/harness-build-rule-chinese-only.md +49 -0
- package/templates/_shared/build-rules/harness-build-rule-memory-write.md +31 -0
- package/templates/_shared/build-rules/harness-build-rule-orchestrator-flow.md +25 -0
- package/templates/_shared/build-rules/harness-build-rule-skills-tasks-output.md +35 -0
- package/templates/_shared/build-rules/harness-build-rule-specs-schema.md +32 -0
- package/templates/_shared/build-rules/harness-build-rule-user-interaction.md +63 -0
- package/templates/_shared/build-skills/harness-build-skill-knowledge-builder.md +120 -0
- package/templates/_shared/build-skills/harness-build-skill-orchestrator.md +87 -0
- package/templates/_shared/build-skills/harness-build-skill-spec-builder.md +85 -0
- package/templates/_shared/build-skills/harness-build-skill-wiki-writer.md +77 -0
- package/templates/_shared/meta/AGENTS.md.ejs +53 -0
- package/templates/_shared/meta/CHANGELOG.md.ejs +15 -0
- package/templates/_shared/meta/README.md.ejs +51 -0
- package/templates/_shared/meta/VERSION.ejs +1 -0
- package/templates/_shared/meta/harness.yaml.ejs +52 -0
- package/templates/_shared/skeleton/agent-env/memory/categories/.gitkeep +1 -0
- package/templates/_shared/skeleton/agent-env/memory/inbox/.gitkeep +1 -0
- package/templates/_shared/skeleton/agent-env/skills/.gitkeep +1 -0
- package/templates/_shared/skeleton/agent-env/tools/.gitkeep +1 -0
- package/templates/_shared/skeleton/assets/baseline/code/.gitkeep +1 -0
- package/templates/_shared/skeleton/assets/baseline/repomix/.gitkeep +1 -0
- package/templates/_shared/skeleton/assets/baseline/wiki/.gitkeep +1 -0
- package/templates/_shared/skeleton/assets/raw/.gitkeep +1 -0
- package/templates/_shared/skeleton/assets/requirements/.gitkeep +1 -0
- package/templates/_shared/skeleton/commands/install/.gitkeep +1 -0
- package/templates/_shared/skeleton/commands/update/.gitkeep +1 -0
- package/templates/_shared/skeleton/specs/behavior/schema.json +39 -0
- package/templates/_shared/skeleton/specs/interfaces/schema.json +38 -0
- package/templates/_shared/skeleton/specs/signals/schema.json +37 -0
- package/templates/_shared/skeleton/specs/ui/schema.json +44 -0
- package/templates/_shared/skeleton/tasks/templates/.gitkeep +0 -0
- package/templates/android-compose/skeleton/agent-env/rules/harness-compose-mandatory.mdc +49 -0
- package/templates/android-compose/skeleton/agent-env/rules/harness-coroutines-scope.mdc +52 -0
- package/templates/android-compose/skeleton/agent-env/rules/harness-hilt-injection.mdc +47 -0
- package/templates/android-compose/skeleton/agent-env/rules/harness-mvi-layering.mdc +58 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-android-architecture/SKILL.md +260 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-android-architecture/references/gradle-module-patterns.md +66 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-android-architecture/references/implementation-checklist.md +45 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-android-architecture/references/udf-data-flow.md +80 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-android-cli/SKILL.md +79 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-android-cli/references/interact.md +83 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-android-cli/references/journeys.md +97 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-compose-audit/SKILL.md +162 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-compose-audit/references/canonical-sources.md +116 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-compose-audit/references/diagnostics.md +182 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-compose-audit/references/report-template.md +135 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-compose-audit/references/scoring.md +277 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-compose-audit/references/search-playbook.md +303 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-compose-audit/scripts/compose-reports.init.gradle +58 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-compose-state/SKILL.md +196 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-compose-ui/SKILL.md +192 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-compose-ui/references/composable-api-guide.md +123 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-compose-ui/references/performance-recipes.md +97 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-compose-ui/references/state-patterns.md +93 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-kotlin-coroutines/SKILL.md +167 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-r8-analyzer/SKILL.md +45 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-r8-analyzer/references/CONFIGURATION.md +44 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-r8-analyzer/references/KEEP-RULES-IMPACT-HIERARCHY.md +83 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-r8-analyzer/references/REDUNDANT-RULES.md +222 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-r8-analyzer/references/REFLECTION-GUIDE.md +139 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-r8-analyzer/references/android/topic/performance/app-optimization/enable-app-optimization.md +176 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-r8-analyzer/references/android/training/testing/other-components/ui-automator.md +312 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-xml-to-compose/SKILL.md +87 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-xml-to-compose/references/analysis-of-the-project-and-layout.md +42 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-xml-to-compose/references/android/develop/ui/compose/designsystems/migrate-xml-theme-to-compose.md +168 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-xml-to-compose/references/android/develop/ui/compose/setup-compose-dependencies-and-compiler.md +183 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-xml-to-compose/references/identify-optimal-xml-candidate.md +31 -0
- package/templates/android-compose/skeleton/agent-env/skills/harness-xml-to-compose/references/xml-layout-migration.md +86 -0
- package/templates/android-xml/skeleton/agent-env/rules/seed-aidl-thread.md +29 -0
- package/templates/android-xml/skeleton/agent-env/rules/seed-lifecycle-awareness.md +32 -0
- package/templates/android-xml/skeleton/agent-env/rules/seed-mvc-layering.md +32 -0
- package/templates/android-xml/skeleton/agent-env/rules/seed-view-binding.md +33 -0
- package/templates/android-xml/skeleton/agent-env/rules/seed-xml-styling.md +27 -0
- package/templates/cpp/skeleton/agent-env/rules/seed-cmake-explicit-sources.md +31 -0
- package/templates/cpp/skeleton/agent-env/rules/seed-header-guards.md +34 -0
- package/templates/cpp/skeleton/agent-env/rules/seed-include-layering.md +39 -0
- package/templates/cpp/skeleton/agent-env/rules/seed-no-cyclic-deps.md +29 -0
- package/templates/cpp/skeleton/agent-env/rules/seed-raii.md +30 -0
- package/templates/python/skeleton/agent-env/rules/seed-context-managers.md +60 -0
- package/templates/python/skeleton/agent-env/rules/seed-docstrings.md +48 -0
- package/templates/python/skeleton/agent-env/rules/seed-import-order.md +49 -0
- package/templates/python/skeleton/agent-env/rules/seed-pep8-naming.md +45 -0
- package/templates/python/skeleton/agent-env/rules/seed-type-annotations.md +43 -0
- package/templates/web-react/skeleton/agent-env/rules/seed-controlled-component.md +43 -0
- package/templates/web-react/skeleton/agent-env/rules/seed-effect-cleanup.md +43 -0
- package/templates/web-react/skeleton/agent-env/rules/seed-hook-rules.md +42 -0
- package/templates/web-react/skeleton/agent-env/rules/seed-key-stability.md +39 -0
- package/templates/web-react/skeleton/agent-env/rules/seed-no-props-drilling.md +43 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
When you introduce Compose in an existing app, you need to migrate your Material
|
|
2
|
+
XML themes to use `MaterialTheme` for Compose components. This means your app's
|
|
3
|
+
theming will have two sources of truth: the View-based theme and the Compose
|
|
4
|
+
theme. Any changes to your styling need to be made in multiple places. Once
|
|
5
|
+
your app is fully migrated to Compose, remove your XML theming.
|
|
6
|
+
|
|
7
|
+
You can use the [Material Theme Builder](https://m3.material.io/theme-builder)
|
|
8
|
+
tool for migrating colors.
|
|
9
|
+
|
|
10
|
+
When you start the migration from XML to Compose, migrate the theming to
|
|
11
|
+
Material 3 Compose theming.
|
|
12
|
+
|
|
13
|
+
## Glossary
|
|
14
|
+
|
|
15
|
+
| Term | Definition |
|
|
16
|
+
|---|---|
|
|
17
|
+
| `MaterialTheme` | The composable function that provides theming (colors, typography, shapes) to Compose UI components. |
|
|
18
|
+
| `Shape` | A Compose object used to define custom component shapes for a `MaterialTheme`. |
|
|
19
|
+
| `Typography` | A Compose object used to define custom text styles (font families, sizes, weights) for a `MaterialTheme`. |
|
|
20
|
+
| `Color` | A Compose object used to define custom color schemes for `MaterialTheme`. |
|
|
21
|
+
| XML Theme | The Android theming system defined in XML files, used by the View system. |
|
|
22
|
+
|
|
23
|
+
## Limitations
|
|
24
|
+
|
|
25
|
+
Before migrating, be aware of the following limitations:
|
|
26
|
+
|
|
27
|
+
- This guide focuses on migrating to Material 3 only. For migrating from alternative design systems, see [Material 2](https://developer.android.com/develop/ui/compose/designsystems/material) or [Custom design systems in Compose](https://developer.android.com/develop/ui/compose/designsystems/custom).
|
|
28
|
+
- The ultimate goal is a complete migration to Compose, which allows for the removal of XML theming. This guide explains how to migrate, but it doesn't explain how to finally remove XML theming.
|
|
29
|
+
|
|
30
|
+
## Step 1: Evaluate the design system
|
|
31
|
+
|
|
32
|
+
Identify which design system is used in the XML View project.
|
|
33
|
+
Analyze the migration path and necessary steps to migrate the existing design
|
|
34
|
+
system to Material 3 in Compose.
|
|
35
|
+
|
|
36
|
+
## Step 2: Identify theme source files
|
|
37
|
+
|
|
38
|
+
In XML you write `?attr/colorPrimary`. In Compose, you access theme values
|
|
39
|
+
with `MaterialTheme.*`:
|
|
40
|
+
|
|
41
|
+
Identify and locate all XML resources and files necessary for theming:
|
|
42
|
+
light and dark color schemes and qualifiers, themes, shapes, dimensions,
|
|
43
|
+
typography, styles and other relevant files.
|
|
44
|
+
|
|
45
|
+
Resources such as strings can be reused as is and don't need to be migrated.
|
|
46
|
+
|
|
47
|
+
## Step 3: Migrate colors
|
|
48
|
+
|
|
49
|
+
**Key principle:** XML uses named hex colors.
|
|
50
|
+
Material 3 uses *semantic roles* (e.g., `primary`, `onPrimary`, `surface`).
|
|
51
|
+
Stop naming colors by their hex; name them by their role.
|
|
52
|
+
|
|
53
|
+
Examples:
|
|
54
|
+
|
|
55
|
+
| XML color name | Material 3 role |
|
|
56
|
+
|---|---|
|
|
57
|
+
| `colorPrimary` | `primary` |
|
|
58
|
+
| `colorPrimaryDark` / `colorPrimaryVariant` | `primaryContainer` or `secondary` |
|
|
59
|
+
| `colorAccent` | `secondary` or `tertiary` |
|
|
60
|
+
| `colorOnPrimary` | `onPrimary` |
|
|
61
|
+
| `android:colorBackground` | `background` |
|
|
62
|
+
| `colorSurface` | `surface` |
|
|
63
|
+
| `colorOnSurface` | `onSurface` |
|
|
64
|
+
| `colorError` | `error` |
|
|
65
|
+
| `colorOnError` | `onError` |
|
|
66
|
+
| `colorOutline` | `outline` |
|
|
67
|
+
| `colorSurfaceVariant` | `surfaceVariant` |
|
|
68
|
+
| `colorOnSurfaceVariant` | `onSurfaceVariant` |
|
|
69
|
+
|
|
70
|
+
*** ** * ** ***
|
|
71
|
+
|
|
72
|
+
Migrate the dark and light color schemes from XML to their equivalents in
|
|
73
|
+
Material 3 Compose.
|
|
74
|
+
|
|
75
|
+
> [!NOTE]
|
|
76
|
+
> **Note:** Material 3 naming differs from Material 2 color naming.
|
|
77
|
+
|
|
78
|
+
## Step 4: Migrate custom shapes and typography
|
|
79
|
+
|
|
80
|
+
- If your app uses custom shapes:
|
|
81
|
+
|
|
82
|
+
1. In your Compose code, define a `Shape` object to replicate your XML shape definitions.
|
|
83
|
+
2. Provide this `Shape` object to your `MaterialTheme`.
|
|
84
|
+
|
|
85
|
+
For more details, see [shapes](https://developer.android.com/develop/ui/compose/designsystems/material3#shapes).
|
|
86
|
+
- If your app uses custom typography:
|
|
87
|
+
|
|
88
|
+
1. In your Compose code, define a `Typography` object in your Compose code to replicate your XML text styles and font definitions.
|
|
89
|
+
2. Provide this `Typography` object to your `MaterialTheme`.
|
|
90
|
+
|
|
91
|
+
For more details, see [typography](https://developer.android.com/develop/ui/compose/designsystems/material3#typography).
|
|
92
|
+
|
|
93
|
+
| Compose role | XML name |
|
|
94
|
+
|---|---|
|
|
95
|
+
| `displayLarge` | `TextAppearance.Material3.DisplayLarge` |
|
|
96
|
+
| `displayMedium` | `TextAppearance.Material3.DisplayMedium` |
|
|
97
|
+
| `displaySmall` | `TextAppearance.Material3.DisplaySmall` |
|
|
98
|
+
| `headlineLarge` | `TextAppearance.Material3.HeadlineLarge` |
|
|
99
|
+
| `headlineMedium` | `TextAppearance.Material3.HeadlineMedium` |
|
|
100
|
+
| `headlineSmall` | `TextAppearance.Material3.HeadlineSmall` |
|
|
101
|
+
| `titleLarge` | `TextAppearance.Material3.TitleLarge` |
|
|
102
|
+
| `titleMedium` | `TextAppearance.Material3.TitleMedium` |
|
|
103
|
+
| `titleSmall` | `TextAppearance.Material3.TitleSmall` |
|
|
104
|
+
| `bodyLarge` | `TextAppearance.Material3.BodyLarge` |
|
|
105
|
+
| `bodyMedium` | `TextAppearance.Material3.BodyMedium` |
|
|
106
|
+
| `bodySmall` | `TextAppearance.Material3.BodySmall` |
|
|
107
|
+
| `labelLarge` | `TextAppearance.Material3.LabelLarge` |
|
|
108
|
+
| `labelMedium` | `TextAppearance.Material3.LabelMedium` |
|
|
109
|
+
| `labelSmall` | `TextAppearance.Material3.LabelSmall` |
|
|
110
|
+
|
|
111
|
+
## Step 5: Migrate styles (styles.xml)
|
|
112
|
+
|
|
113
|
+
XML styles (styles.xml) system defines styles and appearance of:
|
|
114
|
+
1. Widgets, components, themes for windows and dialogs
|
|
115
|
+
2. Typography
|
|
116
|
+
3. Themes and overlays
|
|
117
|
+
4. Shapes
|
|
118
|
+
|
|
119
|
+
XML Views and components combine multiple attributes to create a style.
|
|
120
|
+
They set their styles from styles.xml in two different ways:
|
|
121
|
+
1. Setting "style="@style/..." directly and explicitly in the XML View
|
|
122
|
+
2. Setting the style indirectly and implicitly for a component as part of a larger Theme (theme.xml)
|
|
123
|
+
|
|
124
|
+
Styles have no direct equivalent in Compose - instead styles are passed as:
|
|
125
|
+
parameters to composables, defined in the AppTheme, or by creating layered,
|
|
126
|
+
reusable composable variations with the defined style.
|
|
127
|
+
|
|
128
|
+
Provide separate @Composable functions named according to the style and the
|
|
129
|
+
base component, to signify the difference in styling and use cases for those
|
|
130
|
+
components.
|
|
131
|
+
|
|
132
|
+
- **Pattern:** If an XML element uses a custom style (e.g., `style="@style/MyPrimaryButton"`), don't try to replicate the style inline. Instead, suggest creating a specific composable.
|
|
133
|
+
- **Example:**
|
|
134
|
+
- *XML:* `<Button style="@style/MyPrimaryButton" ... />`
|
|
135
|
+
- *Compose:* `MyPrimaryButton(onClick = { ... })`
|
|
136
|
+
- **Common Attribute Groups:** If a style sets common modifiers (like padding + height), extract them into a readable extension property or a shared Modifier variable.
|
|
137
|
+
|
|
138
|
+
### Common examples
|
|
139
|
+
|
|
140
|
+
| XML | Compose |
|
|
141
|
+
|---|---|
|
|
142
|
+
| `Theme.MaterialComponents.*` | `MaterialTheme(colorScheme, typography, shapes) { }` |
|
|
143
|
+
| `TextAppearance.Material3.BodyMedium` | `TextStyle(...)` defined in `Typography(bodyMedium = ...)` |
|
|
144
|
+
| `ShapeAppearance.*.SmallComponent` | `Shapes(small = RoundedCornerShape(X.dp))` |
|
|
145
|
+
| `Widget.MaterialComponents.Button` | `Button(colors = ButtonDefaults.buttonColors(...))` |
|
|
146
|
+
| `Widget.MaterialComponents.CardView` | `Card(shape=..., elevation=..., colors=...)` |
|
|
147
|
+
| `Widget.*.TextInputLayout.OutlinedBox` | `OutlinedTextField(colors = OutlinedTextFieldDefaults.colors(...))` |
|
|
148
|
+
| `Widget.*.Chip.Filter` | `FilterChip(colors = FilterChipDefaults.filterChipColors(...))` |
|
|
149
|
+
| `Widget.*.Toolbar.Primary` | `TopAppBar(colors = TopAppBarDefaults.topAppBarColors(...))` |
|
|
150
|
+
| `Widget.*.FloatingActionButton` | `FloatingActionButton(containerColor = ...)` |
|
|
151
|
+
| `backgroundTint` | `containerColor` in `ComponentDefaults.ComponentColors()` |
|
|
152
|
+
| `android:textColor` | `contentColor` in `ComponentDefaults.ComponentColors()` |
|
|
153
|
+
| `cornerRadius` | `shape = RoundedCornerShape(X.dp)` |
|
|
154
|
+
| `android:elevation` | `elevation = ComponentDefaults.elevation(defaultElevation = X.dp)` |
|
|
155
|
+
| `android:padding` | `contentPadding = PaddingValues(...)` or `Modifier.padding()` |
|
|
156
|
+
| `android:minHeight` | `Modifier.heightIn(min = X.dp)` |
|
|
157
|
+
| `strokeColor` + `strokeWidth` | `border = BorderStroke(width, color)` |
|
|
158
|
+
| `android:textSize` | `fontSize = X.sp` in `TextStyle` |
|
|
159
|
+
|
|
160
|
+
## Step 6: Validate the theme migration
|
|
161
|
+
|
|
162
|
+
Always use the existing theme values from the original XML theme as the source
|
|
163
|
+
of truth for the new Material Theme in Compose
|
|
164
|
+
Never invent new theme values during migration, to maintain brand consistency
|
|
165
|
+
and avoid visual regressions.
|
|
166
|
+
|
|
167
|
+
Verify all new Compose theme values match the existing XML values.
|
|
168
|
+
Don't hardcode any migrated values.
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
## Set up the Compose Compiler Gradle plugin
|
|
2
|
+
|
|
3
|
+
For Gradle, use the Compose Compiler Gradle plugin to set
|
|
4
|
+
up and configure Compose.
|
|
5
|
+
|
|
6
|
+
> [!NOTE]
|
|
7
|
+
> **Note:** The Compose Compiler Gradle Plugin is only available from Kotlin 2.0+. For migration instructions, see ["Jetpack Compose compiler moving to the Kotlin
|
|
8
|
+
> repository"](https://android-developers.googleblog.com/2024/04/jetpack-compose-compiler-moving-to-kotlin-repository.html).
|
|
9
|
+
|
|
10
|
+
### Set up with Gradle version catalogs
|
|
11
|
+
|
|
12
|
+
Set up the Compose Compiler Gradle plugin:
|
|
13
|
+
|
|
14
|
+
1. In the `libs.versions.toml` file, remove any reference to the Compose Compiler.
|
|
15
|
+
2. In the `versions` and `plugins` sections, add the new dependency:
|
|
16
|
+
|
|
17
|
+
[versions]
|
|
18
|
+
kotlin = "2.3.10"
|
|
19
|
+
|
|
20
|
+
[plugins]
|
|
21
|
+
org-jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
|
22
|
+
|
|
23
|
+
// Add this line
|
|
24
|
+
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
|
25
|
+
|
|
26
|
+
1. In the project's root `build.gradle.kts` file, add the following to the `plugins` section.
|
|
27
|
+
|
|
28
|
+
plugins {
|
|
29
|
+
// Existing plugins
|
|
30
|
+
alias(libs.plugins.compose.compiler) apply false
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
1. In each module that uses Compose, apply the plugin:
|
|
34
|
+
|
|
35
|
+
plugins {
|
|
36
|
+
// Existing plugins
|
|
37
|
+
alias(libs.plugins.compose.compiler)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
The project should now build and compile if it was using the default set up. If
|
|
41
|
+
it had configured custom options on the Compose compiler, follow the next
|
|
42
|
+
section.
|
|
43
|
+
|
|
44
|
+
### Set up the Compose Compiler without Gradle version catalogs
|
|
45
|
+
|
|
46
|
+
Add the plugin to `build.gradle.kts` files associated with modules where Compose
|
|
47
|
+
is used:
|
|
48
|
+
|
|
49
|
+
plugins {
|
|
50
|
+
id("org.jetbrains.kotlin.plugin.compose") version "2.3.10" // this version matches your Kotlin version
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
Add the classpath to your top-level project `build.gradle.kts` file:
|
|
54
|
+
|
|
55
|
+
buildscript {
|
|
56
|
+
dependencies {
|
|
57
|
+
classpath("org.jetbrains.kotlin.plugin.compose:org.jetbrains.kotlin.plugin.compose.gradle.plugin:2.3.10")
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
### Configuration options with the Compose Compiler Gradle Plugin
|
|
62
|
+
|
|
63
|
+
To configure the Compose compiler using the Gradle plugin, add the
|
|
64
|
+
`composeCompiler` block to the module's `build.gradle.kts` file at the top
|
|
65
|
+
level:
|
|
66
|
+
|
|
67
|
+
android { ... }
|
|
68
|
+
|
|
69
|
+
composeCompiler {
|
|
70
|
+
reportsDestination = layout.buildDirectory.dir("compose_compiler")
|
|
71
|
+
stabilityConfigurationFile = rootProject.layout.projectDirectory.file("stability_config.conf")
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
For the full list of available options, see the [documentation](https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-compiler.html#compose-compiler-options-dsl).
|
|
75
|
+
|
|
76
|
+
## Set up Compose dependencies
|
|
77
|
+
|
|
78
|
+
Always use the latest Compose BOM version: `2026.03.00`.
|
|
79
|
+
|
|
80
|
+
Set the `compose` flag to `true` inside the Android [`BuildFeatures`](https://developer.android.com/reference/tools/gradle-api/7.0/com/android/build/api/dsl/BuildFeatures)
|
|
81
|
+
to enable [Compose functionality](https://developer.android.com/develop/ui/compose/tooling) in Android Studio.
|
|
82
|
+
|
|
83
|
+
Add the following definition to your app's `build.gradle` file:
|
|
84
|
+
|
|
85
|
+
### Groovy
|
|
86
|
+
|
|
87
|
+
android {
|
|
88
|
+
buildFeatures {
|
|
89
|
+
compose true
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
### Kotlin
|
|
94
|
+
|
|
95
|
+
android {
|
|
96
|
+
buildFeatures {
|
|
97
|
+
compose = true
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
Add the Compose BOM and the subset of Compose library dependencies:
|
|
102
|
+
|
|
103
|
+
### Groovy
|
|
104
|
+
|
|
105
|
+
dependencies {
|
|
106
|
+
|
|
107
|
+
def composeBom = platform('androidx.compose:compose-bom:2026.03.00')
|
|
108
|
+
implementation composeBom
|
|
109
|
+
androidTestImplementation composeBom
|
|
110
|
+
|
|
111
|
+
// Choose one of the following:
|
|
112
|
+
// Material Design 3
|
|
113
|
+
implementation 'androidx.compose.material3:material3'
|
|
114
|
+
// or skip Material Design and build directly on top of foundational components
|
|
115
|
+
implementation 'androidx.compose.foundation:foundation'
|
|
116
|
+
// or only import the main APIs for the underlying toolkit systems,
|
|
117
|
+
// such as input and measurement/layout
|
|
118
|
+
implementation 'androidx.compose.ui:ui'
|
|
119
|
+
|
|
120
|
+
// Android Studio Preview support
|
|
121
|
+
implementation 'androidx.compose.ui:ui-tooling-preview'
|
|
122
|
+
debugImplementation 'androidx.compose.ui:ui-tooling'
|
|
123
|
+
|
|
124
|
+
// UI Tests
|
|
125
|
+
androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
|
|
126
|
+
debugImplementation 'androidx.compose.ui:ui-test-manifest'
|
|
127
|
+
|
|
128
|
+
// Optional - Add window size utils
|
|
129
|
+
implementation 'androidx.compose.material3.adaptive:adaptive'
|
|
130
|
+
|
|
131
|
+
// Optional - Integration with activities
|
|
132
|
+
implementation 'androidx.activity:activity-compose:1.13.0'
|
|
133
|
+
// Optional - Integration with ViewModels
|
|
134
|
+
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.10.0'
|
|
135
|
+
// Optional - Integration with LiveData
|
|
136
|
+
implementation 'androidx.compose.runtime:runtime-livedata'
|
|
137
|
+
// Optional - Integration with RxJava
|
|
138
|
+
implementation 'androidx.compose.runtime:runtime-rxjava2'
|
|
139
|
+
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
### Kotlin
|
|
143
|
+
|
|
144
|
+
dependencies {
|
|
145
|
+
|
|
146
|
+
val composeBom = platform("androidx.compose:compose-bom:2026.03.00")
|
|
147
|
+
implementation(composeBom)
|
|
148
|
+
androidTestImplementation(composeBom)
|
|
149
|
+
|
|
150
|
+
// Choose one of the following:
|
|
151
|
+
// Material Design 3
|
|
152
|
+
implementation("androidx.compose.material3:material3")
|
|
153
|
+
// or skip Material Design and build directly on top of foundational components
|
|
154
|
+
implementation("androidx.compose.foundation:foundation")
|
|
155
|
+
// or only import the main APIs for the underlying toolkit systems,
|
|
156
|
+
// such as input and measurement/layout
|
|
157
|
+
implementation("androidx.compose.ui:ui")
|
|
158
|
+
|
|
159
|
+
// Android Studio Preview support
|
|
160
|
+
implementation("androidx.compose.ui:ui-tooling-preview")
|
|
161
|
+
debugImplementation("androidx.compose.ui:ui-tooling")
|
|
162
|
+
|
|
163
|
+
// UI Tests
|
|
164
|
+
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
|
|
165
|
+
debugImplementation("androidx.compose.ui:ui-test-manifest")
|
|
166
|
+
|
|
167
|
+
// Optional - Add window size utils
|
|
168
|
+
implementation("androidx.compose.material3.adaptive:adaptive")
|
|
169
|
+
|
|
170
|
+
// Optional - Integration with activities
|
|
171
|
+
implementation("androidx.activity:activity-compose:1.13.0")
|
|
172
|
+
// Optional - Integration with ViewModels
|
|
173
|
+
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.10.0")
|
|
174
|
+
// Optional - Integration with LiveData
|
|
175
|
+
implementation("androidx.compose.runtime:runtime-livedata")
|
|
176
|
+
// Optional - Integration with RxJava
|
|
177
|
+
implementation("androidx.compose.runtime:runtime-rxjava2")
|
|
178
|
+
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
> [!NOTE]
|
|
182
|
+
> **Note:** Jetpack Compose is shipped using a Bill of Materials (BOM), to keep the versions of all library groups in sync. Read more about it in the [Bill of
|
|
183
|
+
> Materials page](https://developer.android.com/develop/ui/compose/bom/bom).
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
### 1. Analysis scope
|
|
2
|
+
|
|
3
|
+
**Action:** Use find files and examine all XML layout files within the project (typically located in `res`directories). For each file, parse the view hierarchy and metadata.
|
|
4
|
+
|
|
5
|
+
### 2. Selection criteria
|
|
6
|
+
|
|
7
|
+
Prioritize layouts that meet the following criteria:
|
|
8
|
+
|
|
9
|
+
- **Hierarchy depth:** Target **leaf nodes** or components at the bottom of the UI tree.
|
|
10
|
+
- **Complexity:** Select layouts with the **smallest number of nested children** and minimal logic.
|
|
11
|
+
- **State management:** Prioritize **stateless** components or those with the fewest UI state variables.
|
|
12
|
+
- **Dependency footprint:** Identify layouts with **zero to minimal external UI dependencies**.
|
|
13
|
+
- **Isolation:** Focus on **self-contained** components that do not rely heavily on parent context or complex data binding.
|
|
14
|
+
|
|
15
|
+
### 3. Risk assessment
|
|
16
|
+
|
|
17
|
+
Evaluate the migration risk based on:
|
|
18
|
+
\* **Reusability:** Find layouts with **minimum reuse** across the project to limit regression impact.
|
|
19
|
+
\* **Accessibility:** Ensure the layout has an **easily accessible entry point** (e.g., used in a simple Activity, Fragment, or as a standalone include).
|
|
20
|
+
|
|
21
|
+
*** ** * ** ***
|
|
22
|
+
|
|
23
|
+
## Output requirements
|
|
24
|
+
|
|
25
|
+
Provide a ranked list of the top 3-5 candidates. For each candidate, include:
|
|
26
|
+
1. **File path:** (e.g., `res/layout/item_user_profile.xml`)
|
|
27
|
+
2. **Rationale:** Why this is a good candidate based on the provided criteria.
|
|
28
|
+
3. **Complexity score:** A rating from 1-5 (1 being simplest).
|
|
29
|
+
4. **Dependency count:** List of custom/external views found within.
|
|
30
|
+
|
|
31
|
+
**Action:** If you support user interaction, ask the user to choose which XML to proceed with. Else proceed with the best option, based on the previous criteria.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
## 1. Structural analysis \& mapping
|
|
2
|
+
|
|
3
|
+
**Identify the precise mapping** between XML elements and Compose equivalents.
|
|
4
|
+
You must determine:
|
|
5
|
+
|
|
6
|
+
- The exact `@Composable` functions (e.g., `ConstraintLayout`, `Column`, `LazyColumn`) that replace the XML tag hierarchy.
|
|
7
|
+
- The specific parameters and `Modifier` extensions required to replicate XML attributes (e.g., `layout_width`, `padding`, `elevation`).
|
|
8
|
+
- The appropriate state management strategy for interactive elements.
|
|
9
|
+
|
|
10
|
+
## 2. Migration execution
|
|
11
|
+
|
|
12
|
+
**Convert the XML layout code to Jetpack Compose**, ensuring the visual
|
|
13
|
+
hierarchy and layout logic are preserved while leveraging Compose's declarative
|
|
14
|
+
nature.
|
|
15
|
+
|
|
16
|
+
## 3. Theming \& design system integrity
|
|
17
|
+
|
|
18
|
+
**Do not use hard-coded values.** Follow these rules for styling:
|
|
19
|
+
|
|
20
|
+
- **Token Alignment:** Cross-reference XML dimensions, colors, and style attributes with the existing Compose `Theme` (e.g., `MaterialTheme.colorScheme` or custom design system tokens).
|
|
21
|
+
- **Reuse over Creation:** If matching values exist in the current Compose theme, reuse them. If a value is missing but required for the design, define it within the theme structure rather than hard-coding it in the Composable.
|
|
22
|
+
- **Project Consistency:** You **MUST** strictly adhere to existing code conventions, naming standards, and implementation patterns found in the project. **Prioritize** project-specific reusable components over generic Material defaults.
|
|
23
|
+
|
|
24
|
+
## 4. Component layering \& reusability
|
|
25
|
+
|
|
26
|
+
Evaluate if the XML layout serves as a foundation-level design system component
|
|
27
|
+
(reused across the app with a distinct role). If it is:
|
|
28
|
+
|
|
29
|
+
- **Create a reusable composable:** Do not just inline the code. Define a new standalone `@Composable`.
|
|
30
|
+
- **Parameterization:** Expose specific parameters for variable data (text, colors, styles) and use `Modifier` for layout-specific customizations.
|
|
31
|
+
- **Feature parity \& restriction:** Ensure the new composable enforces the same UI constraints as the original XML component, preventing unauthorized style overrides while maintaining the intended flexibility.
|
|
32
|
+
|
|
33
|
+
Example before migration:
|
|
34
|
+
|
|
35
|
+
<style
|
|
36
|
+
name="Widget.Rounded.Button"
|
|
37
|
+
parent="Widget.Button.Borderless">
|
|
38
|
+
<item name="android:fontFamily">sans-serif-medium</item>
|
|
39
|
+
<item name="android:minWidth">@dimen/min_width</item>
|
|
40
|
+
<item name="android:paddingStart">@dimen/padding_2</item>
|
|
41
|
+
<item name="android:paddingEnd">@dimen/padding_2</item>
|
|
42
|
+
<item name="cornerRadius">8dp</item>
|
|
43
|
+
</style>
|
|
44
|
+
|
|
45
|
+
Example after migration:
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
```kotlin
|
|
49
|
+
@Composable
|
|
50
|
+
fun RoundedBorderlessButton(
|
|
51
|
+
text: String,
|
|
52
|
+
onClick: () -> Unit,
|
|
53
|
+
modifier: Modifier = Modifier,
|
|
54
|
+
enabled: Boolean = true
|
|
55
|
+
) {
|
|
56
|
+
TextButton(
|
|
57
|
+
onClick, modifier
|
|
58
|
+
.defaultMinSize(minWidth = dimensionResource(R.dimen.min_width))
|
|
59
|
+
.padding(
|
|
60
|
+
start = dimensionResource(R.dimen.padding_2),
|
|
61
|
+
end = dimensionResource(R.dimen.padding_2)
|
|
62
|
+
), enabled, shape = RoundedCornerShape(8.dp),
|
|
63
|
+
colors = ButtonDefaults.textButtonColors(
|
|
64
|
+
contentColor = MaterialTheme.colorScheme.primary
|
|
65
|
+
)
|
|
66
|
+
) {
|
|
67
|
+
Text(
|
|
68
|
+
text = text,
|
|
69
|
+
style = MaterialTheme.typography.bodyMedium.copy(
|
|
70
|
+
fontFamily = FontFamily.SansSerif,
|
|
71
|
+
fontWeight = FontWeight.Medium
|
|
72
|
+
)
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
<br />
|
|
79
|
+
|
|
80
|
+
*** ** * ** ***
|
|
81
|
+
|
|
82
|
+
## 5. Output requirements
|
|
83
|
+
|
|
84
|
+
- Provide the full Kotlin file content.
|
|
85
|
+
- Include necessary imports.
|
|
86
|
+
- Add documentation comments (`/** ... */`) explaining the mapping logic for complex transformations.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# AIDL 回调切主线程(种子规则)
|
|
2
|
+
|
|
3
|
+
> 种子规则:可保留、修改或删除。
|
|
4
|
+
|
|
5
|
+
## 是什么
|
|
6
|
+
|
|
7
|
+
所有通过 AIDL / Messenger / IPC 跨进程回传的结果,UI 消费前必须切主线程;
|
|
8
|
+
禁止在 Binder 线程直接更新 UI 或修改 LiveData/StateFlow 的主观察者。
|
|
9
|
+
|
|
10
|
+
## 正例
|
|
11
|
+
|
|
12
|
+
```java
|
|
13
|
+
private final IWirelessCallback aidlCb = new IWirelessCallback.Stub() {
|
|
14
|
+
@Override public void onState(WirelessState s) {
|
|
15
|
+
mainHandler.post(() -> liveData.setValue(s));
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 反例
|
|
21
|
+
|
|
22
|
+
```java
|
|
23
|
+
// ❌ Binder 线程直接 setValue,LiveData 会抛异常
|
|
24
|
+
public void onState(WirelessState s) { liveData.setValue(s); }
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 如何检测
|
|
28
|
+
|
|
29
|
+
- AIDL `.Stub` 实现内 grep `liveData\.setValue` / `view\.` 命中即违规。
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# 生命周期感知(种子规则)
|
|
2
|
+
|
|
3
|
+
> 种子规则:可保留、修改或删除。
|
|
4
|
+
|
|
5
|
+
## 是什么
|
|
6
|
+
|
|
7
|
+
订阅 / 注册 / 监听,必须在 `onStart` 建立、在 `onStop` 释放(或更严格),
|
|
8
|
+
避免在 `onCreate`/`onDestroy` 对称以外的地方偷偷改动。
|
|
9
|
+
|
|
10
|
+
## 正例
|
|
11
|
+
|
|
12
|
+
```java
|
|
13
|
+
@Override protected void onStart() {
|
|
14
|
+
super.onStart();
|
|
15
|
+
controller.setDataChangeListener(callback);
|
|
16
|
+
}
|
|
17
|
+
@Override protected void onStop() {
|
|
18
|
+
controller.removeDataChangeListener(callback);
|
|
19
|
+
super.onStop();
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 反例
|
|
24
|
+
|
|
25
|
+
```java
|
|
26
|
+
// ❌ onCreate 注册、onDestroy 释放:Activity 不可见时仍回调
|
|
27
|
+
@Override protected void onCreate(Bundle s) { controller.setDataChangeListener(cb); }
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 如何检测
|
|
31
|
+
|
|
32
|
+
- PR 评审:任何 `setXxxListener` 必须在同一类中能找到对称 `removeXxxListener`。
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# MVC 分层铁律(种子规则)
|
|
2
|
+
|
|
3
|
+
> 种子规则:可保留、修改或删除。
|
|
4
|
+
|
|
5
|
+
## 是什么
|
|
6
|
+
|
|
7
|
+
Activity / Fragment 只能依赖 ViewModel 或 Presenter;不得直接访问 Repository、
|
|
8
|
+
Manager、AIDL 代理、`CarPropertyManager`,也不得在 Activity 里解析数据。
|
|
9
|
+
|
|
10
|
+
## 正例
|
|
11
|
+
|
|
12
|
+
```java
|
|
13
|
+
public class WirelessFragment extends BaseFragment {
|
|
14
|
+
private WirelessViewModel viewModel;
|
|
15
|
+
|
|
16
|
+
@Override public void onViewCreated(@NonNull View v, Bundle s) {
|
|
17
|
+
viewModel.getState().observe(getViewLifecycleOwner(), this::render);
|
|
18
|
+
}
|
|
19
|
+
private void render(WirelessState s) { binding.sw.setChecked(s.isEnabled()); }
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 反例
|
|
24
|
+
|
|
25
|
+
```java
|
|
26
|
+
// ❌ Activity 直接调 Manager
|
|
27
|
+
MyCarPropertyManager.INSTANCE().sendSignal(ID, new int[]{1}, "");
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 如何检测
|
|
31
|
+
|
|
32
|
+
- UI 目录下 grep `MyCarPropertyManager` / `CarPropertyManager` 命中即违规。
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# 禁止 findViewById(种子规则)
|
|
2
|
+
|
|
3
|
+
> 种子规则:可保留、修改或删除。
|
|
4
|
+
|
|
5
|
+
## 是什么
|
|
6
|
+
|
|
7
|
+
Activity / Fragment 必须使用 DataBinding 或 ViewBinding 访问视图,
|
|
8
|
+
严禁 `findViewById` + 手动 cast。
|
|
9
|
+
|
|
10
|
+
## 正例
|
|
11
|
+
|
|
12
|
+
```java
|
|
13
|
+
public class WirelessActivity extends BaseActivity {
|
|
14
|
+
private ActivityWirelessBinding binding;
|
|
15
|
+
@Override protected void onCreate(Bundle s) {
|
|
16
|
+
super.onCreate(s);
|
|
17
|
+
binding = ActivityWirelessBinding.inflate(getLayoutInflater());
|
|
18
|
+
setContentView(binding.getRoot());
|
|
19
|
+
binding.sw.setOnCheckedChangeListener((v, c) -> vm.setEnabled(c));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 反例
|
|
25
|
+
|
|
26
|
+
```java
|
|
27
|
+
// ❌ 手写 findViewById
|
|
28
|
+
Switch sw = (Switch) findViewById(R.id.sw);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 如何检测
|
|
32
|
+
|
|
33
|
+
- grep `findViewById\s*\(` 命中即违规(过渡期可加白名单)。
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# XML 样式不得硬编码(种子规则)
|
|
2
|
+
|
|
3
|
+
> 种子规则:可保留、修改或删除。
|
|
4
|
+
|
|
5
|
+
## 是什么
|
|
6
|
+
|
|
7
|
+
`color` / `dimen` / `textSize` 等视觉属性必须走 `@color/...` / `@dimen/...` / `style`,
|
|
8
|
+
禁止在 layout XML 里硬编码 `#RRGGBB` 或 `16dp`。
|
|
9
|
+
|
|
10
|
+
## 正例
|
|
11
|
+
|
|
12
|
+
```xml
|
|
13
|
+
<TextView
|
|
14
|
+
android:textSize="@dimen/text_body"
|
|
15
|
+
android:textColor="@color/fg_primary" />
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## 反例
|
|
19
|
+
|
|
20
|
+
```xml
|
|
21
|
+
<!-- ❌ 直接写字面量 -->
|
|
22
|
+
<TextView android:textSize="16sp" android:textColor="#FFFFFF" />
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 如何检测
|
|
26
|
+
|
|
27
|
+
- 对 `res/layout/**/*.xml` grep `#[0-9A-Fa-f]{6}` / `\d+(sp|dp)\s*"` 命中即违规。
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# CMake target 显式列源文件(种子规则)
|
|
2
|
+
|
|
3
|
+
> 种子规则:可保留、修改或删除。
|
|
4
|
+
|
|
5
|
+
## 是什么
|
|
6
|
+
|
|
7
|
+
每个库 / 可执行 target 必须显式列出源文件,**禁止** `file(GLOB ...)` 搜集源文件;
|
|
8
|
+
理由:GLOB 不会触发 CMake 重新生成,新增/删除文件编译结果错乱难以察觉。
|
|
9
|
+
|
|
10
|
+
## 正例
|
|
11
|
+
|
|
12
|
+
```cmake
|
|
13
|
+
add_library(wireless STATIC
|
|
14
|
+
wireless_controller.cpp
|
|
15
|
+
wireless_parser.cpp
|
|
16
|
+
wireless_sender.cpp)
|
|
17
|
+
target_include_directories(wireless PUBLIC include)
|
|
18
|
+
target_link_libraries(wireless PUBLIC common core)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 反例
|
|
22
|
+
|
|
23
|
+
```cmake
|
|
24
|
+
# ❌ 新增文件不会触发重新配置
|
|
25
|
+
file(GLOB SRCS "*.cpp")
|
|
26
|
+
add_library(wireless STATIC ${SRCS})
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 如何检测
|
|
30
|
+
|
|
31
|
+
- grep 所有 `CMakeLists.txt`:`file\s*\(\s*GLOB` 命中即违规。
|