the code is:
# android/device/mediatek/build/core/build_dtboimage.mk
...
my_dtbo_id := 0
define mk_dtboimg_cfg
$(eval name := $$(basename $1)) \
echo "file name:$(name)"; \
$(eval dts_file_name := $(notdir $(name))) \
echo "terminal_name:$$(echo $(dts_file_name) | awk -F '_' '{print $$1}')"; \
$(eval terminal_name := $$(echo $(dts_file_name) | awk -F '_' '{print $$1}')) \
$(eval main_name := $$(echo $(dts_file_name) | awk -F '_' '{print $$3}')) \
echo "terminal_name :$(terminal_name), main_name :$(main_name )"; \
...
and the output is:
file name:out/target/product/k62v1_64_pax/obj/KERNEL_OBJ/arch/arm64/boot/dts/mediatek/A3700_MT6762_V02_V01
terminal_name:A3700
terminal_name:, main_name:
As shown above, the code echo "terminal_name:$$(echo $(dts_file_name) | awk -F '_' '{print $$1}')"; \ can get the right output of A3700, but i don't know why the output of terminal_name and main_name is null.
the right output i expect is terminal_name:A3700, main_name:V02, in other words, i hope terminal_name and main_name can correctly assigned.
What should I do to solve this problem?
thanks!
You're making this far too complicated.
Remove the unnecessary functions and be generous with $:
...
dts_file_name := $$(notdir $$(name))
terminal_name := $$(shell echo $$(dts_file_name) | awk -F '_' '{print $$$$1}')
main_name := $$(shell echo $$(dts_file_name) | awk -F '_' '{print $$$$3}')
$$(info terminal: $$(terminal_name), main: $$(main_name))
...
Related
I went through some posts, but still didn't get how it work.
My request is:
for i in *.json
do
file = `echo $i |cut -d _ -f2`
echo ${file}
# do the rest tasks
done
How to convert above script to target of Makefile?
Here is what I tried
foo:
for i in *.json; do \
$(eval FILE = $(shell echo $$i |cut -d _ -f2)); \
echo $(FILE) ;\
done
But it doesn't work
Using $(eval) or $(shell) is ... not even wrong.
foo:
for i in *.json; do \
file=$$(echo "$$i" |cut -d _ -f2); \
echo "$$file"; \
done
Notice the quoting of the filename variables, and the absence of spaces around the = assignment operator, and the doubling of any dollar sign in order to pass it through from make to the shell.
However, the shell provides a much better mechanism for this;
foo:
for i in *.json; do \
j=$${i#*_}; \
echo "$${j%%_*}"; \
done
or perhaps
foo:
printf '%s\n' *.json \
| sed 's/[^_]*_\([^_]*\)_.*/\1/'
If you only expect a single underscore, both of these can be further simplified.
Or maybe you are just looking for
makefile_variable := $(foreach x,$(wildcard *.json),$(word 2,$(subst _, ,$x)))
I'm having difficulties with makefiles.
So in a recipe, I'm making a file (with a name and a .ujc extension) in a for loop and would like to have a text file at the end which contains all the created files. Purpose is to feed it to an application.
For example, in a semi high-level example,
List= [Class1,Class2,Class3]
foreach(Class C in List) {
#do operations on C > outputs a ClassX.ujc file
# add name of file to a text file named "list_of_files"
}
At the end I should have a text file, list_of_files.txt, which contains the following string:
Class1.ujc Class2.ujc Class3.ujc
As a reference, the code I have at the moment (and which does a bit of the stuff above but does not work is) is:
pc: $(APP)
$(foreach C, $(shell echo $(CLASS) | tr ',' ' '), \
make -C BUILDENV CLASS=$(C) BUILD=just_filelist OUTPUT=filelist.txt SKIPSELF=yes && \
../classCvt/classCvt <./Applications/$(C).class> ./Applications/$(C).ujc && \
cat app_file_list.txt | xargs echo ./Applications/$(C).ujc >app_file_list.txt && \
) true
time -p ./$(APP) `cat app_file_list.txt` `cat filelist.txt`
The internal make does make a filelist which is fed to the app, but I'd also like to feed the app_file_list but its construction goes totally wrong.
Probably simple, but I'm not getting there.
Edit:
The code below does what I want:
pc: $(APP)
rm -f cat app_file_list.txt
$(foreach C, $(shell echo $(CLASS) | tr ',' ' '), \
make -C BUILDENV CLASS=$(C) BUILD=just_filelist OUTPUT=filelist.txt SKIPSELF=yes && \
../classCvt/classCvt <./Applications/$(C).class> ./Applications/$(C).ujc && \
cat app_file_list.txt | echo ./Applications/$(C).ujc >>app_file_list.txt && \
) true
time -p ./$(APP) `cat app_file_list.txt` `cat filelist.txt`
Notable mistake I made was the xargs.
(Also in the post)
The solution turned out to be not-so-difficult. I needed to remove the xargs command and do the correct operation (i.e., >> instead of >) in the 'cat app_file_list.txt | etc...' line.
The code below does what I want:
pc: $(APP)
rm -f cat app_file_list.txt
$(foreach C, $(shell echo $(CLASS) | tr ',' ' '), \
make -C BUILDENV CLASS=$(C) BUILD=just_filelist OUTPUT=filelist.txt SKIPSELF=yes && \
../classCvt/classCvt <./Applications/$(C).class> ./Applications/$(C).ujc && \
cat app_file_list.txt | echo ./Applications/$(C).ujc >>app_file_list.txt && \
) true
time -p ./$(APP) `cat app_file_list.txt` `cat filelist.txt`
Notable mistake I made was the xargs which caused strings to repeat into the .txt file.
I'm trying make Ubuntu version specific distros of my tool so I want to get the os name and version. I have the following code:
ifeq ($(OS),Windows_NT)
OS_POD+=win
else
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
OS_VERS := $(shell lsb_release -a 2>/dev/null | grep Description | awk '{ print $2 "-" $3 }')
OS_POD=./dist/linux/$(OS_VERS)
endif
ifeq ($(UNAME_S),Darwin)
OS_POD=./dist/mac
endif
endif
I use the shell one-liner:
lsb_release -a 2>/dev/null | grep Description | awk '{ print $2 "-" $3 }'
Which properly returns Ubuntu-12.04.2 outside of the Makefile, but inside it it returns nothing. That is, the OS_VERS variable is just -.
How can I fix this?
In a Makefile, $ is special. Use $$ where you want the shell to find a dollar.
OS_VERS := $(shell lsb_release -a 2>/dev/null | grep Description | awk '{ print $$2 "-" $$3 }')
You need to escape the $ inside your command.
OS_VERS:=$(shell lsb_release -a 2>/dev/null | grep Description | awk '{ print $$2 "-" $$3 }')
The following sample Makefile prints correctly so it may be a different part of your Makefile.
print:
#echo $(OS_VERS)
OS_VERS:=$(shell lsb_release -a 2>/dev/null | grep Description | awk '{ print $$2 "-" $$3 }')
OS_VERS := $(shell cat /etc/os-release | grep ^NAME | cut -d'=' -f2 | sed 's/\"//gI')
I don't know too much about scripts but I need a script that will run this command:
g++ -O0 -c fileName.cpp && nm fileName.o | egrep ' [A-Z] ' | egrep -v ' [UTV] ' | grep -v .eh > fileName.txt
for files with names 000000 - 008577. So how should my script be written?
UPD2:
I've written a script and it works:
#!/bin/bash
s1="g++ -O0 -c "
s2=".cpp && nm "
s3=".o | egrep ' [A-Z] ' | egrep -v ' [UTV] ' | grep -v .eh >> "
s4=".txt"
for ((i=0; i<=8577; i++)) do
num="$( printf '%06d' ${i})"
s="${s1}${num}${s2}${num}${s3}${num}${s4}"
eval $s
done
Try removing the spaces around the equal sign when you get to num and s.
I've written working code:
#!/bin/bash
s1="g++ -O0 -c "
s2=".cpp && nm "
s3=".o | egrep ' [A-Z] ' | egrep -v ' [UTV] ' | grep -v .eh >> "
s4=".txt"
for ((i=0; i<=8577; i++)) do
num="$( printf '%06d' ${i})"
s="${s1}${num}${s2}${num}${s3}${num}${s4}"
eval $s
done
I have this:
echo -e "\n\n"
find /home/*/var/*/logs/ \
-name transfer.log \
-exec awk -v SUM=0 '$0 {SUM+=1} END {print "{} " SUM}' {} \; \
> >( sed '/\b0\b/d' \
| awk ' BEGIN {printf "\t\t\tTRANSFER LOG\t\t\t\t\t#OF HITS\n"}
{printf "%-72s %-s\n", $1, $2}
' \
| (read -r; printf "%s\n" "$REPLY"; sort -nr -k2)
)
echo -e "\n\n"
When run on a machine with bash 4.1.2 always returns correctly except I get all 4 of my new lines at the top.
When run on a machine with bash 3.00.15 it gives all 4 of my new lines at the top, returns the prompt in the middle of the output, and never completes just hangs.
I would really like to fix this for both versions as we have a lot of machines running both.
Why make life so difficult and unintelligible? Why not simplify?
TXFRLOG=$(find /home..... transfer.log)
awk .... ${TXFRLOG}
The answer I found was to use a while read
echo -e "\n\n"; \
printf "\t\t\tTRANSFER LOG\t\t\t\t\t#OF HITS\n"; \
while read -r line; \
do echo "$line" |sed '/\b0\b/d' | awk '{printf "%-72s %-s\n", $1, $2}'; \
done < <(find /home/*/var/*/logs/ -name transfer.log -exec awk -v SUM=0 '$0 {SUM+=1} END{print "{} " SUM}' {} \;;) \
|sort -nr -k2; \
echo -e "\n\n"