Make command on Kubuntu device - linux

I have to compile a source code to get the executables. However, the make command fails to compile due to the presence of a parantheses with the following error message:
sh: 4: Syntax error: "(" unexpected (expecting ")")
Makefile: 36: recipe for target 'dynamic' failed
make[1]: [dynamic] Error 2
I visited the Makefile which I attach to this post:
# get PETSC_DIR, PETSC_ARCH and MPIHOME from NEMO 5 build system
#LIBMESH_VERSION = 0.8.0
include ../../make.inc
#all: libmesh/configure static dynamic
all: libmesh/configure dynamic
# <ss 12/09/10> static stuff is only needed on jaguar
libmesh/configure:
#echo "Extracting libmesh-$(LIBMESH_VERSION).tar.gz..."
tar zxf libmesh-$(LIBMESH_VERSION).tar.gz
# <ss 17.7.2010> PETSc now is mandatory for libmesh - however, libmesh takes MPI configuration from petsc configuration files in that case.
# libmesh searches for $PETSC_DIR/include/petsc.h and needs $PETSC_ARCH to be set
# On nanohub, things got messed up and OpenMIP libraries linked to executables. to prevent this, I had to disable VTK within libmesh.
# <ss 13.8.2010> disabled tetgen because libtetgen.a seems to contain an int main() which makes static linking impossible.
# Note: the 'make clean' before 'make all' for the contributions is mandatory, otherwise shared LASPACK will not compile.
static: libmesh/configure
#echo "###########################################"
#echo "# #"
#echo "# Configuring Libmesh (STATIC libraries) #"
#echo "# #"
#echo "###########################################"
(export libmesh_CXXFLAGS=$(libmesh_CXXFLAGS) ; \
export libmesh_INCLUDE=$(libmesh_INCLUDE); \
export SLEPC_DIR=$(SLEPC_DIR); \
cd libmesh; ./configure PETSC_DIR=$(PETSC_REAL_BUILD) MPIHOME=$(MPIHOME) PETSC_ARCH=$(PETSC_REAL_ARCH) \
F77="$(MPIF77)" CC="$(MPICC)" GCC="$(GCC)" CXX="$(MPICXX)" --enable-vtk --with-vtk-include=$(VTKINC_PATH) \
--with-vtk-lib=$(VTKLIB_PATH) --disable-tetgen --disable-tecplot \
--disable-nemesis --disable-shared --enable-parmesh --enable-amr; \
make clean; make; \
cd contrib; make clean; make all)
dynamic: libmesh/configure
#echo "###########################################"
#echo "# #"
#echo "# Configuring Libmesh (DYNAMIC libraries) #"
#echo "# #"
#echo "###########################################"
(export libmesh_CXXFLAGS=$(libmesh_CXXFLAGS); \
export libmesh_CPPFLAGS=$(libmesh_CPPFLAGS); \
export libmesh_INCLUDE=$(libmesh_INCLUDE); \
export METHODS=(opt,dbg);\
export SLEPC_DIR=$(SLEPC_DIR)/build-real; \
cd libmesh; ./configure PETSC_DIR=$(PETSC_REAL_BUILD) MPIHOME=$(MPIHOME) PETSC_ARCH=$(PETSC_REAL_ARCH) \
F77="$(MPIF77)" CC="$(MPICC)" GCC="$(GCC)" CXX="$(MPICXX)" --enable-vtk --with-vtk-include=$(VTKINC_PATH) \
--with-vtk-lib=$(VTKLIB_PATH) --disable-tetgen --enable-triangle --enable-slepc --disable-nemesis --disable-cxx11 --disable-strict-lgpl \
--enable-parmesh --enable-amr --enable-shared=yes --disable-glibcxx-debugging ; \
make clean; make --jobs=4; \
cd contrib; make clean; make all --jobs=4;)
clean:
cd libmesh; make clean
distclean:
rm -rf libmesh
I think the problem is about forcing to use the bash shell as I read from other posts. I did so but it didn't work.
I run it using Kubuntu: KDE version of Ubuntu.
Many thanks in advance for help.

The project's README.md looks like you should have used
../configure --with-methods="opt dbg"
(without parentheses, whitespace separated) and not (apparently) ../configure --with-methods="(opt,dbg)"

