I'm trying to debug an issue with a makefile I am working on.. What is confusing is that the target works when I run it from the command line, but does not work in my makefile..
Here is the makefile:
DDS_OUT_DIR = $(PWD)
IDL_DIR=/opt/idl/dds
IDL_TYPES=common.idl
GENERATED_SOURCES = $(IDL_TYPES:%.idl=%Support.cxx) $(IDL_TYPES:%.idl=%Plugin.cxx) $(IDL_TYPES:%.idl=%.cxx)
GENERATED_HEADERS = $(IDL_TYPES:%.idl=%Support.h) $(IDL_TYPES:%.idl=%Plugin.h) $(IDL_TYPES:%.idl=%.h)
OBJS_DIR = obj.$(CPUTYPE)
GENERATED_OBJS = $(GENERATED_SOURCES:%.cxx=$(OBJS_DIR)/%.o)
LIBDIR = ../../lib.$(CPUTYPE)
BINDIR = ../../../../bin.$(CPUTYPE)
CC = $(C_COMPILER)
CXX = $(CPP_COMPILER)
OS = $(shell uname)
DDSCOMMON = ../../Common/src
CFLAGS = -m32 -g
CXXFLAGS = -m32 -g
LDFLAGS = -m32 -static-libgcc
SYSLIBS = -ldl -lnsl -lpthread -lm -lc
DEFINES_ARCH_SPECIFIC = -DRTI_UNIX
DEFINES = $(DEFINES_ARCH_SPECIFIC) $(cxx_DEFINES_ARCH_SPECIFIC)
INCLUDES = -I. -I$(NDDSHOME)/include -I$(NDDSHOME)/include/ndds
INCLUDES += -I$(DDSCOMMON)
LIBS = -L$(NDDSLIBDIR) -L$(LIBDIR) -lrt \
-lnddscppz -lnddscz -lnddscorez $(SYSLIBS) $(OS_SPECIFIC_LIBS)
COMMONLIBSRC = $(DDSCOMMON)/dds_common.cxx
COMMONLIBOBJS = $(DDSCOMMON)/obj.$(CPUTYPE)/%.o
$(shell mkdir -p $(OBJS_DIR) $(DDSCOMMON)/obj.$(CPUTYPE))
default: ${IDL_TYPES} $(GENERATED_OBJS)
$(OBJS_DIR)/%.o : %.cxx %.h $(DDSCOMMON)/dds_common.h
$(CPP_COMPILER) -o $# $(DEFINES) $(INCLUDES) $(CXXFLAGS) -c $<
%.idl:
#echo "Generating CXX from $# ..." $(GENERATED_OBJS); \
$(NDDSHOME)/scripts/rtiddsgen ${IDL_DIR}/$# -d $(DDS_OUT_DIR) -I ${IDL_DIR} -replace -language C++;
if I just do this:
make
The %.idl target is called fine, when that finishes I get this output:
Generating CXX from common.idl ... obj.Linux-i686/commonSupport.o obj.Linux-i686/commonPlugin.o obj.Linux-i686/common.o
Running rtiddsgen version 4.5d, please wait ...
Done
make: *** No rule to make target `obj.Linux-i686/commonSupport.o', needed by `default'. Stop.
But then when I re-run it and everything compiles, so it works fine...
Why is this not working in one step?
commonSupport.cxx seems to depend on common.idl. Tell this to make.
commonSupport.cxx: common.idl
#echo "Generating CXX from $# ..." $(GENERATED_OBJS); \
$(NDDSHOME)/scripts/rtiddsgen ${IDL_DIR}/$# -d $(DDS_OUT_DIR) -I ${IDL_DIR} -replace -language C++;
Or, to ensure all dependencies are right:
$(GENERATED_SOURCES): common.idl
.... steps to make GENERATED_SOURCES from common.idl
Related
I have the following Makefile:
SOURCES = part1.cpp part2.cpp main.cpp
OBJECTS = ${SOURCES:.cpp=.o}
DEPS = ${SOURCES:.cpp=.d}
CXX = g++
CXXFLAGS = -Wall -I -std=c++11
ExecutableName = Partsapp
BUILD_DIR = build/host
MahApp: $(BUILD_DIR)/$(DEPS) $(BUILD_DIR)/$(OBJECTS)
$(CXX) $(CXXFLAGS) -o $# $(BUILD_DIR)/$(OBJECTS)
build/host/%.d: ./%.cpp
$(CXX) -MT$(#:.d=.o) -MM $(CXXFLAGS) $^ > $#
-include build/host/$(DEPS)
clean:
rm -f $(OBJECTS) $(DEPS) MahApp
Now, whenever I try to run it, I get the following error:
No rule to make target 'part2.d', needed by 'MahApp'. Stop.
Now, the funny thing is that it does manage to create part1.d correctly from the pattern matching rule, however after that it just seizes to work, and I just can't figure out why!
Any help would be much appreciated :)
SOURCES = part1.cpp part2.cpp main.cpp
...
DEPS = ${SOURCES:.cpp=.d}
...
BUILD_DIR = build/host
MahApp: $(BUILD_DIR)/$(DEPS) ...
...
DEPS expands to part1.d part2.d main.d, so $(BUILD_DIR)/$(DEPS) expands to build/host/part1.d part2.d main.d, and Make is telling you it can't find part2.d.
The construction you want is:
BUILD_DIR = build/host
DEPS = $(patsubst %.cpp, $(BUILD_DIR)/%.d, $(SOURCES))
(There are other ways to do it.) And the way to examine your variables to see if they are what you think they are is like this:
$(info $(DEPS))
Here is my makefile, until today I never try to use OS detection in it. Mine looks like this :
CC = gcc
CFLAGS = -Wall -Wextra -O1 -Wuninitialized
OUT = project.exe
ifeq ($(UNAME),Darwin) #Mac OS
echo "Darwin"
SRC = sdl_gui.c libSDLextra.c libImageProcessing.c SDLmain.m
OBJ = sdl_gui.o libSDLextra.o libImageProcessing.o SDLmain.o
LIBS = -I /Library/Frameworks/SDL.framework/Headers -framework SDL -I /Library/Frameworks/SDL_ttf.framework/Versions/A/Headers -framework SDL_ttf -framework Cocoa
endif
ifeq ($(UNAME),Linux) #Linux based systems
SRC = sdl_gui.c libSDLextra.c libImageProcessing.c
OBJ = sdl_gui.o libSDLextra.o libImageProcessing.o
LIBS = -lSDL -lSDL_ttf
endif
all : $(OUT)
$(OUT) : $(OBJ)
$(CC) $(CFLAGS) $(OBJ) -o $(OUT)
$(OBJ) : $(SRC)
$(CC) $(CFLAGS) -c $(SRC)
clean :
rm -f $(OBJ) $(OUT)
When I do make I've got this error :
gcc -Wall -Wextra -O1 -Wuninitialized -o projet.exe
clang: error: no input files
make: *** [projet.exe] Error 1
I understand the error but I don't know how to fix it.
It looks like you are missing this from (near) the top of the file:
UNAME := $(shell uname)
I am new to Mac OS, and want to execute following makefile program.
GCCBASE = $(GCMDIR)/where/cplusplus/gcc
SRCS:=$(wildcard *.cpp) program.cpp
OBJS:=$(SRCS:.cpp=$(OBJDIR).o)
INCLUDES:=-I. -I$(ADD_INCLUDES)/Auto*.h -I$(ADD_INCLUDES)/program.h
OUTBASE =$(OUTBASE_EX)
OUT_ARTIFACT=Program
ifeq ($(OSNAME),Linux)
ifeq ($(GFLIB_MODEL),64bit)
CXXEXTRA_FLAGS = -m64
GCCDIR = $(GCCBASE)/linux64/4.5.3
GCCLIBDIR_W = $(GCCBASE)/linux64/4.5.3/lib64
GCCLIBDIR = $(GCCLIBDIR_W)
CFLAGS_common += -I$(GCCBASE)/linux64/4.5.3/include
OUTDIR = $(OUTBASE)/64
CFLAGS_link_libs = -L$(GCCLIBDIR) -lmyLib
else
CXXEXTRA_FLAGS = -m32
GCCDIR = $(GCCBASE)/linux/4.5.3
GCCLIBDIR_W = $(GCCBASE)/linux/4.5.3/lib
GCCLIBDIR = $(GCCLIBDIR_W)
CFLAGS_common += -I$(GCCBASE)/linux/4.5.3/include
OUTDIR = $(OUTBASE)/32
CFLAGS_link_libs = -L$(GCCLIBDIR) -lmyLib
endif
endif
ifeq ($(OSNAME),Darwin)
echo "Mac OS"
ifeq ($(GFLIB_MODEL),64bit)
CXXEXTRA_FLAGS = -m64
GCCDIR = $(GCCBASE)/macosx/4.8.1
GCCLIBDIR_W = $(GCCBASE)/macosx/4.8.1/lib
GCCLIBDIR = $(GCCLIBDIR_W)
CFLAGS_common += -I$(GCCBASE)/macosx/4.8.1/include
OUTDIR = $(OUTBASE)/64
CFLAGS_link_libs = -L$(GCCLIBDIR) -lmyLib
else
CXXEXTRA_FLAGS = -m32
GCCDIR = $(GCCBASE)/macosx/4.8.1
GCCLIBDIR_W = $(GCCBASE)/macosx/4.8.1/lib/i386
GCCLIBDIR = $(GCCLIBDIR_W)
CFLAGS_common += -I$(GCCBASE)/macosx/4.8.1/include
OUTDIR = $(OUTBASE)/32
CFLAGS_link_libs = -L$(GCCLIBDIR) -lmyLib
endif
endif
all: $(SRCS)
echo "Building Program application..."
$(CXX) $(CXXEXTRA_FLAGS) $(CFLAGS_common) $(INCLUDES) $^ -o $(OUTDIR)/$(OUT_ARTIFACT) $(CFLAGS_link_libs)
rm -f *.[o] *.log core
Command that gets executed on mac OS looks like this with linker errors since myLib was not found:
[exec] c++ -I. -IAuto*.h -IProgram.h Program.cpp -o /Program
While I am expecting my command to be like this:
[exec] c++ -m32 -I. -IAuto*.h -IProgram.h Program.cpp -o /Program -LmyPath -lmyLib
Why is my command not including -m32 and Linking library path?
I also tried printing CXXEXTRA_FLAGS and CFLAGS_link_libs, but they are empty.
You never set the variables OSNAME or GFLIB_MODEL to any value in this makefile, so they're both empty. Thus neither of the tests for OSNAME are true, and those values are never set in CXXEXTRA_FLAGS etc.
ETA: Here's an example based on your comments:
$ cat Makefile
ifeq ($(OSTYPE),Mac OS X)
$(info got mac)
endif
all: ; #:
$ make
$ make OSTYPE=Mac
$ make OSTYPE='Mac OS X'
got mac
I am facing errors in make file in CentOS 6.02 64 bit. I need to know what should be done to make the makefile workable. Any suggestion will be greatly helpful. My make file is pasted below: -
#
.SUFFIXES: .cc $(.SUFFIXES)
ALL = libpal.a
#all = $(ALL)
all: $(ALL)
.cpp.o:
$(C++) -o $# -c $(PROF) $(CFLAGS) $*.cpp
.cc.o:
$(C++) -o $# -c $(PROF) $(CFLAGS) $*.cc
.c.o:
$(CC) -o $# -c $(PROF) $(CFLAGS) $*.c
top_srcdir = ..
OPENSSL_LIB_DIR = ../../ThirdPartyLibs/openssl-0.9.8e/include
BOOST_DIR = ../../ThirdPartyLibs/boost/stage/lib
BOOST_INCLUDE_DIR = ../../ThirdPartyLibs/boost
CC = gcc
C++ = g++
CCOPT = -Os -Wall -Wno-deprecated
CCOPT_DEBUG = -Wall -g -Wno-deprecated
PROF =
STATIC = -static
INCLUDE = \
-I./usr/include/sys
-I./Headers \
-I$(top_srcdir)/PAL/Headers \
-I$(top_srcdir)/BaseMulti/Headers \
-I$(top_srcdir)/NetworkMulti/Headers \
-I$(top_srcdir)/RTP/Headers \
-I$(BOOST_INCLUDE_DIR) \
-I$(OPENSSL_LIB_DIR) \
LIBDIRS = \
-L$(BOOST_DIR) \
#XXX NLAYER define / MB_DEBUG
DEFINE = -D_LINUX -DDEBUGLOG -D_INDENT_DB_PRINT -fsigned-char -fno-inline -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -D_POSIX_PER_PROCESS_TIMER_SOURCE -D_PTHREADS -DUNICODE #-DDISABLE_LOG
SHLIB_SUFFIX = .so
SHLIB_LD = gcc -shared
SHLIB_LD_LIBS =
SHLIB_CFLAGS = -fPIC
BFLAGS = $(DEFINE) $(INCLUDE)
CFLAGS = $(CCOPT) $(BFLAGS)
OBJ_C =
OBJ_CC = \
./Sources/PALsystime.o \
./Sources/PALdebug.o \
./Sources/PALdebuglog.o \
./Sources/PALthread.o \
./Sources/PALcritsec.o \
./Sources/PALprofiler.o \
./Sources/PALserializable.o \
./Sources/PALinet.o \
./Sources/PALnetwork.o \
./Sources/PALsocket.o \
./Sources/PALlocalhostUdpEvent.o \
./Sources/PALpollarray.o \
./Sources/PALrandom.o \
OBJS = $(OBJ_C) $(OBJ_CC)
SRCS = $(OBJ_C:.o=.c) $(OBJ_CC:.o=.cc)
debug: DEFINE += -DDEBUG
debug: BFLAGS = $(DEFINE) $(INCLUDE)
debug: CFLAGS = $(CCOPT_DEBUG) $(BFLAGS)
debug: $(OBJS)
ar crsu libpal_debug.a $(OBJS)
libpal.a: $(OBJS)
ar crsu libpal.a $(OBJS)
cleandeps:
$(RM) ./Sources/*.o .depend* core
clean: cleandeps
$(RM) ./libpal.a ./libpal_debug.a
$(RM) $(ALL)
And the resultant error is:
Makefile:34: *** missing separator. Stop.
You can find an explanation of this error in Appendix B Errors Generated by Make.
Every line in a recipe must begin with a tab character. The recipes starting with $(C++) and $(CC) near the top of your file do not seem to start with a tab character.
Additionally, the section
INCLUDE = \
-I./usr/include/sys
-I./Headers \
seems to be missing a backslash after sys and that same section (and many more) have superfluous empty lines.
Open your make file in vim rather than in editors like gedit. Every line in a recipe must begin with a tab character.
This answer is for other Make newbies such as myself who find this question from Googling and get stuck because they are modifying a large pre-existing Makefile, with no lines beginning with a space character. My problem occurred because a makefile in a subdirectory with spaces instead of tabs was getting called by a parent makefile, where I erroneously thought the problem existed.
Once I fixed the makefile in the subdirectory, everything worked like a charm.
First of all, I'm trying to get used to makefiles but yet I#m new with this. The following file is supposed to, first, compile all ./src/*.cpp files to ./src/*.o (where the filename survives) and afterwards complete compilation with simulation.cpp and linking the whole stuff together. Now, make returns the error message:
make: -c: Command not found
I have literally no clue how to proceed! Would the wildcard-construct even work in the way desired? Thanks a lot for your effort!
#basic stuff
TRUE = 1
FALSE = 0
SHELL := #!/bin/bash
# path names
SRCPATH = ./src/
CLEANPATH = ./res/ \
./crash/
# source files.
MAIN = simulation.cpp
OBJS = $(wildcard $(SRCPATH)*.o)
SRCS = $(wildcard $(SRCPATH)*.cpp)
INCLUDES = $(wildcard $(SRCPATH)*.h)
#GLOBAL MACROS PASSED TO PROGRAM!
MODEL_MRT = $(TRUE) #if true model used is MRT else SRT
PARALLEL = $(TRUE)
GRAVITY = $(TRUE)
# output file name
OUT = simulation
# C++ compiler flags (-g -O2 -Wall)
CXXFLAGS = -g -Wall -O -fopenmp
CXXDEFINES = -D MODEL=$(MODEL_MRT) -D PARALLEL=$(PARALLEL) -D GRAVITY=$(GRAVITY)
# compiler
CXX = g++
$(OUT) : $(OBJS)
$(CXX) $(CXXFLAGS) $(MAIN) $(OBJS) $(CXXDEFINES) -o $(OUT)
$(OBJS) : $(SRCS) $(INCLUDES)
$(CXX) $(CXXFLAGS) -c $(SRCS) -o $(OBJS)
clean : $(OUT)
rm $(OBJS)
rm $(CLEANPATH)/*.*
run : $(OUT) clean
./$(OUT)
.PHONY: clean run
You're tricking make with your SHELL variable, it sees is at empty as it is just a comment.
Change
SHELL := #!/bin/bash
to
SHELL := /bin/bash
This line:
SHELL := #!/bin/bash
is incorrect.
Your makefile should work perfectly well if you leave that line out altogether. If you do need something there, try
SHELL := /bin/bash