I try to run a target inside another target if a condition is satisfied.
Here is a MVP for my Makefile
val = 2
.PHONY: target1
target1:
clear
.PHONY: target2
target2:
ifeq ($(val), 2)
target1
else
#echo 'wrong value'
endif
If I replace target1(inside the if statement) by #echo 'success' the code works properly so I guess the if statement is correct. However when running make target2 I obtain the following error
make: target1: Command not found
Related
I am using Ubuntu 20.04.4 LTS and have just installed the package libreoffice-dev.
The intention is to run the C++ DocumentLoader sample noted here. (The 3 files constituting the sample may be viewed here.)
The instructions are mostly embedded in the sample Makefile. Here is what happens:
The soffice command opened a new LibreOffice window - but did not actually finish (ie: no 'ready' message).
Q1: Is this expected behaviour?
It's catch-22. I'm prevented from running make DocumentLoader.run (or any) command but if I manually close the LibreOffice window (whereupon terminal bursts back into life) I am able to compile (but not successfully run) the program - as follows:
daz#daz-NUC8i7BEH:~/mpa/LO-SDK$ soffice "--accept=socket,host=localhost,port=2083;urp;StarOffice.ServiceManager"
daz#daz-NUC8i7BEH:~/mpa/LO-SDK$ make DocumentLoader.run
cd /home/daz/libreoffice7.3_sdk/LINUXexample.out/bin && DocumentLoader -env:URE_MORE_TYPES=file://"/usr/lib/libreoffice/program/types/offapi.rdb" "/home/daz/libreoffice7.3_sdk/matt/test.odt"
DocumentLoader.cxx has started. nCount=1
Error: cannot establish a connection using 'uno:socket,host=localhost,port=2083;urp;StarOffice.ServiceManager':
loading component library </libmergedlo.so> failed /build/libreoffice-SshRy0/libreoffice-7.3.1~rc3/cppuhelper/source/shlib.cxx:311
make: *** [Makefile:68: DocumentLoader.run] Error 1
daz#daz-NUC8i7BEH:~/mpa/LO-SDK$
Q2: Have I just made a procedural error?
Here is the actual Makefile ... [%.run: is Makefile:66]
# Builds the C++ DocumentLoader example of the SDK.
# From here: https://api.libreoffice.org/examples/cpp/DocumentLoader/
#PRJ=../../.. Original
PRJ=$(OO_SDK_HOME)
SETTINGS=$(PRJ)/settings
include $(SETTINGS)/settings.mk
include $(SETTINGS)/std.mk
# Define non-platform/compiler specific settings
COMPONENT_NAME=DocumentLoader
OUT_COMP_INC = $(OUT_INC)/$(COMPONENT_NAME)
OUT_COMP_GEN = $(OUT_MISC)/$(COMPONENT_NAME)
OUT_COMP_OBJ=$(OUT_OBJ)/$(COMPONENT_NAME)
CXXFILES = DocumentLoader.cxx
OBJFILES = $(patsubst %.cxx,$(OUT_SLO_COMP)/%.$(OBJ_EXT),$(CXXFILES))
ENV_OFFICE_TYPES=-env:URE_MORE_TYPES=$(URLPREFIX)$(OFFICE_TYPES)
# Targets
.PHONY: ALL
ALL : \
CppDocumentLoaderExample
include $(SETTINGS)/stdtarget.mk
$(OUT_COMP_OBJ)/%.$(OBJ_EXT) : %.cxx $(SDKTYPEFLAG)
-$(MKDIR) $(subst /,$(PS),$(#D))
$(CC) $(CC_FLAGS) $(CC_INCLUDES) -I$(OUT_COMP_INC) $(CC_DEFINES) $(CC_OUTPUT_SWITCH)$(subst /,$(PS),$#) $<
$(OUT_BIN)/DocumentLoader$(EXE_EXT) : $(OUT_COMP_OBJ)/DocumentLoader.$(OBJ_EXT)
-$(MKDIR) $(subst /,$(PS),$(#D))
-$(MKDIR) $(subst /,$(PS),$(OUT_COMP_GEN))
ifeq "$(OS)" "WIN"
$(LINK) $(EXE_LINK_FLAGS) /OUT:$# /MAP:$(OUT_COMP_GEN)/$(basename $(#F)).map \
$< $(CPPUHELPERLIB) $(CPPULIB) $(SALHELPERLIB) $(SALLIB)
else
$(LINK) $(EXE_LINK_FLAGS) $(LINK_LIBS) -o $# $< \
$(CPPUHELPERLIB) $(CPPULIB) $(SALHELPERLIB) $(SALLIB) $(STDC++LIB)
ifeq "$(OS)" "MACOSX"
$(INSTALL_NAME_URELIBS_BIN) $#
endif
endif
CppDocumentLoaderExample : $(OUT_BIN)/DocumentLoader$(EXE_EXT)
#echo --------------------------------------------------------------------------------
#echo The example loads the "$(QM)test.odt$(QM)" document in the DocumentLoader example directory.
#echo If you want to load your own document, please use:
#echo $(SQM) $(SQM)DocumentLoader -env:URE_MORE_TYPES="$(QM)<fileurl_office_types_rdb>$(QM)" "$(QM)filename$(QM)" [connection_url]
#echo -
#echo Use the following command to execute the example!
#echo -
#echo $(MAKE) DocumentLoader.run
#echo -
#echo NOTE: This example does not use the new UNO bootstrap mechanism, it uses still a socket
#echo $(SQM) $(SQM)connection. The example use the defaultBootstrap_InitialComponentContext method and provides
#echo $(SQM) $(SQM)the additional office types via the UNO environment variable -env:URE_MORE_TYPES=...
#echo $(SQM) $(SQM)Before you can run this example you have to start your office in listening mode.
#echo -
#echo $(SQM) $(SQM)soffice "$(QM)--accept=socket,host=localhost,port=2083;urp;StarOffice.ServiceManager$(QM)"
#echo --------------------------------------------------------------------------------
%.run: $(OUT_BIN)/DocumentLoader$(EXE_EXT)
# cd $(subst /,$(PS),$(OUT_BIN)) && $(basename $#) $(ENV_OFFICE_TYPES) $(subst \\,/,$(subst /,$(PS),"$(OO_SDK_HOME)/examples/cpp/DocumentLoader/test.odt"))
cd $(subst /,$(PS),$(OUT_BIN)) && $(basename $#) $(ENV_OFFICE_TYPES) $(subst \\,/,$(subst /,$(PS),"/home/daz/libreoffice7.3_sdk/matt/test.odt"))
.PHONY: clean
clean :
-$(DELRECURSIVE) $(subst /,$(PS),$(OUT_COMP_INC))
-$(DELRECURSIVE) $(subst /,$(PS),$(OUT_COMP_GEN))
-$(DELRECURSIVE) $(subst /,$(PS),$(OUT_COMP_OBJ))
-$(DEL) $(subst \\,\,$(subst /,$(PS),$(OUT_BIN)/DocumentLoader*))
I'm trying to build a project with subdirectories using make, I've gotten the recursive make part working but for some reason, it seems to take the prerequisites of the source file dependencies and appends .o to them and then tries to compile them, which doesn't work obviously, why is it doing this?
The rule in question looks like this:
operations_cache.o : memory_management/operations_cache.cpp memory_management/operations_cache.hpp \
function.hpp operations/operation_base.hpp
cd memory_management && $(MAKE) $#
The rule that compiles the operations directory looks like this:
operation_%.o : function.hpp
cd operations && $(MAKE) $#
for some reason, make keeps trying to say that operations/operation_base.hpp.o is a valid target even though I don't have it listed anywhere in the make file. I've read the documentation for and I didn't see anything in it about trying to implicitly define objects based on prerequisite filenames, so I'm super confused as to what is compelling it to do this.
The error I'm getting is this:
g++ -c -o main.o main.cpp
g++ -c -o node.o node.cpp
cd memory_management && make unique_table.o
make[1]: Entering directory './memory_management'
g++ -o ../unique_table.o -c unique_table.cpp
make[1]: Leaving directory './memory_management'
cd operations && make operations/operation_base.hpp.o
make[1]: Entering directory './operations'
g++ -o ../operations/operation_base.hpp.o -c
g++: fatal error: no input files
compilation terminated.
Makefile:10: recipe for target 'operations/operation_base.hpp.o' failed
make[1]: *** [operations/operation_base.hpp.o] Error 1
make[1]: Leaving directory './operations'
Makefile:24: recipe for target 'operations/operation_base.hpp.o' failed
make: *** [operations/operation_base.hpp.o] Error 2
Edit Added complete files
At user request, here are the complete make files of my 3 directories
./Makefile
CC = g++
objects = main.o node.o unique_table.o operations_cache.o function.o operation_base.o operation_and.o
# shared_lib = nodelib.so
all : edit # $(shared_lib)
edit : $(objects)
$(CC) -o edit $(objects)
main.o : main.cpp node.hpp memory_management/unique_table.hpp memory_management/operations_cache.hpp
node.o : node.cpp node.hpp
unique_table.o : memory_management/unique_table.cpp memory_management/unique_table.hpp node.hpp
cd memory_management && $(MAKE) $#
operations_cache.o : memory_management/operations_cache.cpp memory_management/operations_cache.hpp \
function.hpp operations/operation_base.hpp
cd memory_management && $(MAKE) $#
function.o : function.cpp function.hpp node.hpp memory_management/unique_table.hpp
operation_%.o : function.hpp
cd operations && $(MAKE) $#
.PHONY : clean
clean :
rm edit $(objects)
./operations/Makefile
CC = g++
objects = operation_base.o operation_and.o operation_or.o operation_xor.o operation_restrict.o operation_composition.o operation_satisfy.o operation_satisfy_all.o
proj_dir = ../
operation_base.o : operation_base.cpp operation_base.hpp $(proj_dir)function.hpp
operation_and.o : operation_and.cpp operation_and.hpp operation_base.hpp $(proj_dir)function.hpp
operation_or.o : operation_or.cpp operation_or.hpp operation_base.hpp $(proj_dir)function.hpp
operation_xor.o : operation_xor.cpp operation_xor.hpp operation_base.hpp $(proj_dir)function.hpp
operation_composition.o : operation_composition.cpp operation_composition.hpp operation_base.hpp $(proj_dir)function.hpp
operation_restrict.o : operation_restrict.cpp operation_restrict.hpp operation_base.hpp $(proj_dir)function.hpp
operation_satisfy.o : operation_satisfy.cpp operation_satisfy.hpp operation_base.hpp $(proj_dir)function.hpp
operation_satisfy_all.o : operation_satisfy_all.cpp operation_satisfy_all.hpp operation_satisfy.hpp
%.o :
$(CC) -o $(proj_dir)$# -c $<
./memory_management/Makefile
CC = g++
objects = operations_cache.o unique_table.o
proj_dir = ../
operations_cache.o : operations_cache.cpp operations_cache.hpp \
$(proj_dir)function.hpp $(proj_dir)operations/operation_base.hpp
unique_table.o : unique_table.cpp unique_table.hpp $(proj_dir)node.hpp
%.o :
$(CC) -o $(proj_dir)$# -c $<
Edit I found a solution
Removing memory_management/operations_cache.cpp memory_management/operations_cache.hpp function.hpp operations/operation_base.hpp from the operations_cache.o line solves the problem, it doesn't explain why the error was there, but it works, I'd still be interested in understanding why that happened though.
That's because your operations/operation_base.hpp happens to match operation_%.o rule and due to the fact of built-in rule:
.o:
# Builtin rule
# recipe to execute (built-in):
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $#
It works this way:
check if operations/operation_base.hpp can be updated with an explicit rule (no),
check all implicit (pattern) rules whether they can be resolved (candidate: built-in %: %.o),
check if prerequisite operations/operation_base.hpp.o can be resolved (candidate: operation_%.o: functions.hpp),
check if prerequisite functions.hpp can be resolved (yes, file exists),
follow the rule operation_%.o: functions.hpp with stem operations/base.hpp (execute recipe that fails).
I have prepared a simplified Makefile that reproduces the issue. It requires that both functions.hpp exist and built-in rules are enabled.
all: operations/operation_base.hpp
operation_%.o: functions.hpp
echo Making $# from $<
Output:
# Only Makefile (no functions.hpp)
$ ls
Makefile
$ make
make: *** No rule to make target 'operations/operation_base.hpp', needed by 'all'. Stop.
# Create functions.hpp to fulfill pattern rule (this is the case in question)
$ touch functions.hpp
$ make
echo Making operations/operation_base.hpp.o from functions.hpp
Making operations/operation_base.hpp.o from functions.hpp
# The following output comes from built-in rule %: %.o
cc operations/operation_base.hpp.o -o operations/operation_base.hpp
make: cc: Command not found
<builtin>: recipe for target 'operations/operation_base.hpp' failed
# The same, but with disabled built-in rules
$ make -r
make: *** No rule to make target 'operations/operation_base.hpp', needed by 'all'. Stop.
Generally when you don't know why make decided to do something, it's useful to run it with -d to debug decision making and -p to get final resolved Makefile. It confirms the scenario:
$ make -d
…
No implicit rule found for 'all'.
Considering target file 'operations/operation_base.hpp'.
File 'operations/operation_base.hpp' does not exist.
Looking for an implicit rule for 'operations/operation_base.hpp'.
…
Trying implicit prerequisite 'operations/operation_base.hpp.o'.
Looking for a rule with intermediate file 'operations/operation_base.hpp.o'.
Avoiding implicit rule recursion.
Trying pattern rule with stem 'base.hpp'.
Trying rule prerequisite 'functions.hpp'.
Found an implicit rule for 'operations/operation_base.hpp'.
…
No need to remake target 'functions.hpp'.
Considering target file 'operations/operation_base.hpp.o'.
File 'operations/operation_base.hpp.o' does not exist.
Pruning file 'functions.hpp'.
Finished prerequisites of target file 'operations/operation_base.hpp.o'.
Must remake target 'operations/operation_base.hpp.o'.
echo Making operations/operation_base.hpp.o from functions.hpp
…
Successfully remade target file 'operations/operation_base.hpp.o'.
Finished prerequisites of target file 'operations/operation_base.hpp'.
Must remake target 'operations/operation_base.hpp'.
cc operations/operation_base.hpp.o -o operations/operation_base.hpp
…
make: cc: Command not found
…
<builtin>: recipe for target 'operations/operation_base.hpp' failed
Fragments of resolved Makefile (make -p):
operations/operation_base.hpp: operations/operation_base.hpp.o
# Implicit rule search has been done.
# Implicit/static pattern stem: 'operations/operation_base.hpp'
# Modification time never checked.
# File has been updated.
# Failed to be updated.
# automatic
# # := operations/operation_base.hpp
# automatic
# % :=
# automatic
# * := operations/operation_base.hpp
# automatic
# + := operations/operation_base.hpp.o
# automatic
# | :=
# automatic
# < := operations/operation_base.hpp.o
# automatic
# ^ := operations/operation_base.hpp.o
# automatic
# ? := operations/operation_base.hpp.o
# variable set hash-table stats:
# Load=8/32=25%, Rehash=0, Collisions=1/22=5%
# recipe to execute (built-in):
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $#
operations/operation_base.hpp.o: functions.hpp
# Implicit rule search has been done.
# Implicit/static pattern stem: 'operations/base.hpp'
# File is an intermediate prerequisite.
# File does not exist.
# File has been updated.
# Successfully updated.
# automatic
# # := operations/operation_base.hpp.o
# automatic
# % :=
# automatic
# * := operations/base.hpp
# automatic
# + := functions.hpp
# automatic
# | :=
# automatic
# < := functions.hpp
# automatic
# ^ := functions.hpp
# automatic
# ? := functions.hpp
# variable set hash-table stats:
# Load=8/32=25%, Rehash=0, Collisions=1/13=8%
# recipe to execute (from 'Makefile', line 4):
echo Making $# from $<
I have imported the veins_inet subproject when importing the veins 4.5 project (by selecting the "Search for nested projects") in Omnet++.
I have built veins and can run the Erlangen example.
However, I cannot build the veins_inet project.
The sources can be found here: https://github.com/sommer/veins/tree/master/subprojects/veins_inet
I get the following error:
make MODE=debug all
make[1]: Entering directory '/home/XX/omnetpp-5.1.1/samples/veins/subprojects/veins_inet/src'
veins_inet/VeinsInetManager.cc
veins_inet/VeinsInetManager.cc:21:41: fatal error: veins_inet/VeinsInetManager.h: No such file or directory
compilation terminated.
Makefile:97: recipe for target '../out/gcc-debug/src/veins_inet/VeinsInetManager.o' failed
make[1]: Leaving directory '/home/XX/omnetpp-5.1.1/samples/veins/subprojects/veins_inet/src'
Makefile:12: recipe for target 'all' failed
make[1]: *** [../out/gcc-debug/src/veins_inet/VeinsInetManager.o] Error 1
make: *** [all] Error 2
It seems like the header files have failed to be included.
I can bypass the "No such file or directory" errors by manually copying all necessary *.h files into the veins_inet/src/veins_inet folder and editing the *.cc and *.h files, such that the compiler finds the required header files.
I guess the issue lies in the Makefiles, or rather in the configure file, which generates the Makefiles.
veins_inet/configure:
#!/usr/bin/env python
"""
Creates Makefile(s) for building Veins_INET.
"""
import os
import sys
import subprocess
from logging import warning, error
from optparse import OptionParser
# Option handling
parser = OptionParser()
parser.add_option("--with-veins", dest="veins", help="link Veins_INET with a version of Veins installed in PATH [default: do not link with Veins]", metavar="PATH", default="../..")
parser.add_option("--with-inet", dest="inet", help="link Veins_INET with a version of the INET Framework installed in PATH [default: do not link with INET]", metavar="PATH", default="../../../inet")
(options, args) = parser.parse_args()
if args:
warning("Superfluous command line arguments: \"%s\"" % " ".join(args))
# Start with default flags
makemake_flags = ['-f', '--deep', '--no-deep-includes', '--make-so', '-I', '.', '-o', 'veins_inet', '-O', 'out']
run_libs = [os.path.join('src', 'veins_inet')]
run_neds = [os.path.join('src', 'veins_inet')]
# Add flags for Veins
if options.veins:
check_fname = os.path.join(options.veins, 'src/veins/package.ned')
expect_version = '4'
if not os.path.isfile(check_fname):
error('Could not find Veins (by looking for %s). Check the path to Veins (--with-veins=... option) and the Veins version (should be version %s)' % (check_fname, expect_version))
sys.exit(1)
veins_header_dirs = [os.path.join(os.path.relpath(options.veins, 'src'), 'src')]
veins_includes = ['-I' + s for s in veins_header_dirs]
veins_link = ["-L" + os.path.join(os.path.relpath(options.veins, 'src'), 'src'), "-lveins"]
veins_defs = []
makemake_flags += veins_includes + veins_link + veins_defs
run_libs = [os.path.relpath(os.path.join(options.veins, 'src', 'veins'))] + run_libs
run_neds = [os.path.relpath(os.path.join(options.veins, 'src', 'veins'))] + run_neds
# Add flags for INET
if options.inet:
fname = os.path.join(options.inet, '_scripts/get_version')
expect_version = '3.4.0'
try:
print 'Running "%s" to determine INET version.' % fname
version = subprocess.check_output(fname).strip()
if not version == expect_version:
warning('Unsupported INET Version. Expecting %s, found "%s"' % (expect_version, version))
else:
print 'Found INET version "%s". Okay.' % version
except OSError as e:
error('Could not determine INET Version (by running %s): %s. Check the path to INET (--with-inet=... option) and the INET version (should be version %s)' % (fname, e, expect_version))
sys.exit(1)
inet_header_dirs = [os.path.join(os.path.relpath(options.inet, 'src'), 'src')]
inet_includes = ['-I' + s for s in inet_header_dirs]
inet_link = ["-L" + os.path.join(os.path.relpath(options.inet, 'src'), 'src'), "-lINET"]
inet_defs = ["-DINET_IMPORT"]
makemake_flags += inet_includes + inet_link + inet_defs
run_libs = [os.path.relpath(os.path.join(options.inet, 'src', 'INET'))] + run_libs
run_neds = [os.path.relpath(os.path.join(options.inet, 'src'))] + run_neds
# Start creating files
if not os.path.isdir('out'):
os.mkdir('out')
f = open(os.path.join('out', 'config.py'), 'w')
f.write('run_libs = %s\n' % repr(run_libs))
f.write('run_neds = %s\n' % repr(run_neds))
f.close()
subprocess.check_call(['env', 'opp_makemake'] + makemake_flags, cwd='src')
print 'Configure done. You can now run "make".'
veins_inet/Makefile
.PHONY: all makefiles clean cleanall doxy
# if out/config.py exists, we can also create command line scripts for running simulations
ADDL_TARGETS =
ifeq ($(wildcard out/config.py),)
else
ADDL_TARGETS += run debug memcheck
endif
# default target
all: src/Makefile $(ADDL_TARGETS)
#cd src && $(MAKE)
# command line scripts
run debug memcheck: % : src/scripts/%.in.py out/config.py
#echo "Creating script \"./$#\""
#head -n1 "$<" > "$#"
#cat out/config.py >> "$#"
#tail -n+2 "$<" >> "$#"
#chmod a+x "$#"
# legacy
makefiles:
#echo
#echo '====================================================================='
#echo 'Warning: make makefiles has been deprecated in favor of ./configure'
#echo '====================================================================='
#echo
./configure
#echo
#echo '====================================================================='
#echo 'Warning: make makefiles has been deprecated in favor of ./configure'
#echo '====================================================================='
#echo
clean: src/Makefile
cd src && $(MAKE) clean
rm -f run debug memcheck
cleanall: src/Makefile
cd src && $(MAKE) MODE=release clean
cd src && $(MAKE) MODE=debug clean
rm -f src/Makefile
rm -f run debug memcheck
src/Makefile:
#echo
#echo '====================================================================='
#echo '$# does not exist.'
#echo 'Please run "./configure" or use the OMNeT++ IDE to generate it.'
#echo '====================================================================='
#echo
#exit 1
out/config.py:
#echo
#echo '====================================================================='
#echo '$# does not exist.'
#echo 'Please run "./configure" to generate it.'
#echo '====================================================================='
#echo
#exit 1
# autogenerated documentation
doxy:
doxygen doxy.cfg
doxyshow: doxy
xdg-open doc/doxy/index.html
veins_inet/src/Makefile
#
# OMNeT++/OMNEST Makefile for $(LIB_PREFIX)veins_inet
#
# This file was generated with the command:
# opp_makemake --make-so -f --deep -KINET_PROJ=../../../../inet -KVEINS_PROJ=../../.. -L$$\(INET_PROJ\)/out/$$\(CONFIGNAME\)/src -L$$\(VEINS_PROJ\)/out/$$\(CONFIGNAME\)/src -lINET -lveins
#
# Name of target to be created (-o option)
TARGET = $(LIB_PREFIX)veins_inet$(SHARED_LIB_SUFFIX)
# C++ include paths (with -I)
INCLUDE_PATH =
# Additional object and library files to link with
EXTRA_OBJS =
# Additional libraries (-L, -l options)
LIBS = $(LDFLAG_LIBPATH)$(INET_PROJ)/out/$(CONFIGNAME)/src $(LDFLAG_LIBPATH)$(VEINS_PROJ)/out/$(CONFIGNAME)/src -lINET -lveins
# Output directory
PROJECT_OUTPUT_DIR = ../out
PROJECTRELATIVE_PATH = src
O = $(PROJECT_OUTPUT_DIR)/$(CONFIGNAME)/$(PROJECTRELATIVE_PATH)
# Object files for local .cc, .msg and .sm files
OBJS = $O/veins_inet/VeinsInetManager.o $O/veins_inet/VeinsInetMobility.o
# Message files
MSGFILES =
# SM files
SMFILES =
# Other makefile variables (-K)
INET_PROJ=../../../../inet
VEINS_PROJ=../../..
#------------------------------------------------------------------------------
# Pull in OMNeT++ configuration (Makefile.inc)
ifneq ("$(OMNETPP_CONFIGFILE)","")
CONFIGFILE = $(OMNETPP_CONFIGFILE)
else
ifneq ("$(OMNETPP_ROOT)","")
CONFIGFILE = $(OMNETPP_ROOT)/Makefile.inc
else
CONFIGFILE = $(shell opp_configfilepath)
endif
endif
ifeq ("$(wildcard $(CONFIGFILE))","")
$(error Config file '$(CONFIGFILE)' does not exist -- add the OMNeT++ bin directory to the path so that opp_configfilepath can be found, or set the OMNETPP_CONFIGFILE variable to point to Makefile.inc)
endif
include $(CONFIGFILE)
# Simulation kernel and user interface libraries
OMNETPP_LIBS = -loppenvir$D $(KERNEL_LIBS) $(SYS_LIBS)
ifneq ($(TOOLCHAIN_NAME),clangc2)
LIBS += -Wl,-rpath,$(abspath $(INET_PROJ)/out/$(CONFIGNAME)/src) -Wl,-rpath,$(abspath $(VEINS_PROJ)/out/$(CONFIGNAME)/src)
endif
COPTS = $(CFLAGS) $(IMPORT_DEFINES) $(INCLUDE_PATH) -I$(OMNETPP_INCL_DIR)
MSGCOPTS = $(INCLUDE_PATH)
SMCOPTS =
# we want to recompile everything if COPTS changes,
# so we store COPTS into $COPTS_FILE and have object
# files depend on it (except when "make depend" was called)
COPTS_FILE = $O/.last-copts
ifneq ("$(COPTS)","$(shell cat $(COPTS_FILE) 2>/dev/null || echo '')")
$(shell $(MKPATH) "$O" && echo "$(COPTS)" >$(COPTS_FILE))
endif
#------------------------------------------------------------------------------
# User-supplied makefile fragment(s)
# >>>
# <<<
#------------------------------------------------------------------------------
# Main target
all: $O/$(TARGET)
$(Q)$(LN) $O/$(TARGET) .
$O/$(TARGET): $(OBJS) $(wildcard $(EXTRA_OBJS)) Makefile $(CONFIGFILE)
#$(MKPATH) $O
#echo Creating shared library: $#
$(Q)$(SHLIB_LD) -o $O/$(TARGET) $(OBJS) $(EXTRA_OBJS) $(AS_NEEDED_OFF) $(WHOLE_ARCHIVE_ON) $(LIBS) $(WHOLE_ARCHIVE_OFF) $(OMNETPP_LIBS) $(LDFLAGS)
$(Q)$(SHLIB_POSTPROCESS) $O/$(TARGET)
.PHONY: all clean cleanall depend msgheaders smheaders
.SUFFIXES: .cc
$O/%.o: %.cc $(COPTS_FILE) | msgheaders smheaders
#$(MKPATH) $(dir $#)
$(qecho) "$<"
$(Q)$(CXX) -c $(CXXFLAGS) $(COPTS) -o $# $<
%_m.cc %_m.h: %.msg
$(qecho) MSGC: $<
$(Q)$(MSGC) -s _m.cc $(MSGCOPTS) $?
%_sm.cc %_sm.h: %.sm
$(qecho) SMC: $<
$(Q)$(SMC) -c++ -suffix cc $(SMCOPTS) $?
msgheaders: $(MSGFILES:.msg=_m.h)
smheaders: $(SMFILES:.sm=_sm.h)
clean:
$(qecho) Cleaning...
$(Q)-rm -rf $O
$(Q)-rm -f $(TARGET)
$(Q)-rm -f $(call opp_rwildcard, . , *_m.cc *_m.h *_sm.cc *_sm.h)
cleanall: clean
$(Q)-rm -rf $(PROJECT_OUTPUT_DIR)
# include all dependencies
-include $(OBJS:%.o=%.d)
Has anybody solved the issue ?
To solve the problem I had to add missing "Include Paths" to the project properties:
1. Select your veins_inet project and click Project>>Properties in Omnet++
2. In the new window expand the OMNeT++ entry and select Makemake
3. select src:makemake(deep,recurse)-->veins_inet(dynamic lib)
4. Click on the Options... button
It should look like this: Properties for veins_inet window
5. Go to the Compile tab in the window that opens
6. Enter the missing include directories:
[workspace]/veins/subprojects/veins_inet/src
[workspace]/veins/src
[workspace]/inet/src
You should end up with something similar: Makemake Options window
7. Click OK in both windows
8. You should be able to build the veins_inet project without errors
if you use omnet++ 5.0 version :
IDE Project->properties->OMNET++ -> Makemake -> select src -> build makemake selected options button -> compile -> check [add all source folders under this deep makefile] :: then refresh and build project ..
I am struggling with the following problem :
I would like to use tput in my Makefile for color but it needs the environment variable $TERM ( and the echo alternative with \033[0;31m is not portable and will no behave the same way on all computers ).
When on an environment that does not have the variable, make fails and the program is not compiled.
I already tried searching for environment variable testing in a Makefile but with no success so far.
This is an example of what I would like to do :
define my_color
#tput setaf $2
#tput bold
#echo $1
#tput sgr0
endef
CC = gcc
CFLAGS = -Wall -Wextra
SRCS = my_super_file.c
OBJS = $(SRCS:.c=.o)
NAME = super_programm
all: $(NAME)
$(NAME): $(OBJS)
$(call my_color, " Compiling $<", 2)
$(CC) -o $(NAME) $(OBJS)
clean:
rm -rf $(OBJS)
fclean: clean
rm -rf $(NAME)
re: fclean all
.PHONY: all re clean fclean
a more complete example here : https://github.com/Hellfire01/Makefile/blob/master/Makefile
both will work just fine any computer but not on my server
What I am trying to do is have only one Makefile capable of working on both my computer and my server, I tried looking at the function ifeq but I did not succeed in getting it to work.
Any help will be greatly appreciated thank you for reading.
I think this makefile illustrates what you want:
have_term := $(shell echo $$TERM)
ifdef have_term
define my_color =
#tput setaf $2
#tput bold
#echo $1
#tput sgr0
endef
else
my_color = #echo $1
endif
all:
$(call my_color, "Hello world", 2)
If TERM is defined in the environment then make prints Hello World in
green, otherwise in plain white.
See 7.2 Syntax of Conditionals
Assuming the issue here is just that you want make to ignore errors/failures from tput when it can't operate correctly and continue you can do that by sticking a leading - on the tput lines (the same as the leading #).
So either #-tput ... or -#tput ....
This will cause make to see (and output) the errors but won't fail the target because of them.
From Errors in the GNU Make Manual:
To ignore errors in a recipe line, write a ‘-’ at the beginning of the line’s text (after the initial tab). The ‘-’ is discarded before the line is passed to the shell for execution.
For example,
clean:
-rm -f *.o
#- won't work, you'll get lots of error messages.
Something like this would work, but you could defintely write this more elegantly.
have_term := $(TERM)
ifeq ($(TERM),dumb)
have_term=
endif
ifdef have_term
color_blue = #tput setaf 6
color_end = #tput sgr0
else
color_blue =
color_end =
endif
I am trying to have a command executed depending on the current target from a list of targets (currently only one entry in that list) before another makefile is executed.
i have this:
$(LIBS):
ifeq ($#,libname)
my command here
endif
$(MAKE) -C ./lib/$#
the problem is, that the ifeq does not get executed even if the target name is correct. Using an $(info $#) shows exactly the libname but the expression is not evaluated as true.
I thought maybe there is a problem with expansion of the automatic variable in a conditional so i tried using an eval like this:
$(LIBS):
$(eval CURRENT_LIB := $#)
ifeq ($(CURRENT_LIB),libname)
my command here
endif
$(MAKE) -C ./lib/$#
info shows that the variable now equals exactly the libname but the ifeq does not get excuted.
When i enter something like ifeq (libname,libname) it works so the statement is working, but the comparison between variable and text does not evaluate to true even if the two are equal and it should work.
GNU make version is 4.1
What am i missing here?
Complete Makefile:
CC := g++
CFLAGS := -v -std=c++0x -pthread -Wall -g -O3
OBJ := mycode.o
OBJ += moreobjects.o
#more objects in here
LIBS = libname
.PHONY: libs $(LIBS)
SRC = $(OBJ:%.o=%.cpp)
DEPFILE := .depend
mytarget: libs $(OBJ)
$(CC) $(CFLAGS) -o $# $(OBJ)
-include $(DEPFILE)
%.o: %.cpp
$(CC) $(CFLAGS) -c $<
$(CC) -MM -std=c++11 $(SRC) > $(DEPFILE)
libs: $(LIBS)
$(LIBS):
$(eval CURRENT_LIB := $#)
ifeq ($(CURRENT_LIB),libname)
./lib/$(CURRENT_LIB)/configure
endif
$(MAKE) -C ./lib/$#
.PHONY: clean_all
clean_all: clean
$(foreach dir,$(LIBS),$(MAKE) clean -C ./lib/$(dir))
.PHONY: clean
clean:
rm -rf mytarget $(OBJ) $(DEPFILE)
Thank You very much!
What you are trying to do cannot work. From the documentation:
Conditionals control what 'make' actually "sees" in the makefile, so they cannot be used to control recipes at the time of execution.
The way I put it is that conditionals are evaluated at the time the Makefile is read. So make reads your Makefile, your conditional is false and it is removed.
"Normal" conditionals, don't work in a recipe with GNU make. Unfortunately that's true.
Workaround:
But you can use Functions for Conditionals and The eval Function instead. A small example for error detection from my build system. Here I use the eval and if function.
Snippet from Makefile.xu, which use eval and if:
xubuild_check_objects:
$(eval RESULT = $(call xu-obj_func-valid,$(xu-src-c-y)))
#echo 'echo nothing (dummy)' >/dev/null
$(if $(filter n,$(RESULT)), \
$(error XUbuild: error: xubuild_check_objects: xu-obj->xu-src-c-y override detected! Cannot build target! Aborting),)
NOTE:
#echo 'echo nothing (dummy)' >/dev/null
This here is required. When no command will be executed after eval, you get a make: Nothing to be done for 'xubuild_check_objects message.
Project Makefile (root directory) with error:
# XUbuild system (MUST included first)
include Makefile.xu
# This produces an error and aborts the build
xu-src-c-y = test.c
all: xubuild_check_objects
Error output:
$ make
Makefile.xu:104: *** XUbuild: error: xubuild_check_objects: xu-obj->xu-src-c-y override detected! Cannot build target! Aborting. Stop.
$
Project Makefile (root directory) without error:
# XUbuild system (MUST included first)
include Makefile.xu
# My build system is happy with this:
xu-src-c-y += test.c
all: xubuild_check_objects
Output (no error):
$ make
$
The full error detection from my build system simplified. I removed the most Makefile.xu "code" and only post the error detection here. (I don't explain my whole build system in this answer):
# XUbuild generic object
xu-obj := :xu-obj
xu-obj_del := :
# XUbuild object types
xu-obj_nop := n
xu-obj_yes := y
xu-obj_module := m
xu-obj_src := s
xu-obj_flag := f
# XUbuild source priority
xu-obj_src_head := 0
xu-obj_src_normal := 1
# XUbuild source types
xu-obj_src_a := 0
xu-obj_src_c := 1
xu-obj_src_cpp := 2
# XUbuild object functions
xu-obj_func-get = $(filter $(xu-obj)%,$(1))
xu-obj_func-remove = $(filter-out $(xu-obj)%,$(1))
xu-obj_func-valid = $(if $(call xu-obj_func-get,$(1)),y,n)
# XUbuild source objects
xu-src := $(xu-obj)$(xu-obj_del)
# XUbuild C source
xu-src-c := $(xu-src)$(xu-obj_src_normal)$(xu-obj_del)$(xu-obj_src_c)$(xu-obj_del)
xu-src-c- := $(xu-src-c)$(xu-obj_nop)
xu-src-c-y := $(xu-src-c)$(xu-obj_yes)
XUBUILD_PHONY += xubuild_check_objects
xubuild_check_objects:
$(eval RESULT = $(call xu-obj_func-valid,$(xu-src-c-y)))
#echo 'echo nothing (dummy)' >/dev/null
$(if $(filter n,$(RESULT)), \
$(error XUbuild: error: xubuild_check_objects: xu-obj->xu-src-c-y override detected! Cannot build target! Aborting),)
.PHONY: $(XUBUILD_PHONY)