diff options
Diffstat (limited to 'classes/go-mod-discovery.bbclass')
| -rw-r--r-- | classes/go-mod-discovery.bbclass | 441 |
1 files changed, 441 insertions, 0 deletions
diff --git a/classes/go-mod-discovery.bbclass b/classes/go-mod-discovery.bbclass new file mode 100644 index 00000000..0d703d0a --- /dev/null +++ b/classes/go-mod-discovery.bbclass | |||
| @@ -0,0 +1,441 @@ | |||
| 1 | # | ||
| 2 | # Copyright OpenEmbedded Contributors | ||
| 3 | # | ||
| 4 | # SPDX-License-Identifier: MIT | ||
| 5 | # | ||
| 6 | |||
| 7 | # go-mod-discovery.bbclass | ||
| 8 | # | ||
| 9 | # Provides a do_discover_modules task for Go projects that downloads complete | ||
| 10 | # module metadata from proxy.golang.org for use with the bootstrap strategy. | ||
| 11 | # | ||
| 12 | # USAGE: | ||
| 13 | # 1. Add to recipe: inherit go-mod-discovery | ||
| 14 | # 2. Set required variables (see CONFIGURATION below) | ||
| 15 | # 3. Run discovery: bitbake <recipe> -c discover_modules | ||
| 16 | # (This automatically: downloads modules, extracts metadata, regenerates recipe) | ||
| 17 | # 4. Build normally: bitbake <recipe> | ||
| 18 | # | ||
| 19 | # CONFIGURATION: | ||
| 20 | # | ||
| 21 | # Required (must be set by recipe): | ||
| 22 | # | ||
| 23 | # GO_MOD_DISCOVERY_BUILD_TARGET - Build target for go build | ||
| 24 | # Example: "./cmd/server" or "./..." | ||
| 25 | # | ||
| 26 | # Optional (have sensible defaults): | ||
| 27 | # | ||
| 28 | # GO_MOD_DISCOVERY_SRCDIR - Directory containing go.mod | ||
| 29 | # Default: "${S}/src/import" (standard Go recipe layout) | ||
| 30 | # | ||
| 31 | # GO_MOD_DISCOVERY_BUILD_TAGS - Build tags for go build | ||
| 32 | # Default: "${TAGS}" (uses recipe's TAGS variable if set) | ||
| 33 | # Example: "netcgo osusergo static_build" | ||
| 34 | # | ||
| 35 | # GO_MOD_DISCOVERY_LDFLAGS - Linker flags for go build | ||
| 36 | # Default: "-w -s" | ||
| 37 | # Example: "-X main.version=${PV} -w -s" | ||
| 38 | # | ||
| 39 | # GO_MOD_DISCOVERY_GOPATH - GOPATH for discovery build | ||
| 40 | # Default: "${S}/src/import/.gopath:${S}/src/import/vendor" | ||
| 41 | # | ||
| 42 | # GO_MOD_DISCOVERY_OUTPUT - Output binary path | ||
| 43 | # Default: "${WORKDIR}/discovery-build-output" | ||
| 44 | # | ||
| 45 | # GO_MOD_DISCOVERY_DIR - Persistent cache location | ||
| 46 | # Default: "${TOPDIR}/go-mod-discovery/${PN}/${PV}" | ||
| 47 | # | ||
| 48 | # GO_MOD_DISCOVERY_MODULES_JSON - Output path for extracted module metadata | ||
| 49 | # Default: "${GO_MOD_DISCOVERY_DIR}/modules.json" | ||
| 50 | # | ||
| 51 | # GO_MOD_DISCOVERY_SKIP_EXTRACT - Set to "1" to skip automatic extraction | ||
| 52 | # Default: "0" (extraction runs automatically) | ||
| 53 | # | ||
| 54 | # GO_MOD_DISCOVERY_SKIP_GENERATE - Set to "1" to skip automatic recipe generation | ||
| 55 | # Default: "0" (generation runs automatically) | ||
| 56 | # | ||
| 57 | # GO_MOD_DISCOVERY_GIT_REPO - Git repository URL for recipe generation | ||
| 58 | # Example: "https://github.com/rancher/k3s.git" | ||
| 59 | # Required for automatic generation | ||
| 60 | # | ||
| 61 | # GO_MOD_DISCOVERY_GIT_REF - Git ref (commit/tag) for recipe generation | ||
| 62 | # Default: "${SRCREV}" (uses recipe's SRCREV) | ||
| 63 | # | ||
| 64 | # GO_MOD_DISCOVERY_RECIPEDIR - Output directory for generated .inc files | ||
| 65 | # Default: "${FILE_DIRNAME}" (recipe's directory) | ||
| 66 | # | ||
| 67 | # MINIMAL EXAMPLE (manual generation - no GIT_REPO set): | ||
| 68 | # | ||
| 69 | # TAGS = "netcgo osusergo" | ||
| 70 | # GO_MOD_DISCOVERY_BUILD_TARGET = "./cmd/myapp" | ||
| 71 | # inherit go-mod-discovery | ||
| 72 | # # Run: bitbake myapp -c discover_modules | ||
| 73 | # # Then manually: oe-go-mod-fetcher.py --discovered-modules ... --git-repo ... | ||
| 74 | # | ||
| 75 | # FULL AUTOMATIC EXAMPLE (all-in-one discovery + generation): | ||
| 76 | # | ||
| 77 | # TAGS = "netcgo osusergo" | ||
| 78 | # GO_MOD_DISCOVERY_BUILD_TARGET = "./cmd/myapp" | ||
| 79 | # GO_MOD_DISCOVERY_GIT_REPO = "https://github.com/example/myapp.git" | ||
| 80 | # inherit go-mod-discovery | ||
| 81 | # # Run: bitbake myapp -c discover_modules | ||
| 82 | # # Recipe files are automatically regenerated! | ||
| 83 | # | ||
| 84 | # See: meta-virtualization/scripts/BOOTSTRAP-STRATEGY.md (Approach B) | ||
| 85 | # | ||
| 86 | # This task is NOT part of the normal build - it must be explicitly invoked | ||
| 87 | # via bitbake <recipe> -c discover_modules | ||
| 88 | # | ||
| 89 | # PERSISTENT CACHE: The discovery cache is stored in ${TOPDIR}/go-mod-discovery/${PN}/${PV}/ | ||
| 90 | # instead of ${WORKDIR}. This ensures the cache survives `bitbake <recipe> -c cleanall` | ||
| 91 | # since TOPDIR is the build directory root (e.g., /path/to/build/). | ||
| 92 | # To clean the discovery cache, run: rm -rf ${TOPDIR}/go-mod-discovery/${PN}/${PV}/ | ||
| 93 | |||
| 94 | # Required variable (must be set by recipe) | ||
| 95 | GO_MOD_DISCOVERY_BUILD_TARGET ?= "" | ||
| 96 | |||
| 97 | # Optional variables with sensible defaults for standard Go recipe layout | ||
| 98 | GO_MOD_DISCOVERY_SRCDIR ?= "${S}/src/import" | ||
| 99 | GO_MOD_DISCOVERY_BUILD_TAGS ?= "${TAGS}" | ||
| 100 | GO_MOD_DISCOVERY_LDFLAGS ?= "-w -s" | ||
| 101 | GO_MOD_DISCOVERY_GOPATH ?= "${S}/src/import/.gopath:${S}/src/import/vendor" | ||
| 102 | GO_MOD_DISCOVERY_OUTPUT ?= "${WORKDIR}/discovery-build-output" | ||
| 103 | |||
| 104 | # Persistent discovery cache location - survives cleanall | ||
| 105 | GO_MOD_DISCOVERY_DIR ?= "${TOPDIR}/go-mod-discovery/${PN}/${PV}" | ||
| 106 | |||
| 107 | # Output JSON file for discovered modules (used by oe-go-mod-fetcher.py --discovered-modules) | ||
| 108 | GO_MOD_DISCOVERY_MODULES_JSON ?= "${GO_MOD_DISCOVERY_DIR}/modules.json" | ||
| 109 | |||
| 110 | # Set to "1" to skip automatic extraction (only download modules, don't extract metadata) | ||
| 111 | GO_MOD_DISCOVERY_SKIP_EXTRACT ?= "0" | ||
| 112 | |||
| 113 | # Set to "1" to skip automatic recipe regeneration (only discover and extract) | ||
| 114 | GO_MOD_DISCOVERY_SKIP_GENERATE ?= "0" | ||
| 115 | |||
| 116 | # Git repository URL for recipe generation (required if SKIP_GENERATE != "1") | ||
| 117 | # Example: "https://github.com/rancher/k3s.git" | ||
| 118 | GO_MOD_DISCOVERY_GIT_REPO ?= "" | ||
| 119 | |||
| 120 | # Git ref (commit/tag) for recipe generation - defaults to recipe's SRCREV | ||
| 121 | GO_MOD_DISCOVERY_GIT_REF ?= "${SRCREV}" | ||
| 122 | |||
| 123 | # Recipe directory for generated .inc files - defaults to recipe's directory | ||
| 124 | GO_MOD_DISCOVERY_RECIPEDIR ?= "${FILE_DIRNAME}" | ||
| 125 | |||
| 126 | # Empty default for TAGS if not set by recipe (avoids undefined variable errors) | ||
| 127 | TAGS ?= "" | ||
| 128 | |||
| 129 | # Shell task that mirrors do_compile but with network access and discovery GOMODCACHE | ||
| 130 | do_discover_modules() { | ||
| 131 | # Validate required variable | ||
| 132 | if [ -z "${GO_MOD_DISCOVERY_BUILD_TARGET}" ]; then | ||
| 133 | bbfatal "GO_MOD_DISCOVERY_BUILD_TARGET must be set (e.g., './cmd/server' or './...')" | ||
| 134 | fi | ||
| 135 | |||
| 136 | # Validate source directory exists and contains go.mod | ||
| 137 | if [ ! -d "${GO_MOD_DISCOVERY_SRCDIR}" ]; then | ||
| 138 | bbfatal "GO_MOD_DISCOVERY_SRCDIR does not exist: ${GO_MOD_DISCOVERY_SRCDIR} | ||
| 139 | Hint: Set GO_MOD_DISCOVERY_SRCDIR in your recipe if go.mod is not in \${S}/src/import" | ||
| 140 | fi | ||
| 141 | if [ ! -f "${GO_MOD_DISCOVERY_SRCDIR}/go.mod" ]; then | ||
| 142 | bbfatal "go.mod not found in GO_MOD_DISCOVERY_SRCDIR: ${GO_MOD_DISCOVERY_SRCDIR} | ||
| 143 | Hint: Set GO_MOD_DISCOVERY_SRCDIR to the directory containing go.mod" | ||
| 144 | fi | ||
| 145 | |||
| 146 | # Use PERSISTENT cache location outside WORKDIR to survive cleanall | ||
| 147 | # This is stored in ${TOPDIR}/go-mod-discovery/${PN}/${PV}/ so it persists | ||
| 148 | DISCOVERY_CACHE="${GO_MOD_DISCOVERY_DIR}/cache" | ||
| 149 | |||
| 150 | # Create required directories first | ||
| 151 | mkdir -p "${DISCOVERY_CACHE}" | ||
| 152 | mkdir -p "${WORKDIR}/go-tmp" | ||
| 153 | mkdir -p "$(dirname "${GO_MOD_DISCOVERY_OUTPUT}")" | ||
| 154 | |||
| 155 | # Use discovery-cache instead of the normal GOMODCACHE | ||
| 156 | export GOMODCACHE="${DISCOVERY_CACHE}" | ||
| 157 | |||
| 158 | # Enable network access to proxy.golang.org | ||
| 159 | export GOPROXY="https://proxy.golang.org,direct" | ||
| 160 | export GOSUMDB="sum.golang.org" | ||
| 161 | |||
| 162 | # Standard Go environment - use recipe-provided GOPATH or default | ||
| 163 | export GOPATH="${GO_MOD_DISCOVERY_GOPATH}:${STAGING_DIR_TARGET}/${prefix}/local/go" | ||
| 164 | export CGO_ENABLED="1" | ||
| 165 | export GOTOOLCHAIN="local" | ||
| 166 | |||
| 167 | # Use system temp directory for Go's work files | ||
| 168 | export GOTMPDIR="${WORKDIR}/go-tmp" | ||
| 169 | |||
| 170 | # Disable excessive debug output from BitBake environment | ||
| 171 | unset GODEBUG | ||
| 172 | |||
| 173 | # Build tags from recipe configuration | ||
| 174 | TAGS="${GO_MOD_DISCOVERY_BUILD_TAGS}" | ||
| 175 | |||
| 176 | # Change to source directory | ||
| 177 | cd "${GO_MOD_DISCOVERY_SRCDIR}" | ||
| 178 | |||
| 179 | echo "======================================================================" | ||
| 180 | echo "MODULE DISCOVERY: ${PN} ${PV}" | ||
| 181 | echo "======================================================================" | ||
| 182 | echo "GOMODCACHE: ${GOMODCACHE}" | ||
| 183 | echo "GOPROXY: ${GOPROXY}" | ||
| 184 | echo "Source dir: ${GO_MOD_DISCOVERY_SRCDIR}" | ||
| 185 | echo "Build target: ${GO_MOD_DISCOVERY_BUILD_TARGET}" | ||
| 186 | echo "Build tags: ${TAGS:-<none>}" | ||
| 187 | echo "LDFLAGS: ${GO_MOD_DISCOVERY_LDFLAGS}" | ||
| 188 | echo "" | ||
| 189 | |||
| 190 | # Use native go binary (not cross-compiler) | ||
| 191 | GO_NATIVE="${STAGING_DIR_NATIVE}${bindir_native}/go" | ||
| 192 | |||
| 193 | # NOTE: Do NOT run go mod tidy during discovery - it can upgrade versions in go.mod | ||
| 194 | # without adding checksums to go.sum, causing version mismatches. | ||
| 195 | # The source's go.mod/go.sum should already be correct for the commit. | ||
| 196 | # echo "Running: go mod tidy" | ||
| 197 | # ${GO_NATIVE} mod tidy | ||
| 198 | # ${GO_NATIVE} mod download # If tidy is re-enabled, this ensures go.sum gets all checksums | ||
| 199 | |||
| 200 | echo "" | ||
| 201 | echo "Running: go build (to discover all modules)..." | ||
| 202 | |||
| 203 | # Build to discover ALL modules that would be used at compile time | ||
| 204 | # This is better than 'go mod download' because it handles build tags correctly | ||
| 205 | BUILD_CMD="${GO_NATIVE} build -v -trimpath" | ||
| 206 | if [ -n "${TAGS}" ]; then | ||
| 207 | BUILD_CMD="${BUILD_CMD} -tags \"${TAGS}\"" | ||
| 208 | fi | ||
| 209 | BUILD_CMD="${BUILD_CMD} -ldflags \"${GO_MOD_DISCOVERY_LDFLAGS}\"" | ||
| 210 | BUILD_CMD="${BUILD_CMD} -o \"${GO_MOD_DISCOVERY_OUTPUT}\" ${GO_MOD_DISCOVERY_BUILD_TARGET}" | ||
| 211 | |||
| 212 | echo "Executing: ${BUILD_CMD}" | ||
| 213 | eval ${BUILD_CMD} | ||
| 214 | |||
| 215 | echo "" | ||
| 216 | echo "Fetching ALL modules referenced in go.sum..." | ||
| 217 | # go build downloads .zip files but not always .info files | ||
| 218 | # We need .info files for VCS metadata (Origin.URL, Origin.Hash) | ||
| 219 | # Extract unique module@version pairs from go.sum and download each | ||
| 220 | # go.sum format: "module version/go.mod hash" or "module version hash" | ||
| 221 | # | ||
| 222 | # IMPORTANT: We must download ALL versions, including /go.mod-only entries! | ||
| 223 | # When GOPROXY=off during compile, Go may need these for dependency resolution. | ||
| 224 | # Strip the /go.mod suffix to get the base version, then download it. | ||
| 225 | awk '{gsub(/\/go\.mod$/, "", $2); print $1 "@" $2}' go.sum | sort -u | while read modver; do | ||
| 226 | ${GO_NATIVE} mod download "$modver" 2>/dev/null || true | ||
| 227 | done | ||
| 228 | |||
| 229 | # Download ALL modules in the complete dependency graph. | ||
| 230 | # The go.sum loop above only gets direct dependencies. Replace directives | ||
| 231 | # can introduce transitive deps that aren't in go.sum but are needed at | ||
| 232 | # compile time when GOPROXY=off. `go mod download all` resolves and | ||
| 233 | # downloads the entire module graph, including transitive dependencies. | ||
| 234 | echo "" | ||
| 235 | echo "Downloading complete module graph (including transitive deps)..." | ||
| 236 | ${GO_NATIVE} mod download all 2>&1 || echo "Warning: some modules may have failed to download" | ||
| 237 | |||
| 238 | # Additionally scan for any modules that go build downloaded but don't have .info | ||
| 239 | # This ensures we capture everything that was fetched dynamically | ||
| 240 | echo "" | ||
| 241 | echo "Ensuring .info files for all cached modules..." | ||
| 242 | find "${GOMODCACHE}/cache/download" -name "*.zip" 2>/dev/null | while read zipfile; do | ||
| 243 | # Extract module@version from path like: .../module/@v/version.zip | ||
| 244 | version=$(basename "$zipfile" .zip) | ||
| 245 | moddir=$(dirname "$zipfile") | ||
| 246 | infofile="${moddir}/${version}.info" | ||
| 247 | if [ ! -f "$infofile" ]; then | ||
| 248 | # Reconstruct module path from directory structure | ||
| 249 | # cache/download/github.com/foo/bar/@v/v1.0.0.zip -> github.com/foo/bar@v1.0.0 | ||
| 250 | modpath=$(echo "$moddir" | sed "s|${GOMODCACHE}/cache/download/||" | sed 's|/@v$||') | ||
| 251 | echo " Fetching .info for: ${modpath}@${version}" | ||
| 252 | ${GO_NATIVE} mod download "${modpath}@${version}" 2>/dev/null || true | ||
| 253 | fi | ||
| 254 | done | ||
| 255 | |||
| 256 | # Download transitive deps of REPLACED modules. | ||
| 257 | # Replace directives can point to older versions whose deps aren't in the MVS | ||
| 258 | # graph. At compile time with GOPROXY=off, Go validates the replaced version's | ||
| 259 | # go.mod. We parse replace directives and download each replacement version, | ||
| 260 | # which fetches all its transitive dependencies. | ||
| 261 | echo "" | ||
| 262 | echo "Downloading dependencies of replaced modules..." | ||
| 263 | |||
| 264 | # Extract replace directives: "old_module => new_module new_version" | ||
| 265 | awk '/^replace \($/,/^\)$/ {if ($0 !~ /^replace|^\)/) print}' go.mod | \ | ||
| 266 | grep "=>" | while read line; do | ||
| 267 | # Parse: github.com/foo/bar => github.com/baz/qux v1.2.3 | ||
| 268 | new_module=$(echo "$line" | awk '{print $(NF-1)}') | ||
| 269 | new_version=$(echo "$line" | awk '{print $NF}') | ||
| 270 | |||
| 271 | if [ -n "$new_module" ] && [ -n "$new_version" ] && [ "$new_version" != "=>" ]; then | ||
| 272 | echo " Replace target: ${new_module}@${new_version}" | ||
| 273 | # Download this specific version - Go will fetch all its dependencies | ||
| 274 | ${GO_NATIVE} mod download "${new_module}@${new_version}" 2>/dev/null || true | ||
| 275 | fi | ||
| 276 | done | ||
| 277 | |||
| 278 | # Count modules discovered | ||
| 279 | MODULE_COUNT=$(find "${GOMODCACHE}/cache/download" -name "*.info" 2>/dev/null | wc -l) | ||
| 280 | |||
| 281 | echo "" | ||
| 282 | echo "======================================================================" | ||
| 283 | echo "DISCOVERY COMPLETE" | ||
| 284 | echo "======================================================================" | ||
| 285 | echo "Modules discovered: ${MODULE_COUNT}" | ||
| 286 | echo "Cache location: ${GOMODCACHE}" | ||
| 287 | |||
| 288 | # Extract module metadata automatically (unless skipped) | ||
| 289 | if [ "${GO_MOD_DISCOVERY_SKIP_EXTRACT}" != "1" ]; then | ||
| 290 | echo "" | ||
| 291 | echo "Extracting module metadata..." | ||
| 292 | |||
| 293 | # Find the extraction script relative to this class file | ||
| 294 | EXTRACT_SCRIPT="${COREBASE}/../meta-virtualization/scripts/extract-discovered-modules.py" | ||
| 295 | if [ ! -f "${EXTRACT_SCRIPT}" ]; then | ||
| 296 | # Try alternate location | ||
| 297 | EXTRACT_SCRIPT="$(dirname "${COREBASE}")/meta-virtualization/scripts/extract-discovered-modules.py" | ||
| 298 | fi | ||
| 299 | if [ ! -f "${EXTRACT_SCRIPT}" ]; then | ||
| 300 | # Last resort - search in layer path | ||
| 301 | for layer in ${BBLAYERS}; do | ||
| 302 | if [ -f "${layer}/scripts/extract-discovered-modules.py" ]; then | ||
| 303 | EXTRACT_SCRIPT="${layer}/scripts/extract-discovered-modules.py" | ||
| 304 | break | ||
| 305 | fi | ||
| 306 | done | ||
| 307 | fi | ||
| 308 | |||
| 309 | if [ -f "${EXTRACT_SCRIPT}" ]; then | ||
| 310 | python3 "${EXTRACT_SCRIPT}" \ | ||
| 311 | --gomodcache "${GOMODCACHE}" \ | ||
| 312 | --output "${GO_MOD_DISCOVERY_MODULES_JSON}" | ||
| 313 | EXTRACT_RC=$? | ||
| 314 | if [ $EXTRACT_RC -eq 0 ]; then | ||
| 315 | echo "" | ||
| 316 | echo "✓ Module metadata extracted to: ${GO_MOD_DISCOVERY_MODULES_JSON}" | ||
| 317 | else | ||
| 318 | bbwarn "Module extraction failed (exit code $EXTRACT_RC)" | ||
| 319 | bbwarn "You can run manually: python3 ${EXTRACT_SCRIPT} --gomodcache ${GOMODCACHE} --output ${GO_MOD_DISCOVERY_MODULES_JSON}" | ||
| 320 | EXTRACT_RC=1 # Mark as failed for generation check | ||
| 321 | fi | ||
| 322 | else | ||
| 323 | bbwarn "Could not find extract-discovered-modules.py script" | ||
| 324 | bbwarn "Run manually: extract-discovered-modules.py --gomodcache ${GOMODCACHE} --output ${GO_MOD_DISCOVERY_MODULES_JSON}" | ||
| 325 | EXTRACT_RC=1 # Mark as failed for generation check | ||
| 326 | fi | ||
| 327 | else | ||
| 328 | echo "" | ||
| 329 | echo "Skipping automatic extraction (GO_MOD_DISCOVERY_SKIP_EXTRACT=1)" | ||
| 330 | EXTRACT_RC=1 # Skip generation too if extraction skipped | ||
| 331 | fi | ||
| 332 | |||
| 333 | # Step 3: Generate recipe .inc files (unless skipped or extraction failed) | ||
| 334 | if [ "${GO_MOD_DISCOVERY_SKIP_GENERATE}" != "1" ] && [ "${EXTRACT_RC:-0}" = "0" ]; then | ||
| 335 | # Validate required git repo | ||
| 336 | if [ -z "${GO_MOD_DISCOVERY_GIT_REPO}" ]; then | ||
| 337 | bbwarn "GO_MOD_DISCOVERY_GIT_REPO not set - skipping recipe generation" | ||
| 338 | bbwarn "Set GO_MOD_DISCOVERY_GIT_REPO in your recipe to enable automatic generation" | ||
| 339 | echo "" | ||
| 340 | echo "NEXT STEP: Regenerate recipe manually:" | ||
| 341 | echo "" | ||
| 342 | echo " ./meta-virtualization/scripts/oe-go-mod-fetcher.py \\" | ||
| 343 | echo " --discovered-modules ${GO_MOD_DISCOVERY_MODULES_JSON} \\" | ||
| 344 | echo " --git-repo <your-git-repo-url> \\" | ||
| 345 | echo " --git-ref ${GO_MOD_DISCOVERY_GIT_REF} \\" | ||
| 346 | echo " --recipedir ${GO_MOD_DISCOVERY_RECIPEDIR}" | ||
| 347 | else | ||
| 348 | echo "" | ||
| 349 | echo "Generating recipe .inc files..." | ||
| 350 | |||
| 351 | # Find the fetcher script (same search as extraction script) | ||
| 352 | FETCHER_SCRIPT="${COREBASE}/../meta-virtualization/scripts/oe-go-mod-fetcher.py" | ||
| 353 | if [ ! -f "${FETCHER_SCRIPT}" ]; then | ||
| 354 | FETCHER_SCRIPT="$(dirname "${COREBASE}")/meta-virtualization/scripts/oe-go-mod-fetcher.py" | ||
| 355 | fi | ||
| 356 | if [ ! -f "${FETCHER_SCRIPT}" ]; then | ||
| 357 | for layer in ${BBLAYERS}; do | ||
| 358 | if [ -f "${layer}/scripts/oe-go-mod-fetcher.py" ]; then | ||
| 359 | FETCHER_SCRIPT="${layer}/scripts/oe-go-mod-fetcher.py" | ||
| 360 | break | ||
| 361 | fi | ||
| 362 | done | ||
| 363 | fi | ||
| 364 | |||
| 365 | if [ -f "${FETCHER_SCRIPT}" ]; then | ||
| 366 | python3 "${FETCHER_SCRIPT}" \ | ||
| 367 | --discovered-modules "${GO_MOD_DISCOVERY_MODULES_JSON}" \ | ||
| 368 | --git-repo "${GO_MOD_DISCOVERY_GIT_REPO}" \ | ||
| 369 | --git-ref "${GO_MOD_DISCOVERY_GIT_REF}" \ | ||
| 370 | --recipedir "${GO_MOD_DISCOVERY_RECIPEDIR}" | ||
| 371 | GENERATE_RC=$? | ||
| 372 | if [ $GENERATE_RC -eq 0 ]; then | ||
| 373 | echo "" | ||
| 374 | echo "✓ Recipe files regenerated in: ${GO_MOD_DISCOVERY_RECIPEDIR}" | ||
| 375 | else | ||
| 376 | bbwarn "Recipe generation failed (exit code $GENERATE_RC)" | ||
| 377 | bbwarn "Check the output above for errors" | ||
| 378 | fi | ||
| 379 | else | ||
| 380 | bbwarn "Could not find oe-go-mod-fetcher.py script" | ||
| 381 | bbwarn "Run manually: oe-go-mod-fetcher.py --discovered-modules ${GO_MOD_DISCOVERY_MODULES_JSON} --git-repo ${GO_MOD_DISCOVERY_GIT_REPO} --git-ref ${GO_MOD_DISCOVERY_GIT_REF} --recipedir ${GO_MOD_DISCOVERY_RECIPEDIR}" | ||
| 382 | fi | ||
| 383 | fi | ||
| 384 | elif [ "${GO_MOD_DISCOVERY_SKIP_GENERATE}" = "1" ]; then | ||
| 385 | echo "" | ||
| 386 | echo "Skipping automatic generation (GO_MOD_DISCOVERY_SKIP_GENERATE=1)" | ||
| 387 | echo "" | ||
| 388 | echo "NEXT STEP: Regenerate recipe manually:" | ||
| 389 | echo "" | ||
| 390 | echo " ./meta-virtualization/scripts/oe-go-mod-fetcher.py \\" | ||
| 391 | echo " --discovered-modules ${GO_MOD_DISCOVERY_MODULES_JSON} \\" | ||
| 392 | echo " --git-repo <your-git-repo-url> \\" | ||
| 393 | echo " --git-ref <your-git-ref> \\" | ||
| 394 | echo " --recipedir ${GO_MOD_DISCOVERY_RECIPEDIR}" | ||
| 395 | fi | ||
| 396 | |||
| 397 | echo "" | ||
| 398 | echo "NOTE: Cache is stored OUTSIDE WORKDIR in a persistent location." | ||
| 399 | echo " This cache survives 'bitbake ${PN} -c cleanall'!" | ||
| 400 | echo " To clean: rm -rf ${GO_MOD_DISCOVERY_DIR}" | ||
| 401 | echo "" | ||
| 402 | echo "======================================================================" | ||
| 403 | } | ||
| 404 | |||
| 405 | # Make this task manually runnable (not part of default build) | ||
| 406 | # Run after unpack and patch so source is available | ||
| 407 | addtask discover_modules after do_patch | ||
| 408 | |||
| 409 | # Task dependencies - need source unpacked and full toolchain available | ||
| 410 | # Depend on do_prepare_recipe_sysroot to get cross-compiler for CGO | ||
| 411 | do_discover_modules[depends] = "${PN}:do_prepare_recipe_sysroot" | ||
| 412 | |||
| 413 | # Enable network access for this task ONLY | ||
| 414 | do_discover_modules[network] = "1" | ||
| 415 | |||
| 416 | # Don't create stamp file - allow running multiple times | ||
| 417 | do_discover_modules[nostamp] = "1" | ||
| 418 | |||
| 419 | # Track all configuration variables for proper task hashing | ||
| 420 | do_discover_modules[vardeps] += "GO_MOD_DISCOVERY_DIR GO_MOD_DISCOVERY_SRCDIR \ | ||
| 421 | GO_MOD_DISCOVERY_BUILD_TARGET GO_MOD_DISCOVERY_BUILD_TAGS \ | ||
| 422 | GO_MOD_DISCOVERY_LDFLAGS GO_MOD_DISCOVERY_GOPATH GO_MOD_DISCOVERY_OUTPUT \ | ||
| 423 | GO_MOD_DISCOVERY_MODULES_JSON GO_MOD_DISCOVERY_SKIP_EXTRACT \ | ||
| 424 | GO_MOD_DISCOVERY_SKIP_GENERATE GO_MOD_DISCOVERY_GIT_REPO \ | ||
| 425 | GO_MOD_DISCOVERY_GIT_REF GO_MOD_DISCOVERY_RECIPEDIR" | ||
| 426 | |||
| 427 | # Task to clean the persistent discovery cache | ||
| 428 | # Usage: bitbake <recipe> -c clean_discovery | ||
| 429 | do_clean_discovery() { | ||
| 430 | if [ -d "${GO_MOD_DISCOVERY_DIR}" ]; then | ||
| 431 | echo "Removing discovery cache: ${GO_MOD_DISCOVERY_DIR}" | ||
| 432 | rm -rf "${GO_MOD_DISCOVERY_DIR}" | ||
| 433 | echo "Discovery cache removed." | ||
| 434 | else | ||
| 435 | echo "Discovery cache not found: ${GO_MOD_DISCOVERY_DIR}" | ||
| 436 | fi | ||
| 437 | } | ||
| 438 | |||
| 439 | addtask clean_discovery | ||
| 440 | do_clean_discovery[nostamp] = "1" | ||
| 441 | do_clean_discovery[vardeps] += "GO_MOD_DISCOVERY_DIR" | ||