Check line 4 of the dynamic target, as the error message states:
export METHODS=(opt,dbg);\
should probably be something else, or the part (opt,dbg) should be in double-quotes:
export METHODS="(opt,dbg)";\

Related

Creating variable from bash command output in makefile

Hello I would like to ask how I can create bash variable in makefile.
Below code does work but variable "targets" keeps being empty. How I can actually create "targets" and "current_target" variables in makefile?. Problem is that I have to create this variables from actual bash commands.
SHELL=/bin/bash
...
MAIN_APPS = 01_prep 02_prep 03_prep 04_prep 05_prep
foo : .check_targets .check_segment
#for f in $(MAIN_APPS) ; do \
targets=$(expr $(last_target) + 1); \
echo $(targets) + 1; \
curent_target=$(expr "$(echo $(f) | head -c 2) + 0"); \
if [ $(targets) = $(current_target)]; then \
break; \
else \
make $(f); \
fi \
done
output:
make foo last_target="02" segm=KI
+ 1
What I want to do is to make targets from my makefile which actually starts from 01 to 05 if I pass an argument last_target="05"
You mix up between make variables and shell variables. And you did not consider that make expands the recipes before passing them to the shell, reason why you frequently need to use $$ instead of $. Or, for command expansion, `...` instead of $(...). You are also using double quotes where you shouldn't (expr "..."). Finally, you use make in your recipe, which is not a good idea. You should use $(MAKE) (see the How the MAKE Variable Works section of the GNU make manual for the details).
Try the following (not tested) maybe:
SHELL=/bin/bash
...
MAIN_APPS = 01_prep 02_prep 03_prep 04_prep 05_prep
foo : .check_targets .check_segment
#for f in $(MAIN_APPS) ; do \
targets=`expr "$(last_target)" + 1`; \
echo "$$targets + 1"; \
tmp=`echo "$$f" | head -c 2`; \
curent_target=`expr "$$tmp" + 0`; \
if [ "$$targets" = "$$current_target" ]; then \
break; \
else \
$(MAKE) "$$f"; \
fi \
done
But I am almost 100% convinced that you are trying to use make as a kind of scripting language instead of as a sophisticated build system. If I understand well you are trying to rebuild only a subset of your MAIN_APPS by specifying a last target number. You could probably achieve the same with a much more make-ish style:
TARGETS := $(shell printf '%02d_prep\n' $$(seq $(last_target)))
.PHONY: foo
foo: $(TARGETS) .check_targets .check_segment
And that's all, no complex recipe for foo. Nothing at all (except, of course, the rules to build .check_targets, .check_segment and all xx_prep targets, that you do not show).
Explanation: I used the $(shell ...) make function and a small shell script to initialize make variable TARGETS with 01_prep 02_prep ... up to $(last_target)_prep. As noted in the comments this shell script does not even require bash and would work with the default make shell (sh). So, if you do not have other good reasons to use bash, get rid of the SHELL=/bin/bash line and your Makefile will be a bit more portable.
Then, I declared foo as phony because you probably don't have a file named foo and, in case you have one, you probably want make to build foo anyway.
Finally, I declared $(TARGETS), .check_targets, and .check_segment as prerequisites of foo. If you ask make to build foo and any of these prerequisites is out-of-date, make will build it using the rules you declared for it.
This is far more make-ish because it clearly tells make what depends on what instead of hiding it in a recipe. And make needs this to do its job correctly, which consist in comparing last modification dates of files to decide if something must be rebuilt or not. It also has extra benefits like, for instance, exploiting the parallelism of your computer to build several xx_prep in parallel if it is possible.

How to run Linux shell commands from GNU make file to setup preconditions for a build target

