Is it possible to call a postgres internal method from a util? - c

Is it possible to make a function call (function is in Postgres code like hash_estimate_size(long, long) from a util like pg_ctl or pg_dump?
hash_estimate_size (long, long) is defined in file src/backend/utils/hash/dynahash.c and is declared in src/include/utils/hsearch.h.
I created a new util folder: src/bin/test_code with Makefile and test_code.c.
contents of Makefile
PGFILEDESC = "test_code"
PGAPPICON=win32
subdir = src/bin/test_code
top_builddir = ../../..
include $(top_builddir)/src/Makefile.global
OBJS= test_code.o $(WIN32RES)
all: test_code
test_code: $(OBJS) | submake-libpgport
$(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $#$(X)
install: all installdirs
$(INSTALL_PROGRAM) test_code$(X) '$(DESTDIR)$(bindir)/test_code$(X)'
installdirs:
$(MKDIR_P) '$(DESTDIR)$(bindir)'
uninstall:
rm -f '$(DESTDIR)$(bindir)/test_code$(X)'
clean distclean maintainer-clean:
rm -f test_code$(X) $(OBJS)
test_code.c
#include "postgres.h"
#include "replication/walreceiver.h"
int main(int argc, char *argv[])
{
printf("Has estimate value is = %zu\n", hash_estimate_size(10, 10));
return 0;
}
When I am running "make", it errors out like
test_code.o: In function main':
test_code.c:(.text+0x17a): undefined reference tohash_estimate_size'
collect2: ld returned 1 exit status
make: *** [test_code] Error 1
Any help in solving this issue ?

Most backend code cannot be called from utilities because it's not linked to utility programs. Nor can it easily be, since frontend code doesn't have palloc and memory contexts, ereport, and the other stuff backend code tends to rely heavily on.
Only code in libpq, libpgcommon and libpgport can be used from utilities. src/backend cannot, with a few exceptions that are recompiled as frontend code and linked into source trees (like pg_xlogdump's use of the xlogdesc code).
If what you want to call is generic enough and will work when compiled as frontend code, consider submitting a patch to move it to libpgcommon (src/common).

Related

Why is this Makefile wrong? Linker fails only if preceded by compiler error

This is the example program to make it easier to explain. Have this 4 files, main.c, sum.c and header.h. and finally the Makefile.
main.c
#include <stdio.h>
#include "header.h"
int main()
{
int a = 1;
int b = 1;
int c = sum(a, b);
printf("Sum: %i\n",c);
return (0);
}
sum.c
#include "header.h"
int sum(int a, int b)
{
return (a + b);
}
header.h
int sum(int a, int b);
Makefile
TEST_SRCS = *.c
TEST_OBJS = $(TEST_SRCS:%.c=%.o)
%.o : %.c *.h
gcc -c $^
assemble_test: $(TEST_OBJS);
test: assemble_test
gcc -o test *.o
./test
clean:
#rm -rf *.o *.gch test
#echo "Cleaned"
Steps to reproduce:
Call test rule: make test > all ok.
Introduce any error on purpose, example two commas:
printf("Sum: %i\n",,c);
Call test rule: make test > Getting normal syntax error.
Remove the error. Save file.
Call test rule: make test > Getting linker error no matter what.
gcc -o test *.o
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [test] Error 1
Use clean rule to start again every time.
Have this behaviuor for a while and i cant figure the problem. To be honest im new to Makefiles so i must be doing something very wrong.
About the test rule calling assemble_test. Its because part of a larger Makefile and i need diferent rules for diferent purposes to compile the objects, so dont mind.
Can you please help me understand what is going on?
Thanks.
It's wrong to use wildcards for the object files. Wildcards match files that already exist on the disk when make runs. That doesn't help because obviously they won't match files that do not yet exist, and the entire point of your makefile is to create files that don't exist.
So this:
TEST_SRCS = *.c
TEST_OBJS = $(TEST_SRCS:%.c=%.o)
leaves the value of TEST_SRCS the string *.c and the value of TEST_OBJS the string *.o (perhaps you were thinking that wildcards are expanded immediately, somehow? No, that's not the case).
Then this line:
assemble_test: $(TEST_OBJS);
causes the target assemble_test to list *.o as a prerequisite: this will be expanded to all the object files that already exist in the directory. But of course it won't expand to object files that you want make to create, but don't exist yet.
There are lots of other problems here: for example you don't want to compile $^ because that expands to all the prerequisites but you only want to compile source files, not header files. And the addition of assemble_test seems odd and makes things harder.
You probably want this, assuming you're using GNU make:
TEST_SRCS := $(wildcard *.c )
TEST_OBJS = $(TEST_SRCS:%.c=%.o)
%.o : %.c *.h
gcc -c $<
test: $(TEST_OBJS)
gcc -o $# $^
./$#
By using the wildcard function you expand the value of the sources glob first before you replace the results with .o.

Makefile not detecting changes to source file when running make

Issue Description
I have a Makefile that is not recognizing when changes to the underlying source code are made. When I attempt a build I get the following message to the console: "make: Nothing to be done for 'all'." My sense is that this probably has to do with a flawed understanding on my part regarding how to work with files in different directories. I have seen similar questions on StackOverflow but none seem to deal quite with this issue or the issue appears to result from other problems.
Project Structure
src: the source code files live here.
include: header files live here.
build: object files live here.
bin: executables live here.
test: test code lives here.
Makefile: the make file.
Makefiles
I have created a basic source file called main.c and placed it in src and implemented a simple make file as follows:
CC = gcc
CFLAGS = -DTESTABLE -Wall -std=c99 -g
all: bin/main
bin/main: build/main.o
build/main.o: src/main.c
clean:
rm -f build/main.o
rm -f bin/main
Source File
#include <stdio.h>
int main( int argc, char *argv[] )
{
printf( "Hi there. For real." );
}
These lines:
bin/main: build/main.o
build/main.o: src/main.c
tell make that to build bin/main it needs build/main.o and to build build/main.o it needs src/main.c, but you haven't actually told make how to build either build/main.o or bin/main. You have to provide a recipe that make can use to actually do the build; maybe:
bin/main: build/main.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $# $^ $(LDLIBS)
build/main.o: src/main.c
$(CC) $(CFLAGS) -c -o $# $<

C actualize files through makefile all at once

I am working on project, where i use couple of .c and .h files.
I created Makefile where i actualize executable program based on changes in all of these files.
Problem is, when i use make, program is compiled, but when i execute program, it runs without any change. I need to save ( working in vim so :w ) all included files, even when i changed only one.
If i don't save all these files, program is compiled, but executes the same thing as it did before change.
Could someone explain me why is that ?
Makefile code :
CC=gcc
CFLAGS=-WALL
execFile: execFile.o functions.h newDataTypes.h
Thank you.
The reason you are not getting execFile updated is because you're NOT updating it. Or at least you don't seem to be in this particular case.
There are many ways to get about doing this. However since you are using gcc and I assume you're using gnu make the following is probably the best solution you can execute1.
Given the files:
-rw-r--r-- 1 user sudo 73 Nov 4 22:54 exeFile.c
-rw-r--r-- 1 user sudo 74 Nov 4 22:54 exeFile.h
-rw-r--r-- 1 user sudo 90 Nov 4 22:55 hello_world.c
-rw-r--r-- 1 user sudo 888 Nov 4 23:03 Makefile
cat exeFile.c
#include <stdio.h>
#include "exeFile.h"
int main()
{
hello_world();
}
exeFile.h
#ifndef _EXEFILE_H
#define _EXEFILE_H
extern void hello_world();
#endif
hello_world.c
#include <stdio.h>
#include "exeFile.h"
void hello_world()
{
printf("Hello World\n");
}
you can set up a make file that generates dependencies and ensures that the program will always be compiled correctly:
CC=gcc
CFLAGS=-Wall
SOURCES=exeFile.c hello_world.c
EXE=exeFile
OBJ=$(SOURCES:%.c=%.o)
DEPDIR := .deps
$(shell mkdir -p $(DEPDIR) >/dev/null)
DEPFLAGS = -MT $# -MMD -MP -MF $(DEPDIR)/$*.Td
COMPILE.c = $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
COMPILE.cc = $(CXX) $(DEPFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
POSTCOMPILE = #mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d && touch $#
%.o: %.c
%.o: %.c $(DEPDIR)/%.d
$(COMPILE.c) $(OUTPUT_OPTION) $<
$(POSTCOMPILE)
%.o : %.cc
%.o : %.cc $(DEPDIR)/%.d
$(COMPILE.cc) $(OUTPUT_OPTION) $<
$(POSTCOMPILE)
%.o : %.cxx
%.o : %.cxx $(DEPDIR)/%.d
$(COMPILE.cc) $(OUTPUT_OPTION) $<
$(POSTCOMPILE)
$(DEPDIR)/%.d: ;
.PRECIOUS: $(DEPDIR)/%.d
$(EXE): $(OBJ)
$(CC) -o $# $(OBJ) $(LDFLAGS)
clean:
$(RM) $(OBJ) $(EXE)
dev-clean: clean
$(RM) -r $(DEPDIR)
include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SOURCES))))
Let's go over the relevant parts about dependencies
DEPDIR =
This implementation places dependency files into a subdirectory named .deps .
$(shell mkdir -p $(DEPDIR) 2>/dev/null)
GCC does not create subdirectories for output, this line ensures that the DEPDIR directory always exists.
DEPFLAGS = ...
These are GCC-specific flags which tell the compiler to generate dependency info.
-MT $#
Set the name of the target in the generated dependency file.
-MMD
Generate dependency information in addition to compiling. -MMD omits system headers from the generated dependencies: if you prefer to preserve system headers as prerequisites, use -MD instead.
-MP
Adds a make target for each prerequisite in the list, this avoids errors when deleting files.
-MF $(DEPDIR)/$*.Td
Write the generated dependency file to a temporary file $(DEPDIR)/$*.Td e.g. hello_world.c will generate hello_world.Td as temp dependency content for use in Makefile.
POSTCOMPILE = ...
First rename the generated temporary dependency file to the real dependency file. We do this in a separate step to side-step compile errors. Next we explicitly touch the files to avoid a gcc bug.
%.o : %.c
Delete the built-in rules for building object files from .c files, so that our rule is used instead. Do the same for the other built-in rules.
... $(DEPDIR)/%.d
Declare the generated dependency file as a prerequisite of the target, so that if it’s missing the target will be rebuilt.
$(DEPDIR)/%.d: ;
Create a pattern rule with an empty recipe, so that make won’t fail if the dependency file doesn’t exist.
.PRECIOUS: $(DEPDIR)/%.d
Mark the dependency files precious to make, so they won’t be automatically deleted as intermediate files.
include ...
Include the dependency files that exist: translate each file listed in SOURCES into its dependency file. Use wildcard to avoid failing on non-existent files.
1 See Auto-Dependencies Generation for details.
Fix:
Tell make that the executable depends only on the object file and the object file depends on the header files:
execFile: execFile.o
execFile.o: functions.h newDataTypes.h
Explanation:
In order to build your executable two steps are needed:
compilation of C source files (that include header files) to produce object files,
linking of the object files to produce the executable.
So, when changing your header files you must re-compile, that is re-built the object files, not just re-link that would produce the same executable from the same object files.
In your Makefile the dependencies are not properly defined. You did not tell make that the object file (execFile.o) shall be rebuilt when your header files change. Instead, you told it that the executable (execFile) shall be rebuilt.
First of all, your dependencies are mistaken. Your executable does not depend on the .h header files, as they are using only at compilation time. The dependencies are normally between .o files and .h files, as when you modify one .h file, the including .c file must be compiled to generate the .o file. so in case you have execFile.o (which, on lack of complete information, I'll suppose it depends on execFile.c, which #includes functions.h and newDataTypes.h, the rule should be:
execFile.o: execFile.c functions.h newDataTypes.h
As it has been pointed out in other responses, there's no need to write the command to build the .o file, as there is a default rule like this:
.c.o:
$(CC) $(CFLAGS) -o $# -c $<
(observe there's a -c option to the compiler indicating to compile only and don't link, we'll return here below) which means that once you detect the .o is outdated (as the dependencies on .c and .hs mark) it will be compiled with the above command, which result in:
gcc -Wall -o execFile.o -c execFile.c
making the appropiate compilation.
Other thing is the dependencies of the executable file. These have to be included, as make(1) doesn't know which object files form your final executable. In this case, assuming you have your program execFile depend on execFile.o and a.o, b.o and c.o, I normally use to write:
execFile_objs = execFile.o a.o b.o c.o
execFile: $(execFile_objs)
$(CC) $(LDFLAGS) -o $# $(execFile_objs)
so any of the .os is changed (because an indirect change in a source file) the whole program is linked again (but only the touched files are compiled)
NOTE
In the case (not normal) that you have a Makefile to create a program that has only one source file and several include files you can compile each time the whole thing each time you modify one source file, in this way:
execFile: execFile.c functions.h newDataTypes.h
$(CC) $(CFLAGS) $(LDFLAGS) -o $# execFile.c
This will execute
gcc -Wall -o execFile execFile.c
Observe that there is no -c (compile only, don't link) option in this command.
There's no mention of the include files (they are included because of the #include directives in the code... and you only state here that the executable depends also (and have to be built) in case any of the .h files are modified.
Automatic dependency rules are a little confusing at first, as they induce you to think there are such rules to make any kind of file from any other kind of file (well, there are for .c -> .o files, and .c -> <nothing> to compile directly to an executable) normally you have to include dependencies in such cases when your target depends on more files than the automatic rule states. In such cases, it is very important not to include any command, so the compiler selects the automatic rule (when you don't include a command to generate the target, the make(1) program tries to use a default rule for it, or nothing at all if you have not included commands, it only assumes your dependencies are indirect through this fake target --- and, as this fake target is not built in the process, it will fail always and be followed)

Embedding python interpreter in the TM4c1294XL

I have a python file that I want to run on the board. Hence I want to embed the python interpreter (written in C) in the board. I managed to write separate C project that runs the Python file. It compiles and runs as I want to. Here's the makefile for same:-
CC=gcc
CFLAGS=-I python3.5 -I config -I . -c -w
LDFLAGS= -lpython3.5m -lpthread -ldl -lutil -lm -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions
all: classifier trainer test link
test:
$(CC) $(CFLAGS) test.c
trainer: Trainer.c
$(CC) $(CFLAGS) Trainer.c
$(CC) Trainer.o $(LDFLAGS) -o Trainer
.ONESHELL:
classifier: Classifier.c
$(CC) $(CFLAGS) Classifier.c
# $(CC) Classifier.o $(LLFLAGS) -o Classifier
link:
$(CC) test.o Classifier.o $(LDFLAGS) -o test
clean:
rm -f Trainer.o Trainer Classifier.o Classifier
http://dpaste.com/3BCY2RE is my entire directory of project "hello" (It is not the one from the examples).
I included "Classifier.h" in my "hello.c" and I am getting the following errors: http://dpaste.com/3KKCF84
Compiler include options (No preincludes):
"${CG_TOOL_ROOT}/include"
"${workspace_loc:/${ProjName}/TerrainPredict}"
"${workspace_loc:/${ProjName}/TerrainPredict/config}"
"${workspace_loc:/${ProjName}/TerrainPredict/python3.5}"
"${SW_ROOT}/examples/boards/ek-tm4c1294xl"
"${SW_ROOT}"
Linker file search paths:
"libc.a"
"${workspace_loc:/${ProjName}/TerrainPredict/libterrainclf.a}"
"${SW_ROOT}/driverlib/ccs/Debug/driverlib.lib"
and:
"${CG_TOOL_ROOT}/lib"
"${workspace_loc:/hello/TerrainPredict/libterrainclf.a}"
"${CG_TOOL_ROOT}/include"
Am I wrong with some of my configurations? Or is this some problem with python interpreter? Any help is greatly appreciated
EDIT:-
As #KevinDTimm suggested, the problem is that there is no pyconfig.h for my environment. This file is required by python to define important variables like source of system clock. I tried removing safety checks in existing pyconfig.h. The first error I am getting is in pytime.h as :
"_PyTime_t need signed 64-bit integer type"
Which was further because of the following code block:
#ifdef PY_INT64_T
/* _PyTime_t: Python timestamp with subsecond precision. It can be used to
store a duration, and so indirectly a date (related to another date, like
UNIX epoch). */
typedef PY_INT64_T _PyTime_t;
#define _PyTime_MIN PY_LLONG_MIN
#define _PyTime_MAX PY_LLONG_MAX
#else
# error "_PyTime_t need signed 64-bit integer type"
#endif
It appears to me that it needs a variable that stores time. I need help in assigning that variable.
From the linked problem
The multiarch error message is a bit misleading. It's not failing because there's a multiarch problem, it's failing because there's a multi-OS problem. /usr/include/python*/pyconfig.h is trying to figure out where to find the real pyconfig.h from, and since it doesn't know, it's bailing out.
You essentially need a pyconfig.h generated for the target environment. I don't know what produced pyconfig.h, perhaps building cython from source? pyconfig.h looks like something generated by gnu autoconf, so there should not be any big problems in generating it.

Apache Avro C Installation

I am working on a project and I am using Apache Avro. I have downloaded Apache Avro for C and I followed the instructions provided in order to install it on my system (Ubuntu Linux v14.04). After the installation, I have some header files under the /include directory and some libraries under /lib directory. All of those are the ones that were installed from Apache Avro.
At this point, I have created my C source files which are as follows:
1) socket_client.h :
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "avro.h"
#include <errno.h>
#include <stdint.h>
#ifndef SOCKET_CLIENT_H_
#define SOCKET_CLIENT_H_
void init_schema(void);
int client_execution_connect(char* ip_addr, int port, char* type);
#endif /* SOCKET_CLIENT_H_ */
2) socket_client.c :
#include <stdio.h>
#include "socket_client.h"
avro_schema_t bigpeer_schema;
void init_schema(void)
{
if( avro_schema_from_json_literal(BIG_PEER_SCHEMA, &bigpeer_schema) )
{
printf("Unable to parse big_peer schema");
exit(EXIT_FAILURE);
}
}
int client_execution_connect(char* ip_addr, int port, char* type)
{
...
}
and a test main file. Also, I have created the following makefile to compile my code:
CC=gcc
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=test_main.c socket_client.c
OBJECTS=$(SOURCES:.c=.o)
EXECUTABLE=avro_test
INC_PATH=/include/avro/
INC=-I/include
LIB=-L/lib
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(LIB) $(OBJECTS) -o $#
.c.o:
$(CC) $(INC) $(CFLAGS) $< -o $#
clean:
rm -rf *.o avro_test
But, when I try to make my application, I get the following:
nick#rethimno:~/Downloads/AvroClient$ make
gcc -I/include -c -Wall test_main.c -o test_main.o
test_main.c: In function ‘main’:
test_main.c:22:6: warning: unused variable ‘port’ [-Wunused-variable]
int port = atoi(argv[2]);
^
test_main.c:15:8: warning: unused variable ‘type’ [-Wunused-variable]
char* type = "db_node";
^
gcc -I/include -c -Wall socket_client.c -o socket_client.o
gcc -L/lib test_main.o socket_client.o -o avro_test
socket_client.o: In function `init_schema':
socket_client.c:(.text+0x14): undefined reference to `avro_schema_from_json_length'
collect2: error: ld returned 1 exit status
make: *** [avro_test] Error 1
What am I doing wrong? I am not quite certain if the libraries of Apache Avro are loaded properly.
Thank you,
Nick
You are including the Avro headers, but you aren't linking your final executable against the Avro libraries. Assuming you have libavro.so or libavro.a in the lib directory (where *.so is a shared library, and *.a is a static library), you will want to change this line of your Makefile:
LDFLAGS=-lavro
Note that, if the library binary is called something other than libavro.so or libavro.a, you'll need to change the -lavro value to match. Also note that certain packages can contain more than one shared library you will need to link against. I am not familiar enough with Apache Avro to say whether or not this is the case; you will mostly just need to look and see what is inside your lib directory.
You can more information about linking to libraries in the GCC documentation.

Resources