1

I'm trying to debug a problem in my gcc Makefile that came from the ChatScript open source chat-bot project:

http://chatscript.sourceforge.net/

Here are my relevant version numbers:

Ubuntu 14.04
make version 3.81
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

I can't seem to get it to find a source file in another directory that is along-side the current working directory. If I move the source file into the current directory, it works fine, but if I put the file back in the old directory, it complains it can't find it:

make: *** No rule to make target `privatesrc.cpp', needed by `all'.  Stop.

The current directory I am in when executing make is SRC, the directory where Makefile is located. privatesrc.cpp resides in a sibling directory that should be reachable from SRC with this relative path:

../privatecode/privatesrc.cpp

To debug this problem I want to see exactly what the files are for each of the make target's variables. I used these two SO posts to try and dump those values:

How to print out a variable in makefile

Jim Nisby's answer. And:

gnu make: list the values of all variables (or "macros") in a particular run

The accepted answer.

I created this new make target called server_dry_run to facilitate this:

server_dry_run: DEFINES+= -DPRIVATE_CODE -DLOCKUSERFILE=1 -DEVSERVER=1 -DEVSERVER_FORK=1 -DDISCARDDATABASE=1
server_dry_run: PGLOAD= -pthread
server_dry_run: INCLUDEDIRS=-Ievserver
server_dry_run: all
server_dry_run: EXECUTABLE=../BINARIES/ChatScript
server_dry_run: CFLAGS=-c -Wall  -funsigned-char  -Wno-write-strings -Wno-char-subscripts -Wno-strict-aliasing 
# Uncomment this line if you want to filter out variables already defined.
# VARS_OLD := $(.VARIABLES)
CUR-DIR := $(shell pwd)
LOG-DIR := $(CUR-DIR)/make-logs
$(info INCLUDEDIRS="$(INCLUDEDIRS)")
$(foreach v,$(filter-out $(VARS_OLD) VARS_OLD,$(.VARIABLES)),$(info $(v) = $($(v))))

However, INCLUDEDIRS always shows as empty:

INCLUDEDIRS=""

How can I see the value of INCLUDEDIRS so I can fix this problem?

Below is the entire content of my Makefile. Note, I did try removing the quotes I added around the value assigned to INCLUDEDIRS, but that didn't help. One other bit of data. If I do "make clean" I get the error "rm: cannot remove `../': Is a directory", which seems to indicate the EXECUTABLE target variable may not be right.

MAKEFILE:

debugserver: DEFINES+= -DPRIVATE_CODE -DLOCKUSERFILE=1 -DEVSERVER=1 -DEVSERVER_FORK=1 -DDISCARDDATABASE=1 -DDEBUG
debugserver: PGLOAD= -pthread
debugserver: INCLUDEDIRS="-Ievserver -I../privatecode"
debugserver: all
debugserver: EXECUTABLE=../BINARIES/ChatScriptDebug
debugserver: CFLAGS=-c -Wall  -funsigned-char  -Wno-write-strings -Wno-char-subscripts -Wno-strict-aliasing -g

debugpgserver: DEFINES+= -DPRIVATE_CODE -DLOCKUSERFILE=1 -DEVSERVER=1 -DEVSERVER_FORK=1  -DDEBUG
debugpgserver: PGLOAD= -lpq -pthread
debugpgserver: INCLUDEDIRS="-Ievserver -I../privatecode"
debugpgserver: all
debugpgserver: EXECUTABLE=../BINARIES/ChatScriptpgDebug
debugpgserver: CFLAGS=-c -Wall  -funsigned-char  -Wno-write-strings -Wno-char-subscripts -Wno-strict-aliasing -g

server: DEFINES+= -DPRIVATE_CODE -DLOCKUSERFILE=1 -DEVSERVER=1 -DEVSERVER_FORK=1 -DDISCARDDATABASE=1
server: PGLOAD= -pthread
server: INCLUDEDIRS="-Ievserver -I../privatecode"
server: all
server: EXECUTABLE=../BINARIES/ChatScript
server: CFLAGS=-c -Wall  -funsigned-char  -Wno-write-strings -Wno-char-subscripts -Wno-strict-aliasing 

standalone: DEFINES+= -DPRIVATE_CODE  -DDISCARDSERVER=1 -DDISCARDDATABASE=1 
standalone: PGLOAD= -pthread
standalone: INCLUDEDIRS="-Ievserver -I../privatecode"
standalone: all
standalone: EXECUTABLE=../BINARIES/ChatScript
standalone: CFLAGS=-c -Wall  -funsigned-char  -Wno-write-strings -Wno-char-subscripts -Wno-strict-aliasing 

pgserver: DEFINES+= -DPRIVATE_CODE -DLOCKUSERFILE=1 -DEVSERVER=1 -DEVSERVER_FORK=1 
pgserver: PGLOAD= -lpq -pthread
pgserver: all
pgserver: EXECUTABLE=../BINARIES/ChatScriptpg
pgserver: INCLUDEDIRS="-Ievserver -Ipostgres -I../privatecode"
pgserver: CFLAGS=-c -Wall  -funsigned-char  -Wno-write-strings -Wno-char-subscripts -Wno-strict-aliasing 


