首页 > 其他分享 >uboot的Makefile添加c文件复制功能--Apple的学习笔记

uboot的Makefile添加c文件复制功能--Apple的学习笔记

时间:2023-10-31 20:32:51浏览次数:36  
标签:uboot Apple -- make Makefile include config arm built

一,前言

如何能快速知道哪些c被编译到boot了。通过看编译信息,通过看编译完成后的ouput文件夹中的o文件,能否直接copy这些c文件到某个文件夹中,这样搜索看代码定位比较容易。若makefile自己有全部的c路径,那么我做个脚本后处理下,copy这些路径的c即可,另外,makefile居然有复制o文件,那么我只要找到它的位置,再加一句copy c文件即可,不过这是编译过程中copy会浪费点时间。

二,Makefile复习

  1. 常用关键字含义
$<                第一个依赖文件名。
$?                所有依赖文件中比目标文件新的文件列表。
$^         目标文件在本规则中的所有依赖文件,省略了重复的依赖。
$+         目标文件在本规则中的所有依赖文件,保留了重复的依赖。
$&               目标文件在所有规则中的所有依赖文件。
  1. 关于origin语法,告诉变量从后面的参数来,也就是从command line过来
ifeq ("$(origin V)", "command line")
  KBUILD_VERBOSE = $(V)
endif

用户输入为make V=1,那么$(V)的值就是1,也就是KBUILD_VERBOSE的值是1.

  1. 关于@make中@的作用就是禁止make命令输出。 如果 V=0 的话上述命令展开就是“@ make $(build)=tools”, make 在执行的时候默认会在终 端输出命令,但是在命令前面加上“@”就不会在终端输出命令了。当 V=1 的时候 Q 就为空, 上述命令就是“make $(build)=tools”,因此在 make 执行的过程,命令会被完整的输出在终端上。
  2. 如下什么含义
$(filter-out _all sub-make $(CURDIR)/Makefile, $(MAKECMDGOALS)) _all: sub-make
	@:

filter-out是反过滤函数,语法是:uboot的Makefile添加c文件复制功能--Apple的学习笔记_ci(MAKECMDGOALS)中符合规则_all的所有字符串后,剩下的作为返回值。MAKECMDGOALS我打印出来是空,所以展开后等于,@:就是什么都不做的意思,因为_all是伪目标,所以不是真实存在,没有动作。但是过程中会去执行sub-make的依赖项。

_all: sub-make
	@:
  1. 关于4个等号的作用 "="是全部遍历完的值。 ":="是向前看,不是遍历完的值。 "?="之前已经赋值过,就忽略。 "+="追加。
  2. 有个好玩的归递调用
sub-make: FORCE
	$(Q)$(MAKE) -C $(KBUILD_OUTPUT) KBUILD_SRC=$(CURDIR) \
	-f $(CURDIR)/Makefile $(filter-out _all sub-make,$(MAKECMDGOALS))


# Leave processing to above invocation of make
skip-makefile := 1
$(info appletest1 is [${skip-makefile}])
endif # ifneq ($(KBUILD_OUTPUT),)
endif # ifeq ($(KBUILD_SRC),)
$(info appletest2 is [${skip-makefile}])
# We process the rest of the Makefile if this is the final invocation of make
ifeq ($(skip-makefile),)
$(info appletest3 is [${skip-makefile}])

我加了打印信息显示如下

make ARCH=arm CROSS_COMPILE=arm-none-eabi- O=stm -n |grep appletest
appletest1 is [1]
appletest2 is [1]
appletest2 is []
appletest3 is []

说明这个Makefile被调用了2次。关键就是在sub-make:中的-f后面跟的Makefile就包括了此文件。所以再次进行了归递调用,感觉这样设计是否很复杂。调用完还要继续调用下方的内容吗?再细看下ifeq ($(skip-makefile),)对的结尾endif # skip-makefile等于在最后一行,所以后面等于没了。也不算一个归档调用。我验证了下,内容修改如下,改成刚刚学习到的什么都不做。

sub-make: FORCE
	@:

