How to write a shell script to compile multiple embedded sql in C files (.sqc)? - sql

I have written 3 .sqc files i.e. embedded sql in host language C. I need to make a (Unix) shell script to simply compile all 3 sqc files in a row. How can I do that? Right now, I can individually run each .sqc file using a Makefile that basically converts the .sqc file to a c file and then compiles it. Can I make 3 individual Makefiles and run all of them through a shell script? If so, then how? Can I make one Makefile that can compile all 3 .sqc independently and compile them thereafter through a shell script? If so, then how? Any other options?
Here is the Makefile that can only compile a single .sqc file:
NAME=sample
DB2PATH = /sqllib
CC=gcc
CFLAGS=-I$(DB2PATH)/include
LIBS=-L$(DB2PATH)/lib -R$(DB2PATH)/lib -ldb2
all: $(NAME)
$(NAME): $(NAME).sqc util.o
db2 connect to sampleDB
db2 prep $(NAME).sqc bindfile
db2 bind $(NAME).bnd
db2 connect reset
$(CC) $(CFLAGS) -c $(NAME).c
$(CC) $(CFLAGS) -o $(NAME) $(NAME).o util.o $(LIBS)
clean:
rm -f $(NAME) $(NAME).c $(NAME).o $(NAME).bnd
util.o : util.c
$(CC) -c util.c $(CFLAGS)
A possible (Unix) shell script and Makefile example would suffice to help.
Thank you.

This Makefile should do all three in one step, just type "make". Note that you'll have to change the second line to reflect the names of your real .sqc files.
Also note that I'm not familiar with sqc and I haven't tested this, I'm just working from your Makefile.
# THIS IS THE ONLY LINE YOU'LL HAVE TO CHANGE:
NAMES = file1 file2 file3
DB2PATH = /sqllib
CC=gcc
CFLAGS=-I$(DB2PATH)/include
LIBS=-L$(DB2PATH)/lib -R$(DB2PATH)/lib -ldb2
all: $(NAMES)
# This will convert .sqc into .c
%.c: %.sqc
db2 connect to sampleDB
db2 prep $< bindfile
db2 bind $*.bnd
db2 connect reset
# This will compile .c into .o, whether it's fileN.c or util.c
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
# This will link fileN.o and util.o into fileN
$(NAMES): % : %.o util.o
$(CC) $(CFLAGS) -o $# $^ $(LIBS)
# This is just to assure Make that that isn't really a file called "clean"
.PHONY: clean
clean:
rm -f $(NAMES) $(NAMES:=.c) $(NAMES:=.o) $(NAMES:=.bnd)

DB2PATH = /sqllib
CC=gcc
CFLAGS=-I$(DB2PATH)/include
LIBS=-L$(DB2PATH)/lib -R$(DB2PATH)/lib -ldb2
all: $(NAME)
$(NAME): $(NAME).sqc util.o
db2 connect to sampleDB
db2 prep $(NAME).sqc bindfile
db2 bind $(NAME).bnd
db2 connect reset
$(CC) $(CFLAGS) -c $(NAME).c
$(CC) $(CFLAGS) -o $(NAME) $(NAME).o util.o $(LIBS)
clean:
rm -f $(NAME) $(NAME).c $(NAME).o $(NAME).bnd
util.o : util.c
$(CC) -c util.c $(CFLAGS)
suppose you have three files: file1.sqc file2.sqc file3.sqc, and your makefile is saved as mksqc.mk
Script:
make -f mksqc.mk NAME=file1
make -f mksqc.mk NAME=file2
make -f mksqc.mk NAME=file3

Related

makefile with debug option

I am kinda rookie in makefile field but trying to write makefile that would go in two modes: normal mode make outputing executable file called say bingo depending on some files and a mode make debug outputing executable file called bingo.debug that shall be compiled with debug option. I'm trying to use target variable with the following result:
PROGRAM = bingo
SUFIX = .debug
CC = gcc
CFLAGS = -Wall -O2
DEBUG = -g -D DEBUG
all: $(PROGRAM)
debug: CFLAGS += $(DEBUG)
debug: PROGRAM += $(SUFIX)
debug: all
file1.o: file1.c file1.h
$(CC) -c $(CFLAGS) -o $# $<
file2.o: file2.c file2.h
$(CC) -c $(CFLAGS) -o $# $<
$(PROGRAM).o: $(PROGRAM).c
$(CC) -c $(CFLAGS) -o $# $<
$(PROGRAM): file1.o file2.o ($PROGRAM).o
$(CC) -o $# $^
.PHONY: all clean
clean:
rm -rf $(PROGRAM) *.o
It looks like make debug correctly compiles the file with debug flags but it does not change the file name (i.e. both modes outputs the same bingo file). Any help much appriciated!
You cannot use target-specific variables in targets. The documentation is very clear that they are available only in recipes.
In general it's problematic to do things this way, because make has no idea which objects were built with debug and which weren't. If you forget to do a complete clean and/or run make the wrong way then you'll get a mix of different object files: some compiled with debug and some not.
Instead, you should put your debug object files in a different directory from your non-debug object files so you don't have to worry about that.

