This failure appears late—during packaging—but the mistake usually happened much earlier at the final linker command. That timing sends people into the recipe’s do_install() function even though copying the file is not what removed its GNU hash table.
What the error is saying
ERROR: example-1.0-r0 do_package_qa: QA Issue:
No GNU_HASH in the ELF binary:
'/usr/bin/example' [ldflags]
ERROR: QA run found fatal errors.Read the bracketed check first
[ldflags]names the OpenEmbedded package QA test that failed.The path is inside the package staging area, not necessarily the original build location.
The ELF may still run; the failure proves it did not follow the distribution’s expected link policy.
Changing
FILESonly moves ownership between packages and does not relink the binary.
Inspect the ELF and the captured link command
readelf -S path/to/example | grep -E '.(gnu.)?hash'
readelf -d path/to/example | grep -E 'GNU_HASH|HASH'
grep -n -- '--hash-style|LDFLAGS' tmp/work/*/*/temp/log.do_compile[ 5] .gnu.hash GNU_HASH
0x000000006ffffef5 (GNU_HASH)Three pieces of evidence, not one guess
.gnu.hashandDT_GNU_HASHshow that the GNU hash table reached the final ELF.A
.hashsection orDT_HASHentry is the older System V hash and does not satisfy a GNU-hash expectation by itself.log.do_compilereveals the command BitBake actually ran; exported variables are useless if the Makefile omits them.Use the exact failing file from
${WORKDIR}/packages-splitwhen confirming the packaged result.
Best fix: repair the build system
example: main.o helper.o
$(CC) $(CFLAGS) $(CPPFLAGS) main.o helper.o $(LDFLAGS) $(LDLIBS) -o $@
main.o: main.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@Pass compiler flags while compiling and linker flags only on the final link.
Why placement matters
$(CC)is normally the correct driver for linking C objects because it supplies the target sysroot and runtime components.LDFLAGSbelongs on the link invocation; adding it only while compiling.cto.ocannot alter the final ELF.LDLIBScarries libraries and generally follows the object files so link-order rules work.Do not replace Yocto-provided flags with a private value; append project-specific options when necessary.
Recipe-level workaround for a stubborn Makefile
EXTRA_OEMAKE += "CC='${CC}' CFLAGS='${CFLAGS}' LDFLAGS='${LDFLAGS}'"
# Documented fallback for build systems that use CC but discard LDFLAGS:
TARGET_CC_ARCH:append = " ${LDFLAGS}"Prefer explicit variables; retain TARGET_CC_ARCH only for legacy build systems that ignore LDFLAGS.
Use the fallback with eyes open
EXTRA_OEMAKEpasses the cross compiler and policy flags intooe_runmake.Modern override syntax uses
:append; older Yocto branches used_append.Appending linker flags to
TARGET_CC_ARCHworks because that variable reaches compiler invocations, but it mixes two concepts and is a compatibility workaround.A Makefile patch is clearer and remains correct outside one recipe.
Clean only enough to force relinking
bitbake -c clean example
bitbake example
bitbake -c package_qa -f exampleNOTE: Tasks Summary: Attempted ... tasks ... all succeeded.Risk level: caution. Review the command before running it.
What this rebuild proves
cleanremoves recipe outputs so an old ELF cannot survive the Makefile change.The normal build recreates and packages the artifact under the target toolchain.
Forcing
package_qareruns the relevant gate; inspect its log rather than trusting a successful compile alone.This affects one recipe, unlike
cleansstate, which also discards shared-state output and is usually unnecessary.
Prebuilt vendor binaries are a different case
A recipe cannot add a missing dynamic hash table by setting LDFLAGS after a binary has already been linked. Ask the vendor for a binary built with the target distribution’s toolchain and ABI. If replacement is impossible, test the binary on the exact image and document why accepting the exception is safer than pretending it was rebuilt.
# Vendor supplies this ELF without rebuildable source.
# Verified on MACHINE targets listed in the layer README.
INSANE_SKIP:${PN} += "ldflags"A narrow last-resort exception for the runtime package.
An exception is not a repair
INSANE_SKIPdisables only named checks for the selected output package.${PN}is the main package; use the actual package name when the file lands in a subpackage.The older underscore form,
INSANE_SKIP_${PN}, is for historical BitBake releases.Never remove
ldflagsglobally fromERROR_QA; that hides newly introduced build regressions across the image.
Why common attempts fail
Adding LDFLAGS only to the recipe: the upstream build can ignore the environment.
Editing do_install: installation copies the already-linked ELF.
Changing FILES: package assignment changes, binary contents do not.
Using HOST_LDFLAGS: host-tool flags are not target executable flags.
Skipping the wrong package: the QA message applies to the package that owns the file.
Keeping stale work output: the repaired link command never runs until the ELF is rebuilt.
References
Yocto QA checks explains the ldflags failure and documented workaround.
Yocto variable glossary defines
TARGET_CC_ARCHand its compatibility use with LDFLAGS.Current Yocto manual documents scoped
INSANE_SKIPsyntax.
Comments and corrections