通过命令make ARCH=arm CROSS_COMPILE=arm-none-eabi- O=stm -n V=1 >1c.txt打印的所有信息如下,等于这个Makefile直接完结了。因为第二次调用的时候KBUILD_SRC已经定义,所以skip-makefile就为空了,才导致了路径不同。

$MK_ARCH is ["arm"]
appletest1 is [1]
appletest2 is [1]
:
:
  1. 打印的make[1],make[2],make[3]是什么含义 变量MAKELEVEL的值在向下层传递时发生变化。该变量的值是字符型,它用十进制数表示层的深度。‘0’代表顶层make,‘1’代表子make,‘2’代表子-子-make,以此类推。
  2. 显示重定向 0、1、2指的是文件描述符。 0:stdin 1:stdout 2:stderr “&” &用来指明其后跟的是文件描述符 “>”则是重定向符号。 1>&2 意思是把标准输出重定向到标准错误. 2>&1 意思是把标准错误输出重定向到标准输出。直接echo xxx >&2就是把echo打印到标准输出的内容重定向到标准错误。
  3. 关于替换 INPUTS-y += $(CONFIG_BUILD_TARGET:"%"=%) 就是把CONFIG_BUILD_TARGET中格式为"任意字符",替换为任意字符,简单来说就是删除双引号。
  4. MAKECMDGOALS是一个make的特殊变量,保存了指定的目标名。若make没有指定目标则此变量为空。
  5. Make命令不带目标的情况下,就执行第一个不带点的目标。一般makefile有很多代点的伪目标,用来执行文件操作等,因为它其实没有实际要编译的target。
  6. 我用的makefile调试命令,除了用$(info $(xxx))打印条件变量,还可以用如下命令。另外makefile是全部解析完成后,再进行命令执行的,这点很重要。 make ARCH=arm CROSS_COMPILE=arm-none-eabi- O=stm V=1 >1e.txtmake ARCH=arm CROSS_COMPILE=arm-none-eabi- O=stm -qpmake ARCH=arm CROSS_COMPILE=arm-none-eabi- O=stm -tmake ARCH=arm CROSS_COMPILE=arm-none-eabi- O=stm -nmake ARCH=arm CROSS_COMPILE=arm-none-eabi- O=stm -d
  7. 如何快速看uboot。 先自己从主Makefile开始看,找到首个目标,然后找到依赖关系,此时可能遇到很对变量,这些变量的值我期望直接告诉我,一个是遇到不清楚的自己打印出来,另外一个就是一下子全部打印出来,用-qp即可 make ARCH=arm CROSS_COMPILE=arm-none-eabi- O=stm -qp >A.txt 可以不执行用-n,可以打印全路径执行顺序用V=1 make ARCH=arm CROSS_COMPILE=arm-none-eabi- O=stm -n V=1 >B.txt

比如我从all的依赖项找到如下binman_stamp的依赖项,遇到一个INPUTS-y,我需要快速知道此变量的内容,就去A.txt搜索INPUTS-y即可,也可以搜索binman_stamp:关键字,因为-pq都展开了。是不是超级快呀!

.binman_stamp: $(INPUTS-y) FORCE
ifeq ($(CONFIG_BINMAN),y)
	$(call if_changed,binman)
endif
	@touch $@

A.txt中找到的信息

.binman_stamp: checkarmreloc u-boot.srec u-boot.bin u-boot.sym System.map binary_size_check FORCE
#  Implicit rule search has not been done.
#  Last modified 2023-10-31 09:15:34.966171096
#  File has been updated.
#  Needs to be updated (-q is set).
# variable set hash-table stats:
# Load=0/32=0%, Rehash=0, Collisions=0/36=0%
#  recipe to execute (from '/work/uboot/u-boot-2023.10/Makefile', line 1123):
	@touch $@

很明显出来完成"checkarmreloc u-boot.srec u-boot.bin u-boot.sym System.map binary_size_check FORCE"这些依赖项后,最后touch一个binmain_stamp的文件。还可以继续用make ARCH=arm CROSS_COMPILE=arm-none-eabi- O=stm -t >C.txt来查看touch文件的顺序。先touch的是"include/config/uboot.release"最后是binmain_stamp文件。

  1. 我不准备按顺序全部看了,随便挑选一个,看看uboot.release是如何生成的。因为我的目的是快速看,快速看的目的是将来万一有问题可以便于定位,所以掌握方法最重要。 若要按顺序就是从第一个依赖项checkarmreloc开始继续用同样的套路来看即可。 先看主makekfile搜索关键自己uboot.release
