linux - 如何将 librt 和 libpthread 链接到 Yocto 中的新层?
问题描述
这个问题跟
在哪里可以找到关于 aarch64-poky-linux-ld 的文档?
请忽略外部双引号集。他们似乎有必要让“StackOverflow”接受我的输入。
我的层是“meta-oca-so”,它的包是“oca”,它的配方是 oca_1.2.7.bb。
我修改了我的“oca makefile”以修复之前的和一些与无效链接标志有关的链接器错误,现在当我执行“bitbake oca”时,我可以将完整的 29 个“oca”.a 库链接在一起。在更改链接标志和重做“bitbake oca”时,我不必做任何清理工作。
现在,当我执行“bitbake oca”时,错误消息是:
~/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
在这个问题中关注“librt”和“libpthread”,我将这些行添加到我的“local.conf”中:
IMAGE_INSTALL_append=" librt"
TOOLCHAIN_TARGET_TASK_append=" librt"
IMAGE_INSTALL_append=" libpthread"
TOOLCHAIN_TARGET_TASK_append=" libpthread"
但是当我重做“bitbake oca”时,它并没有清除它的两个链接错误。
当我尝试整体“bitbake imx-image-multimedia”时,我收到了关于“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']
很难找到关于“rt”的很多信息,因为这个两个字母的组合在统计上并非不可能。
同样,当我从“local.conf”中注释掉两个“librt”行并重试“bitbake imx-image-multimedia”时,我收到了关于“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']
如何获得“librt”和“libpthread”?
我需要每个添加一个图层来构建它们吗?每个人都需要支持包的“依赖地狱”树吗?
这是相关的makefile 组件makeOCA.inc。OCA项目中有63个不同描述、不同级别的“make”文件。它很长,大约 1070 行。我剪掉了非 Linux 系统的部分;我只关心这里的 linuxRelease。
# 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
有人可以指出一个完整的 Yocto 层的简单示例,包括生成文件和交叉编译的简单代码吗?对我来说似乎很难找到,尤其是支持在交叉编译中使用的makefile。
一个重要的认识是文档是关于 CFLAGS 和 LDFLAGS 的路径变量和其他设置的:在 Yocto 大型手册中的所有变量,在“第 33 章。变量词汇表”,https://www.yoctoproject.org/ docs/3.0/mega-manual/mega-manual.html#ref-variables-glos
解决方案
Yocto 依赖概念
首先,您似乎在 Yocto 中混合了各种依赖概念:
IMAGE_INSTALL
是一个图像依赖项,告诉 Yocto 参数中的配方必须安装在最终图像中。它应该放在图像配方中,而不是包装配方中。我不认为将它添加到包配方中会告诉 Yocto 将此依赖项添加到配方的暂存目录中。RDEPENDS
在包配方中使用,并告诉 Yocto 配方取决于运行时参数中的包。然后,如果您安装需要它们的包,它将在最终映像中安装所需的运行时依赖项。
一个基本示例是包含脚本 shell 的配方在运行时依赖于某些 shell 解释器。DEPENDS
也在包配方中使用,并告诉 Yocto 配方取决于编译时参数中的包。它将在配方的暂存目录中添加头文件和库。
话虽如此libstdc++
,libpthread
和librt
是工具链的一部分,您无需为此在配方中添加显式依赖项。它们将毫不费力地安装在暂存目录或您的配方中。
关于libdns_sd
,经过我的快速研究,这个库是由 mDNS 提供的。然后,您需要添加对它的依赖项:
DEPENDS = "mdns"
如上所述,这将在配方的暂存目录中添加头文件 *.a 和 *.so。
什么不见了 ?
一旦正确配置了依赖项,您的编译器需要知道包含和库目录在哪里,而 Makefile 中显然缺少这可能是因为您假设依赖项是主机工具链的一部分。当您直接为主机构建时,编译器知道在哪里可以找到包含(例如在 /usr/include 中搜索)和库,这使得这个过程变得非常简单。
但是,对于标准交叉编译项目,在 Yocto 中,头文件和库位于其他位置,您需要在 Makefile 中正确指定。
在 Yocto 中管理 Makefile 项目有多种可能性,但在所有情况下,您都需要一个可以接收变量(CFLAGS、LDFLAGS 等)或可选参数的 Makefile,以便在从您的配方调用时传递给编译器/链接器。
由于您不提供 Yocto 食谱,我将举例说明如何完成并提出一些建议。此外,我专注于编译方面,该示例并不完整,可能应该适用于其他构建步骤(如安装)。
DEPENDS += "my-extralib"
# Change eventually the default source directory
S = "${WORKDIR}/git"
EXTRA_OEMAKE = " 'CC=${CC}' \
'CFLAGS=${CFLAGS} ${TARGET_CC_ARCH} -I${S}/inc -I${STAGING_DIR_TARGET}${includedir}/my-extralib-include' \
'LDFLAGS=-lrt -lpthread -lm -lmy-extralib -L${STAGING_DIR_TARGET}${libdir}/my-extralib-libdir' \
'BUILDDIR=${S}' \
'OTHER_DEFINE=${OTHER_YOCTO_VAR}' \
"
使用 EXTRA_OEMAKE 可以让 Yocto 自动为您完成许多任务,例如配置、编译和安装。如果你想覆盖它们,这也是可能的:
do_compile() {
# modify the Makefile on the fly as an example
cp ${S}/Makefile.orig ${S}/Makefile
sed -i -e 's:= $(LDFLAGS):?= $(LDFLAGS):' ${S}/Makefile
oe_runmake SOME_OVERRIDE='some-override'
}
您还可以禁用可能未在您的情况下使用的配置步骤:
do_configure[noexec] = "1"
一些技巧
- 如果你从 Yocto 开始,有很多东西要学,而且一开始很难找到如何管理所有可能性和选项。我强烈建议您从一个简单的 Makefile 和最少的源文件开始,以专注于 Yocto 方面。
- 您可以在网络上找到很多食谱示例(还有 Yocto、Poky 基础食谱),这些示例可能与您正在努力实现的目标很接近。Yocto 的文档确实很完整,但它更像是一个基础参考。具体的实现可以在现有的配方中找到。
- 配方构建目录中的临时目录是一个金矿,其中包含不同构建步骤的所有脚本和日志。这是您创建食谱时首先要看的地方。
推荐阅读
- ios - AVPlayer 无法正常工作
- angular - 如何解决 Angular 8 解析器中的“NullInjectorError:StaticInjectorError”
- docusignapi - 有没有办法修复这个 cURL SSL 错误?
- javascript - 如何从 MySQL DB 渲染(反应)图像?
- python - 如何在不使用括号的情况下调用 Python 部分?
- cloudinary - 总是出错:在签名上传 Cloudinary Widget 时上传签名错误
- java - 使用单独的线程池而不是公共池有什么缺点吗?
- matplotlib - 如何从列表列表中为直方图设置动画
- postgresql - 解决死锁:并发事务调用存储函数插入/更新表
- css - 多次调用 StyleSheet.create 会影响性能吗?