How to make a makefile for Oracle on Solaris/Linux Server? - c

I have an application which is running properly for Informix database. But now I want it to compile it for Oracle too. What changes should be made in the makefile shown below which is running properly for Informix?
ESQL:=esql
CFLAGS:=$(CFLAGS) -DSOLARIS
PROCFLAGS:=$(PROCFLAGS) -DSOLARIS
HEADERS= $(HOME)/tmiD/headers
target = $(HOME)
CC=gcc
%.o :%.ec ; $(ESQL) -I$(HEADERS) -c $(CFLAGS) -DINFORMIX -EDINFORMIX -I/usr/local/include $<
%.o :%.c ; $(CC) -I$(HEADERS) -c $(CFLAGS) $<
MAKEC= mv $(target)/$(#F) $(target)/$(#F).old; \
$(ESQL) -DINFORMIX -EDINFORMIX \
$^ $(CFLAGS) -lnsl -L $(target) \
-o $(target)/$(#F)
$(target)/%:%.o $(CLIBFILES); $(MAKEC)
%:%.o $(CLIBFILES); $(MAKEC)
all: a tw_interface clean
tw_interface: tcp.o trace.o global.o rmi.o License.o purge.o libswx.a
ap: tcp.o trace.o global.o rmi.o License.o purge.o
clean:
-rm tcp.o trace.o global.o rmi.o purge.o License.o\
trace.c global.c rmi.c
a:
-rm tw_interface
I am very new to these things. So please help me.
Thank you in advance.

Hmm....you say you're very new to these things.
Re-writing a Makefile is a non-trivial exercise, if you're not an experienced programmer.
But, if you want to give this a try, I recommend starting out by installing the Pro*C demos in your ORACLE_HOME. Once that's done, and you've verified it, by building the sample Pro*C programs, I recommend using the demo_proc.mk makefile, (which will be installed with the demo programs) as a template to convert the makefile.
Also, note, I don't know anything about Informix, but the code itself will probably need to be converted to Pro*C, as I assume Informix has some other precompiler, or alternate set of libraries for database access.
Hope that helps.

I think the Pro*C precompiler is invoked with "proc" so the first line
ESQL:=esql
should become
PRO_C:=proc
It looks like Pro*C files normally have a .pc file extension. Assuming your Pro*C files will be slightly different than your Informix *.es files, and you will create them with a .pc extension, then this line
%.o :%.ec ; $(ESQL) -I$(HEADERS) -c $(CFLAGS) -DINFORMIX -EDINFORMIX -I/usr/local/include $<
would become
%.o :%.pc ; $(PRO_C) CONFIG=proc_c_config.txt -I$(HEADERS) -c $(CFLAGS) -I/usr/local/include $<
The above line has "proc_c_config.txt" which is a file to create to put any desired Pro*C options. That part could be removed if there are no options desired other than defaults.
$(ESQL) -DINFORMIX -EDINFORMIX \
would become
$(PRO_C) CONFIG=pro_c_config.txt \
They talk about Pro*C options here

Related

Using a Makefile in C (make: *** No rule to make target .. needed by ... Stop

I'm trying to create a communication channel between two devices, such as two computers, that will work with the cryptographic network protocol Salt channelv2 and forward data to each other. I created 2 applications, where the first application demonstrates the functionality of the Salt channelv2 protocol and the second application creates a secure communication channel (specifically using the TCP / IP model). Applications are working, I compiled them using linking in the CLI and now I am trying to create a makefile file for easy compilation of the program for the user.
This is my Makefile:
CC=gcc
CFLAGS=-O2 -Wall -g -fcommon -I./salt_org -I./header_folders -I./library
#LDFLAGS=
all:program
program: salt_buffer.o libcrypto.a
$(CC) $(CFLAGS) -o program.exe salt_buffer.o libcrypto.a
randombytes.o: randombytes.c
$(CC) $(CFLAGS) -c randombytes.c
tweetnacl_modified.o: tweetnacl_modified.c tweetnacl_modified.h
$(CC) $(CFLAGS) -c tweetnacl_modified.c
tweetnacl_modified_wrapper.o: tweetnacl_modified_wrapper.c
$(CC) $(CFLAGS) -c tweetnacl_modified_wrapper.c
salt.o: salt.c salt.h salti_handshake.h salti_util.h
$(CC) $(CFLAGS) -c salt.c
salt_io.o: salt_io.c salti_util.h
$(CC) $(CFLAGS) -c salt_io.c
salti_handshake.o: salti_handshake.c salti_handshake.h
$(CC) $(CFLAGS) -c salti_handshake.c
salti_util.o: salti_util.c salti_util.h
$(CC) $(CFLAGS) -c salti_util.c
salt_modified.o: salt_modified.c salt_modified.h salt.h
$(CC) $(CFLAGS) -c salt_modified.c
salt_buffer.o: salt_buffer.c header_folders/salt.h \
header_folders/salti_handshake.h header_folders/salti_util.h \
header_folders/salt_modified.h header_folders/salt_io.h
$(CC) $(CFLAGS) -c salt_buffer.c
libcrypto.a: salt.o salti_handshake.o salti_util.o salt_io.o tweetnacl_modified_wrapper.o \
tweetnacl_modified.o randombytes.o salt_modified.o
ar -cvq -o libcrypto.a salt.o salti_handshake.o salti_util.o salt_io.o \
tweetnacl_modified_wrapper.o tweetnacl_modified.o randombytes.o salt_modified.o
clean:
rm -f program *.o *.a hlavickove_subory/*.gch
In one folder are source codes and folders such as salt_org, header_folders, library, salt_buffer.c, salt_modified.c and makefile. The main program is salt_buffer.c and salt_modified.c contains the source file I supplied with the body functions needed for the application that salt_buffer.c works with. With auxiliary source codes I try to create a static library libcrypto.a. Source codes such as randombytes.c, tweetnacl_modified.c, tweetnacl_modified_wrapper.c are in the library folder. Other source codes such as salt.c, salti_handshake.c, salti_util.c, salt_io.c are in the salt_org folder. All the header files I use are in the header_folders folder.
At work, I was inspired by the topic: enter link description here.
The problem I get when running the makefile file is:
gcc -o .o
gcc.exe: fatal error: no input files
compilation terminated.
make: *** [: .o] Error 1
In source files, I have paths to files like this for example salt_buffer.c:
#include "salt.h"
#include "salt_io.h"
#include "salti_util.h"
#include "salti_handshake.h"
#include "salt_modified.h"
I work with the Winlibs compiler with 11.2
Can you please advise me about my errors ?
First, when asking questions like this you should always include (via cut and paste) the actual compile line that generated the errors, not just the errors. The reason for errors like this is always found on the compile line.
Second, your problem is that you should never include the header files on the compile line. The compiler will include the headers because of the #include ... commands inside the source file: you must not include them on the compilation line as well. Rules like this:
salt.o: salt.c salt.h salti_handshake.h salti_util.h
$(CC) $(CFLAGS) -c salt.c salti_handshake.h salti_util.h
should simply be:
salt.o: salt.c salt.h salti_handshake.h salti_util.h
$(CC) $(CFLAGS) -c salt.c
and that's all. Ditto for all other recipes where header files appear on the compilation line.
There are many better ways to write this makefile so you don't have to repeat yourself so many times, but fixing the above should allow your current makefile to work properly.

'linker input file unused because linking not done' error when running make

I'm compiling C programs I made for a project.
Goals
Compiling get_next_line.c and get_next_line_utils.c.
Structure
I have 3 files, get_next_line.c, get_next_line_utils.c and get_next_line.h in my folder (excluding Makefile). Nothing more, nothing less.
Code
NAME = get_next_line
SRCS = get_next_line.c get_next_line_utils.c
OBJS = $(SRCS:.c=.o)
CC = gcc
CFLAGS = -Wall -Wextra -Werror
LIB_CRT = ar rcs
all: $(NAME)
$(NAME) : $(OBJS)
#$(LIB_CRT) $(NAME) $(OBJS)
%.o: %.c $(INCLUDE)
#$(CC) -c $(CFLAGS) -o $# $<
clean:
#rm -f $(OBJS) a.out
fclean: clean
#rm -f $(NAME)
re : fclean all
Error Message
linker input file unused because linking not done. I get this error several times.
I keep on running on this error when I run make. I followed another Makefile I had for another project, to no avail. I also read this article and that one too but they aren't relevant to my issue.
Any input appreciated.
Your makefile appears to be aimed at building a program named "get_next_line", but this is not altogether clear because what you are actually building is a static archive file with that (unconventional for an archive) name. That's what the ar utility does. With the gcc toolchain and many others, one would normally use the same front end (gcc in this case) for both compiling and linking. That is,
$(NAME) : $(OBJS)
$(CC) -o $(NAME) $(OBJS)
... or, a bit DRYer ...
$(NAME) : $(OBJS)
$(CC) -o $# $^
It is not clear why you are getting the specific message you report. It looks like a message from the linker, ld, but I see no reason in the makefile presented to think that the linker would ever run. As such, I am inclined to suppose that the message is associated with something altogether different. Possibly you are running make in a different working directory, and therefore using a different makefile. Or perhaps it is associated with some other command than make itself. Or maybe you have an influential variable set in your environment that alters the meaning of your makefile. Maybe you get that message when you try to run the archive as if it were a program (though that's not what I would expect to happen in that case).

gmake (Gnu) to make (Cygwin) - verification of my implementation [only 3 statements]

I need to convert a makefile built for gmake into a makefile that could be executed via cygwin "make" command.
The GMAKE code is below:
OBJ := ${SOURCES:%.c=%.o}
%.o: %.c
$(CC) -c -o $# $< $(CFLAGS) $(DEFINES)
$(LIBNAME).lib: $(OBJ)
$(AR) rcs $# $(OBJ)
clean:
del $(OBJ)
del *.out
I've used the statements below in the Cygwin makefile. Could you please confirm, if it replicates the gmake statements above or am I missing something. Any inputs would be helpful.
Cygwin "make":
OBJ := ${SOURCES:%.c=%.o}
%.obj: %.c
$(CC) -c -o `cygpath -w $#` `cygpath -w $<` $(CFLAGS) $(DEFINES)
.DEFAULT_GOAL := ${LIBNAME}.lib
${LIBNAME}.lib: $(OBJS)
$(SILENCE)echo -e "Archive: ${LIBNAME}.lib\n"
$(SILENCE)$(AR) $(ARFLAGS) `cygpath -w $#` ${OBJS}}
clean:
rm $(OBJ)
rm *.out
Thanks much in advance.
As pointed out by #matzeri, cygwin make is gnu make.
That's why I use it.
The first makefile looks fine to me.
If all your files use relative paths, everything should be fine.
Even the Microsoft compiler can build subdir/file.cpp and stick the object into objdir/file.o (cl subdir/file.cpp -o objdir/file.o).
Hint: Strive manfully to use forward slashes in your filenames. Always.
The only difficulty you might have is with absolute paths,
as typically appear in include paths say.
/usr/local/include only makes sense to cygwin programs.
cl.exe would like this translated to C:/cygwin64/usr/local/include.
Don't use backslashes unless the command really really requires it.
One issue then is that bash interprets backslashes,
so you will have to quote the filename in some way to prevent this.
objdir/1.o: /usr/local/src/1.cpp
some-odd-compiler "$$(cygpath -wa $<)" -o "$$(cygpath -w $#)"
Quoting not required if you use forward slashes (cygpath -ma).
Why prefer $(…) over `…`? Because then the double quotes nest.
Useful if the path in question expands to something with a space in it ("$$(cygpath -wa "$<")")

Makefile dependencies on multiple files

I have created a Makefile for unit tests which uses GCC with arguments to create profiling files (gcno) during compiling. Here's a similified part of it where compiling and linking takes place:
UTEXE = $(UTOBJSDIR)\$(UTUNIT).exe
UTOBJS = $(UTUUTSRC:.c=.o) $(UTUTSRC:.c=.o) $(UTCSRC:.c=.o)
UTOBJSFULL = $(addprefix $(UTOBJSDIR)\,$(UTOBJS))
UTOBJSGCNO = $(addprefix $(UTOBJSDIR)\,$(UTOBJS:.o=.gcno))
$(UTOBJS): %.o: %.c $(UTMAKEDEP)
$(call report,Compiling $(*F).c)
$(MKDEP) $(MKDFLAGS) -o.o -f$(UTOBJSDIR)\$(*F).dep $(subst /,\,$<)
$(CC) -c $(CFLAGS) $(subst /,\,$<) -o $(UTOBJSDIR)/$#
$(UTOBJSGCNO): $(UTOBJS) $(UTMAKEDEP)
utbuild: $(UTEXE) $(UTOBJSGCNO) $(UTOBJS) $(UTMAKEDEP)
$(UTEXE): $(UTOBJSGCNO) $(UTOBJS) $(UTMAKEDEP)
$(call report,Linking to $(UTUNIT).exe)
$(LINK) $(UTOBJSFULL) $(LNKFLAGS) -o $(UTEXE)
It compiles all the object and profile files and links together a binary. However when i delete some profile file (gcno) and call "utbuild" again it won't re-compile to restore the .gcno file. It tries to do linking again because gcno is a prequisite to it, but it wont do the compiling.
I don't know how to name this case so couldn't find solution from internet. Basically one recipe creates two files and i don't know how to write the rule that re-run's recipe even when only one file needs to re-created.
I would appreciate some links or hints.
thanks for all the comments. I've tried no-op ";" and ":=" with same outcome.
I think i need to take one step back and explain why i asked this question. It's not just about deleting or not-deleting gcno files manually, it's about general understanding how to write such a Makefile which restores any missing or out-of-date file. My Makefile has similar cases in few places and it's using parallel build so when some file goes missing it gives lot of weird errors. Usually it's solved by "clean" and "all", but i'd like the Makefile to be perfect and handle the missing file issues nicely.
As the example above is not so clear without all the rest of the Makefile then i made a new simple test.
hello.c
#include <stdio.h>
int main()
{
printf("Hello world\n");
}
Makefile
CCDIR = C:\tools\MinGW
CCBINDIR = $(CCDIR)\bin
CCINCDIR = $(CCDIR)\include;$(CCDIR)\lib\gcc\mingw32\4.8.1\include
CCLIBDIR = $(CCDIR)\lib;$(CCDIR)\lib\gcc\mingw32\4.8.1
# Overcome "missing dll file" messages on Windows
CC = set PATH=%PATH%;$(CCBINDIR)& $(CCBINDIR)\gcc.exe
LINK = set PATH=%PATH%;$(CCBINDIR)& $(CCBINDIR)\gcc.exe
# Compile and link for code coverage
CFLAGS = -fprofile-arcs -ftest-coverage -g3 -O0 $(addprefix -I,$(CCINCDIR))
LNKFLAGS = -fprofile-arcs -ftest-coverage -static -static-libgcc $(addprefix -L,$(CCLIBDIR))
OBJECTS = hello.o
EXE = hello.exe
$(OBJECTS): %.o: %.c
$(CC) -c $(CFLAGS) $(subst /,\,$<) -o $#
$(EXE): $(OBJECTS)
$(LINK) $(OBJECTS) $(LNKFLAGS) -o $(EXE)
build: $(EXE)
"make build" creates following files:
hello.o
hello.gcno
hello.exe
Now if i delete the "hello.gcno" and run build again it tells me:
mingw32-make: Nothing to be done for 'build'.
The goal is to update Makefile so that the make re-creates the "hello.gcno". It would probably re-create "hello.o" and "hello.exe" also during that process but that's not a problem.
Edit:
Just to be clear: in real Makefile i really-really need the .gcno files. It's not just an additional information or something which to avoid or do optionally. The Makefile builds the unit test executables, runs them and executes gcov to generate code coverage information and gcovr creates a report of all the .gcov files. If .gcno file is missing it won't work. Also - as it's parallel build then dependencies shall be absolutely correct to avoid some process starting earlier and it's tricky because coverage report has dependencies coming from two "branches" - .gcno files from compile stage and .gcda files from execute stage. So that's why i need it to be correct.
your only option here is this :
(if you can change the rule)
$(EXE): $(OBJECTS)
$(LINK) $(OBJECTS) $(LNKFLAGS) -o $(EXE)
to this:
%.exe %.gnco: $(OBJECTS)
$(LINK) $(OBJECTS) $(LNKFLAGS) -o $(EXE)
$(GENERATE_GNCO) $<
Here is a very simple solution of one thing dependig on two other things
compile:./src/main.c ./src/error.c
gcc ./src/error.c ./src/main.c -o ./exe/calc
run : ./exe/calc
./exe/calc
The correct answer in my opinion, is, don't delete any .gcno files by themselves. If you have to "clean", use make clean, but don't just go about deleting files.
The "build" is a state machine, with all the files constituting a "state". Don't corrupt the state!
Some people say, one should be able to delete arbitrary files and the build should recover. My answer is, what about if you corrupt some .o file by hand, say, add some 0's and 1's, making it unusable (thank you user3629249 for pointing that needs to be clarified, that I am talking about corruption, not intentional editing). Should the build also recover from that? Obviously no - no build system in the world will recover if you touch the .o file this way. Then why allow deleting a file, but not allow modifying it?? Where do you draw the line?
Simply put, any corruption should not be allowed. Use make clean only, or better yet, write your Makefile properly, so you never need to clean period.
The whole Makefile has a number of problems, here is how it should look like (I am assuming this is on Windows/DOS):
.SUFFIXES:
UTEXE := $(UTOBJSDIR)\$(UTUNIT).exe
UTOBJSFULL := $(addprefix $(UTOBJSDIR)\,$(subst /,\, $(UTUUTSRC:.c=.o) $(UTUTSRC:.c=.o) $(UTCSRC:.c=.o)))
UTOBJSGCNO := $(UTOBJSFULL:.o=.gcno)
.PHONY: utbuild all
all: utbuild
utbuild: $(UTEXE) $(UTOBJSGCNO) $(UTMAKEDEP)
$(UTOBJSGCNO): %.gcno: %.o $(UTMAKEDEP) ;
.SECONDARY: %\.
%\.: Makefile
mkdir $*
.SECONDEXPANSION:
$(UTOBJSFULL): $(UTOBJSDIR)\%.o: %.c $(UTMAKEDEP) | $$(#D)\.
$(call report,Compiling $<)
$(MKDEP) $(MKDFLAGS) -o.o -f$(UTOBJSDIR)\$(*F).dep $<
$(CC) -c $(CFLAGS) $< -o $#
$(UTEXE): $(UTOBJSFULL) $(UTMAKEDEP) | $$(#D)\.
$(call report,Linking to $(#F))
$(LINK) $(UTOBJSFULL) $(LNKFLAGS) -o $#

Make recursive all C files

I really can't get into makefiles. In previous projects, I hardcoded all compile tasks in the Makefile:
all: compile_a compile_b compile_c
compile_a:
${CC} ${CFLAGS} ${A_SRC} -o ${A_OUT}
and so on.
But as the latest project has more files than every project before, I want to write better make tasks and of course LESS characters as make is not really friendly to my eyes (it makes them suffer)! :-P
What I want:
One task to rule them all (just make projectname or make all, you know?)
One task for every C file to compile (I read something about this %.o: %.c syntax, but didn't really get it)
One task for linking (how to get all .o files and link them without hardcoding each?)
One task for cleaning (oh, i can do this!)
The project structure is:
bin (binary goes here!)
src
some
directories
are
here
I don't know if I need a directory for object files, I put them in ./bin, I think that's good enough, isn't it?
Maybe I just need someone who can explain it with easy words!
EDIT:
As someone pointed out, there's no real question, so here it goes:
how to recursively compile all C files to bin/(filename).o
how to link all .o files in 'bin/' without knowing their names
maybe this helps.
Try this:
CC = gcc
CFLAGS = -c -Wall -g -Os
LD = $(CC)
LDFLAGS = -lfoo
TARGET = MyProject
OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(LD) -o $# $^ $(LDFLAGS)
# You don't even need to be explicit here,
# compiling C files is handled automagically by Make.
%.o: %.c
$(CC) $(CFLAGS) $^ -o $#
clean:
rm $(TARGET) $(OBJECTS)
I frequently use the wildcard function in combination with the foreach function for something like you want to achieve.
If your sources are in src/ and you want to put the binaries into bin/ the basic construction of my Makefile would look like follows:
SOURCES=$(shell find src -type f -iname '*.c')
OBJECTS=$(foreach x, $(basename $(SOURCES)), $(x).o)
TARGET=bin/MyProject
$(TARGET): $(OBJECTS)
$(CC) $^ -o $#
clean:
rm -f $(TARGET) $(OBJECTS)
I usually take advantage of make's built in implicit rules and predefined variables (Make manual, Chap 10).
without going into specifics of makefiles, use the * to your advantage.
i.e.
compileAll: gcc -c *.c
linkAll: gcc *.o -o output.exe

Resources