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.
I have a really strange issue with the Makefile in one of my off-time projects.
I have a Makefile (shown below) that generates dependency information in .d files following https://www.gnu.org/software/make/manual/html_node/Automatic-Prerequisites.html.
The problem is that a change in one of my header files (shader.h) does not trigger the recompilation of shader.o (out of shader.cpp).
The problem started happening recently when I re-organized the directory structure in my project so I suspect it is related to that.
The strange thing is that if I do make --print-data-base it does seem like it has found the correct prerequisites matching the shader.d file.
The diretory structure is as follows:
|-src
|-engine
|-shader.h
|-shader.cpp
|-bin
|-Debug
|-OpenGLTest
|-obj
|-Debug
|-engine
|-shader.o
|-dep
|-engine
|-shader.d
Makefile:
WORKDIR = `pwd`
CC = gcc
CXX = g++
AR = ar
LD = g++
WINDRES = windres
INC = -I/usr/local/include
CFLAGS = -Wall -Werror
CXX_FLAGS = -std=c++11
RESINC =
LIBDIR = -L/usr/local/lib
LIB = -lSDL2 -lGLEW -framework OpenGL
LDFLAGS =
DEPDIR = dep
SRCDIR = src
INC_DEBUG = $(INC)
CFLAGS_DEBUG = $(CFLAGS) -g
RESINC_DEBUG = $(RESINC)
RCFLAGS_DEBUG = $(RCFLAGS)
LIBDIR_DEBUG = $(LIBDIR)
LIB_DEBUG = $(LIB)
LDFLAGS_DEBUG = $(LDFLAGS)
OBJDIR_DEBUG = obj/Debug
DEP_DEBUG =
OUT_DEBUG = bin/Debug/OpenGLTest
CXX_SRCS = $(wildcard $(SRCDIR)/*.cpp) $(wildcard $(SRCDIR)/**/*.cpp)
CXX_REL_SRCS = $(subst $(SRCDIR)/,,$(CXX_SRCS))
OBJS = $(CXX_REL_SRCS:%.cpp=%.o)
OBJ_DEBUG = $(addprefix $(OBJDIR_DEBUG)/,$(OBJS))
# ----------------------------- debug -----------------------------
clean: clean_debug clean_release
rm -rf $(DEPDIR)
before_debug:
#test -d bin/Debug || mkdir -p bin/Debug
#test -d $(OBJDIR_DEBUG) || mkdir -p $(OBJDIR_DEBUG)
#mkdir -p $(dir $(OBJ_DEBUG))
after_debug:
debug: before_debug out_debug after_debug
out_debug: before_debug $(OBJ_DEBUG) $(DEP_DEBUG)
$(LD) $(LIBDIR_DEBUG) -o $(OUT_DEBUG) $(OBJ_DEBUG) $(LDFLAGS_DEBUG) $(LIB_DEBUG)
$(OBJDIR_DEBUG)/%.o: $(SRCDIR)/%.cpp
$(CXX) $(CFLAGS_DEBUG) $(CXX_FLAGS) $(INC_DEBUG) -c $< -o $#
clean_debug:
rm -f $(OBJ_DEBUG) $(OUT_DEBUG)
rm -rf bin/Debug
rm -rf $(OBJDIR_DEBUG)
# ----------------------------- dependencies -----------------------------
# Generate dependencies in *.d files
$(DEPDIR)/%.d: $(SRCDIR)/%.cpp
#test -d $(DEPDIR) || mkdir -p $(DEPDIR)
#mkdir -p $(dir $#)
#set -e; rm -f $#; \
$(CXX) -MM $(CFLAGS) $(CXX_FLAGS) $(INC) $< > $#.$$$$; \
sed 's,\(.*\)\.o[ :]*,$(OBJDIR_RELEASE)/\1.o $(OBJDIR_DEBUG)/\1.o $# : ,g' < $#.$$$$ > $#; \
rm -f $#.$$$$
# Include the *.d files
include $(patsubst %,$(DEPDIR)/%.d,$(basename $(CXX_REL_SRCS)))
# ----------------------------- targets -----------------------------
.PHONY: before_debug after_debug clean_debug
all: debug
shader.d:
obj/Debug/shader.o dep/engine/shader.d : src/engine/shader.cpp src/engine/shader.h \
src/engine/transform.h src/engine/camera.h src/engine/constants.h
I'll answer this since the issue has been found by #G.M. in the comments.
Turns out that the dependency generation was flawed.
In shader.d obj/Debug/shader.o should really be obj/Debug/engine/shader.o. Modifying the sed command as shown below fixes this.
sed 's,\(.*\)\.o[ :]*,$(OBJDIR_RELEASE)/$(subst $(SRCDIR)/,,$(dir $<))\1.o $(OBJDIR_DEBUG)/$(subst $(SRCDIR)/,,$(dir $<))\1.o $# : ,g' < $#.$$$$ > $#;
I use opencv in my project, and now I compile the project into a static library using makefile, but always output 'fatal error: 'cv.h' file not found'. I have searched this site and elsewhere, it's not what I need. I only know a little makefile syntax. What should I do?
Makefile
LIBS_DIR = ./lib/
OBJS_DIR = ./obj/
DEPENDENT_DIR = ./dependent/
HEADER_PATH = -I./include -I./implement -I.
LIB_PATH = -L./lib
SRCDIRS := $(patsubst ./%, %, $(shell find . -type d))
SRCS_CXX := $(foreach dir, $(SRCDIRS), $(wildcard $(addprefix $(dir)\/*, .cpp)))
OBJS := $(SRCS_CXX:.cpp=.o)
%.o: %.cpp
#echo "---------- .o begin ----------"
$(CXX) -c $< $(HEADER_PATH)
$(CXX) -o $# $^ $(LIB_PATH)
mv $# $(OBJS_DIR)
%.d: %.cpp
#echo "---------- dependent begin ----------"
#set -e; \
rm -f $#; \
$(CXX) -MM $< > $#.tmp; \
sed 's,\($*\)\.o[ :]*,\1.o $# : ,g' < $#.tmp > $#; \
rm -f $#.tmp
mv $# $(DEPENDENT_DIR)
-include $(DEPS)
.PHONY: clean
clean:
rm -f obj/*.o lib/*.a dependent/*.d
rm -rf SunWS_cache
In my file
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
File directory
Used makefile
New error
I modified the HEADER_PATH like HEADER_PATH = -I./include/opencv -I./include/opencv2 -I./implement -I. but a new error appeared, fatal error: 'opencv2/core/core_c.h' file not found.
I try to add a new subfolder path like -I./include/opencv -I./include/opencv2 -I./include/opencv2/core -I./implement -I. this error is still being output, -I command doesn't automatically find the path to the subfolder? am I doing anything wrong?
Your header paths are HEADER_PATH = -I./include -I./implement -I.
Inside the include folder you show in the attachment you have 2 subfolders opencv and opencv2.
When including the cv.h file is included directly without the subfolders.
For the compiler to find the files you either need to add the subfolders on the HEADER_PATH like HEADER_PATH = -I./include/opencv -I./include/opencv2 -I./implement
or you need to #include <opencv/cv.h>, that if cv.h is directly inside the opencv subfolder.
Side note: you have a typo in the folder denpendent
Finally, I solved this error and compiled successfully, I still use CMake. but after I successfully compiled with CMake, I can use the Makefile again to compile. I think it was my own mistake, #zomeck's answer helped me.
This is my CMakeLists.txt
cmake_minimum_required(VERSION 3.2)
project(library_name)
add_definitions(-Wall)
set(OPENCV_PATH ../sdk3/opencv3.0.0)
set(OPENCL_PATH ../sdk3/opencl)
link_directories(
${OPENCL_PATH}/bin
${OPENCV_PATH}
)
link_libraries(
${OPENCV_PATH}/opencv2.framework
${OPENCL_PATH}/bin/OpenCL.DLL
)
include_directories(
./
./implement
${OPENCV_PATH}/include
${OPENCV_PATH}/include/opencv
${OPENCL_PATH}/include/CL
)
set(SOURCES_FILES
HS_Process.cpp
implement/iclear/H_Proc.cpp
)
add_library(library_name STATIC ${SOURCES_FILES})
target_link_libraries(library_name opencv2 OpenCL)
New Makefile after #zomeck's answer
# The following is modified
SDK_PATH = ../sdk3
OPENCL_PATH = ../sdk3/opencl
OPENCV_PATH = ../sdk3/opencv3.0.0/include
vpath = %.h implement : %.h $(OPENCV_PATH) : %.h $(OPENCV_PATH)/opencv : %.h $(OPENCL_PATH) : %.h $(CALCTIME_PATH)
HEADER_PATH = \
-I. \
-I./implement \
-I$(OPENCV_PATH) \
-I$(OPENCV_PATH)/opencv \
-I$(OPENCV_PATH)/opencv2 \
-I$(OPENCL_PATH)/include/CL \
%.o: %.cpp
#echo "---------- .o begin ----------"
$(CXX) $(CXXFLAGS) -c $(HEADER_PATH) $< -o $#
mv $# $(OBJS_DIR)
I am new to using CMake and am attempting to transfer our previous Makefiles into CMakeLists. I have one file, *dsplink_defines.txt* that has the following compile-time defines.
*-DOS_LINUX -DMAX_DSPS=1 -DMAX_PROCESSORS=2 -DID_GPP=1 -DOMAPL1XX -DPROC_COMPONENT -DPOOL_COMPONENT -DNOTIFY_COMPONENT -DMPCS_COMPONENT -DRINGIO_COMPONENT -DMPLIST_COMPONENT -DMSGQ_COMPONENT -DMSGQ_ZCPY_LINK -DCHNL_COMPONENT -DCHNL_ZCPY_LINK -DZCPY_LINK -DKFILE_DEFAULT -DDA8XXGEM -DDA8XXGEM_PHYINTERFACE=SHMEM_INTERFACE -DGPP_SWI_MODE -D_REENTRANT -DVERIFY_DATA -DDDSP_DEBUG*
Our previous Makefile took care of this in the following manner and took care of this by using shell cat starting on line 8:
BIN = ../../build/bin
TMP = build
BUILD_DEF = -DBUILD=$(BUILD_VERSION) -DBUILD_DATE=$(BUILD_DATE)
# these files are captured from the DSPLink Sample build directory (and the named changed)
# they contain the appropriate includes and flags to build a dsplink application.
DSPLINK_INCLUDES = $(shell cat ../dsplink_config/dsplink_includes.txt)
DSPLINK_FLAGS = $(shell cat ../dsplink_config/dsplink_flags.txt)
DSPLINK_DEFINES = $(shell cat ../dsplink_config/dsplink_defines.txt)
DSPLINK_LIBS = $(DSPLINK_PACKAGE_DIR)/dsplink/gpp/export/BIN/Linux/OMAPL1XX/RELEASE/dsplink.lib
#Our project variables
INCLUDE = -I../framework -I../io_master -I../logging -I../../dsp/include - I../flagDictionary
#TOOLCHAIN = ${FACTORY_DIR}/build_armv5l-timesys-linux-uclibcgnueabi/toolchain/bin
TOOLCHAIN = /OMAP-L137/timesys/SDK/omapl137_evm/toolchain/bin
PLATFORM=armv5l-timesys-linux-uclibcgnueabi
#Compile Options
CC=$(TOOLCHAIN)/$(PLATFORM)-g++
LINKER=$(TOOLCHAIN)/$(PLATFORM)-g++
CFLAGS+= $(BUILD_DEF) $(INCLUDE) $(DSPLINK_DEFINES) $(DSPLINK_FLAGS) $(DSPLINK_INCLUDES)
DEBUG = -O
#list of things to compile.
FW_BUILD_DIR=../framework/build
LOG_BUILD_DIR=../logging/build
FLAG_DICT_BUILD_DIR=../flagDictionary/build
FRAMEWORK_OBJECTS= $(FW_BUILD_DIR)/com.o \
$(FW_BUILD_DIR)/application.o \
$(FW_BUILD_DIR)/memoryManagerBase.o \
$(FW_BUILD_DIR)/memoryManager.o \
$(FW_BUILD_DIR)/arguments.o \
$(FW_BUILD_DIR)/lockManager.o \
$(FW_BUILD_DIR)/controlCom.o \
$(FW_BUILD_DIR)/paths.o \
$(LOG_BUILD_DIR)/subsystemLogMasks.o \
$(LOG_BUILD_DIR)/logger.o
FLAG_DICT_OBJECTS= $(FLAG_DICT_BUILD_DIR)/flagEntry.o \
$(FLAG_DICT_BUILD_DIR)/flagDictionary.o
OBJECTS = spidev_test.o sysMon.o
EXES = sysMon
all: $(OBJECTS) $(EXES)
.c.o:
mkdir -p build
$(CC) -c $(CFLAGS) $(DEBUG) -o $(TMP)/$# $<
.cpp.o:
mkdir -p build
$(CC) -c $(CFLAGS) $(DEBUG) -o $(TMP)/$# $<
spidev_test: $(FRAMEWORK_OBJECTS) spidev_test.o
$(LINKER) -lpthread -lc -o $(BIN)/$# $(DSPLINK_LIBS) build/spidev_test.o $(FRAMEWORK_OBJECTS)
sysMon: $(FRAMEWORK_OBJECTS) sysMon.o
$(LINKER) -lpthread -lc -o $(BIN)/$# $(DSPLINK_LIBS) build/sysMon.o $(FLAG_DICT_OBJECTS) $(FRAMEWORK_OBJECTS)
deploy:
../../build/deploy
How do I pass these in using a CMakeList
This should work:
file(READ path/to/dsplink_defines.txt defines) #read file into variable 'defines'
string(REPLACE " " ";" defines "${defines}") #turn space separation into CMake list
add_definitions(${defines})
Of course, if you have full control of the file and can change its format to use semicolons for separation instead of spaces, you can do that and skip the string() line (probably speeding up your CMake processing a little bit by this).
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)