This question follows
Where can I find documentation on aarch64-poky-linux-ld?
Please ignore sets of outer double-quotes. They seem necessary to get
"StackOverflow" to accept my input.
My layer is "meta-oca-so", its package is "oca" and its recipe is oca_1.2.7.bb.
I revised my "oca makefile" to fix the previous and some linker errors to do with
invalid link flags, and I'm now getting the full 29 "oca" .a libs to link together
when I do "bitbake oca". I didn't have to do any clean while changing the link
flags and redoing "bitbake oca".
Now when I do "bitbake oca", the error messages are:
~/Yocto/imx-yocto-bsp/build-wayland/tmp/work/aarch64-poky-linux/oca/1.2.7-r0/oca-1.2.7/Obj/linuxApp/Release/OcaProto
aarch64-poky-linux-ld: cannot find -lstdc++
aarch64-poky-linux-ld: cannot find -lrt
aarch64-poky-linux-ld: cannot find -lpthread
aarch64-poky-linux-ld: cannot find -ldns_sd
Focusing on "librt" and "libpthread" in this question, I added these lines to my "local.conf":
IMAGE_INSTALL_append=" librt"
TOOLCHAIN_TARGET_TASK_append=" librt"
IMAGE_INSTALL_append=" libpthread"
TOOLCHAIN_TARGET_TASK_append=" libpthread"
But it didn't clear its two link errors when I redid "bitbake oca".
When I tried the overall "bitbake imx-image-multimedia" I got these messages about "librt":
NOTE: Resolving any missing task queue dependencies
ERROR: Nothing RPROVIDES 'librt' (but /home/james/Yocto/imx-yocto-bsp/sources/meta-imx/meta-sdk/recipes-fsl/images/imx-image-multimedia.bb RDEPENDS on or otherwise requires it)
NOTE: Runtime target 'librt' is unbuildable, removing...
Missing or unbuildable dependency chain was: ['librt']
ERROR: Required build target 'imx-image-multimedia' has no buildable providers.
Missing or unbuildable dependency chain was: ['imx-image-multimedia', 'librt']
It's hard to find much info about "rt" because this two-letter combination is not statistically improbable.
Similarly, when I commented-out the two "librt" lines from "local.conf" and retried "bitbake imx-image-multimedia", I got these messages about "libpthread":
ERROR: Nothing RPROVIDES 'libpthread' (but /home/james/Yocto/imx-yocto-bsp/sources/meta-imx/meta-sdk/recipes-fsl/images/imx-image-multimedia.bb RDEPENDS on or otherwise requires it)
NOTE: Runtime target 'libpthread' is unbuildable, removing...
Missing or unbuildable dependency chain was: ['libpthread']
ERROR: Required build target 'imx-image-multimedia' has no buildable providers.
Missing or unbuildable dependency chain was: ['imx-image-multimedia', 'libpthread']
How do I obtain "librt" and "libpthread"?
Do I need to add a layer each to build them? Will there be a "dependency hell"
tree of supporting packages needed for each of them?
Here's the relevant makefile component, makeOCA.inc. There are 63 "make" files of different descriptions and at different levels in the OCA project. It's pretty long, at ~1070 lines. I snipped the sections for non-Linux systems; I'm only concerned with linuxRelease here.
# Project : OCA
# Module : Multiple components
# Description : Include file for C / CPP makefiles.
#
################################################################################
# Environment variable checking
################################################################################
#
# If one of the variables below is not set,
# calling make will result in a "missing separator" error.
#
ifeq ($(CAP_HOME),)
variable CAP_HOME is not set
else
CAP_HOME := $(patsubst %/,%,$(subst \,/,$(CAP_HOME)))
endif
################################################################################
# Variables
################################################################################
ifeq ($(NAME_MKE),)
NAME_MKE := makefileOCA
endif
ifeq ($(IGNORE_MAKE_ERRORS),Y)
PREFIX := -@
else
ifneq ($(DISPLAY_MAKE_CMDS),Y)
PREFIX := @
endif
endif
EMPTY :=
SPACE := $(EMPTY) $(EMPTY)
#
# Only set variables when the makefile is called with an actual target
# (not a phony one).
#
ifneq ($(PLATFORM),)
ifneq ($(RELEASE),)
# Project home
PRJ_HOME := $(CAP_HOME)
# Src home
SRC_HOME := $(PRJ_HOME)/Src
# Include directories
ifneq ($(USRINC),)
INCDIRS := $(subst ; ,;,$(subst \,/,.;\
$(SRC_HOME)/inc;\
$(SRC_HOME)/lib/inc;\
$(SRC_HOME)/common;\
$(SRC_HOME)/common/OCA;\
$(SRC_HOME)/common/HostInterface;\
$(SRC_HOME)/platform;\
$(SRC_HOME)/platform/common;\
$(SRC_HOME)/adamson;\
$(USRINC)))
else
INCDIRS := $(subst ; ,;,$(subst \,/,.;\
$(SRC_HOME)/inc;\
$(SRC_HOME)/lib/inc;\
$(SRC_HOME)/common;\
$(SRC_HOME)/common/OCA;\
$(SRC_HOME)/common/HostInterface;\
$(SRC_HOME)/platform;\
$(SRC_HOME)/platform/common;\
$(SRC_HOME)/adamson))
endif
# Output directories
OBJDIR := Obj
OBJINT := intermediate
OUTDIR := $(subst \,/,$(PRJ_HOME))/$(OBJDIR)/$(PLATFORM)/$(RELEASE)
ifeq ($(GINTDIR),)
GINTDIR := $(OUTDIR)/$(OBJINT)
endif
INTDIR := $(GINTDIR)/$(NAME)
# Tools
SD := CC -M -MP -march=native
SE := sed
RC :=
ifeq ($(OS),Windows_NT)
RM := erase /F
MD := mkdir
RN := ren _PATH__OLDNAME_ _NEWNAME_
RD := rd /s/q
else
RM := rm -f
MD := mkdir -p
RN := mv _PATH__OLDNAME_ _PATH__NEWNAME_
RD := rm -rf
endif
# Commands
ifeq ($(OS),Windows_NT)
IFEXIST := if exist _FILE_ _COMMAND_
IFNOTEXIST := if not exist _FILE_ _COMMAND_
else
IFEXIST := if [ -e "_FILE_" ]; then _COMMAND_; fi
IFNOTEXIST := if [ ! -e "_FILE_" ]; then _COMMAND_; fi
endif
# Other OS dependent variables
# Work around to make sure only a single backslash is set
ifeq ($(OS),Windows_NT)
PATH_SEP := $(subst \\,\,\\)
else
PATH_SEP := $(subst \\,/,/)
endif
ifeq ($(PLATFORM),winntApp)
CXXFLAGS :=
RCFLAGS := -I "$(subst ;," -I ",$(INCDIRS))"
### linuxRelease ###############################################################
ifeq ($(RELEASE),Release)
# Tools
# CC := gcc
# Determine the extensions for the target platform
OBJ_EXT := o
DEP_EXT := dep
EXE_EXT :=
LIB_EXT := a
DLL_EXT := so
# Lists
OBJS := $(patsubst %.cpp,%.$(OBJ_EXT),$(SRCS) $(LINUXSRCS))
OBJS := $(patsubst %.c,%.$(OBJ_EXT),$(OBJS))
DEPS := $(patsubst %.$(OBJ_EXT),%.$(DEP_EXT),$(OBJS))
LIBS := $(LIBS) $(LINUXLIBS) $(EXTERNAL_LIBS)
LIBS := $(addsuffix .$(LIB_EXT), $(LIBS))
LIBS := $(addprefix $(OUTDIR)/, $(LIBS))
SDFLAGS := -O2 -nostdlib -fno-strict-aliasing -ffunction-sections -fdata-sections -c -Wall -Wno-unknown-pragmas -x none \
-I"$(subst ;," -I",$(INCDIRS))" \
-D"NDEBUG" -DTARGET_LINUX -D"CPPUNIT_TUI_VERSION" -D"__STDC_FORMAT_MACROS" \
$(foreach USRDEF,$(USRDEFS),-D"$(USRDEF)") \
$(foreach USRUNDEF,$(USRUNDEFS),-U"$(USRUNDEF)")
SDCFLAGS :=
SDCPPFLAGS := -std=c++0x
CCFLAGS = $(SDFLAGS) -fexceptions -fvisibility=hidden -march=armv8-a -mtune=cortex-a53 -o $(INTDIR)/$@
# That's for Linaro and the Snapdragon410 (Qualcomm APQ8016) processor; next is for Ubuntu 18.04.1
# CCFLAGS = $(SDFLAGS) -fexceptions -fvisibility=hidden -m64 -mtune=generic -o $(INTDIR)/$@
CXXFLAGS := -std=gnu++0x
ifeq ($(TYPE),EXE)
OUT_EXT := $(EXE_EXT)
# LD := gcc
LD := aarch64-poky-linux-ld
# LDFLAGS = -Wl,--gc-sections -fno-keep-static-consts -fexceptions -march=armv8-a -maarch64linux -L$(OUTDIR) -o$@
# Use the above -Wl when using gcc. When using ld directly, it doesn't take -Wl. aarch64-poky-linux-ld doesn't have the -f options.
LDFLAGS = --gc-sections -march=armv8-a -maarch64linux -L$(OUTDIR) -o$@
# That's for Linaro and the Snapdragon410 (Qualcomm APQ8016) processor; next is for Ubuntu 18.04.1
# LDFLAGS = -Wl,--gc-sections -fno-keep-static-consts -fexceptions -m64 -mtune=x86-64 -L$(OUTDIR) -o$@
LINUXSYSTEMLIBS := -lstdc++ -lrt -lpthread $(addprefix -l, $(LINUXSYSTEMLIBS))
endif
ifeq ($(TYPE),LIB)
OUT_EXT := $(LIB_EXT)
# LD := ar
LDFLAGS = crus $@
endif
ifeq ($(TYPE),DLL)
OUT_EXT := $(DLL_EXT)
# LD := gcc
LD := aarch64-poky-linux-ld
# LDFLAGS = -Wl,--gc-sections -export-dynamic -fno-keep-static-consts -fexceptions -march=armv8-a -maarch64linux -L$(OUTDIR) -o$@
# Use the above -Wl when using gcc. When using ld directly, it doesn't take -Wl. aarch64-poky-linux-ld doesn't have the -f options.
LDFLAGS = --gc-sections -export-dynamic -march=armv8-a -maarch64linux -L$(OUTDIR) -o$@
# That's for Linaro and the Snapdragon410 (Qualcomm APQ8016) processor; next is for Ubuntu 18.04.1
# LDFLAGS = -Wl,--gc-sections -export-dynamic -fno-keep-static-consts -fexceptions -m64 -mtune=x86-64 -L$(OUTDIR) -o$@
LINUXSYSTEMLIBS := -lstdc++ -lrt -lpthread $(addprefix -l, $(LINUXSYSTEMLIBS))
endif
endif
endif #ifeq ($(PLATFORM),linuxApp)
endif #ifneq ($(RELEASE),)
endif #ifneq ($(PLATFORM),)
################################################################################
# Phony target specification
################################################################################
.PHONY: goal all clean phonyclean $(NAME)\
winntDebug winntRelease \
winntDebug64 winntRelease64 \
winntDebugClean winntReleaseClean \
winntDebug64Clean winntRelease64Clean \
linuxDebug linuxRelease \
linuxDebugClean linuxReleaseClean
################################################################################
# Targets
################################################################################
goal: winntDebug winntRelease
all: winntDebug winntRelease \
winntDebug64 winntRelease64
clean: winntDebugClean winntReleaseClean \
winntDebug64Clean winntRelease64Clean
linuxRelease:
ifneq (,$(findstring linux,$(TARGETS)))
$(PREFIX)$(MAKE) -f $(NAME_MKE) $(NAME) --no-print-directory PLATFORM=linuxApp RELEASE=Release
else
$(PREFIX)echo $@ not configured for $(NAME)
endif
linuxReleaseClean:
ifneq (,$(findstring linux,$(TARGETS)))
$(PREFIX)$(MAKE) -f $(NAME_MKE) phonyclean --no-print-directory PLATFORM=linuxApp RELEASE=Release CLEAN=Yes
else
$(PREFIX)echo linuxRelease not configured for $(NAME)
endif
### Dependency files ###########################################################
$(INTDIR)/%.$(DEP_EXT) : %.c
$(PREFIX)echo $(@F)
$(PREFIX)$(subst _FILE_,$(subst /,$(PATH_SEP),$@),$(subst _COMMAND_,$(RM) $(subst /,$(PATH_SEP),$@),$(IFEXIST)))
$(PREFIX)$(subst _FILE_,$(subst /,$(PATH_SEP),$@.tmp),$(subst _COMMAND_,$(RM) $(subst /,$(PATH_SEP),$@.tmp),$(IFEXIST)))
$(PREFIX)$(subst _FILE_,$(subst /,$(PATH_SEP),$(GINTDIR)),$(subst _COMMAND_,$(MD) $(subst /,$(PATH_SEP),$(GINTDIR)),$(IFNOTEXIST)))
$(PREFIX)$(subst _FILE_,$(subst /,$(PATH_SEP),$(INTDIR)),$(subst _COMMAND_,$(MD) $(subst /,$(PATH_SEP),$(INTDIR)),$(IFNOTEXIST)))
#
# Do not use (OBJ_EXT) in the SED command, since all dependencies are generated with gcc.
# Use .o instead
#
$(PREFIX)$(SD) $(SDCFLAGS) $(SDFLAGS) $< | $(SE) "s/$*.o:/$*.$(OBJ_EXT) $(subst /,\/,$@):/" > $(subst /,$(PATH_SEP),$@.tmp)
$(PREFIX)$(subst _PATH_,$(subst /,$(PATH_SEP),$(INTDIR)/),$(subst _OLDNAME_,$(@F).tmp,$(subst _NEWNAME_,$(@F),$(RN))))
$(INTDIR)/%.$(DEP_EXT) : %.cpp
$(PREFIX)echo $(@F)
$(PREFIX)$(subst _FILE_,$(subst /,$(PATH_SEP),$@),$(subst _COMMAND_,$(RM) $(subst /,$(PATH_SEP),$@),$(IFEXIST)))
$(PREFIX)$(subst _FILE_,$(subst /,$(PATH_SEP),$@.tmp),$(subst _COMMAND_,$(RM) $(subst /,$(PATH_SEP),$@.tmp),$(IFEXIST)))
$(PREFIX)$(subst _FILE_,$(subst /,$(PATH_SEP),$(GINTDIR)),$(subst _COMMAND_,$(MD) $(subst /,$(PATH_SEP),$(GINTDIR)),$(IFNOTEXIST)))
$(PREFIX)$(subst _FILE_,$(subst /,$(PATH_SEP),$(INTDIR)),$(subst _COMMAND_,$(MD) $(subst /,$(PATH_SEP),$(INTDIR)),$(IFNOTEXIST)))
#
# Do not use (OBJ_EXT) in the SED command, since all dependencies are generated with gcc.
# Use .o instead
#
$(PREFIX)$(SD) $(SDCPPFLAGS) $(SDFLAGS) $< | $(SE) "s/$*.o:/$*.$(OBJ_EXT) $(subst /,\/,$@):/" > $(subst /,$(PATH_SEP),$@.tmp)
$(PREFIX)$(subst _PATH_,$(subst /,$(PATH_SEP),$(INTDIR)/),$(subst _OLDNAME_,$(@F).tmp,$(subst _NEWNAME_,$(@F),$(RN))))
### Object files ###############################################################
%.$(OBJ_EXT) : %.asm
$(PREFIX)echo $(@F)
$(PREFIX)$(AS) $(ASFLAGS) $<
%.$(OBJ_EXT) : %.S
$(PREFIX)echo $(@F)
$(PREFIX)$(AS) $(ASFLAGS) $<
%.$(RES_EXT) : %.rc
$(PREFIX)echo $(@F)
$(PREFIX)"$(RC)" $(RCFLAGS) -fo "$(INTDIR)/$(@F)" $<
%.$(OBJ_EXT) : %.c $(TOOL_DEPS)
ifneq ($(CC),cl.exe)
$(PREFIX)echo $(@F)
endif
$(PREFIX)$(subst _FILE_,$(subst /,$(PATH_SEP),$(INTDIR)/$@),$(subst _COMMAND_,$(RM) $(subst /,$(PATH_SEP),$(INTDIR)/$@),$(IFEXIST)))
$(PREFIX)$(subst _FILE_,$(subst /,$(PATH_SEP),$(INTDIR)),$(subst _COMMAND_,$(MD) $(subst /,$(PATH_SEP),$(INTDIR)),$(IFNOTEXIST)))
$(PREFIX)$(CC) $(CCFLAGS) $<
%.$(OBJ_EXT) : %.cpp $(TOOL_DEPS)
ifneq ($(CC),cl.exe)
$(PREFIX)echo $(@F)
endif
$(PREFIX)$(subst _FILE_,$(subst /,$(PATH_SEP),$(INTDIR)/$@),$(subst _COMMAND_,$(RM) $(subst /,$(PATH_SEP),$(INTDIR)/$@),$(IFEXIST)))
$(PREFIX)$(subst _FILE_,$(subst /,$(PATH_SEP),$(INTDIR)),$(subst _COMMAND_,$(MD) $(subst /,$(PATH_SEP),$(INTDIR)),$(IFNOTEXIST)))
$(PREFIX)$(CC) $(CCFLAGS) $(CXXFLAGS) $<
### Output file ################################################################
$(NAME): $(OUTFILE) $(BINFILE)
$(OUTFILE): $(INTDIR)/$(NAME).x $(OBJS) $(LIBS) $(NAME_MKE)
$(PREFIX)echo $@
$(PREFIX)$(subst _FILE_,$@,$(subst _COMMAND_,$(RM) $@,$(IFEXIST)))
$(PREFIX)$(subst _FILE_,$(subst /,$(PATH_SEP),$(OUTDIR)),$(subst _COMMAND_,$(MD) $(subst /,$(PATH_SEP),$(OUTDIR)),$(IFNOTEXIST)))
ifneq (,$(findstring $(OBJINT),$(OBJS)))
$(foreach obj,$(OBJS),$(shell echo $(obj) >> $(LSTFILE)))
else
$(foreach obj,$(OBJS),$(shell echo $(subst /,$(PATH_SEP),$(INTDIR)/$(obj)) >> $(LSTFILE)))
endif
ifneq (,$(filter $(PLATFORM),linuxApp))
ifeq ($(TYPE),LIB)
$(PREFIX)ar $(LDFLAGS) @$(LSTFILE) $(LIBS) $(LINUXSYSTEMLIBS)
else
ifeq ($(TYPE),EXE)
$(PREFIX)aarch64-poky-linux-ld $(LDFLAGS) @$(LSTFILE) $(LIBS) $(LINUXSYSTEMLIBS)
else
ifeq ($(TYPE),DLL)
$(PREFIX)aarch64-poky-linux-ld $(LDFLAGS) @$(LSTFILE) $(LIBS) $(LINUXSYSTEMLIBS)
else
$(PREFIX)LD $(LDFLAGS) @$(LSTFILE) $(LIBS) $(LINUXSYSTEMLIBS)
endif
endif
endif
else
ifeq ($(PLATFORM),winntApp)
$(PREFIX)$(LD) $(LDFLAGS) @$(LSTFILE) $(WINNTSYSTEMLIBS)
else
$(PREFIX)$(LD) $(LDFLAGS) @$(LSTFILE)
endif
endif
$(PREFIX)$(subst _FILE_,$(LSTFILE),$(subst _COMMAND_,$(RM) $(LSTFILE),$(IFEXIST)))
$(BINFILE): $(OUTFILE)
$(PREFIX)echo $@
$(PREFIX)$(B2B) $(B2BFLAGS) $(OUTFILE) $(BINFILE)
$(INTDIR)/$(NAME).x:
$(PREFIX)$(subst _FILE_,$(subst /,$(PATH_SEP),$(INTDIR)),$(subst _COMMAND_,$(MD) $(subst /,$(PATH_SEP),$(INTDIR)),$(IFNOTEXIST)))
$(PREFIX)echo Checkpoint file for component $(NAME) > $(subst /,$(PATH_SEP),$@)
### Clean ######################################################################
phonyclean:
ifneq ($(PLATFORM),)
ifneq ($(RELEASE),)
$(PREFIX)$(subst _FILE_,$(subst /,$(PATH_SEP),$(INTDIR)),$(subst _COMMAND_,$(RD) $(subst /,$(PATH_SEP),$(INTDIR)),$(IFEXIST)))
$(PREFIX)$(subst _FILE_,$(patsubst %.$(OUT_EXT),%.pdb,$(OUTFILE)),$(subst _COMMAND_,$(RM) $(patsubst %.$(OUT_EXT),%.pdb,$(OUTFILE)),$(IFEXIST)))
$(PREFIX)$(subst _FILE_,$(patsubst %.$(OUT_EXT),%.map,$(OUTFILE)),$(subst _COMMAND_,$(RM) $(patsubst %.$(OUT_EXT),%.map,$(OUTFILE)),$(IFEXIST)))
$(PREFIX)$(subst _FILE_,$(patsubst %.$(OUT_EXT),%.dat,$(OUTFILE)),$(subst _COMMAND_,$(RM) $(patsubst %.$(OUT_EXT),%.dat,$(OUTFILE)),$(IFEXIST)))
$(PREFIX)$(subst _FILE_,$(patsubst %.$(OUT_EXT),%.exp,$(OUTFILE)),$(subst _COMMAND_,$(RM) $(patsubst %.$(OUT_EXT),%.exp,$(OUTFILE)),$(IFEXIST)))
$(PREFIX)$(subst _FILE_,$(patsubst %.$(OUT_EXT),%.lib,$(OUTFILE)),$(subst _COMMAND_,$(RM) $(patsubst %.$(OUT_EXT),%.lib,$(OUTFILE)),$(IFEXIST)))
$(PREFIX)$(subst _FILE_,$(patsubst %.$(OUT_EXT),%.err,$(OUTFILE)),$(subst _COMMAND_,$(RM) $(patsubst %.$(OUT_EXT),%.err,$(OUTFILE)),$(IFEXIST)))
$(PREFIX)$(subst _FILE_,$(OUTFILE),$(subst _COMMAND_,$(RM) $(OUTFILE),$(IFEXIST)))
else
$(PREFIX)echo Target $@ should not be used from command line
endif
else
$(PREFIX)echo Target $@ should not be used from command line
endif
################################################################################
# Include dependency files
################################################################################
ifneq ($(PLATFORM),)
ifneq ($(RELEASE),)
#
# If cleaning, we must not include dependency files.
# Otherwise they will be created before cleaning.
#
ifeq ($(CLEAN),)
ifeq (,$(findstring $(OBJINT),$(OBJS)))
#
# Use a - in front of the include, otherwise make will complain
# when it is ran the first time (when there are no .dep files).
#
-include $(patsubst %.$(DEP_EXT),$(INTDIR)/%.$(DEP_EXT),$(DEPS))
endif
endif
endif
endif
Could someone point me at a simple example of a complete Yocto layer including makefile and simple code that cross-compiles? It seems difficult for me to find, especially the makefile that supports being used in cross-compilation.
An important realization is where the documentation is about the path variables and other settings for the CFLAGS and LDFLAGS: with all variables in the Yocto mega-manual, in "Chapter 33. Variables Glossary", https://www.yoctoproject.org/docs/3.0/mega-manual/mega-manual.html#ref-variables-glos