mongoserver: DEFINES+= -DPRIVATE_CODE -DLOCKUSERFILE=1 -DEVSERVER=1 -DEVSERVER_FORK=1 
mongoserver: PGLOAD= -lpq -pthread
mongoserver: all
mongoserver: EXECUTABLE=../BINARIES/ChatScriptmongo
mongoserver: INCLUDEDIRS="-Ievserver -I../privatecode"
mongoserver: CFLAGS=-c -Wall  -funsigned-char  -Wno-write-strings -Wno-char-subscripts -Wno-strict-aliasing 

server_dry_run: DEFINES+= -DPRIVATE_CODE -DLOCKUSERFILE=1 -DEVSERVER=1 -DEVSERVER_FORK=1 -DDISCARDDATABASE=1
server_dry_run: PGLOAD= -pthread
server_dry_run: INCLUDEDIRS=-Ievserver -I../privatecode
server_dry_run: all
server_dry_run: EXECUTABLE=../BINARIES/ChatScript
server_dry_run: CFLAGS=-c -Wall  -funsigned-char  -Wno-write-strings -Wno-char-subscripts -Wno-strict-aliasing 
# Uncomment this line if you want to filter out variables already defined.
# VARS_OLD := $(.VARIABLES)
CUR-DIR := $(shell pwd)
LOG-DIR := $(CUR-DIR)/make-logs
$(info INCLUDEDIRS="$(INCLUDEDIRS)")
$(foreach v,$(filter-out $(VARS_OLD) VARS_OLD,$(.VARIABLES)),$(info $(v) = $($(v))))

UNAME := $(shell uname)

CC=g++

ifeq ($(UNAME), Linux)
$(info ************ LINUX VERSION ************)
LDFLAGS= -lrt -lcurl --verbose $(PGLOAD) 
endif

ifeq ($(UNAME), Darwin)
$(info ************ MAC VERSION ************)
LDFLAGS=-mmacosx-version-min=10.7 $(PGLOAD)  
CFLAGS=-mmacosx-version-min=10.7 -c -Wall  -funsigned-char -Wno-write-strings -Wno-char-subscripts 
endif

SOURCES=constructCode.cpp evserver.cpp csocket.cpp cs_ev.c dictionarySystem.cpp englishTagger.cpp factSystem.cpp  functionExecute.cpp english.cpp infer.cpp javascript.cpp jsmn.cpp markSystem.cpp os.cpp outputSystem.cpp patternSystem.cpp privatesrc.cpp scriptCompile.cpp spellcheck.cpp secure.cpp systemVariables.cpp tagger.cpp testing.cpp textUtilities.cpp tokenSystem.cpp topicSystem.cpp userCache.cpp userSystem.cpp variableSystem.cpp mainSystem.cpp 
OBJECTS=$(SOURCES:.cpp=.o)

all: $(SOURCES) binary

clean:
    -rm -f $(EXECUTABLE)
    -rm -f ../$(EXECUTABLE)
    -rm -f *.o

binary: $(OBJECTS)
    $(CC) $(OBJECTS) $(LDFLAGS) $(DEFINES) $(INCLUDEDIRS) -o $(EXECUTABLE)

.cpp.o:
    $(CC) $(CFLAGS) $(DEFINES) $(INCLUDEDIRS) $< -o $@
Community
  • 1
  • 1
Robert Oschler
  • 14,153
  • 18
  • 94
  • 227
  • 1
    `info` is executed as part of the first pass make performs on the file, at that point in time `INCLUDEDIRS` is empty, it's only set when make starts parsing through the targets. Also as far as I can tell make has no way of knowing that those source files can be found in `../privatecode`, you need to specify `vpath`s for that. Why are the source files a target of `all` anyway, that also doesn't make much sense. – user657267 Apr 12 '16 at 22:24
  • @ user657267 1) Thanks for the note about info. Is there any way to see that "second pass" information then? 2) My understanding is that the -I directive tells gcc to look in those other paths for source files. – Robert Oschler Apr 12 '16 at 22:58
  • 1
    To see the value of the variable inside the rule (where it matters), add a command: `echo the value of INCLUDEDIRS is $(INCLUDEDIRS)` – Beta Apr 12 '16 at 23:12
  • 1
    `-I` only affects the preprocessor, i.e. where gcc looks for `include` directives. The issue here is before the compiler is even invoked, make has no idea where to find the source files because you haven't told it where they are (and they don't have a relative or absolute path). Try adding the directive `vpath %.cpp ../privatecode`, and get rid of the `SOURCES` prerequisite on `all`, assuming you invoke make in the directory where the makefile is. This is a bit of a dirty fix however, there's a lot of other issues with this Makefile. – user657267 Apr 12 '16 at 23:15
  • @user657267 Thanks. I ended up using the simpler form VPATH = ../privatecode but your suggestion worked great. If you're interested, please turn your comment into a reply to my post and I will mark it as the accepted answer. – Robert Oschler Apr 13 '16 at 02:29
  • @RobertOschler You should probably update the question and title first as the root issue was how to get make to see the sources rather than printing target specific variables. – user657267 Apr 13 '16 at 02:32

0 Answers0