My issue is that in my make file I want to create the directory for all object code before building it and I cannot find a way to do this whithout having it impact the output of make. Also, i want to do it in ONE place and not for each and every object file.
I have tried this:
build: setup exe.i686
setup:
mkdir -p obj
exe.i686: $(OBJS)
#echo 'Building target: $#'
#echo 'Invoking: GCC C++ Linker'
${GCC_LOCATION}/Linux/i686/bin/i686-pc-linux-gnu-g++ $(OBJS) -o "exe.i686" -L...
#echo 'Finished building target: $#'
#echo ' '
where OBJS is all my object code. If I don't run setup first and there is no ./obj directory present the build will fail because of the missing directory when trying to build the object code.
Just to be clear, here is an example of how one object file is built:
./obj/Cell.o: ${CELL_ROOT}/main/cell/Cell/src/Cell.cc
#echo 'Building file: $<'
#echo 'Invoking: GCC C++ Compiler'
$(GCC_C++_BUILD) -MF"$(#:%.o=%.d)" -MT"$(#:%.o=%.d)" -o "$#" "$<"
#echo 'Finished building: $<'
#echo ' '
I don't want to build the object code in the same directory I have my make file.
Now to the actual problem. When I build tarket "build" the first time like this everything works fine:
make build
But if I build it again and there are no updates in my source code (object code is up-to-date) it behaves like this:
[7:37] [user1] [/local/repo/user1/project_x/test/bin] $ make build
mkdir -p obj
[7:37] [user1] [/local/repo/user1/project_x/test/bin] $
In this situation I would have liked make to return the nothing-to-be-done string like this:
[7:37] [user1] [/local/repo/user1/project_x/test/bin] $ make build
make: Nothing to be done for `build'.
[7:41] [user1] [/local/repo/user1/project_x/test/bin] $
This would have been the case if I didn't have to depend on the setup target (which is added to .PHONY). Is the only alternative to do it for each object code file? That would be possible I suppose but I wanted to avoid that if possible as it clutters the make file quite a bit. At least in my opinion.
Thanks
Your target setup is always executed because it has no dependency.
You have two choices:
(1) Make a stamp or use some other mechanism so that there is an actual dependency. The directory itself can be the target but that may incur some wrinkles: see http://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html for an example.
Modified relevant extract from the linked article:
$(OBJS): | obj
obj:
mkdir $(OBJDIR)
(2) Suppress the output by testing for existence:
setup:
test -d obj || mkdir -p obj
This is similar to the earlier answer, just to make it easier to read:
build: exe.i686
$(OBJS): | obj
obj:
#if [ ! -d obj ]; then mkdir -p obj; fi
exe.i686: $(OBJS)
#echo 'Building target: $#'
...

Target for make gives "nothing to be done"

I have an issue with "make" (Oh, the horror!).
We're trying to migrate some COBOL code from Windows to Linux. The compiler and such are from Micro Focus. Under Windows the code is developed with Micro Focus Net Express. Linux has Micro Focus Server Express as the equivalent. The programs are compiled and linked using "make" scripts.
So much for the background.
The problem is a "make" script that doesn't want to compile and link an executable under Linux. The targets look like this:
# HP INIT-Daten laden
#
datLoad$O: \
$(UI)/defretrn.cpy \
$(UI)/e12sy00s.cpy \
$(UI)/e12sy005.cpy \
$(UI)/e12sy006.cpy \
$(UI)/e12sy010.cpy \
$(UI)/e12sy013.cpy \
$(UI)/e12sy050.cpy \
$(UI)/e12db001.cpy \
$(UI)/e12db050.cpy \
$(UI)/evlg.cpy \
$(UI)/deffehl.cpy \
datLoad.xcbl $(FRC)
# #echo "dollar-O is \"$O\" in $#"
datLoad$X: $(LIBDSQL) datLoad$O \
$(LP)/evlg$O $(LP)/alock$O
$(LCOB) -o $(#:$X=) -e $(#:$X=) $(LCOBFLAGS) \
-d e12db001 -d e12db003 -d e12db012 \
-d e12sy005 -d e12sy006 -d e12sy009 \
-d e12sy010 -d e12sy012 -d e12sy013 \
-d e12sy050 \
-I EvLgSetCategory $(LP)/evlg$O \
-I ALckSetDebug $(LP)/alock$O \
$(LIBEXEEXT) "$(LIBXSQL)"
if [ -f $B/$# -a ! -w $B/$# ] ; then rm -f $B/$# ; fi
cp $# $B
To put this into context, $0=".o" (i.e. an object file extension). $(LCOB) is the link command. $X=".exe" (an executable ... just forget about the extension, we'll fix that in due course). All the other stuff relates to paths ==> not relevant to the issue at hand and, yes, they've all been checked and verified.
Ultimately, I am trying to get "make" to resolve a target called "datLoad.o".
Included is a second "make" script containing the following:
COBFLAGS = -cx # create object file
GNTFLAGS = -ug # create .gnt file
SOFLAGS = -z # create
LCOB = cob
...
.cbl$O:
$(CCOB) $(COBFLAGS) $*.cbl, $*$O, NUL, NUL
if [ -f $(LP)/$*$O -a ! -w $(LP)/$*$O ] ; then rm -f $(LP)/$*$O ; fi
cp $*$O $(LP)
The relevant part is the target which resolves to ".cbl.o:". Yes, that's the shorthand version and I don't really like it but I did not write this script. I'm assured that it really means *.o:*.cbl and other similar constructs in the script do work correctly.
With a simple "make" I get a link error:
> In function `cbi_entry_point': (.data+0x384): undefined reference to
> `datLoad' /tmp/cobwZipkt/%cob0.o: In function `main': (.text+0x28):
> undefined reference to `datLoad' make: *** [datLoad.exe] Error 1
That means datLoad.o was not created. If I do create it explicitly with:
cob -cx datload
Then "make" still gives the same error as above. Weird! However, what I really cannot understand is the response I get from "make datLoad.o" when the target does not exist:
make: Nothing to be done for `datLoad.o'.
I assumed (heaven help me) that the target "datLoad.o" would try to create the required target file if that file does not already exist. Am I going mad?
Sorry if this seems a bit obscure, I'm not sure how to phrase it better. If anybody has an idea what might be going on, I'd be really grateful...
Thank you Mad Scientist. Your tip was correct.
The included .mk contained a .SUFFIXES rule. The problem was that the $O was not being used consistently. $O was originally set to ".obj" for Windows. Under Linux it's ".o". However, the .SUFFIXES rule had the ".obj" hard coded into it, so of course the ".o" targets were not being recognised. I replaced the hard coded suffix with the $O variable and it now works.
Achim