# Store (new) UBOOTRELEASE string in include/config/uboot.release
include/config/uboot.release: include/config/auto.conf FORCE
	$(call filechk,uboot.release)

然后到A.txt中

include/config/uboot.release: include/config/auto.conf FORCE
#  Implicit rule search has not been done.
#  Implicit/static pattern stem: ''
#  Last modified 2023-10-31 09:10:57.346234441
#  File has been updated.
#  Needs to be updated (-q is set).
# automatic
# @ := include/config/uboot.release
# automatic
# % := 
# automatic
# * := 
# automatic
# + := include/config/auto.conf FORCE
# automatic
# | := 
# automatic
# < := include/config/auto.conf
# automatic
# ^ := include/config/auto.conf FORCE
# automatic
# ? := 
# variable set hash-table stats:
# Load=8/32=25%, Rehash=0, Collisions=6/35=17%
#  recipe to execute (from '/work/uboot/u-boot-2023.10/Makefile', line 1880):
	$(call filechk,uboot.release)

这里的call没有展开,那么继续在A.txt中找,里面变量没有展开

# makefile (from 'scripts/Kbuild.include', line 56)
filechk = 	$(Q)set -e; mkdir -p $(dir $@); $(filechk_$(1)) < $< > [email protected]; if [ -r $@ ] && cmp -s $@ [email protected]; then rm -f [email protected]; else $(kecho) '  UPD     $@'; mv -f [email protected] $@; fi

在V=1的B.txt找到具体信息

set -e; mkdir -p include/config/; 	echo "2023.10$(/bin/bash ../scripts/setlocalversion ..)" < include/config/auto.conf > include/config/uboot.release.tmp; if [ -r include/config/uboot.release ] && cmp -s include/config/uboot.release include/config/uboot.release.tmp; then rm -f include/config/uboot.release.tmp; else : '  UPD     include/config/uboot.release'; mv -f include/config/uboot.release.tmp include/config/uboot.release; fi

应该先找依赖项哦

include/config/auto.conf: .config include/config/auto.conf.cmd ../tools/Kconfig ../test/overlay/Kconfig ...太多了../include/linux/byteorder/little_endian.h ../include/linux/byteorder/swab.h ../include/linux/byteorder/generic.h
#  Implicit rule search has been done.
#  Implicit/static pattern stem: 'auto'
#  Last modified 2023-10-31 08:47:44.116596641
#  File has been updated.
#  Successfully updated.
#  recipe to execute (from '/work/uboot/u-boot-2023.10/Makefile', line 613):
	$(Q)$(MAKE) -f $(srctree)/Makefile syncconfig
	@# If the following part fails, include/config/auto.conf should be
	@# deleted so "make silentoldconfig" will be re-run on the next build.
	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.autoconf || \
		{ rm -f include/config/auto.conf; false; }
	@# include/config.h has been updated after "make silentoldconfig".
	@# We need to touch include/config/auto.conf so it gets newer
	@# than include/config.h.
	@# Otherwise, 'make silentoldconfig' would be invoked twice.
	$(Q)touch include/config/auto.conf

这个太多了的内容也好分析,从第一个.config就是一个文件,include/config/auto.conf.cmd是一个脚本,此脚本包括了那么多内容 但是问题来了uboot的Makefile添加c文件复制功能--Apple的学习笔记_目标文件_02(MAKE) -f $(srctree)/Makefile syncconfig中syncconfig是什么,搜索不到,于是把执行动作的3个MAKE删除依然正常跑。再看看注释这应该是关系到config配置文件更新才用到的,于是我distclean不要加-n,其它参数正常加再来一遍。 make ARCH=arm CROSS_COMPILE=arm-none-eabi- O=stm V=1 >33.txt 然后再distclean不加-q,再来一遍,目的是真实的重新编译 make ARCH=arm CROSS_COMPILE=arm-none-eabi- O=stm -p >44.txt 此时再找依赖项,就没有那么多文件了。

