I am trying to create a makefile using the help of this thread, I changed the code provided a little bit since I have many *.c files that need to be compiled.
this the project hierarchy:
/coap
Makefile
/src
/src
/coap
/imc
*.h files
/src
*.c files
/system
/imc
client.h
/src
client.c
**makefile**
/files
sdk.sh
I made the first makefile and it seems to work fine, but my problem is with the second one written in bold.
Here, I provide the changes that I made:
program_NAME := coap
program_C_SRCS += \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/address.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/async.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/block.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/coap_asn1.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/coap_cache.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/coap_debug.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/coap_event.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/coap_gnutls.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/coap_hashkey.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/coap_io.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/coap_mbedtls.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/coap_notls.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/coap_openssl.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/coap_prng.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/coap_session.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/coap_tcp.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/coap_time.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/coap_tinydtls.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/encode.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/mem.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/net.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/option.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/pdu.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/resource.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/str.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/subscribe.c \
/home/iat2/Projects/XXXX/package/coap/src/src/coap/src/uri.c
program_C_OBJS := ${program_C_SRCS:.c=.o}
program_OBJS := $(program_C_OBJS)
program_INCLUDE_DIRS :=/home/iat2/Projects/XXXX/package/coap/src/src/coap/imc
program_LIBRARY_DIRS :=
program_LIBRARIES := router
CFLAGS += $(foreach includedir,$(program_INCLUDE_DIRS),-I$(includedir))
LDFLAGS += $(foreach librarydir,$(program_LIBRARY_DIRS),-L$(librarydir))
LDFLAGS += $(foreach library,$(program_LIBRARIES),-l$(library))
.PHONY: all clean distclean
all: $(program_NAME)
$(program_NAME): $(program_OBJS)
$(LINK.cc) $(program_OBJS) -o $(program_NAME)
clean:
#- $(RM) $(program_NAME)
#- $(RM) $(program_OBJS)
distclean: clean
When I try to compile, the log file output is:
fatal error: sys/random.h: No such file or directory
#include <sys/random.h>
and it can't recognize some of the openssl functions written in the coap_openssl.c file.
Related
I can use the -MM option in g++ to generate the dependencies in a makefile rule format.
g++ -MM module2.cpp -I../src -I../../raven-set -I. -I../src/ext
outputs
module2.o: module2.cpp pch.h ../src/theGlobalDefines.h \
../../raven-set/raven_sqlite.h ../src/ext/sqlite3.h Module2.h \
cPelexMixerComponent.h cErrorHandler.h cTimedEvent.h cPelexConfig.h \
../src/sgp.h ../src/cCircularVector.h ../../raven-set/cTimerBusyLoop.h \
../src/channelIdentification.h ../src/cPacketData.h cRxTx.h \
cOutputTransmitter.h cDelayStats.h cMCUSB202.h cPeakerServer.h cInput.h \
../src/cSequenceNumber.h cRxPelexWireless.h ../../raven-set/cRunCount.h \
cPeakFilter.h cSPO2StateMachine.h wrs_cProcessed.h ../src/log.h \
wrs/cRaw.h wrs/cPacket.h wrs/cCalibrate.h wrs/cStream.h \
../src/cPelexMixerConfig.h ../src/ext/json.h wrs/cSignalProcessor_wrs.h \
cD1ZeroCross.h ../src/cVitals.h cUI.h cTimeProfiler.h \
../licenser/cLicence.h cSignalProcessor.h ../src/cPeakFilterSet.h \
../src/cPeakFinder.h cDataRange.h cDerivativeTemplate.h \
cDerivativePeak.h cInputRecord.h cSGPOutput.h cSignalProcessorConfig.h \
cHeartRate.h ../src/StatusDB.h cLogger.h cKeyBoardMonitor.h \
wrs/cStartSequence.h ../src/Configure.h ../src/HistoryDB.h \
../../raven-set/cRunWatch.h version.h
Now what do I do with this?
Is there a way for make to run the g++ -MM command and then use the generated rule?
Here is the makefile
#source file search paths
VPATH = wrs . ../src ../src/ext ../licenser
# compiler include search paths
INCS=-I../src -I../src/ext \
-I. -I"C:\Users\Public\Documents\Measurement Computing\DAQ\C" \
-I../../boost/boost1_72
# libraries required by linker
LIBS=-lstdc++fs -lws2_32 -lwsock32 \
-L"C:\Users\Public\Documents\Measurement Computing\DAQ\C" \
-lcbw64 -lIphlpapi \
-L../../boost/boost1_72/lib \
-lboost_thread-mgw82-mt-x64-1_72 \
-lboost_system-mgw82-mt-x64-1_72 \
-lboost_program_options-mgw82-mt-x64-1_72 \
-lboost_filesystem-mgw82-mt-x64-1_72
# folder for .o files
ODIR=./obj
# sources
_OBJ = \
cLicence.o \
sha1.o \
ChannelIdentification.o \
ChannelLabels.o \
Configure.o \
CubicSpline.o \
HistoryDB.o \
StatusDB.o \
cPacketData.o \
cPeakFilterSet.o \
cPeakFinder.o \
cPelexMixerConfig.o \
cVitals.o \
cRunWatch.o \
cSpline.o \
cTimerBusyLoop.o \
json.o \
raven_sqlite.o \
sqlite3.o \
log.o \
cD1ZeroCross.o \
cDataRange.o \
cDelayStats.o \
cDerivativeTemplate.o \
cErrorHandler.o \
cHeartRate.o \
cInput.o \
cInputRecord.o \
cMCUSB202.o \
cOutputTransmitter.o \
cPacketAlpha.o \
cPacketWRS.o \
cPeakFilter.o \
cPeakFinderSustainedD1.o \
cPeakFinderTallPoppy.o \
cPeakerServer.o \
cPelexConfig.o \
cPelexMixerComponent.o \
cRxPelexWireless.o \
cRxTx.o \
cSGPOutput.o \
cSPO2StateMachine.o \
cSignalProcessor.o \
cTimeProfile.o \
cTimedEvent.o \
cUI.o \
module2.o \
sgp.o \
cCalibrate.o \
cRaw.o \
cSignalProcessor_wrs.o \
cStartSequence.o \
cStream.o \
wrs_cProcessed.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/sqlite3.o: sqlite3.c
gcc -c -o $# $<
$(ODIR)/%.o: %.cpp
g++ -std=c++17 -m64 -fexceptions -D_mingw_ -DMODULE2 -O2 \
-c -o $# $< $(INCS)
mixer: $(OBJ)
g++ -m64 -O2 -s -o ../bin/PelexMixer.exe $^ $(LIBS)
I need to do the following steps to generate, store and include the dependency files
This follows the hints in the link provided by #G.M and helpful comments added to this answer
Step 1: define some flags requesting the generation and storage of dependencies. Notice that I am storing both the .o and the .d files in the same folder - makes things a bit simpler
# flags requesting dependency generation
DEPFLAGS = -MT $# -MMD -MP -MF $(ODIR)/$*.d
Step 2 add flags to compilation rule so that they will be generated as we go along
$(ODIR)/%.o: %.cpp
g++ -std=c++17 -m64 -fexceptions -D_mingw_ -DMODULE2 -O2 \
$(DEPFLAGS) \
-c -o $# $< $(INCS)
Step 3 Include the dependency files
# convert list of object files to list of dependency files
DEPFILES := $(_OBJ:%.o=$(ODIR)/%.d)
# empty rule, so make won't complain
# about not having a rule to make the dependency file if missing
$(DEPFILES):
# include the dependency files
include $(wildcard $(DEPFILES))
Here is my complete makefile with the changes described above
#source file search paths
VPATH = wrs . ../src ../src/ext ../licenser
# compiler include search paths
INCS=-I../src -I../src/ext \
-I. -I"C:\Users\Public\Documents\Measurement Computing\DAQ\C" \
-I../../boost/boost1_72
# libraries required by linker
LIBS=-lstdc++fs -lws2_32 -lwsock32 \
-L"C:\Users\Public\Documents\Measurement Computing\DAQ\C" \
-lcbw64 -lIphlpapi \
-L../../boost/boost1_72/lib \
-lboost_thread-mgw82-mt-x64-1_72 \
-lboost_system-mgw82-mt-x64-1_72 \
-lboost_program_options-mgw82-mt-x64-1_72 \
-lboost_filesystem-mgw82-mt-x64-1_72
# folder for .o files and depedency files
ODIR = ../pelexmixer/obj
# flags requesting dependency generation
DEPFLAGS = -MT $# -MMD -MP -MF $(ODIR)/$*.d
# sources
_OBJ = \
cLicence.o \
sha1.o \
ChannelIdentification.o \
ChannelLabels.o \
Configure.o \
CubicSpline.o \
HistoryDB.o \
StatusDB.o \
cPacketData.o \
cPeakFilterSet.o \
cPeakFinder.o \
cPelexMixerConfig.o \
cVitals.o \
cRunWatch.o \
cSpline.o \
cTimerBusyLoop.o \
json.o \
raven_sqlite.o \
sqlite3.o \
log.o \
cD1ZeroCross.o \
cDataRange.o \
cDelayStats.o \
cDerivativeTemplate.o \
cErrorHandler.o \
cHeartRate.o \
cInput.o \
cInputRecord.o \
cMCUSB202.o \
cOutputTransmitter.o \
cPacketAlpha.o \
cPacketWRS.o \
cPeakFilter.o \
cPeakFinderSustainedD1.o \
cPeakFinderTallPoppy.o \
cPeakerServer.o \
cPelexConfig.o \
cPelexMixerComponent.o \
cRxPelexWireless.o \
cRxTx.o \
cSGPOutput.o \
cSPO2StateMachine.o \
cSignalProcessor.o \
cTimeProfile.o \
cTimedEvent.o \
cUI.o \
module2.o \
sgp.o \
cCalibrate.o \
cRaw.o \
cSignalProcessor_wrs.o \
cStartSequence.o \
cStream.o \
wrs_cProcessed.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/sqlite3.o: sqlite3.c
gcc -c -o $# $<
$(ODIR)/%.o: %.cpp
g++ -std=c++17 -m64 -fexceptions -D_mingw_ -DMODULE2 -O2 \
$(DEPFLAGS) \
-c -o $# $< $(INCS)
mixer: $(OBJ)
g++ -m64 -O2 -s -o ../bin/PelexMixer.exe $^ $(LIBS)
DEPFILES := $(_OBJ:%.o=$(ODIR)/%.d)
$(DEPFILES):
include $(wildcard $(DEPFILES))
The compiler in Qt Creator does not support c++11. So in my .pro file I added QMAKE_CXXFLAGS += -std=c++11
So my .pro file now looks like this:
TEMPLATE = app
QMAKE_CXXFLAGS += -std=c++11
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += main.cpp \
server.cpp \
Section.cpp \
mainwindow.cpp \
main2.cpp \
client.cpp \
Chapter.cpp \
Book.cpp
HEADERS += \
Year.h \
Term.h \
Student.h \
Section.h \
mainwindow.h \
Load.h \
List.h \
Course.h \
ContentManager.h \
client.h \
Chapter.h \
Book.h
OTHER_FILES += \
Makefile \
D2.pro.user
This is my makefile:
#############################################################################
# Makefile for building: D2
# Generated by qmake (2.01a) (Qt 4.8.1) on: Mon Nov 10 23:00:21 2014
# Project: D2.pro
# Template: app
# Command: /usr/bin/qmake-qt4 -spec /usr/share/qt4/mkspecs/linux-g++ CONFIG+=debug CONFIG+=declarative_debug -o Makefile D2.pro
#############################################################################
####### Compiler, tools and options
CC = gcc
CXX = g++
DEFINES = -DQT_WEBKIT
CFLAGS = -pipe -g -Wall -W $(DEFINES)
CXXFLAGS = -pipe -std=c++11 -g -Wall -W $(DEFINES)
INCPATH = -I/usr/share/qt4/mkspecs/linux-g++ -I.
LINK = g++
LFLAGS =
LIBS = $(SUBLIBS)
AR = ar cqs
RANLIB =
QMAKE = /usr/bin/qmake-qt4
TAR = tar -cf
COMPRESS = gzip -9f
COPY = cp -f
SED = sed
COPY_FILE = $(COPY)
COPY_DIR = $(COPY) -r
STRIP = strip
INSTALL_FILE = install -m 644 -p
INSTALL_DIR = $(COPY_DIR)
INSTALL_PROGRAM = install -m 755 -p
DEL_FILE = rm -f
SYMLINK = ln -f -s
DEL_DIR = rmdir
MOVE = mv -f
CHK_DIR_EXISTS= test -d
MKDIR = mkdir -p
####### Output directory
OBJECTS_DIR = ./
####### Files
SOURCES = main.cpp \
server.cpp \
Section.cpp \
mainwindow.cpp \
main2.cpp \
client.cpp \
Chapter.cpp \
Book.cpp
OBJECTS = main.o \
server.o \
Section.o \
mainwindow.o \
main2.o \
client.o \
Chapter.o \
Book.o
DIST = /usr/share/qt4/mkspecs/common/unix.conf \
/usr/share/qt4/mkspecs/common/linux.conf \
/usr/share/qt4/mkspecs/common/gcc-base.conf \
/usr/share/qt4/mkspecs/common/gcc-base-unix.conf \
/usr/share/qt4/mkspecs/common/g++-base.conf \
/usr/share/qt4/mkspecs/common/g++-unix.conf \
/usr/share/qt4/mkspecs/qconfig.pri \
/usr/share/qt4/mkspecs/modules/qt_webkit_version.pri \
/usr/share/qt4/mkspecs/features/qt_functions.prf \
/usr/share/qt4/mkspecs/features/qt_config.prf \
/usr/share/qt4/mkspecs/features/exclusive_builds.prf \
/usr/share/qt4/mkspecs/features/default_pre.prf \
/usr/share/qt4/mkspecs/features/debug.prf \
/usr/share/qt4/mkspecs/features/default_post.prf \
/usr/share/qt4/mkspecs/features/declarative_debug.prf \
/usr/share/qt4/mkspecs/features/unix/gdb_dwarf_index.prf \
/usr/share/qt4/mkspecs/features/warn_on.prf \
/usr/share/qt4/mkspecs/features/resources.prf \
/usr/share/qt4/mkspecs/features/uic.prf \
/usr/share/qt4/mkspecs/features/yacc.prf \
/usr/share/qt4/mkspecs/features/lex.prf \
/usr/share/qt4/mkspecs/features/include_source_dir.prf \
D2.pro
QMAKE_TARGET = D2
DESTDIR =
TARGET = D2
first: all
####### Implicit rules
.SUFFIXES: .o .c .cpp .cc .cxx .C
.cpp.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$#" "$<"
.cc.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$#" "$<"
.cxx.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$#" "$<"
.C.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$#" "$<"
.c.o:
$(CC) -c $(CFLAGS) $(INCPATH) -o "$#" "$<"
####### Build rules
all: Makefile $(TARGET)
$(TARGET): $(OBJECTS)
$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS)
{ test -n "$(DESTDIR)" && DESTDIR="$(DESTDIR)" || DESTDIR=.; } && test $$(gdb --version | sed -e 's,[^0-9]\+\([0-9]\)\.\([0-9]\).*,\1\2,;q') -gt 72 && gdb --nx --batch --quiet -ex 'set confirm off' -ex "save gdb-index $$DESTDIR" -ex quit '$(TARGET)' && test -f $(TARGET).gdb-index && objcopy --add-section '.gdb_index=$(TARGET).gdb-index' --set-section-flags '.gdb_index=readonly' '$(TARGET)' '$(TARGET)' && rm -f $(TARGET).gdb-index || true
Makefile: D2.pro /usr/share/qt4/mkspecs/linux-g++/qmake.conf /usr/share/qt4/mkspecs/common/unix.conf \
/usr/share/qt4/mkspecs/common/linux.conf \
/usr/share/qt4/mkspecs/common/gcc-base.conf \
/usr/share/qt4/mkspecs/common/gcc-base-unix.conf \
/usr/share/qt4/mkspecs/common/g++-base.conf \
/usr/share/qt4/mkspecs/common/g++-unix.conf \
/usr/share/qt4/mkspecs/qconfig.pri \
/usr/share/qt4/mkspecs/modules/qt_webkit_version.pri \
/usr/share/qt4/mkspecs/features/qt_functions.prf \
/usr/share/qt4/mkspecs/features/qt_config.prf \
/usr/share/qt4/mkspecs/features/exclusive_builds.prf \
/usr/share/qt4/mkspecs/features/default_pre.prf \
/usr/share/qt4/mkspecs/features/debug.prf \
/usr/share/qt4/mkspecs/features/default_post.prf \
/usr/share/qt4/mkspecs/features/declarative_debug.prf \
/usr/share/qt4/mkspecs/features/unix/gdb_dwarf_index.prf \
/usr/share/qt4/mkspecs/features/warn_on.prf \
/usr/share/qt4/mkspecs/features/resources.prf \
/usr/share/qt4/mkspecs/features/uic.prf \
/usr/share/qt4/mkspecs/features/yacc.prf \
/usr/share/qt4/mkspecs/features/lex.prf \
/usr/share/qt4/mkspecs/features/include_source_dir.prf
$(QMAKE) -spec /usr/share/qt4/mkspecs/linux-g++ CONFIG+=debug CONFIG+=declarative_debug -o Makefile D2.pro
/usr/share/qt4/mkspecs/common/unix.conf:
/usr/share/qt4/mkspecs/common/linux.conf:
/usr/share/qt4/mkspecs/common/gcc-base.conf:
/usr/share/qt4/mkspecs/common/gcc-base-unix.conf:
/usr/share/qt4/mkspecs/common/g++-base.conf:
/usr/share/qt4/mkspecs/common/g++-unix.conf:
/usr/share/qt4/mkspecs/qconfig.pri:
/usr/share/qt4/mkspecs/modules/qt_webkit_version.pri:
/usr/share/qt4/mkspecs/features/qt_functions.prf:
/usr/share/qt4/mkspecs/features/qt_config.prf:
/usr/share/qt4/mkspecs/features/exclusive_builds.prf:
/usr/share/qt4/mkspecs/features/default_pre.prf:
/usr/share/qt4/mkspecs/features/debug.prf:
/usr/share/qt4/mkspecs/features/default_post.prf:
/usr/share/qt4/mkspecs/features/declarative_debug.prf:
/usr/share/qt4/mkspecs/features/unix/gdb_dwarf_index.prf:
/usr/share/qt4/mkspecs/features/warn_on.prf:
/usr/share/qt4/mkspecs/features/resources.prf:
/usr/share/qt4/mkspecs/features/uic.prf:
/usr/share/qt4/mkspecs/features/yacc.prf:
/usr/share/qt4/mkspecs/features/lex.prf:
/usr/share/qt4/mkspecs/features/include_source_dir.prf:
qmake: FORCE
#$(QMAKE) -spec /usr/share/qt4/mkspecs/linux-g++ CONFIG+=debug CONFIG+=declarative_debug -o Makefile D2.pro
dist:
#$(CHK_DIR_EXISTS) .tmp/D21.0.0 || $(MKDIR) .tmp/D21.0.0
$(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/D21.0.0/ && (cd `dirname .tmp/D21.0.0` && $(TAR) D21.0.0.tar D21.0.0 && $(COMPRESS) D21.0.0.tar) && $(MOVE) `dirname .tmp/D21.0.0`/D21.0.0.tar.gz . && $(DEL_FILE) -r .tmp/D21.0.0
clean:compiler_clean
-$(DEL_FILE) $(OBJECTS)
-$(DEL_FILE) *~ core *.core
####### Sub-libraries
distclean: clean
-$(DEL_FILE) $(TARGET)
-$(DEL_FILE) Makefile
check: first
compiler_rcc_make_all:
compiler_rcc_clean:
compiler_uic_make_all:
compiler_uic_clean:
compiler_image_collection_make_all: qmake_image_collection.cpp
compiler_image_collection_clean:
-$(DEL_FILE) qmake_image_collection.cpp
compiler_yacc_decl_make_all:
compiler_yacc_decl_clean:
compiler_yacc_impl_make_all:
compiler_yacc_impl_clean:
compiler_lex_make_all:
compiler_lex_clean:
compiler_clean:
####### Compile
main.o: main.cpp Course.h \
Year.h \
Term.h \
Student.h \
ContentManager.h \
Book.h \
List.h \
Chapter.h \
Section.h \
Load.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o main.o main.cpp
server.o: server.cpp
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o server.o server.cpp
Section.o: Section.cpp Section.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o Section.o Section.cpp
mainwindow.o: mainwindow.cpp mainwindow.h \
client.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o mainwindow.o mainwindow.cpp
main2.o: main2.cpp mainwindow.h \
client.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o main2.o main2.cpp
client.o: client.cpp client.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o client.o client.cpp
Chapter.o: Chapter.cpp Chapter.h \
List.h \
Section.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o Chapter.o Chapter.cpp
Book.o: Book.cpp Book.h \
List.h \
Chapter.h \
Section.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o Book.o Book.cpp
####### Install
install: FORCE
uninstall: FORCE
FORCE:
Unfortunately, I'm getting this error: [main.o] Error 1
This error was non-existent before adding c++11. I can't solve this problem. Can someone please help me here?
UPDATE:
Typing in gcc -v in the command line in Qt creator gave me:
Starting command 'gcc -v'
Using built-in specs.
COLLECT_GCC=/usr/bin/gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.6/lto-wrapper
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
'gcc -v' finished
I think the compiler version is 4.6.3, which means it supports C++11
There's more to that error message than just [main.o] Error 1. Paste the whole error message.
However, some guesses as to your problem might include:
You use both $(OBJCOMP) and $(SUBLIBS) in your linker command, but neither of them is defined anywhere. Could this be the cause of the error?
Some old versions of g++ (for example, 4.6.3) spell the option -std=c++0x instead of -std=c++11. Depending on the output of g++ --version, you might need to use the older spelling.
You might need to add -std=c++11 to the LFLAGS as well as to the CXXFLAGS, to make sure that you're linking against the correct C++ library. (I don't know of any systems for which this matters, but I always try to get it right anyway.)
I got this error a few times as well.
I was frankly amazed at the lack of information in the error message, well, I mean, there is basically none.
Here is my interpretation of what the erro means:
main.o doesn't exist / can't be found / is entirely broken.
There are a few ways you could've ended up in this situation:
Location where main.o is supposed to be written is write protected. (You could try toggling shadowbuild in Qt creator)
You're out of space (I know, sounds absurd with 8TB HDDs on the market. This was what was happening for me tho.)
Your project is ill configured. (Sometimes there is a difference between / and \ in paths)
Your compiler is ill configured.
There is something very wrong with your code.
Unfortunately, I'm getting this error: [main.o] Error 1
.....
Believe me, that was the only error. I tried all your suggestions but none could solve the problem, unfortunately
Interestingly, Qt Creator does not remove your project's Makefile even if you do Cleaning and Rebuilding.
Those options does remove your output binary files (including .o files), but sometimes it can't be sufficient especially when you're editing the .pro file or .qrc file.
In most cases where the build error message is unclear and it's claimed, "Well it just worked before!" it's worth trying making sure that you're building it completely from the scratch all the way through by:
Going to your build directory such as:
../build-*
Deleting all relevant Makefile scripts and others if necessary,
Then re-building it again.
When I use the Makefile in the examples folder of Pythia8185 I get an error (ME below!):
ME: This is mymain.cc
#include "Pythia8/Pythia.h" // Include Pythia headers.
using namespace Pythia8; // Let Pythia8:: be implicit.
int main() { // Begin main program.
// Set up generation.
Pythia pythia; // Declare Pythia object
pythia.readString("Top:gg2ttbar = on"); // Switch on process.
pythia.readString("Beams:eCM = 7000."); // 7 TeV CM energy.
pythia.init(); // Initialize; incoming pp beams is default.
// Generate event(s).
pythia.next(); // Generate an(other) event. Fill event record.
return 0;
} // End main program with error-free return.
This is the Makefile before edit:
#
# Examples Makefile.
#
# M. Kirsanov 07.04.2006
# Modified 18.11.2006
# 26.03.2008 CLHEP dependency removed
SHELL = /bin/sh
-include config.mk
ifeq (x$(PYTHIA8LOCATION),x)
PYTHIA8LOCATION=..
endif
-include $(PYTHIA8LOCATION)/config.mk
# Location of directories.
TOPDIR=$(shell \pwd)
INCDIR=include
SRCDIR=src
LIBDIR=lib
LIBDIRARCH=lib/archive
BINDIR=bin
# Libraries to include if GZIP support is enabled
ifeq (x$(ENABLEGZIP),xyes)
LIBGZIP=-L$(BOOSTLIBLOCATION) -lboost_iostreams -L$(ZLIBLOCATION) -lz
endif
# There is no default behaviour, so remind user.
all:
#echo "Usage: for NN = example number: make mainNN"
# Create an executable for one of the normal test programs
main00 main01 main02 main03 main04 main05 main06 main07 main08 main09 main10 \
main11 main12 main13 main14 main15 main16 main17 main18 main19 main20 \
main21 main22 main23 main24 main25 main26 main27 main28 main29 main30 \
main31 main32 main33 main34 main35 main36 main37 main38 main39 main40 \
main80: \
$(PYTHIA8LOCATION)/$(LIBDIRARCH)/libpythia8.a
#mkdir -p $(BINDIR)
$(CXX) $(CXXFLAGS) -I$(PYTHIA8LOCATION)/$(INCDIR) $#.cc -o $(BINDIR)/$#.exe \
-L$(PYTHIA8LOCATION)/$(LIBDIRARCH) -lpythia8 -llhapdfdummy $(LIBGZIP)
#ln -fs $(BINDIR)/$#.exe $#.exe
# Create an executable linked to HepMC (if all goes well).
# Owing to excessive warning output -Wshadow is not used for HepMC.
ifneq (x$(HEPMCLOCATION),x)
main41 main42: \
$(PYTHIA8LOCATION)/$(LIBDIRARCH)/libpythia8.a $(PYTHIA8LOCATION)/$(LIBDIRARCH)/libpythia8tohepmc.a
#mkdir -p $(BINDIR)
$(CXX) $(CXXFLAGS) -Wno-shadow -I$(PYTHIA8LOCATION)/$(INCDIR) -I$(HEPMCLOCATION)/include \
$#.cc -o $(BINDIR)/$#.exe \
-L$(PYTHIA8LOCATION)/$(LIBDIRARCH) -lpythia8 -llhapdfdummy $(LIBGZIP) \
-lpythia8tohepmc \
-L$(HEPMCLOCATION)/lib -lHepMC
#ln -fs $(BINDIR)/$#.exe $#.exe
else
main41 main42:
#echo ERROR, this target needs HepMC, variable HEPMCLOCATION
endif
# Create an executable that links to LHAPDF
main51 main52 main53 main54: $(PYTHIA8LOCATION)/$(LIBDIRARCH)/libpythia8.a
#mkdir -p $(BINDIR)
$(CXX) $(CXXFLAGS) -I$(PYTHIA8LOCATION)/$(INCDIR) $#.cc -o $(BINDIR)/$#.exe \
-L$(PYTHIA8LOCATION)/$(LIBDIRARCH) -lpythia8 $(LIBGZIP) \
-L$(LHAPDFLOCATION) $(LHAPDFLIBNAME) \
$(FLIBS)
#ln -fs $(BINDIR)/$#.exe $#.exe
# Create an executable that links to LHAPDF and HepMC
main61 main62 main85 main86 main87 main88: \
$(PYTHIA8LOCATION)/$(LIBDIRARCH)/libpythia8.a $(PYTHIA8LOCATION)/$(LIBDIRARCH)/libpythia8tohepmc.a
#mkdir -p $(BINDIR)
$(CXX) $(CXXFLAGS) -Wno-shadow -I$(PYTHIA8LOCATION)/$(INCDIR) -I$(HEPMCLOCATION)/include \
$#.cc -o $(BINDIR)/$#.exe \
-L$(PYTHIA8LOCATION)/$(LIBDIRARCH) -lpythia8 -lpythia8tohepmc $(LIBGZIP) \
-L$(LHAPDFLOCATION) $(LHAPDFLIBNAME) \
-L$(HEPMCLOCATION)/lib -lHepMC \
$(FLIBS)
#ln -fs $(BINDIR)/$#.exe $#.exe
# Create an executable that links to Fastjet
# Owing to excessive warning output -Wshadow is not used for Fastjet.
# (Fixed as of Fastjet 3.0.1, so will be modified eventually.)
ifneq (x$(FASTJETLOCATION),x)
main71 main72: $(PYTHIA8LOCATION)/$(LIBDIRARCH)/libpythia8.a
#mkdir -p $(BINDIR)
# Note: $(CXXFLAGS) is after Fastjet flags as Fastjet includes
# optimisation/debug flags which may be unwanted (e.g. -g -O2)
$(CXX) -I$(PYTHIA8LOCATION)/$(INCDIR) $#.cc \
`$(FASTJETLOCATION)/bin/fastjet-config --cxxflags --plugins` \
$(CXXFLAGS) -Wno-shadow \
-o $(BINDIR)/$#.exe \
-L$(PYTHIA8LOCATION)/$(LIBDIRARCH) -lpythia8 -llhapdfdummy $(LIBGZIP) \
-L$(FASTJETLOCATION)/lib \
`$(FASTJETLOCATION)/bin/fastjet-config --libs --plugins`
#ln -fs $(BINDIR)/$#.exe $#.exe
#rm -f $#.o
else
main71 main72:
#echo ERROR, this target needs Fastjet, variable FASTJETLOCATION
endif
# Create an executable that links to Fastjet, HepMC and LHApdf
# Owing to excessive warning output -Wshadow is not used for Fastjet.
# (Fixed as of Fastjet 3.0.1, so will be modified eventually.)
ifneq (x$(FASTJETLOCATION),x)
main81 main82 main83 main84: \
$(PYTHIA8LOCATION)/$(LIBDIRARCH)/libpythia8.a $(PYTHIA8LOCATION)/$(LIBDIRARCH)/libpythia8tohepmc.a
#mkdir -p $(BINDIR)
# Note: $(CXXFLAGS) is after Fastjet flags as Fastjet includes
# optimisation/debug flags which may be unwanted (e.g. -g -O2)
$(CXX) -I$(PYTHIA8LOCATION)/$(INCDIR) $#.cc \
`$(FASTJETLOCATION)/bin/fastjet-config --cxxflags --plugins` \
$(CXXFLAGS) -Wno-shadow \
-I$(PYTHIA8LOCATION)/$(INCDIR) -I$(HEPMCLOCATION)/include \
-o $(BINDIR)/$#.exe \
-L$(PYTHIA8LOCATION)/$(LIBDIRARCH) -lpythia8 \
-L$(LHAPDFLOCATION) $(LHAPDFLIBNAME) \
-lpythia8tohepmc \
-L$(HEPMCLOCATION)/lib -lHepMC \
-L$(FASTJETLOCATION)/lib \
-L$(LHAPDFLOCATION)/lib \
`$(FASTJETLOCATION)/bin/fastjet-config --libs --plugins`
#ln -fs $(BINDIR)/$#.exe $#.exe
#rm -f $#.o
else
main81 main82 main83 main84:
#echo ERROR, this target needs Fastjet, variable FASTJETLOCATION
endif
# Clean up: remove executables and outdated files.
.PHONY: clean
clean:
rm -rf $(BINDIR)
rm -rf *.exe
rm -f *~; rm -f \#*; rm -f core*
After edit I add mymain: just after main80 and then I write make mymain and get the error as follows:
I edit the Makefile and add mymain to the list:
# Create an executable for one of the normal test programs
main00 main01 main02 main03 main04 main05 main06 main07 main08 main09 main10 \
main11 main12 main13 main14 main15 main16 main17 main18 main19 main20 \
main21 main22 main23 main24 main25 main26 main27 main28 main29 main30 \
main31 main32 main33 main34 main35 main36 main37 main38 main39 main40 \
main80 mymain: \
as suggested in the worksheet example page 4.
Then when I write make mymain in the Terminal I get the following error:
*** No rule to make target `../lib/archive/libpythia8.a', needed by `mymain'. Stop.
It should be noted that everything worked fine yesterday, I really don't know how to proceed. I deleted all pythia folders and untarred them again but the problem remains. Anyone know what the solution might be? I'm on a MacBook.
Is there a way to uninstall something like pythia completely and reinstall it? It seems some file in some cache is the problem
I am trying to implement the non-recursive make solution outlined in the paper "Recursive Make Considered Harmful". I'm currently stuck on getting the *.d dependency files to generate. I've provided the makefile, sample module.mk and error below. Any ideas how I can fix this?
MODULES := \
module1 \
module2
# define compiler
CC = /opt/local/bin/clang++-mp-3.1
# exclude the following warnings for clang
CLANG_NO_WARN = \
-Wno-c++98-compat \
-Wno-weak-vtables \
-Wno-padded \
-Wno-global-constructors \
-Wno-exit-time-destructors
# look for include files in each of the modules
CFLAGS += \
-g -Weverything -Wall -std=c++11 -stdlib=libc++ $(CLANG_NO_WARN) \
-I../ -I/usr/local/include $(patsubst %, -I%, $(MODULES))
# linker flags
LDFLAGS := \
-stdlib=libc++ \
-L/usr/local/boost_1_50_0/stage/lib -L/usr/local/lib
# extra libraries if required (each module will add to this)
LIBS := \
-lboost_program_options \
-lboost_system \
-lglog \
-lpugixml
# source files to be compiled (each module will add to this)
SRCS := \
Main.cpp
# include the descriptions for each module
include $(patsubst %, %/module.mk, $(MODULES))
# determine the object files
OBJS := \
$(patsubst %.cpp, %.o, $(filter %.cpp, $(SRCS)))
# link the program
prog: $(OBJS)
$(CC) -o $# $(OBJS) $(LDFLAGS) $(LIBS)
# include the C include dependencies
include $(OBJS:.o=.d)
# calculate C include dependencies
%.d: %.cpp
depend.sh `dirname $*.cpp` $(CFLAGS) $*.cpp > $#
----------
#!/bin/sh
# Evaluate dependencies for use by the makefile
echo "Called"
DIR="$1"
shift 1
case "$DIR" in
"" | ".")
$CC -MM -MG "$#" | sed -e 's#ˆ\(.*\)\.o:#\1.d \1.o:#' ;;
*)
$CC -MM -MG "$#" | sed -e "s#ˆ\(.*\)\.o:#$DIR/\1.d \ $DIR/\1.o:#" ;;
esac
------------
# module.mk
SRCS += \
Algo.cpp \
CommandHandler.cpp \
Exchange.cpp \
TCPSocket.cpp \
TradingEngine.cpp
----------
$ make
makefile:68: Main.d: No such file or directory
makefile:68: view_string.d: No such file or directory
makefile:68: Algo.d: No such file or directory
makefile:68: CommandHandler.d: No such file or directory
makefile:68: Exchange.d: No such file or directory
makefile:68: TCPSocket.d: No such file or directory
makefile:68: TradingEngine.d: No such file or directory
makefile:68: Exchange.d: No such file or directory
makefile:68: Requests.d: No such file or directory
makefile:68: TickCapture.d: No such file or directory
makefile:68: types.d: No such file or directory
make: *** No rule to make target `types.d'. Stop.
UPDATE
Finished makefile and sample module.mk
$cat makefile
# executable name
BINARY := my_prog
# clang config
CLANG := /opt/local/bin/clang++-mp-3.1
CLANG_WARNINGS := \
-Wno-c++98-compat \
-Wno-weak-vtables \
-Wno-padded \
-Wno-global-constructors \
-Wno-exit-time-destructors
CLANG_CFLAGS := \
-g -Weverything -Wall -std=c++11 -stdlib=libc++
CLANG_LDFLAGS := \
-stdlib=libc++
# generic compiler config
CC := $(CLANG)
CFLAGS := $(CLANG_WARNINGS) $(CLANG_CFLAGS)
LDFLAGS := $(CLANG_LDFLAGS)
INCS := \
-I../ \
-I/usr/local/include \
$(patsubst %, -I%, $(SUBDIRS))
LIBS := \
-L/usr/local/boost_1_50_0/stage/lib \
-L/usr/local/lib \
-lboost_program_options \
-lboost_system \
-lglog \
-lpugixml
# list subdirectories in which to look for dependencies
# must define SRCS first as subdirs will append to this
# their src files
SRCS := Main.cpp
SUBDIRS := \
module1 \
module2
include $(patsubst %, %/module.mk, $(SUBDIRS))
# derive object files from srcs
OBJS := $(patsubst %.cpp, %.o, $(filter %.cpp, $(SRCS)))
# link the program
$(BINARY): $(OBJS)
$(CC) -o $# $(OBJS) $(LDFLAGS) $(LIBS)
# include generated dependency files
DEPS := $(OBJS:.o=.d)
-include $(DEPS)
# generate include dependencies
%.d: %.cpp
./depend.sh `dirname $*.cpp` $(INCS) $*.cpp > $#
# compile
.cpp.o:
$(CC) $(CFLAGS) $(INCS) $< -c -o $#
# clean, obviously
clean:
rm -f $(BINARY)
rm -f $(OBJS)
rm -f $(DEPS)
# et voila!
-----
$cat module1/module.mk
SRCS_PATH := module1
SRCS += \
$(SRCS_PATH)/Algo.cpp \
$(SRCS_PATH)/CommandHandler.cpp \
$(SRCS_PATH)/Exchange.cpp \
$(SRCS_PATH)/TCPSocket.cpp \
$(SRCS_PATH)/TradingEngine.cpp
It looks as if some module adds types.cpp to SRCS, even though no such source file exists.
As for the warnings, the first time you run this makefile, the dependency files (foo.d) do not yet exist, so Make complains that it can't include them. It's not a problem, and the warnings won't appear in subsequent runs when those files do exist beforehand. To supress the warnings entirely, change include to -include.
I've been heavily refactoring my makefiles, with help from Beta, Paul R, and Sjoerd (thanks guys!).
Below is my STARTING product:
#Nice, wonderful makefile written by Jason
CC=g++
CFLAGS=-c -Wall
BASE_DIR:=.
SOURCE_DIR:=$(BASE_DIR)/source
BUILD_DIR:=$(BASE_DIR)/build
TEST_DIR:=$(BASE_DIR)/build/tests
MAKEFILE_DIR:=$(BASE_DIR)/makefiles
DATA_DIR:=$(BASE_DIR)/data
DATA_DIR_TESTS:=$(DATA_DIR)/tests
MOLECULE_UT_SOURCES := $(SOURCE_DIR)/molecule_test/main.cc \
$(SOURCE_DIR)/molecule_manager.h \
$(SOURCE_DIR)/molecule_manager.cpp \
$(SOURCE_DIR)/molecule_manager_main.h \
$(SOURCE_DIR)/molecule_manager_main.cpp \
$(SOURCE_DIR)/molecule_reader.h \
$(SOURCE_DIR)/molecule_reader.cpp \
$(SOURCE_DIR)/molecule_reader_psf_pdb.h \
$(SOURCE_DIR)/molecule_reader_psf_pdb.cpp \
$(SOURCE_DIR)/parameter_manager_lj_molecule.h \
$(SOURCE_DIR)/parameter_manager_lj_molecule.cpp \
$(SOURCE_DIR)/parameter_manager.h \
$(SOURCE_DIR)/parameter_manager.cpp \
$(SOURCE_DIR)/parser.h \
$(SOURCE_DIR)/parser.cpp \
$(SOURCE_DIR)/common.h
MOLECULE_UT_DATA := \
$(DATA_DIR_TESTS)/molecule_test/par_oxalate_and_friends.inp \
$(DATA_DIR_TESTS)/molecule_test/dicarboxy-octane_4.pdb \
$(DATA_DIR_TESTS)/molecule_test/dicarboxy-octane_4.psf
PARAM_UT_SOURCES := $(SOURCE_DIR)/parameter_test/main.cc \
$(SOURCE_DIR)/parameter_manager_lj_molecule.h \
$(SOURCE_DIR)/parameter_manager_lj_molecule.cpp \
$(SOURCE_DIR)/parameter_manager.h \
$(SOURCE_DIR)/parameter_manager.cpp \
$(SOURCE_DIR)/parser.h \
$(SOURCE_DIR)/parser.cpp \
$(SOURCE_DIR)/common.h
PARAM_UT_DATA := $(DATA_DIR_TESTS)/molecule_test/par_oxalate_and_friends.inp
molecule_test : molecule_test_prepare_sources molecule_test_prepare_makefiles \
molecule_test_prepare_data_files
#$(shell cd $(TEST_DIR)/molecule_unit_test/; \
make ./bin/molecule_test)
molecule_test_prepare_sources: molecule_test_dir
#echo Copying sources...
#cp --preserve $(MOLECULE_UT_SOURCES) \
$(TEST_DIR)/molecule_unit_test/source
molecule_test_prepare_makefiles: $(MAKEFILE_DIR)/Makefile.molecule_test
#cp --preserve $(MAKEFILE_DIR)/Makefile.molecule_test \
$(TEST_DIR)/molecule_unit_test/Makefile
molecule_test_prepare_data_files:
cp --preserve $(MOLECULE_UT_DATA) $(TEST_DIR)/molecule_unit_test/bin/
molecule_test_dir:
#if test -d $(BUILD_DIR); then \
echo Build exists...; \
else \
echo Build directory does not exist, making build dir...; \
mkdir $(BUILD_DIR); \
fi
#if test -d $(TEST_DIR); then \
echo Tests exists...; \
else \
echo Tests directory does not exist, making tests dir...; \
mkdir $(TEST_DIR); \
fi
#if test -d $(TEST_DIR)/molecule_unit_test; then \
echo Molecule unit test directory exists...; \
else \
echo Molecule unit test directory does \
not exist, making build dir...; \
mkdir $(TEST_DIR)/molecule_unit_test; \
fi
#if test -d $(TEST_DIR)/molecule_unit_test/source; then \
echo Molecule unit test source directory exists...; \
else \
echo Molecule unit test source directory does \
not exist, making build dir...; \
mkdir $(TEST_DIR)/molecule_unit_test/source; \
fi
#if test -d $(TEST_DIR)/molecule_unit_test/obj; then \
echo Molecule unit test object directory exists...; \
else \
echo Molecule unit test object directory does \
not exist, making object dir...; \
mkdir $(TEST_DIR)/molecule_unit_test/obj; \
fi
#if test -d $(TEST_DIR)/molecule_unit_test/bin; then \
echo Molecule unit test executable directory exists...; \
else \
echo Molecule unit test executable directory does \
not exist, making executable dir...; \
mkdir $(TEST_DIR)/molecule_unit_test/bin; \
fi
param_test : param_test_prepare_sources param_test_prepare_makefiles \
param_test_prepare_data_files
#$(shell cd $(TEST_DIR)/param_unit_test/; \
make ./bin/param_test)
param_test_prepare_sources: param_test_dir
#echo Copying sources...
#cp --preserve $(PARAM_UT_SOURCES) $(TEST_DIR)/param_unit_test/source
param_test_prepare_makefiles: $(MAKEFILE_DIR)/Makefile.param_test
#cp --preserve $(MAKEFILE_DIR)/Makefile.param_test \
$(TEST_DIR)/param_unit_test/Makefile
param_test_prepare_data_files:
cp --preserve $(PARAM_UT_DATA) $(TEST_DIR)/param_unit_test/bin/
param_test_dir:
#if test -d $(BUILD_DIR); then \
echo Build exists...; \
else \
echo Build directory does not exist, making build dir...; \
mkdir $(BUILD_DIR); \
fi
#if test -d $(TEST_DIR); then \
echo Tests exists...; \
else \
echo Tests directory does not exist, making tests dir...; \
mkdir $(TEST_DIR); \
fi
#if test -d $(TEST_DIR)/param_unit_test; then \
echo Param unit test directory exists...; \
else \
echo Param unit test directory does \
not exist, making build dir...; \
mkdir $(TEST_DIR)/param_unit_test; \
fi
#if test -d $(TEST_DIR)/param_unit_test/source; then \
echo Param unit test source directory exists...; \
else \
echo Param unit test source directory does \
not exist, making build dir...; \
mkdir $(TEST_DIR)/param_unit_test/source; \
fi
#if test -d $(TEST_DIR)/param_unit_test/obj; then \
echo Param unit test object directory exists...; \
else \
echo Param unit test object directory does \
not exist, making object dir...; \
mkdir $(TEST_DIR)/param_unit_test/obj; \
fi
#if test -d $(TEST_DIR)/param_unit_test/bin; then \
echo Param unit test executable directory exists...; \
else \
echo Param unit test executable directory does \
not exist, making executable dir...; \
mkdir $(TEST_DIR)/param_unit_test/bin; \
fi
...and the sub makefile:
#Nice, wonderful makefile written by Jason
CC=g++
CFLAGS=-c -Wall
SOURCE_DIR:=./source
OBJ_DIR:=./obj
EXE_DIR:=./bin
$(EXE_DIR)/molecule_test : $(OBJ_DIR)/main.o \
$(OBJ_DIR)/parameter_manager_lj_molecule.o \
$(OBJ_DIR)/parameter_manager.o $(OBJ_DIR)/parser.o \
$(OBJ_DIR)/molecule_manager.o $(OBJ_DIR)/molecule_manager_main.o \
$(OBJ_DIR)/molecule_reader.o \
$(OBJ_DIR)/molecule_reader_psf_pdb.o
#$(CC) $(OBJ_DIR)/main.o $(OBJ_DIR)/parameter_manager.o \
$(OBJ_DIR)/parser.o $(OBJ_DIR)/parameter_manager_lj_molecule.o \
$(OBJ_DIR)/molecule_manager.o $(OBJ_DIR)/molecule_manager_main.o \
$(OBJ_DIR)/molecule_reader.o \
$(OBJ_DIR)/molecule_reader_psf_pdb.o \
-o molecule_test
#mv molecule_test $(EXE_DIR)/
$(OBJ_DIR)/main.o: $(SOURCE_DIR)/parameter_manager.h \
$(SOURCE_DIR)/parameter_manager_lj_molecule.h \
$(SOURCE_DIR)/molecule_manager.h \
$(SOURCE_DIR)/molecule_manager_main.h \
$(SOURCE_DIR)/molecule_reader.h \
$(SOURCE_DIR)/molecule_reader_psf_pdb.h \
$(SOURCE_DIR)/common.h $(SOURCE_DIR)/main.cc
$(CC) $(CFLAGS) $(SOURCE_DIR)/main.cc
#mv main.o $(OBJ_DIR)/
$(OBJ_DIR)/molecule_reader.o: $(SOURCE_DIR)/parameter_manager.h \
$(SOURCE_DIR)/parameter_manager_lj_molecule.h \
$(SOURCE_DIR)/molecule_manager.h \
$(SOURCE_DIR)/molecule_manager_main.h \
$(SOURCE_DIR)/molecule_reader.h \
$(SOURCE_DIR)/common.h
$(CC) $(CFLAGS) $(SOURCE_DIR)/molecule_reader.cpp
#mv molecule_reader.o $(OBJ_DIR)/
$(OBJ_DIR)/molecule_reader_psf_pdb.o: $(SOURCE_DIR)/parameter_manager.h \
$(SOURCE_DIR)/parameter_manager_lj_molecule.h \
$(SOURCE_DIR)/molecule_manager.h \
$(SOURCE_DIR)/molecule_manager_main.h \
$(SOURCE_DIR)/molecule_reader.h \
$(SOURCE_DIR)/molecule_reader_psf_pdb.h \
$(SOURCE_DIR)/common.h
$(CC) $(CFLAGS) $(SOURCE_DIR)/molecule_reader_psf_pdb.cpp
#mv molecule_reader_psf_pdb.o $(OBJ_DIR)/
$(OBJ_DIR)/molecule_manager.o: $(SOURCE_DIR)/molecule_manager.h \
$(SOURCE_DIR)/common.h
$(CC) $(CFLAGS) $(SOURCE_DIR)/molecule_manager.cpp
#mv molecule_manager.o $(OBJ_DIR)/
$(OBJ_DIR)/molecule_manager_main.o: $(SOURCE_DIR)/molecule_manager.h \
$(SOURCE_DIR)/molecule_manager_main.h \
$(SOURCE_DIR)/common.h
$(CC) $(CFLAGS) $(SOURCE_DIR)/molecule_manager_main.cpp
#mv molecule_manager_main.o $(OBJ_DIR)/
$(OBJ_DIR)/parameter_manager_lj_molecule.o: $(SOURCE_DIR)/common.h \
$(SOURCE_DIR)/parameter_manager.h \
$(SOURCE_DIR)/parser.h
$(CC) $(CFLAGS) $(SOURCE_DIR)/parameter_manager_lj_molecule.cpp
#mv parameter_manager_lj_molecule.o $(OBJ_DIR)/
$(OBJ_DIR)/parameter_manager.o: $(SOURCE_DIR)/common.h
$(CC) $(CFLAGS) $(SOURCE_DIR)/parameter_manager.cpp
#mv parameter_manager.o $(OBJ_DIR)/
$(OBJ_DIR)/parser.o: $(SOURCE_DIR)/parser.h
#$(CC) $(CFLAGS) $(SOURCE_DIR)/parser.cpp
#mv parser.o $(OBJ_DIR)/
$(OBJ_DIR)/common.o: $(SOURCE_DIR)/common.h
$(CC) $(CFLAGS) $(SOURCE_DIR)/common.h
mv common.h.gch $(OBJ_DIR)/
With some help from the above users and figuring out a few nifty tricks on my own as well (like use of wildcards), I've refactored the makefiles heavily, plus added comments for posterity.
Here's the top level result:
####################################################
## -------------------------------
## - Monte Carlo Source Makefile -
## -------------------------------
##
## Author: Jason R. Mick
## Date: July 7, 2010
## Company: Wayne State University
##
## CHANGE LOG
## Author Date Description
##
##
##
####################################################
#################################
# These lines set up some basic vars
# such as compiler, flags, and dirs.
#################################
CC=g++
CFLAGS=-c -Wall
BASE_DIR:=.
SOURCE_DIR:=$(BASE_DIR)/source
BUILD_DIR:=$(BASE_DIR)/build
TEST_DIR:=$(BASE_DIR)/build/tests
MAKEFILE_DIR:=$(BASE_DIR)/makefiles
DATA_DIR:=$(BASE_DIR)/data
DATA_DIR_TESTS:=$(DATA_DIR)/tests
#################################
# Note use of wildcards to catch *.h and *.cpp files and all the sub_classes
# ... for future unit tests/classes, follow this approach, please
#################################
MOLECULE_UT_SOURCES := $(SOURCE_DIR)/molecule_test/main.cc \
$(SOURCE_DIR)/molecule_manager* \
$(SOURCE_DIR)/molecule_reader* \
$(SOURCE_DIR)/parameter_manager* \
$(SOURCE_DIR)/parser* \
$(SOURCE_DIR)/common.h
MOLECULE_UT_DATA := \
$(DATA_DIR_TESTS)/molecule_test/par_oxalate_and_friends.inp \
$(DATA_DIR_TESTS)/molecule_test/dicarboxy-octane_4.*
PARAM_UT_SOURCES := $(SOURCE_DIR)/parameter_test/main.cc \
$(SOURCE_DIR)/parameter_manager* \
$(SOURCE_DIR)/parser* \
$(SOURCE_DIR)/common.h
PARAM_UT_DATA := $(DATA_DIR_TESTS)/molecule_test/par_oxalate_and_friends.inp
#################################
# Use sub-make inside subdirectory on test target
# NOTE: # silences output of this call...
#################################
molecule_test : molecule_test_prepare_sources molecule_test_prepare_makefiles \
molecule_test_prepare_data_files
#$(MAKE) -C $(TEST_DIR)/molecule_unit_test/ ./bin/molecule_test
#################################
# NOTE: this target uses --preserve to keep base source modification date
# to prevent unnecessary rebuilds
#################################
molecule_test_prepare_sources: molecule_test_dir
#echo Copying sources...
#cp --preserve $(MOLECULE_UT_SOURCES) \
$(TEST_DIR)/molecule_unit_test/source
molecule_test_prepare_makefiles: $(MAKEFILE_DIR)/Makefile.molecule_test
#cp --preserve $(MAKEFILE_DIR)/Makefile.molecule_test \
$(TEST_DIR)/molecule_unit_test/Makefile
molecule_test_prepare_data_files:
#cp --preserve $(MOLECULE_UT_DATA) $(TEST_DIR)/molecule_unit_test/bin/
#################################
# NOTE: This mkdir command uses -p flag to create any missing parent dirs.
# If all dirs already exist, it also returns no error...
#################################
molecule_test_dir:
mkdir -p $(TEST_DIR)/molecule_unit_test/source
mkdir -p $(TEST_DIR)/molecule_unit_test/obj
mkdir -p $(TEST_DIR)/molecule_unit_test/bin
param_test : param_test_prepare_sources param_test_prepare_makefiles \
param_test_prepare_data_files
#$(MAKE) -C $(TEST_DIR)/param_unit_test/ ./bin/param_test
param_test_prepare_sources: param_test_dir
#echo Copying sources...
#cp --preserve $(PARAM_UT_SOURCES) $(TEST_DIR)/param_unit_test/source
param_test_prepare_makefiles: $(MAKEFILE_DIR)/Makefile.param_test
#cp --preserve $(MAKEFILE_DIR)/Makefile.param_test \
$(TEST_DIR)/param_unit_test/Makefile
param_test_prepare_data_files:
#cp --preserve $(PARAM_UT_DATA) $(TEST_DIR)/param_unit_test/bin/
param_test_dir:
mkdir -p $(TEST_DIR)/param_unit_test/source
mkdir -p $(TEST_DIR)/param_unit_test/obj
mkdir -p $(TEST_DIR)/param_unit_test/bin
Here's the sub-makefile result:
####################################################
## -------------------------------
## - Monte Carlo Source Submake -
## -------------------------------
##
## Author: Jason R. Mick
## Date: July 7, 2010
## Company: Wayne State University
##
## CHANGE LOG
## Author Date Description
##
##
##
####################################################
################################
# These lines set up some basic vars
# such as compiler, flags, and dirs.
################################
CC=g++
CFLAGS=-c -Wall
SOURCE_DIR:=./source
INCDIRS := -I$(SOURCE_DIR)
OBJ_DIR:=./obj
EXE_DIR:=./bin
################################
#This line tells make what directories to search in for rules...
################################
VPATH = $(SOURCE_DIR)
################################
# INFO on the "magic" here:
#$^ is all the prerequisite (.o files), $# is target, and % is wildcard
################################
$(EXE_DIR)/molecule_test : $(OBJ_DIR)/main.o \
$(OBJ_DIR)/parameter_manager_lj_molecule.o \
$(OBJ_DIR)/parameter_manager.o $(OBJ_DIR)/parser.o \
$(OBJ_DIR)/molecule_manager.o $(OBJ_DIR)/molecule_manager_main.o \
$(OBJ_DIR)/molecule_reader.o \
$(OBJ_DIR)/molecule_reader_psf_pdb.o
$(CC) $^ -o $#
################################
# These are extra includes for the general
# rule at the end....
################################
$(OBJ_DIR)/main.o $(OBJ_DIR)/molecule_reader.o \
$(OBJ_DIR)/molecule_reader_psf_pdb.o: \
molecule_manager.h \
molecule_manager_main.h \
parameter_manager.h \
parameter_manager_lj_molecule.h
$(OBJ_DIR)/molecule_manager_main.o: molecule_manager.h
$(OBJ_DIR)/parameter_manager_lj_molecule.o: parser.h
$(OBJ_DIR)/molecule_reader_psf_pdb.o: molecule_reader.h
################################
# Special rule for main object
################################
$(OBJ_DIR)/main.o: $(SOURCE_DIR)/main.cc \
molecule_reader.h \
molecule_reader_psf_pdb.h common.h
$(CC) $(CFLAGS) $(INCDIRS) $< -o $#
################################
# The GENERAL RULE for objects...
# INFO on the "magic" here:
#$< is the first prerequisite (.cpp file), $# is target, and % is wildcard
################################
$(OBJ_DIR)/%.o: $(SOURCE_DIR)/%.cpp $(SOURCE_DIR)/%.h $(SOURCE_DIR)/common.h
$(CC) $(CFLAGS) $(INCDIRS) $< -o $#
... basically I'm pretty satisfied, everything is working, clean, and well documented, but I wanted to see if anyone else has suggestions of things I should change for "best practice" etc. I'm trying to learn as much as I can!! Thanks in advance!!
Cheers,
Jason
I would rethink calling make recursively, and instead #include the submakefiles in the main makefile. It is much easier to get the dependancies to work right, and it allows you to utilize multiple cores for building (using -j). Take a look at Recursive Make Considered Harmful for all the gory details.
Also, take a look at these questions:
What is your experience with non recursive make?
Recursive make friend or foe
(I won't enter into the recursive/non-recursive debate again. 'Nuff said.)
Why copy all of these files around? I understand that you don't want to hardcode a map of your directory structure in the submake, but you can save a lot of time and trouble by giving the submake access to the original files, either by symbolic link:
molecule_test_prepare_sources: molecule_test_dir
#echo linking to sources...
#ln -s $(SOURCE_DIR) $(TEST_DIR)/molecule_unit_test/source
molecule_test_prepare_makefiles: $(MAKEFILE_DIR)/Makefile.molecule_test
#ln -s $< $(TEST_DIR)/molecule_unit_test/Makefile
Or by passing a parameter to the submake:
param_test : param_test_prepare_sources param_test_prepare_makefiles \
param_test_prepare_data_files
#$(MAKE) -C $(TEST_DIR)/param_unit_test/ SOURCE_DIR=$(SOURCE_DIR) \
./bin/param_test # and then use SOURCE_DIR in the submake
The same goes for param_test. I think this actually lets you do away with MOLECULE_UT_SOURCES and PARAM_UT_SOURCES, and good riddance.
(I left out the data directories, because I don't know what this code actually does-- maybe it needs a restriced diet, or modifies its input files or something.)
Finally as a matter of style, almost anywhere you see redundancy you can remove it and make the makefile easier to read. For instance,
$(EXE_DIR)/molecule_test : $(OBJ_DIR)/main.o \
$(OBJ_DIR)/parameter_manager_lj_molecule.o \
$(OBJ_DIR)/parameter_manager.o $(OBJ_DIR)/parser.o \
$(OBJ_DIR)/molecule_manager.o $(OBJ_DIR)/molecule_manager_main.o \
$(OBJ_DIR)/molecule_reader.o \
$(OBJ_DIR)/molecule_reader_psf_pdb.o
$(CC) $^ -o $#
can become
OBJECTS := main \
parameter_manager_lj_molecule \
parameter_manager parser \
molecule_manager molecule_manager_main \
molecule_reader \
molecule_reader_psf_pdb
OBJECTS := $(patsubst %,$(OBJ_DIR)/%.o, $(OBJECTS)
$(EXE_DIR)/molecule_test : $(OBJECTS)
$(CC) $^ -o $#
This isn't the answer you're looking for but have you considered using the "autotools" suite (automake, autoconf, etc.)?
Once you get the hang of it it's quite wonderful to work with. And it has a lot more functionality than pure Make. Functionality such as checking for libraries needed to build, cross-compiling, etc.