Header file not found during compilation with make (Linux)

I am getting the following error during make:
In file included from modGPRS.c:25:
../inc/intModGPRS.h:33:21: error: datapkt.h: No such file or directory
The directory structure is as follows:
datapkt.h is placed at main_proj/libs/ipsec/itf.
libs folder has a Makefile which is as follows:
include $(BUILD_TOP)/build_control/stream/config.mk
SUBDIRS = tracing config stats srandom
SUBDIRS_$(B_HAS_EEPROM) += eeprom
SUBDIRS_$(B_LIBARCHIVE) += libarchive
ifeq ($(B_PLATFORM_openat),y)
SUBDIRS += openat openssl asn1c mib zlib diff ipsec
else
SUBDIRS += iniparser daemon ipsec
endif
stats_needs = config
include $(BUILD_TOP)/build_control/stream/subdirs.mk
Makefile for ipsec is as follows:
SDIRS += src itf
TOP?=..
RECURSIVE_MAKE= [ -n "$(SDIRS)" ] && for i in $(SDIRS) ; do \
(cd $$i && echo "making $$target in $(DIR)/$$i..." && \
$(MAKE) -e TOP=$(TOP)/.. $$target INCLUDES='$(INCLUDES)') || exit 1; \
done;
subdirs:
#target=all; $(RECURSIVE_MAKE)
all: subdirs -I /itf
include $(BUILD_TOP)/build_control/stream/subdirs.mk
Also subdirs.mk is as follows:
# This is a stand-alone file to distribute targets to
# sub-directories. Include this file alone.
# Make bug: It loses track of if/endif over a $(eval) call.
ifndef __subdirs_include
__subdirs_include = yes
# This only works for the standard targets defined in $(TARGETS)
# in utils.mk. However this list can be extended with +=.
install:: install-hdrs
include $(BUILD_TOP)/build_control/stream/utils.mk
include $(BUILD_TOP)/build_control/stream/platform.mk
# This creates a recursion rule for each pair of target and subdirectory.
# The target for doing T in directory D is named T+D.
# If there is a "$(D_needs) = subdirs" then the subdirs become prerequisites
# of D.
define __target_subdir
.PHONY:: $(1)+$(2)
$(1)+$(2) :: $(3); +$(MAKE) -C $(2) $(1)
endef
$(foreach t,$(TARGETS),\
$(foreach d,$(strip $(SUBDIRS) $(SUBDIRS_y)),\
$(eval $(call __target_subdir,$(t),$(d),$(patsubst %,$(t)+%,$($(d)_needs))))))
$(foreach t,$(TARGETS),\
$(foreach d,$(strip $(SUBDIRS) $(SUBDIRS_y)),$(eval $(t)::$(t)+$(d))))
endif # __subdirs_include
could someone please help me figure out, how to solve this issue of the header file: datapkt.h? Please let me know if any other details are required.
Thanks
Sunny
The error message is from your compiler. It is saying that the file modGPRS.c (in whatever directory it is in, call it A) has included a file A/../inc/intModGPRS.h, which is itself trying to include a file called datapkt.h, which cannot be found. This is either because your makefiles are not properly telling the compiler where the file datapkt.h is, or (more likely) you have not installed a prerequisite library.
Make sure you have installed everything that needs to be installed before trying to build whatever it is that you're trying to build. Without at least telling me what it is you're trying to install I can't help you further.