# Not a target:
include/config/auto.conf:
#  Implicit rule search has been done.
#  Last modified 2023-10-31 10:52:31.084670879
#  File has been updated.
#  Successfully updated.

那么应该到了执行阶段了,搜索"syncconfig:"也正常能找到

syncconfig: scripts/kconfig/conf
#  Phony target (prerequisite of .PHONY).
#  Command line target.
#  Implicit rule search has not been done.
#  Implicit/static pattern stem: ''
#  File is an intermediate prerequisite.
#  File does not exist.
#  File has been updated.
#  Successfully updated.
# automatic
# @ := syncconfig
# automatic
# % := 
# automatic
# * := 
# automatic
# + := scripts/kconfig/conf
# automatic
# | := 
# automatic
# < := scripts/kconfig/conf
# automatic
# ^ := scripts/kconfig/conf
# automatic
# ? := scripts/kconfig/conf
# variable set hash-table stats:
# Load=8/32=25%, Rehash=0, Collisions=3/136=2%
#  recipe to execute (from '../scripts/kconfig/Makefile', line 75):
	$< $(silent) --$@ $(Kconfig)

接着继续找依赖项scripts/kconfig/conf

scripts/kconfig/conf: FORCE scripts/kconfig/conf.o scripts/kconfig/zconf.tab.o
#  Implicit rule search has not been done.
#  Implicit/static pattern stem: ''
#  Last modified 2023-10-31 10:51:19.8446895
#  File has been updated.
#  Successfully updated.
# automatic
# @ := scripts/kconfig/conf
# automatic
# % := 
# automatic
# * := 
# automatic
# + := FORCE scripts/kconfig/conf.o scripts/kconfig/zconf.tab.o
# automatic
# | := 
# automatic
# < := FORCE
# automatic
# ^ := FORCE scripts/kconfig/conf.o scripts/kconfig/zconf.tab.o
# automatic
# ? := 
# variable set hash-table stats:
# Load=8/32=25%, Rehash=0, Collisions=14/131=11%
#  recipe to execute (from 'scripts/Makefile.host', line 104):
	$(call if_changed,host-cmulti)

查看if_changed,在scripts/Kbuild.include文件中找到此函数功能就是发现target更新,就重新build,调用执行Kconfig脚本命令$< uboot的Makefile添加c文件复制功能--Apple的学习笔记_搜索_03@ $(Kconfig)

# makefile (from 'scripts/Kbuild.include', line 257)
if_changed = $(if $(strip $(any-prereq) $(arg-check)), @set -e; $(echo-cmd) $(cmd_$(1)); printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)

至于Kconfig的命令我暂时也不清楚,网上搜索主要功能是根据配置文件生成关联关系用的。 根据`recipe to execute (from '../scripts/kconfig/Makefile', line 75)`可以找到没展开的源码。

simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \
	alldefconfig randconfig listnewconfig olddefconfig syncconfig
PHONY += $(simple-targets)

$(simple-targets): $(obj)/conf
	$< $(silent) --$@ $(Kconfig)

通过这个uboot的Makefile添加c文件复制功能--Apple的学习笔记_目标文件_02(MAKE) -f $(srctree)/Makefile syncconfig,也就是把目标从all改成了syncconfig来进行了Kconfig的配置关联。

  1. defconfig配置有更新比没更新V=1打印的多了前30多行,这块等于Kconfig配置文件处理,能生成关键文件touch include/config/auto.conf。它的执行东西是生成了tmp文件,最后好像把版本信息保存了。好了prepare3的依赖条件等于分析完成了。
prepare3: include/config/uboot.release
ifneq ($(KBUILD_SRC),)
	@$(kecho) '  Using $(srctree) as source for U-Boot'
	$(Q)if [ -f $(srctree)/.config -o -d $(srctree)/include/config ]; then \
		echo >&2 "  $(srctree) is not clean, please run 'make mrproper'"; \
		echo >&2 "  in the '$(srctree)' directory.";\
		/bin/false; \
	fi;
