I've built a number of projects with Veins on Omnet++ without issues at this stage, and I decided to implement CAM messages into a simulation. However, upon building I arrive at the following error:
12:41:23 **** Incremental Build of configuration release for project v2x ****
make MODE=release all
cd src && make make[1]: Entering directory '/home/veins/workspace.omnetpp/v2x/src'
Creating executable: ../out/clang-release/src/v2x /usr/bin/ld: cannot open output file ../out/clang-release/src/v2x: Is a directory
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]:
*** [Makefile:117: ../out/clang-release/src/v2x] Error 1 make[1]: Leaving directory '/home/veins/workspace.omnetpp/v2x/src'
make: *** [Makefile:2: all]
Error 2 "make MODE=release all" terminated with exit code 2.
Build might be incomplete.
12:41:24 Build Failed. 3 errors, 0 warnings. (took 549ms)
My Makefile reads:
#
# OMNeT++/OMNEST Makefile for v2x
#
# This file was generated with the command:
# opp_makemake -f --deep -KINET_PROJ=/home/veins/src/inet -KLTE_PROJ=/home/veins/src/simulte -KVEINS_INET_PROJ=/home/veins/src/veins/subprojects/veins_inet -KVEINS_PROJ=/home/veins/src/veins -DINET_IMPORT -DVEINS_IMPORT -DVEINS_INET_IMPORT -I$$\(INET_PROJ\)/src -I$$\(LTE_PROJ\)/src -I$$\(VEINS_INET_PROJ\)/src -I$$\(VEINS_PROJ\)/src -I. -L$$\(INET_PROJ\)/src -L$$\(LTE_PROJ\)/src -L$$\(VEINS_PROJ\)/src -L$$\(VEINS_INET_PROJ\)/src -lINET$$\(D\) -llte$$\(D\) -lveins$$\(D\) -lveins_inet$$\(D\)
#
# Name of target to be created (-o option)
TARGET_DIR = .
TARGET_NAME = v2x$(D)
TARGET = $(TARGET_NAME)$(EXE_SUFFIX)
TARGET_IMPLIB = $(TARGET_NAME)$(IMPLIB_SUFFIX)
TARGET_IMPDEF = $(TARGET_NAME)$(IMPDEF_SUFFIX)
TARGET_FILES = $(TARGET_DIR)/$(TARGET)
# User interface (uncomment one) (-u option)
USERIF_LIBS = $(ALL_ENV_LIBS) # that is, $(TKENV_LIBS) $(QTENV_LIBS) $(CMDENV_LIBS)
#USERIF_LIBS = $(CMDENV_LIBS)
#USERIF_LIBS = $(TKENV_LIBS)
#USERIF_LIBS = $(QTENV_LIBS)
# C++ include paths (with -I)
INCLUDE_PATH = -I$(INET_PROJ)/src -I$(LTE_PROJ)/src -I$(VEINS_INET_PROJ)/src -I$(VEINS_PROJ)/src -I.
# Additional object and library files to link with
EXTRA_OBJS =
# Additional libraries (-L, -l options)
LIBS = $(LDFLAG_LIBPATH)$(INET_PROJ)/src $(LDFLAG_LIBPATH)$(LTE_PROJ)/src $(LDFLAG_LIBPATH)$(VEINS_PROJ)/src $(LDFLAG_LIBPATH)$(VEINS_INET_PROJ)/src -lINET$(D) -llte$(D) -lveins$(D) -lveins_inet$(D)
# 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/v2x/GeneralMessageSerializer.o \
$O/v2x/VeinsInetApplicationBase.o \
$O/v2x/VeinsInetManager.o \
$O/v2x/VeinsInetManagerBase.o \
$O/v2x/VeinsInetManagerForker.o \
$O/v2x/VeinsInetMobility.o \
$O/v2x/VeinsInetSampleApplication.o \
$O/v2x/VeinsInetSampleMessageSerializer.o \
$O/v2x/GeneralMessage_m.o \
$O/v2x/VeinsInetSampleMessage_m.o
# Message files
MSGFILES = \
v2x/GeneralMessage.msg \
v2x/VeinsInetSampleMessage.msg
# SM files
SMFILES =
# Other makefile variables (-K)
INET_PROJ=/home/veins/src/inet
LTE_PROJ=/home/veins/src/simulte
VEINS_INET_PROJ=/home/veins/src/veins/subprojects/veins_inet
VEINS_PROJ=/home/veins/src/veins
#------------------------------------------------------------------------------
# Pull in OMNeT++ configuration (Makefile.inc)
ifneq ("$(OMNETPP_CONFIGFILE)","")
CONFIGFILE = $(OMNETPP_CONFIGFILE)
else
CONFIGFILE = $(shell opp_configfilepath)
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 = $(OPPMAIN_LIB) $(USERIF_LIBS) $(KERNEL_LIBS) $(SYS_LIBS)
ifneq ($(PLATFORM),win32.x86_64)
LIBS += -Wl,-rpath,$(abspath $(INET_PROJ)/src) -Wl,-rpath,$(abspath $(LTE_PROJ)/src) -Wl,-rpath,$(abspath $(VEINS_PROJ)/src) -Wl,-rpath,$(abspath $(VEINS_INET_PROJ)/src)
endif
COPTS = $(CFLAGS) $(IMPORT_DEFINES) -DINET_IMPORT -DVEINS_IMPORT -DVEINS_INET_IMPORT $(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 (if COPTS has changed since last build)
# and make the object files depend on it
COPTS_FILE = $O/.last-copts
ifneq ("$(COPTS)","$(shell cat $(COPTS_FILE) 2>/dev/null || echo '')")
$(shell $(MKPATH) "$O")
$(file >$(COPTS_FILE),$(COPTS))
endif
#------------------------------------------------------------------------------
# User-supplied makefile fragment(s)
-include makefrag
#------------------------------------------------------------------------------
# Main target
all: $(TARGET_FILES)
$(TARGET_DIR)/% :: $O/%
#mkdir -p $(TARGET_DIR)
$(Q)$(LN) $< $#
ifeq ($(TOOLCHAIN_NAME),clang-msabi)
-$(Q)-$(LN) $(<:%.dll=%.lib) $(#:%.dll=%.lib) 2>/dev/null
endif
$O/$(TARGET): $(OBJS) $(wildcard $(EXTRA_OBJS)) Makefile $(CONFIGFILE)
#$(MKPATH) $O
#echo Creating executable: $#
$(Q)$(CXX) $(LDFLAGS) -o $O/$(TARGET) $(OBJS) $(EXTRA_OBJS) $(AS_NEEDED_OFF) $(WHOLE_ARCHIVE_ON) $(LIBS) $(WHOLE_ARCHIVE_OFF) $(OMNETPP_LIBS)
.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 -MD -MP -MF $O/$(basename $<)_m.h.d $(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 $(TARGET)
$(Q)-rm -rf $O
$(Q)-rm -f $(TARGET_FILES)
$(Q)-rm -f $(call opp_rwildcard, . , *_m.cc *_m.h *_sm.cc *_sm.h)
cleanall:
$(Q)$(CLEANALL_COMMAND)
$(Q)-rm -rf $(PROJECT_OUTPUT_DIR)
help:
#echo "$$HELP_SYNOPSYS"
#echo "$$HELP_TARGETS"
#echo "$$HELP_VARIABLES"
#echo "$$HELP_EXAMPLES"
# include all dependencies
-include $(OBJS:%=%.d) $(MSGFILES:%.msg=$O/%_m.h.d)
It's correct in saying that clang-release/src/v2x is a directory, but it has always been so (even before making the recent changes) and it hasn't produced this error.
Other than the MakeFile error, there is no other error in any of the scripts for the project.
You want to create the executable file clang-release/src/v2x but you can't because that file already exists and is a directory.
The name of the file you attempt to create is
v2x$(D)$(EXE_SUFFIX) and nowhere in your Makefile do you have Make variables D or EXE_SUFFIX defined, so they evaluate to empty strings.
Probably you want to make sure you have D and EXE_SUFFIX defined somewhere.
There is a $(CONFIGFILE) you are including, Make finds it but you did not provide the text of it, check if these variables should be defined in there but are not.
Related
following issue: i'm currently working on some small c++ project, and i use imgui for the user interface. For that to work tho, i also need glfw(3). So i downloaded both the precompiled headers for osx and windows (https://www.glfw.org/download). And i added them to my project.
+---shared
+---lib
\---glfw
+---osx
| libglfw.3.dylib
| libglfw3.a
|
\---win
glfw3.dll
libglfw3.a
libglfw3dll.a
The next step (at least what i tried) was adding the lib .a file in the linkin process after creating the object files from my own sourcecode. I did this by specifying the -Lshared/lib/glfw/$(OS) path as well as the -lglfw3 flag. I did not get an error from those two. But when i run the linker, i get the following error message:
g++ -g -Wall -c -o src/core/src/main.o src/core/src/main.cpp
g++ -g -Wall -Ishared/include -Lshared/lib/glfw/win -lglfw3 -o bin/core src/core/src/main.o
c:/programdata/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: src/core/src/main.o:C:\Users\REDACTED\Desktop\LS/src/core/src/main.cpp:10: undefined reference to `glfwSetErrorCallback'
collect2.exe: error: ld returned 1 exit status
make: *** [makefile:78: core] Error 1
As far as i understand, this means that the linking of the library was not successfull.
( the code from src/core/src/main.cpp for completeness )
#include <stdio.h>
#include "../../../shared/include/glfw/glfw3.h"
static void glfw_error_callback(int error, const char *description)
{
}
int main(int argc, char *argv[])
{
glfwSetErrorCallback(glfw_error_callback);
printf("Hello World!\n");
return 0;
}
makefile code:
# ------------------------
# --- Global Settings ----
# ------------------------
CC = g++
# --------------------
# --- Common Flags ---
# --------------------
CFLAGS = -g -Wall
LDFLAGS = -I$(INCLUDE)
# Add correct glfw bins for either windows or osx
ifeq ($(OS), Windows_NT)
LDFLAGS += -L$(LIB)/glfw/win
else
LDFLAGS += -L$(LIB)/glfw/osx
endif
LDFLAGS += -lglfw3
# --------------
# --- Paths ----
# --------------
SRC = src
SHARED = shared
INCLUDE = $(SHARED)/include
LIB = $(SHARED)/lib
BIN = bin
DOCS = docs
# ---------------------
# --- Project Paths ---
# ---------------------
pCORE = $(SRC)/core
pIMPORTER = $(SRC)/importer
pEXPORTER = $(SRC)/exporter
pPROCESSOR = $(SRC)/processor
pUNIVERSALCLIENT = $(SRC)/universalclient
# --------------------------
# --- Housekeeping Tasks ---
# --------------------------
clean:
ifeq ($(OS), Windows_NT)
-del /s /q *.o
-rmdir /s /q $(BIN)
else
-find . -type f -name '*.o' -exec rm -f {} \;
-rm -rf $(BIN)
endif
clean_objs:
ifeq ($(OS), Windows_NT)
-del /s /q *.o
else
-find . -type f -name '*.o' -exec rm -f {} \;
-rm -rf $(BIN)
endif
setup:
ifeq ($(OS), Windows_NT)
-mkdir $(BIN)
else
-mkdir -p $(BIN)
endif
# ------------------------------------
# --- Shared Libraries Build Rules ---
# ------------------------------------
# ---------------------------
# --- Project Build Rools ---
# ---------------------------
pCORE_SRC = $(wildcard $(pCORE)/src/*.cpp)
pCORE_OBJ = $(patsubst %.cpp, %.o, $(pCORE_SRC))
core: $(pCORE_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(BIN)/core $^
$(pCORE_OBJ): $(pCORE_SRC)
$(CC) $(CFLAGS) -c -o $# $<
i worked myself through many documentations on how to link a library. Does someone understand whats going wrong or could someone explain it to me?
( regarding cmake: please don't ask - i can't use it for this project )
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 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)
hen I do make clean it complains about missing files. In particular it complains about mapnameserver.hthat is included in nstest.cc and nstime.cc.
I thought that doing make clean would ignore all other targets, even implicit ones.
What I want is to be able to do make clean and make vectornameserver without make complaining about the headers that nstest.cc and nstime.cc includes that I have not yet written. Is this possible?
Below is the files in the src dir
nameserverinterface.h
nstest.cc
nstime.cc
vectornameserver.cc
vectornameserver.h
And this is the Makefile
#
# Makefile for CPP
#
# Compiler and compiler options:
CC = /usr/local/bin/clang++
CXX = /usr/local/bin/clang++
CXXFLAGS = -c -pipe -O2 -Wall -W -ansi -pedantic-errors
CXXFLAGS += -Wmissing-braces -Wparentheses -Wold-style-cast
CXXFLAGS += -std=c++11 -stdlib=libc++ -nostdinc++
CXXFLAGS += -I/Users/einar/devel/libcxx/include/
LDFLAGS = -stdlib=libc++
LDLIBS = -L/Users/einar/devel/libcxx/lib/
SRCDIR = ../src
LIBDIR = ../lib
BINDIR = ../bin
DEPDIR = ../dep
VPATH = $(SRCDIR):$(LIBDIR):$(BINDIR):$(DEPDIR)
LIB_INSTALL =
BIN_INSTALL =
SRC = $(wildcard $(SRCDIR)/*.cc)
OBJ = $(notdir $(SRC:.cc=.o))
DEP = $(addprefix $(DEPDIR)/, $(notdir $(SRC:.cc=.d)))
PROGS = vectornameserver
MAKEDEPEND = $(CXX) -MM $(CPPFLAGS) -o $*.d $<
CP = /bin/cp
###
#
# Phony targets
#
###
.PHONY: all
all: $(PROGS)
.PHONY: folder_setup
folder_setup:
mkdir -p $(SRCDIR)
mkdir -p $(LIBDIR)
mkdir -p $(BINDIR)
mkdir -p $(DEPDIR)
.PHONY: clean
clean:
#$(RM) $(OBJ)
.PHONY: cleaner
cleaner:
#$(RM) $(OBJ)
#$(RM) $(PROGS)
#$(RM) $(DEP)
#$(RM) $(wildcard $(DEPDIR)/*.d*)
###
#
# Set up targets for program files in this section
# a rule should look like:
# program: obj1.o obj2.o ...
#
###
vectornameserver : vectornameserver.o
###
#
# In this section automatic dependencies are handled.
#
###
$(addprefix $(DEPDIR)/, %.d): %.cc
#set -e; rm -f $#; \
$(CXX) -MM $(CPPFLAGS) $< > $#.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $#: ,g' < $#.$$$$ \
> $#; rm -f $#.$$$$
###
#
# Include the automatically generated dependency files
#
###
include $(DEP)
Thanks in advance.
The problem is that you have an include directive in the makefile. This implicitly makes all the included dependency files implicit targets that must be refreshed BEFORE the primary target can be run. It is those rules that are running the compiler and giving you the errors.
Since generally you don't want/need the dependency files if you're just doing a make clean, the usual thing is to wrap appropriate ifs around the include:
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),cleaner)
-include $(DEP)
endif
endif
This will avoid trying to include the depfiles (and thus regenerate them) if you do make clean or make cleaner. In addition, the - prefix on the include supresses warnings about the depfiles not existing when you first run make (it will (re)generate them and reread the makefile and depfiles if need be.)
I am not very familiar with make; i've always used and modified this highly ancient makefile I inherited from another project, modifying it as necessary. Up until now, it has functioned perfectly, compiling together projects with 20-50 files, even within sub-directories, determining and building all the dependencies properly.
Today I am running a very simple test code to determine if BOOST.MPI will work on a cluster I recently got access to. I am trying to compile a 1-file test case to make sure that the library works. This is also my first time building and linking to boost on this system.
I have boost installed in my user directory: ~/boost, and I've run the appropriate bjam to ensure that BOOST.MPI is present. I don't believe my problem lies there. As you'll see in a moment, however, I had to include -lboost_mpi and -lboost_serialization to get as far as I did.
The makefile seems to compile, and assemble just fine producing the intermediary .a file. It hangs up on the linking step with a surprising error:
Creating dependency for "boosttest.cpp"
Compiling "boosttest.cpp"
Assembling ag...
ar: creating ./libag.a
Linking bt1...
/usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status
make: *** [bt1] Error 1
The only source code I've written (copy/pasted right out of the Boost.MPI implementation page):
boosttest.cpp:
#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>
#include <iostream>
int main(int argc, char* argv[])
{
boost::mpi::environment env(argc, argv);
boost::mpi::communicator world;
std::cout << "I am process " << world.rank() << " of " << world.size()<< "." << std::endl;
return 0;
}
Now for the part where I get lost. This is the makefile I've modified. I mostly understand what parts of it are doing, and it is the only makefile I've ever seen (although as mentioned I'm not very experienced with them) to produce .d files containing a list of all dependent libraries.
Makefile:
PROJECT = boosttest
# The names of the sub-projects that the executable depends on. These names are used later on to define targets, location, libraries, etc.
DEPS =
# The names of the sub-projects that the test executable depends on.
TEST_DEPS =
EXE_DEPS =
LOCAL_O_FILES = boosttest.o
LOCAL_TEST_O_FILES =
LOCAL_LIB_NAME = ag
LOCAL_LIB_DIR = .
LOCAL_TEST_LIB_NAME =
LOCAL_TEST_LIB_DIR =
LOCAL_INCLUDE_ROOT = .
EXE_NAME = BT
MPIC_DIR = /usr/local/mvapich2-1.6-gcc/
#these assume our local path and bin are set up properly since I don't know where the compilers are
CC = $(MPIC_DIR)/bin/mpicc
CCC = $(MPIC_DIR)/bin/mpicxx
F77 = $(MPIC_DIR)/bin/mpif77
CLINKER = $(MPIC_DIR)/bin/mpicc
CCLINKER = $(MPIC_DIR)/bin/mpicxx
FLINKER = $(MPIC_DIR)/bin/mpif90
F90 = $(MPIC_DIR)/bin/mpif90
F90LINKER = $(MPIC_DIR)/bin/mpif90
MAKE = make --no-print-directory
SHELL = /bin/sh
#PROF = -ggdb -O2
PROF = -O2
ADDITIONAL_LIBS = -lboost_mpi -lboost_serialization
SED = $(shell which sed)
GREP = $(shell which grep)
# Warnings will depend on the GCC version -- if it's 4, have "-Wdeclaration-after-statement -Wunused-value -Wunused-variable"
#GCC_MAJOR_VERSION = $(shell $(CCC) --version | $(GREP) "\(egcs\|gcc\)" | $(SED) "s/[^0-9]*\([0-9]\).*/\1/")
#WARNINGS = -Wno-import $(shell if test $(GCC_MAJOR_VERSION) -eq 4; then echo -Wunused-value -Wunused-variable; fi)
#GCC_INSTALL_DIR = /turing/software-linux/mpich-eth
GCC_INSTALL_DIR = $(MPIC_DIR)
GCC_INCLUDE_DIR = $(GCC_INSTALL_DIR)/include/
GCC_LIB_DIR = $(GCC_INSTALL_DIR)/lib/
BOOST_DIR = ~/boost
BOOST_LIB_DIR = ~/boost/stage/lib
# Expand SRCDIR so that it turns into "-I <srcdir>" for each listed directory
INCLUDE_DIRS = -I $(OBJC_ROOT)/include $(foreach dep, $(UNIQUE_DEPS), -I$($(dep)_INCLUDE_ROOT)) -I $(LOCAL_INCLUDE_ROOT) -I $(BOOST_DIR) -I $(GCC_INCLUDE_DIR)
#C_FLAGS = -DROM $(PROF) $(WARNINGS) $(INCLUDE_DIRS)
C_FLAGS = -DROM $(PROF) $(INCLUDE_DIRS)
L_FLAGS = $(foreach dir, $(OBJC_ROOT) $(DEP_LIB_DIRS), -L$(dir)) -L $(BOOST_LIB_DIR) -L $(GCC_LIB_DIR) $(PROF) $(ADDITIONAL_LIBS)
TEST_L_FLAGS = $(foreach dir, $(OBJC_ROOT) $(TEST_DEP_LIB_DIRS), -L$(dir)) -L/usr/lib -Xlinker --whole-archive $(TEST_REQUIRED_LIBS) -Xlinker --no-whole-archive
REQUIRED_LIBS = $(foreach dep, $(DEPS) LOCAL, $(if $($(dep)_LIB_NAME), -l$($(dep)_LIB_NAME)))
TEST_REQUIRED_LIBS = $(foreach dep, $(TEST_DEPS) LOCAL LOCAL_TEST, $(if $($(dep)_LIB_NAME), -l$($(dep)_LIB_NAME)))
.SUFFIXES:
.SUFFIXES: .d .cc .cpp .c .o
ASSEMBLE_TARGETS = $(foreach dep,$(DEPS),$(dep)_LIB_NAME)
ASSEMBLE_TEST_TARGETS = $(foreach dep,$(TEST_DEPS),$(dep)_LIB_NAME)
CLEAN_TARGETS = $(foreach dep, $(UNIQUE_DEPS), $(dep)_CLEAN)
LOCAL_D_FILES = $(LOCAL_O_FILES:.o=.d)
LOCAL_TEST_D_FILES = $(LOCAL_TEST_O_FILES:.o=.d) $(TEST_RUNNER:.o=.d)
DEP_LIB_DIRS = $(foreach dep, $(DEPS) LOCAL, $($(dep)_LIB_DIR))
TEST_DEP_LIB_DIRS = $(foreach dep, $(TEST_DEPS) LOCAL LOCAL_TEST, $($(dep)_LIB_DIR))
UNIQUE_ASSEMBLE_TARGETS = $(sort $(ASSEMBLE_TARGETS) $(ASSEMBLE_TEST_TARGETS))
UNIQUE_DEPS = $(sort $(DEPS) $(TEST_DEPS))
LOCAL_LIB = $(if $(LOCAL_LIB_NAME), $(LOCAL_LIB_DIR)/lib$(LOCAL_LIB_NAME).a)
LOCAL_TEST_LIB = $(if $(LOCAL_TEST_LIB_NAME), $(LOCAL_TEST_LIB_DIR)/lib$(LOCAL_TEST_LIB_NAME).a)
EXE_TARGETS = $(foreach dep,$(EXE_DEPS),$(dep)_EXE_NAME)
INSTALL_TARGETS = $(foreach dep,$(EXE_DEPS),$(dep)_INSTALL)
export PROJECTS += $(PROJECT)
# PHONY targets get remade even if there exists an up-to-date file with the same name.
.PHONY: default clean compile assemble link submit
# Targets for mortals
default: link
clean: $(CLEAN_TARGETS) LOCAL_CLEAN
compile: $(DEPS) $(LOCAL_D_FILES) $(LOCAL_O_FILES)
assemble: compile $(ASSEMBLE_TARGETS) $(LOCAL_LIB)
link: assemble $(EXE_TARGETS) $(EXE_NAME)
install: $(INSTALL_TARGETS) $(if $(EXE_NAME), LOCAL_INSTALL)
submit: link
qsub $(PROJECT).qsub
# Targets for make
# Invoking sub projects
$(UNIQUE_DEPS): MAKE_TARGET = $(if $(filter %_TEST, $#), compile-tests, compile)
$(UNIQUE_DEPS):
$(if $(findstring $(DEP_NAME), $(PROJECTS)),,cd $($#_DIR) && $(MAKE) $(MAKE_TARGET))
# First, remove the _LIB_NAME attached by ASSEMBLE_TARGETS, a
$(UNIQUE_ASSEMBLE_TARGETS): DEP_NAME = $(#:_LIB_NAME=)
$(UNIQUE_ASSEMBLE_TARGETS): MAKE_TARGET = $(if $(filter %_TEST, $(DEP_NAME)), assemble-tests, assemble)
$(UNIQUE_ASSEMBLE_TARGETS):
$(if $(findstring $(DEP_NAME), $(PROJECTS)),,cd $($(DEP_NAME)_DIR) && $(MAKE) $(MAKE_TARGET))
# First, remove the _EXE_NAME attached by EXE_TARGETS, a
$(EXE_TARGETS): DEP_NAME = $(#:_EXE_NAME=)
$(EXE_TARGETS):
$(if $(findstring $(DEP_NAME), $(PROJECTS)),,cd $($(DEP_NAME)_DIR) && $(MAKE) link)
$(CLEAN_TARGETS): DEP_NAME = $(#:_CLEAN=)
$(CLEAN_TARGETS):
$(if $(findstring $(DEP_NAME), $(PROJECTS)),,cd $($(DEP_NAME)_DIR) && $(MAKE) clean)
$(INSTALL_TARGETS): DEP_NAME = $(#:_INSTALL=)
$(INSTALL_TARGETS):
$(if $(findstring $(DEP_NAME), $(PROJECTS)),,cd $($(DEP_NAME)_DIR) && $(MAKE) install)
#Local stuff
# The rule to change either a '.c' or a '.m' to a '.o'
#%.o : %.c %.d %.cc %.cpp
.cc.o .cpp.o .c.o:
#echo "Compiling \"$<\""
#$(CCC) -c $(C_FLAGS) $< -o $#
.cc.d .cpp.d .c.d :
#echo "Creating dependency for \"$<\""
# #$(CCC) $(WARNINGS) $(INCLUDE_DIRS) -MM $< -o $#
# This foogly hack because gcc seems to have issues with emitting the correct target/dependency names of
# files in sub-dirs of the current dir (specifically, it doesn't add the sub-dir to the target
# name, and insists on adding the directory to the dependencies) which ends up breaking dependencies...)
#dependLine=$$( $(CCC) $(C_FLAGS) $(INCLUDE_DIRS) -MM $< ); \
dirName=$$( dirname $< | $(SED) "s/\//\\\\\//g" ); \
dependLine=$$( echo $${dependLine} | $(SED) "s/ $${dirName}\// /g" ); \
oFile=$$( echo $${dependLine} | $(SED) "s/:.*//" ); \
dependencies=$$( echo $${dependLine} | $(SED) "s/.*://" ); \
echo $${oFile} $${oFile%.o}.d: $${dependencies} | $(SED) "s/ \\\//g" > $#
$(UNIQUE_ASSEMBLE_TARGETS): DEP_NAME = $(#:_LIB_NAME=)
$(UNIQUE_ASSEMBLE_TARGETS): MAKE_TARGET = $(if $(filter %_TEST, $(DEP_NAME)), assemble-tests, assemble)
$(UNIQUE_ASSEMBLE_TARGETS):
$(if $(findstring $(DEP_NAME), $(PROJECTS)),,cd $($(DEP_NAME)_DIR) && $(MAKE) $(MAKE_TARGET))
# First, remove the _EXE_NAME attached by EXE_TARGETS, a
$(EXE_TARGETS): DEP_NAME = $(#:_EXE_NAME=)
$(EXE_TARGETS):
$(if $(findstring $(DEP_NAME), $(PROJECTS)),,cd $($(DEP_NAME)_DIR) && $(MAKE) link)
$(CLEAN_TARGETS): DEP_NAME = $(#:_CLEAN=)
$(CLEAN_TARGETS):
$(if $(findstring $(DEP_NAME), $(PROJECTS)),,cd $($(DEP_NAME)_DIR) && $(MAKE) clean)
$(INSTALL_TARGETS): DEP_NAME = $(#:_INSTALL=)
$(INSTALL_TARGETS):
$(if $(findstring $(DEP_NAME), $(PROJECTS)),,cd $($(DEP_NAME)_DIR) && $(MAKE) install)
#Local stuff
# The rule to change either a '.c' or a '.m' to a '.o'
#%.o : %.c %.d %.cc %.cpp
.cc.o .cpp.o .c.o:
#echo "Compiling \"$<\""
#$(CCC) -c $(C_FLAGS) $< -o $#
.cc.d .cpp.d .c.d :
#echo "Creating dependency for \"$<\""
# #$(CCC) $(WARNINGS) $(INCLUDE_DIRS) -MM $< -o $#
# This foogly hack because gcc seems to have issues with emitting the correct target/dependency names of
# files in sub-dirs of the current dir (specifically, it doesn't add the sub-dir to the target
# name, and insists on adding the directory to the dependencies) which ends up breaking dependencies...)
#dependLine=$$( $(CCC) $(C_FLAGS) $(INCLUDE_DIRS) -MM $< ); \
dirName=$$( dirname $< | $(SED) "s/\//\\\\\//g" ); \
dependLine=$$( echo $${dependLine} | $(SED) "s/ $${dirName}\// /g" ); \
oFile=$$( echo $${dependLine} | $(SED) "s/:.*//" ); \
dependencies=$$( echo $${dependLine} | $(SED) "s/.*://" ); \
echo $${oFile} $${oFile%.o}.d: $${dependencies} | $(SED) "s/ \\\//g" > $#
$(LOCAL_LIB): compile $(ASSEMBLE_TARGETS)
#echo Assembling $(LOCAL_LIB_NAME)...
#ar rs $(LOCAL_LIB) $(LOCAL_O_FILES)
# Create the executable
$(EXE_NAME): assemble
#echo Linking $(EXE_NAME)...
#$(CCC) -o $(EXE_NAME) $(L_FLAGS)
# Erase all object files, the dependencies file, the core file and the executable, then rebuild everything
LOCAL_CLEAN:
#echo Cleaning $(PROJECT)...
#rm -f $(LOCAL_O_FILES) $(LOCAL_TEST_O_FILES) $(LOCAL_LIB) $(LOCAL_TEST_LIB) $(EXE_NAME) $(TEST_EXE_NAME) $(LOCAL_D_FILES) $(LOCAL_TEST_D_FILES) $(TEST_RUNNER) $(TEST_RUNNER:.o=.d) core*
ifeq (,$(findstring clean,$(MAKECMDGOALS)))
-include $(LOCAL_O_FILES:.o=.d) $(LOCAL_TEST_O_FILES:.o=.d)
endif
The paths to my mpicxx compiler (needed for the cluster, and for those unfamiliar, it wraps gcc) are correct, as evidenced by the fact that it does compile, it just won't link. Similarly, my boost library paths seem functional, the -lboost_mpi flag gets caught properly.
At this point, my question has extended to be for my own education based on how this makefile works/intends to work. Ultimately the entirely obvious/simple command:
mpicxx boosttest.cpp -L ~/boost/stage/lib/ -lboost_mpi -lboost_serialization -o test
however I want to get a proper makefile going as once I get past this test case verifying Boost.MPI's equivalent of a hello world, I'll be moving on to projects involving my full source code, 20+ files with cross dependencies, etc. Any help or intuition would be greatly appreciated.
Based on the suggestion of #Oktalist above, I was able to find something that works, at least for the single-file case, but I can't see why it won't work when I extend this to multiple files. I'm still at a loss why this worked in the past but not now, but perhaps I changed something I wasn't tracking.
The correction is near the end, in this block:
# Create the executable
$(EXE_NAME): assemble
#echo Linking $(EXE_NAME)...
#$(CCC) $(L_FLAGS) $(LOCAL_LIB) -o $(EXE_NAME)