Can I build my PC file (Oracle Pro*c) conditionally inside of my application's make file?

I'm attempting to combine my makefiles so I can simply build once and it will precompile the pc file completely before continuing to build the application. This should be possible but for the life of me I cannot figure it out. Here is my makefile (for redhat 7).
COMPILEDATE = $(shell date)
COMPILE=g++ -std=c++11 -Wall -Wuninitialized -g
OSTYPE = $(shell uname)
LIBDIR=../../lib/
INC=../../include/
FILES=myProcess
OBJS= myProcess.o \
sqlStuff.o
O8P=$(ORACLE_HOME)
O8P=/u01/app/oracle/11.2.0/client_1
ORACLE_HOME=/u01/app/oracle/11.2.0/client_1
PROC_LINES=proc lines=yes code=ANSI_C iname=sqlStuff.pc parse=partial iname=sqlStuff include=. include=$(ORACLE_HOME)/precomp/public include=$(ORACLE_HOME)/rdbms/public include=$(ORACLE_HOME)/rdbms/demo include=$(ORACLE_HOME)/plsql/public include=$(ORACLE_HOME)/network/public
all: $(FILES)
compileInfo.o : FORCE
$(COMPILE) -c compileInfo.cpp -o $# -I$(INC) -DCDATE="\"$(COMPILEDATE)\"" -DBUILD="\"$(LSWBUILD)\""
FORCE :
%.o : %.cpp $(INC)myProcess.h
$(COMPILE) -c $< -o $# -I$(INC) -DCDATE="\"$(COMPILEDATE)\""
sqlStuff.o : sqlStuff.c
gcc -g -Wall -O -c -lclntsh -I. -I$(ORACLE_HOME)/precomp/public -I$(ORACLE_HOME)/rdbms/public -I$(ORACLE_HOME)/rdbms/demo -I$(ORACLE_HOME)/plsql/lib -I$(ORACLE_HOME)/network/lib
sqlStuff.c : sqlStuff.pc
$(PROC_LINES)
myProcess: $(OBJS) $(LIBDIR)libbase.a $(INC)myProcess.h sqlStuff.o
$(COMPILE) -o myProcess$(OBJS) -L$(LIBDIR) -lbase
clean:
rm -f $(FILES)
rm -f sqlStuff
rm -f sqlStuff.c
rm -f sqlStuff.lis
rm -f $(OBJS)
rm -f core
rm -f *.out
rm -f *.log
rm -f *.err
My fault, I didn't explain what the issue was:
I'm compiling in netbeans using this build command: ${MAKE} -f Makefile. The error is PCC-S-02015, unable to open include file on my object that is not being precompiled, sqlStuff.o
Looking at the gcc command under sqlStuff.o : sqlStuff.c, it looks to me that there should be a -o sqlStuff.o flag to tell gcc that the output should be written to sqlStuff.o instead of the default, which is a.out.
Best of luck.

How to create a makefile for a Fortran program using modules