endif

KBUILD_SRC不为空,所以会继续打印信息,然后执行脚本,通过V=1的信息可以看到

: '  Using .. as source for U-Boot'
if [ -f ../.config -o -d ../include/config ]; then \
	echo >&2 "  .. is not clean, please run 'make mrproper'"; \
	echo >&2 "  in the '..' directory.";\
	/bin/false; \
fi;

prepare3目标完成了,它是prepare2的依赖条件,所以继续做prepare2的依赖条件outputmakefile prepare2: prepare3 outputmakefile cfg

outputmakefile:
ifneq ($(KBUILD_SRC),)
	$(Q)ln -fsn $(srctree) source
	$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile $(srctree)
endif

其实就是调用mkmakefile来生成include/generated/下的文件。然后就是cfg目标,这样看来我反向看真的是不方便呢,还是正向看方便,这样是我不小心选了个不太容易看的目标对象。

三,Makefile修改

  1. 回到我的主要目的,makefile稍微复习了下,然后就要干活了,我希望在vscode中仅搜索这些被编译的c内容,代表我需要修改Makefile让它编译过程把c文件也copy到o文件一起。
  2. 开始按目的,来修改makefile 快速看关键字,很明显o文件在这个依赖项中
u-boot:	$(u-boot-init) $(u-boot-main) $(u-boot-keep-syms-lto) u-boot.lds FORCE
	+$(call if_changed,u-boot__)
ifeq ($(CONFIG_KALLSYMS),y)
	$(call cmd,smap)
	$(call cmd,u-boot__) common/system_map.o
endif

如下可以看出,每个文件夹下都有一个汇总的built-in.o,这是-p展开的内容

u-boot-init := arch/arm/cpu/armv7m/start.o
u-boot-main :=  arch/arm/cpu/built-in.o  arch/arm/cpu/armv7m/built-in.o  arch/arm/lib/built-in.o  arch/arm/mach-stm32/built-in.o  board/st/common/built-in.o  board/st/stm32f429-discovery/built-in.o  boot/built-in.o  cmd/built-in.o  common/built-in.o  disk/built-in.o  drivers/built-in.o  drivers/usb/cdns3/built-in.o  drivers/usb/common/built-in.o  drivers/usb/dwc3/built-in.o  drivers/usb/emul/built-in.o  drivers/usb/eth/built-in.o  drivers/usb/host/built-in.o  drivers/usb/isp1760/built-in.o  drivers/usb/mtu3/built-in.o  drivers/usb/musb-new/built-in.o  drivers/usb/musb/built-in.o  drivers/usb/phy/built-in.o  drivers/usb/ulpi/built-in.o  dts/built-in.o  env/built-in.o  fs/built-in.o  lib/built-in.o  net/built-in.o

makefile源码的相关脚本在如下

libs-y		:= $(patsubst %/, %/built-in.o, $(libs-y))

u-boot-init := $(head-y)
u-boot-main := $(libs-y)

我知道每个文件夹的build-in必定是在这个文件夹中的o文件合成的。在-p生成的文件中搜索"built-in.o:"有很多,来自的路径都是 # recipe to execute (from '/work/uboot/u-boot-2023.10/Makefile', line 1858): 找到makefile脚本代码

$(sort $(u-boot-init) $(u-boot-main)): $(u-boot-dirs) ;
$(u-boot-dirs): prepare scripts
	$(Q)$(MAKE) $(build)=$@

接着找到prepare再接着就找到了scripts/Makefile.build里面感觉看到了关键信息

kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
include $(kbuild-file)

然后看到-p生成的信息去找kbuild-dir好多呀,每个的路径都不同,然后o文件也不同

# makefile (from '../scripts/Makefile.build', line 55)
kbuild-dir := ../disk
# makefile (from '../disk/Makefile', line 19)
obj- = part.o part_mac.o part_dos.o part_iso.o part_amiga.o part_efi.o
# makefile (from 'scripts/Kbuild.include', line 110)
as-instr = $(call try-run, printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3))
......
# makefile (from 'scripts/Makefile.lib', line 254)
cmd_ld = $(LD) $(ld_flags) $(filter-out FORCE,$^) -o $@

