I have a makefile:
#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
That calls a second makefile after it creates and populates the directory structure.
The second makefile is as follows:
#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)/
I admit I'm somewhat of a novice at Makefiles. I would both like advice as to how to streamline these files (without too much "magic") and how to fix these two errors...
First I have to say everything is working, so to speak. When I build my target it creates all the directories right and generates the executable. And all my files get copied properly and get recompiled when I touch the files in my base-level source directory. So these aren't "real" errors so to speak, just annoying error text I want to get rid of...
The first error occurs when I run a build make molecule_test
which requires it to do something. Whatever it needs to do gets done, but I also get:
g++: g++: No such file or directory
g++: g++: No such file or directory
g++: g++: No such file or directory
g++: g++: No such file or directory
g++: g++: No such file or directory
g++: g++: No such file or directory
make: *** [molecule_test] Error 1
..AGAIN the build succeeds, creating the executable properly
The second error I get occurs when there's nothing to be done...when that happens I get:
/bin/sh: -c: line 0: unexpected EOF while looking for matching ``'
/bin/sh: -c: line 1: syntax error: unexpected end of file
Please be gentle... I've read basic makefile tutorials, including the gnu makefile tutorial, but there seems to be a leap between creating a small program with a handful of local sources and a large program with the need for nested directories, data files, etc. I'm trying to make that leap... unfortunately I have no best practice makefiles from past code as I'm at a small research group at a university, not a corporate atmosphere.
My basic approach is to create a base directory with the following
[dir] source/
[dir] data/
[dir] makefiles/
[dir] build/ **gets created
Makefile
The top level makefile creates a subdirectory in the build directory, copies the needed sources (say for a particular test program, and needed data files, and a makefile to make all the sources. The top level makefile then calls the build-level makefile.
I'd be open to ideas on how to streamline this process, but would appreciate if we FIRST resolve the errors.
Thanks in advance!!!
P.S. I'm running on Centos 5.4, GNU Make 3.81, gcc version 4.1.2 20080704 (Red Hat 4.1.2-44) .... GNU Make and gcc are both 64-bit versions...