Location replaced while running makefile

Code snippets of makefile:
ERROR_PARSER_YACC = $(SRCDIR)/ermparseyac.y
ERROR_PARSER_LEX = $(SRCDIR)/ermparselex.l
ERM_OBJS = \
$(OBJDIR)/ermparseyac.o \
$(OBJDIR)/ermparselex.o \
$(OBJDIR)/ermclient.o \
$(OBJDIR)/ermcommit.o \
$(OBJDIR)/erminit.o \
$(OBJDIR)/ermlog.o \
$(OBJDIR)/ermmcp.o \
$(OBJDIR)/ermsyslog.o \
$(OBJDIR)/ermparse.o \
$(OBJDIR)/ermreport.o
$(ERM_OBJS): $(SRCDIR)/$(#F:.o=.c)
#echo .... Compiling $(#:.o=.c)
$(IDA_CC) $(SRCDIR)/$(#F:.o=.c) -o $#
The value of SRCDIR is "/home/wholesale/children/dev5/comps/erm/src".
When I run the makefile, I get the following error:
.... Compiling /home/wholesale/children/dev5/comps/erm/obj/ermparselex.c
cc -g -DANSI -DORA817 -DTRACE_ON -DIDA_VERSION='"ISP-RG-V5.10.7GEN2A"' -DNO_MCP -DBUILDING_ERP -I/home/wholesale/children/dev5/comps/erm/include -I/home/wholesale/children/dev5/comps/erm/src -I/home/wholesale/children/dev5/comps/erm/module_test -I/home/wholesale/children/dev5/comps/erm/include -I/home/wholesale/children/dev5/comps/cfm/include -c /home/wholesale/children/dev5/comps/erm/src/ermparselex.c -o /home/wholesale/children/dev5/comps/erm/obj/ermparselex.o
/pf24/wholesale/dvp/comps/erm/src/ermparselex.l:282: error: static declaration of âget_comment_lineâ follows non-static declaration
/pf24/wholesale/dvp/comps/erm/src/ermparselex.l:168: error: previous implicit declaration of âget_comment_lineâ was here
I don't understand how makefile is replacing the location "/home/wholesale/children/dev5/comps/erm/src" to a different location "/pf24/wholesale/dvp/comps/erm/src/" which is not present in the sever.
You seem to be confusing make output with your compiler output. The error messages you showed are not produced by make, but by whatever compiler (probably gcc) you're using.
Note that the assignemt to ERROR_PARSER_LEX is a deffered assignment. The value of SRCDIR is expanded whenever ERROR_PARSER_LEX is used. That might explain why the value of SRCDIR doesn't appear to be what you think it should be.
Edit
The problem doesn't appear to be related to your makefile. Make clearly shows that it's passed /home/wholesale/children/dev5/comps/erm/src/ermparselex.c to the compiler as source file.
The error message which points to a different file probably means that some source file is including something from /pf24.
The -E option of gcc can be quite useful in diagnosing such issues. Replace the -o ... options by it, and it'll output the preprocessed source code to stdout. This should show you which file is including the file in /pf24.

Resources