搜索cmd_ld无法找到调用,搜索cmd_找到了一些信息,猜测.o.cmd中c文件的信息就是这样写入的

if_changed = $(if $(strip $(any-prereq) $(arg-check)),                       \
	@set -e;                                                             \
	$(echo-cmd) $(cmd_$(1));                                             \
	printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)

我最后加了已经$(info applefile $(any-prereq))打印的信息居然都是.o,不过基本接近了。

applefile lib/libfdt/fdt.o lib/libfdt/fdt_ro.o lib/libfdt/fdt_wip.o lib/libfdt/fdt_strerror.o lib/libfdt/fdt_sw.o lib/libfdt/fdt_rw.o lib/libfdt/fdt_empty_tree.o lib/libfdt/fdt_addresses.o lib/libfdt/fdt.o lib/libfdt/fdt_ro.o lib/libfdt/fdt_wip.o lib/libfdt/fdt_strerror.o lib/libfdt/fdt_sw.o lib/libfdt/fdt_rw.o lib/libfdt/fdt_empty_tree.o lib/libfdt/fdt_addresses.o
  1. 找到了脚本的位置,我自己尝试copy c文件了 现在自己做一个目标,小而美的尝试下功能。不知道为什么用if语句不行,只能用shell,如下不会报错,且功能正常
applecp:lib/crc8.o lib/crc16.o lib/crc16-ccitt.o lib/ldiv.o lib/net_utils.o
	$(foreach name, $(filter-out %/built-in.o,$^), $(shell \
	cp -f $(KBUILD_SRC)/$(name:.o=.c) $(CURDIR)/temp \
	2>/dev/null \
	cp -f $(KBUILD_SRC)/$(name:.o=.S) $(CURDIR)/temp \
	2>/dev/null) \
	)

如下功能正常,但是会报错/bin/sh: 1: Syntax error: ";" unexpected

applecp:lib/crc8.o lib/crc16.o lib/crc16-ccitt.o lib/ldiv.o lib/net_utils.o
	$(foreach name, $(filter-out %/built-in.o,$^), \
	if [ -e $(KBUILD_SRC)/$(name:.o=.S)]; then \
		$(shell cp $(KBUILD_SRC)/$(name:.o=.S) $(CURDIR)/temp 2>/dev/null); \
	else  \
		if [ -e $(KBUILD_SRC)/$(name:.o=.c)]; then \
			$(shell cp $(KBUILD_SRC)/$(name:.o=.c) $(CURDIR)/temp 2>/dev/null); \
			/bin/false; \
		fi; \
	fi; \
	)
  1. 自己对小目标功能验证通过,那么把小功能移植到Makefile的位置即可。修改点对比,如下图

uboot的Makefile添加c文件复制功能--Apple的学习笔记_ci_05

  1. 体验一下成果,开始试用。又开了一个vscode,仅导入stm文件夹,专门用来搜索看代码的。若要修改代码,不知道具体路径可以搜索xx.o.cmd里面有具体路径,然后到另外一个大而全的vscode中按此路径找到文件来修改即可完成整个流程。
{
    // 在使用搜索功能时,将这些文件夹/文件排除在外
    "search.exclude": {
        "source/*": true,
    }, 
    // 这些文件将不会显示在工作空间中
    "files.exclude": {
        "source/*": true,
    },
}

四,小结

学以致用乐趣无穷。简单来说我不是为了学习uboot的Makefile而学习,我是为了解决问题而学习,另外目标并不是uboot而是Makefile复习,因为这个技能是通用的,又多掌握了Makefile的几种调试方法。

标签:uboot,Apple,--,make,Makefile,include,config,arm,built
From: https://blog.51cto.com/AppleCai/8113974

