Makefile error:127 - automake

I compiled the source code with the Makefile, I got Makefile Error:
/bin/sh: line 8: : command not found
make: *** [lib_build] Error 127
My lib_build target is as below:
lib_build:
#echo "--------------------------------------------------------------------";
#echo "VZW Compiling DM Agent 3rd party and native Libraries..." ;
#echo "--------------------------------------------------------------------";
mkdir -p $(VZW_LIB_DIR) ; \
mkdir -p $(VZW_BIN_DIR) ; \
mkdir -p $(VZW_SCR_DIR) ; \
mkdir -p $(VZW_CFG_DIR) ; \
mkdir -p $(VZW_OBJ_DIR) ; \
mkdir -p $(VZW_LOG_DIR) ; \
cd $(VZW_BASE_DIR)/lib/ ; \
make all ; \
cd $(VZW_SYNCML_DIR)/src/bld/linux ; \
make all;
cp -r $(VZW_SYNCML_DIR)/bin/linux/libsml.so $(VZW_LIB_DIR) ;
cp -r $(VZW_SYNCML_DIR)/bin/linux/libxpt.so $(VZW_LIB_DIR) ;
cp -r $(VZW_BASE_DIR)/3rd_party/iksemel-1.4/src/.libs/* $(VZW_LIB_DIR) ;
It was working fine then I try to modify some line in the above source code and later reverted everything. Then something went wrong and I got the error. I am not able to understand what went wrong.
One more thing to add here. Is there any way to know in which line exactly in the Makefile this kind of problem is happening. If there is no way then it is very difficult to spot these kind of problems.

I would suggest restructuring the commands. As the rule is written, it ignores all errors because this is how shell works. At least prepend set -e to this sequence of shell commands.

A lot more mind-tweaking to find if any syntactical mistake is there, I found the solution that there was a space after a line in Makefile ie. after the "/"
cd $(VZW_SYNCML_DIR)/src/bld/linux ; \
This was very difficult to spot though as spaces are not visible.

Related

how to enable host compilation but not cross compilation on yocto on certain files

I am trying to build gutenprint 5.2.14 for arm platform using yocto project "devtool". During the compile process, I am getting this error for the file "lt-extract-strings" saying cannot binary execute file: Exec format error
Upon looking at the file, it a 32-bit arm-executable.
OpenWRT says to implement this when doing cross-compilation.
define Build/Compile
# Replace the cross-compiled "extract-string" by a shell-script that
# runs the host's own compiled version (gutenprint needs to run this)
(cd $(PKG_BUILD_DIR) && $(MAKE) -C src/xml extract-strings && \
$(RM) src/xml/extract-strings && \
echo '#!/bin/sh' > src/xml/extract-strings && \
echo 'exec $(HOST_BUILD_DIR)/src/xml/extract-strings "$$$$#" ' \
>> src/xml/extract-strings && chmod +x src/xml/extract-strings && cp src/xml/extract-strings /tmp/)
$(call Build/Compile/Default)
endef
the link to the file is here
I tried looking for sources on how to implement this fix above in a yocto recipe but I had no luck finding it. Can someone help me solve this issue ?
Thanks in advance

Make: Can we have directories as a target in GNUmakefile

I am working on GNUmake to create symlink to specific file by parsing whole directory which has a folder which needs to be linked.
Here is my makefile snippet.
TGT_LINK = /lan/test/workspace/build/tools
all_target: release_buid complete_test $(TGT_LINK)
$(TGT_LINK):
if [ ! -d $# ]; then mkdir -p $#; fi
cd $#; \
tar_ln=`\ls -d synopsystcl* | sed 's/synopsys//'`; \
sour_dir=`\ls -d synopsystcl*`; \
if ! [ -e $tar_ln ]; then \
ln -s $sour_dir $tar_ln; \
fi
Directory : /lan/test/workspace/build/tools Contains following content in it
polaris.so link.a dynamic.so kbuild.so README.txt license.txt synopsystcl5.5 build.json
Here i am trying to create symlink with name tcl5.5 pointing to synopsystcl5.5 with my above target $(TGT_LINK) code.
tcl5.5 -> synopsystcl5.5
After successful completion of two targets : release_buid complete_test , build is not proceeding to go for next target $(TGT_LINK) to create symlink. Could you please help whats wrong in code?
I would let make itself to check and recreate symlink as needed, i.e.:
TGT_LINK = /lan/test/workspace/build/tools
all_target: release_buid complete_test symlink
.PHONY: symlink
symlink: $(patsubst $(TGT_LINK)/tcl%, $(TGT_LINK)/synopsystcl%, $(wildcard $(TGT_LINK)/tcl*))
$(TGT_LINK)/synopsystcl%: $(TGT_LINK)/tcl%
set -e; \
cd $(#D); \
rm -f $(#F); \
ln -s $(<F) $(#F)
I would also consider reordering targets if there are dependencies indeed. One should never assume that dependency list is processed left to right; it will also lead to errors when parallel build (-j) is involved. If you have dependencies that something should happen before something else, it should be explicitly stated, e.g.:
all_target: symlink
symlink: complete_test
complete_test: release_buid

Pass a path to the "." source in a makefile

In a directory I have a config file with my db variables.
This file (db/database.ini) looks like this:
[PostgreSQL]
host=localhost
database=...
user=postgres
password=...
I have another file (db/create_stmts.sql) where I have all my raw create table statements, and i am trying to experiment the use of a Makefile to have a command like this:
make create-db from_file=db/create_stmts.sql
In order not to repeat myself, I thought of tailing the variables of db/database.ini to a file which I would then source, creating shell variables to pass to psql in the make file.
Here's my plan:
make-db:
# from_file: path to .sql file with all create statements to create the database where to insert
# how to run: make create-db from_file={insert path to sql file}
file_path=$(PWD)/file.sh
tail -n4 db/database.ini > file.sh && . $(file_path)
# -U: --user
# -d: --database
# -q: --quiet
# -f: --file
psql -U $(user) -d $(database) -q -f $(from_file) && rm file.sh
Which I run by: make create-db from_file=db/create_stmts.sql
Which gives me this message - from which i kindof understand that the sourcing just did not work.
#from_file: path to .sql file with all create statements to create the database where to insert
# how to run: make create-db from_file={insert path to sql file}
file_path=/home/gabriele/Desktop/TIUK/companies-house/file.sh
tail -n4 db/database.ini > file.sh && .
# -U: --user
# -d: --database
# -q: --quiet
# -f: --file
psql -U -d -q -f db/schema_tables.sql && rm file.sh
psql: FATAL: Peer authentication failed for user "-d"
Makefile:3: recipe for target 'create-db' failed
make: *** [create-db] Error 2
Any help?
Another solution, perhaps simpler to understand:
make-db:
file_path=$$PWD/file.sh; \
tail -n4 db/database.ini > file.sh && . $$file_path; \
psql -U $$user -d $$database -q -f $$from_file && rm file.sh
Note using ; and \ to convince make to run all commands in a single shell, and using $$ to escape the $ and use shell variable references.
The error is in the text, namely
psql -U -d -q -f db/schema_tables.sql && rm file.sh
This happens because the variables $(user) and $(database) aren't set. Every line within a target is executed in a sub shell. There is now way to use source like you would in a regular script.
You could create a file named database.mk in which you define these variables and use include database.mk at the top of your makefile to include them:
Makefile
CONFILE ?= database
include $(CONFILE).mk
test:
#echo $(user)
#echo $(database)
database.mk
user := user
database := data
If you want to parse the ini file you could do that as such
CONFILE := db/database.ini
make-db: _setup_con
echo $(user) $(database)
# your target
_setup_con:
$(eval user=$(shell grep "user=" $(CONFILE) | grep -Eo "[^=]*$$"))
$(eval database=$(shell grep "database=" $(CONFILE) | grep -Eo "[^=]*$$"))
# and so forward
I would make it more Make-way by using feature of automatic Makefile generation. Given that a configuration file is a simple properties file, its syntax is easily parseable by Make, it's sufficient to just get the lines with variables, i.e.:
include database.mk
database.mk: db/database.ini
grep -E '^\w+=\w+$$' $< > $#
.PHONY: create-db
create-db: $(from_file)
psql -U $(user) -d $(database) -q -f $<
Some additional notes:
create-db should be made .PHONY to avoid situation when nothing is done due to somebody creating (accidentally or not) a file named create-db,
by making create-db depending on from_file one can get a clean and readable error from make that a file does not exist instead of possibly cryptic error later.

How to get Makefile to only produce a file name without extension?

I'm trying to make a Makefile that exports a markdown file to a pdf file that uses the same filename as the original markdown file. I used "basename" command but it produces "inputfile.md.pdf" instead of "inputfile.pdf".
Please see my code below (I adapted a code I found on the Internet. Thank you!):
.PHONY: pdf docx apa format
FILES := $(wildcard ./*.md)
pdf:
for file in $(FILES); do \
pandoc $$file \
--bibliography mypath \
--csl mypath \
--filter pandoc-citeproc \
--template eisvogel \
-o $(basename $$file).pdf; \
open $(basename $$file).pdf; \
done
Anyone who can help me? I'm a novice in Makefile (and programming in general) so any detailed help would be very much appreciated.
I also tried these codes below, but they generated an error message:
-o $(basename -s ".md" $$file).pdf; \
-o $(basename -s .md $$file).pdf; \
The way you write $(basename …) you get the basename make function. This would normally the right thing, but you try to reference a shell variable file in its argument, which is unavailable at the make layer.
In this case, it is probably easiest to call the basename shell utility, at the shell level. Therefore, you need to escape the $ to get shell substitution, like this:
-o "$$(basename -s .md $$file)".pdf; \
open "$$(basename -s .md $$file)".pdf; \
Alternatively, you could try to move the loop to the make layer, perhaps using foreach.

How to execute a make target on file change automatically?

How do I write a make target that will watch for any file changes in specific folders and execute some other make target to compile files? I am looking for a way that can do this with minimal dependency on tools in addition to make itself to keep things simple.
For the watching you can use fswatch. (There's also a go version of this program which may be easier to install: fswatch) For example:
fswatch -ext cpp,c,h make -f Makefile
Anytime you change a cpp, c or h file it will run make again.
Make can be a bit slow for this, so I tend to use ninja instead, but that really depends on the size of your project.
Another option is tup, which has watching built-in:
tup monitor
But, sadly, only for linux.
You can use entr and adjust your Makefile similar to this one
.DEFAULT_GOAL := run
SHELL := /bin/bash
run:
clear && \
cp one.txt two.txt && \
rm -f _* *.l2m *.o2m && \
Ganlib < testgan2.x2m
watch:
while sleep 1 ; do find . -name '*.x2m' -o -name '*.c2m' \
| entr -d make -f ./Makefile ; done
.PHONY: run watch
followed by
$ make watch

Resources