The challenge is to create a makefile which takes a list of modules and does not require me to sort out precendence. For example, the modules are
mod allocations.f08 mod precision definitions.f08 mod unit values.f08
mod blocks.f08 mod shared.f08 mod parameters.f08
mod timers.f08
The main program is characterize.f08. The error message is
Fatal Error: Can't open module file ‘mprecisiondefinitions.mod’ for reading at (1): No such file or directory
The first statement in the main program is use mPrecisionDefinitions, the module defined in mod precision definitions.f08.
The following makefile, based upon Creating a FORTRAN makefile, is:
# compiler
FC := /usr/local/bin/gfortran
# compile flags
FCFLAGS = -g -c -Wall -Wextra -Wconversion -Og -pedantic -fcheck=bounds -fmax-errors=5
# link flags
FLFLAGS =
# source files and objects
SRCS = $(patsubst %.f08, %.o, $(wildcard *.f08))
# program name
PROGRAM = a.out
all: $(PROGRAM)
$(PROGRAM): $(SRCS)
$(FC) $(FLFLAGS) -o $# $^
%.mod: %.f08
$(FC) $(FCFLAGS) -o $# $<
%.o: %.f08
$(FC) $(FCFLAGS) -o $# $<
clean:
rm -f *.o *.mod
For starters, I recommend to replace all spaces in your file names with underscores or something similar.
Spaces are almost universally used as separators, and any program that is started with something like
gfortran -c -o mod precision definitions.o mod precision definitions.f08
would interpret this line as 'create an object file called mod from the source files precision, definitions.o, mod, precision, and definitions.f08. And while there are ways to do it, with increasing automation, you have to jump more and more hoops.
In contrast, this works well:
gfortran -c -o mod_precision_definitions.o mod_precision_definitions.f08
I would use this command to change all the spaces into underscores:
rename 's/ /_/g' *.f08
If that doesn't work, use this command:
for f in *.f08; do mv "$f" ${f// /_}; done
Next, I wouldn't worry about .mod files. They get generated together with the object files when you compile a module. So while technically some routine that uses a module requires the .mod file for that module, you might as well claim in your Makefile that it depends on the object file itself.
So with that said, here's the Makefile I would use (with some assumed inter-module dependencies added):
# Find all source files, create a list of corresponding object files
SRCS=$(wildcard *.f08)
OBJS=$(patsubst %.f08,%.o,$(SRCS))
# Ditto for mods (They will be in both lists)
MODS=$(wildcard mod*.f08)
MOD_OBJS=$(patsubst %.f08,%.o,$(MODS))
# Compiler/Linker settings
FC = gfortran
FLFLAGS = -g
FCFLAGS = -g -c -Wall -Wextra -Wconversion -Og -pedantic -fcheck=bounds -fmax-errors=5
PROGRAM = characterize
PRG_OBJ = $(PROGRAM).o
# make without parameters will make first target found.
default : $(PROGRAM)
# Compiler steps for all objects
$(OBJS) : %.o : %.f08
$(FC) $(FCFLAGS) -o $# $<
# Linker
$(PROGRAM) : $(OBJS)
$(FC) $(FLFLAGS) -o $# $^
# If something doesn't work right, have a 'make debug' to
# show what each variable contains.
debug:
#echo "SRCS = $(SRCS)"
#echo "OBJS = $(OBJS)"
#echo "MODS = $(MODS)"
#echo "MOD_OBJS = $(MOD_OBJS)"
#echo "PROGRAM = $(PROGRAM)"
#echo "PRG_OBJ = $(PRG_OBJ)"
clean:
rm -rf $(OBJS) $(PROGRAM) $(patsubst %.o,%.mod,$(MOD_OBJS))
.PHONY: debug default clean
# Dependencies
# Main program depends on all modules
$(PRG_OBJ) : $(MOD_OBJS)
# Blocks and allocations depends on shared
mod_blocks.o mod_allocations.o : mod_shared.o

Makefile rule using the automatic variable $^ without dependencies

I learnt from the GNU Make manual that the sign $^ is an automatic variable which represents the names of all the prerequisites. However I fell upon a makefile like this one:
SVR_OBJECT_FILES = server.o\
server_func.o
CLT_OBJECT_FILES = client.o
CFLAGS = -Wall -Werror -W
CC = gcc
all: client/client server/serveur
client/client: $(CLT_OBJECT_FILES)
server/serveur: $(SVR_OBJECT_FILES)
client/client server/serveur:
#mkdir -p $(dir $#)
$(CC) $(CFLAGS) $^ -o $#
%.o: %.c
$(CC) -c $<
clean:
rm -f client/client server/serveur *.o
Which works fine so my question is :
How can the command below can link the right object files while the $^ variable is refering no preprerequisites at all. (the rule has no prerequisites)
$(CC) $(CFLAGS) $^ -o $#
$^ contains all the prerequisites of the target, not just the ones that are mentioned with the rule itself. The same file can appear as a target several times in rules with no commands:
sometarget: dependency1
…
sometarget: dependency2
assemble -o $# $^
…
sometarget: dependency3
The dependencies of sometarget are dependency1, dependency2 and dependency3, and when the assemble command is invoked by make sometarget, it will receive all three as arguments.
Here, $^ will contain all $(CLT_OBJECT_FILES) or $(SRV_OBJECT_FILES) depending on which target the command is executed for.

When is the symbol table for this program built

When I run make on the following Makefile, when is the symbol table built, if it even is?
LEX = flex
YACC = yacc
CC = gcc
calcu: y.tab.o lex.yy.o
$(CC) -o calcu y.tab.o lex.yy.o -ly -lfl
y.tab.c y.tab.h: parser.y
$(YACC) -d parser.y
y.tab.o: y.tab.c parser.h
$(CC) -c y.tab.c
lex.yy.o: y.tab.h lex.yy.c
$(CC) -c lex.yy.c
lex.yy.c: calclexer.l parser.h
$(LEX) calclexer.l
clean:
rm *.o
rm *.c
rm calcu
make doesn't build symbol tables (obviously the compilers and linkers it invokes will have to do that!). I'll assume you're referring to whatever the resulting calcu binary does wrt its input, instead.
If any such thing as a "symbol table" is ever built by calcu, it will be by code you inserted into parser.y that gets moved over into yacc.tab.c; as to when, it will be during the course of a calcu run over whatever its input is -- incrementally, as each syntax production including "symbol-table building code" matches.