相关文章

  • 抖音火山版变现项目,火山视频暴利撸钱攻略
    火山小视频大家可能都知道被抖音收购了,现在教抖音火山版,但是不要觉得他被收购之后没有能赚钱的路子了,虽然不如抖音快手,但是他的赚钱能力还是很高的,毕竟市场竞争者少了那我们分到的蛋糕就多了,目前还没有几个在操作抖音火山版项目的,我们就可以利用这一块做项目,赚的真的很多课程来源 ......
  • 互联网捡钱项目,新手小白也可以玩
    简短意赅的给大家说明了项目的几种玩法和引流教程,如果大家是做全职互联网,那建议大家全部去操作一遍,如果是兼职的,那就去流量比较大的几个平台操作一下就可以,已经把盈利方式和各种定给大家清楚列举,都是一些简单暴力的行业,每天只需要发布一下即可获得收益,大部分的玩法有收入即利润,实物......
  • 拍照赚钱项目,不用露脸发布几张图文就行
    你有没有想过就用别人的成品照片,然后我们在图片上画几条竖线横线的就能赚钱,但是这期项目就是来教你如何赚这几条横线竖线的钱,我说过不止一遍了,也希望大家记住,男色女美这个赚钱密码,我们今天这期就是利用女美来赚钱,大家都知道女人钱最好赚,他们为了美可以付出任何东西,在脸上动刀子都是......
  • 钡铼技术BL304基于ARM工控机驱动智慧交通发展
    在交通运输领域,钡铼技术ARM工控机可以实现以下功能:实时监控和管理:利用钡铼技术ARM工控机,可以对交通运输中的车辆、船只、飞机等进行实时监测和管理,帮助调度员提高车辆调度和路线规划的准确性和效率。安全保障:利用钡铼技术ARM工控机,可以建立健全的交通安全预警系统,及时响应各种突发......
  • 资源倒卖项目,照做就能赚钱的玩法(附千g资源)
    今天给大家分享的这期也是虚拟项目,虽然已经讲解了很多的虚拟项目了,但是每个项目的赛道和分类都是不同的,还有一些资源也是不一样的,所以说今天给大家做的是一个我现实朋友实例,他就是依靠着几千个g的资源,各种地方去引流然后收益的,引流方式后期还会再更新,后期会出一些脚本和简版教程,让......
  • 确定已安装的PowerShell版本
    内容来自DOChttps://q.houxu6.top/?s=确定已安装的PowerShell版本我如何确定计算机上安装了哪种版本的PowerShell,以及是否确实安装了它?使用$PSVersionTable.PSVersion来确定引擎版本。如果该变量不存在,可以安全地假设引擎版本为1.0。请注意,$Host.Version和(Get-Host).Vers......
  • [Azure Developer]把Azure Function中ILogger对象静态化为静态方法提供日志记录
    问题描述在AzureFunction代码中,有默认的ILogger对象来记录函数的日志,如果函数引用了一些静态对象,是否有办法使用这个默认的ILogger对象来记录日志呢?usingSystem.Net;usingMicrosoft.Azure.Functions.Worker;usingMicrosoft.Azure.Functions.Worker.Http;usingMicrosoft......
  • 回文自动机(PAM)的简单应用
    记录回文自动机的一些应用实例​ 题目主要来源模板​ 跑\(PAM\)就是构建两棵字典树,字典树上(奇偶)根到不同节点都对应了一个原串中本质不同的回文串,同时维护了每个回文串对应的最长回文后缀。​ 这个模板定义节点\(0\)为偶根,节点\(1\)为奇根(有些板子可能反过来)\(next[i][j]\):当......
  • VMware vCenter证书过期解决方法
    注意操作前请生成快照,避免不可逆错误导致系统崩溃!!!vCenter内含各种证书,部分证书过期会导致登录webclient时,出现“获取身份认证程序时出错”(https://ip/ui),“nohealthyupstream”(https://ip)的提示,导致无法登陆,错误代码500、400。本手册介绍证书过期问题的解决方法。操作步骤......
  • 边界-不可忽视的问题
    边界,边界,还是边界在Java程序设计中,边界值处理是一个容易被忽视但极其重要的环节。尤其是当涉及到基本数据类型如int时,边界值的处理不当将会导致潜在的安全隐患和错误。本文将通过一个实际案例,详细分析int边界值不做校验的潜在危害,以及针对这一问题的改进建议。先来了解一下int数......