PostgreSQL: compile C function on Windows 8 64bit - c

I'm learning how to compile a C trigger to load on PostgreSQL
When compile the "trigf.c" (in the example at http://www.postgresql.org/docs/9.3/interactive/trigger-example.html), I get some issue related to int64 error (c.h header)
#ifdef HAVE_LONG_INT_64
/* Plain "long int" fits, use it */
#ifndef HAVE_INT64
typedef long int int64;
#endif
#ifndef HAVE_UINT64
typedef unsigned long int uint64;
#endif
#elif defined(HAVE_LONG_LONG_INT_64)
/* We have working support for "long long int", use that */
#ifndef HAVE_INT64
typedef long long int int64;
#endif
#ifndef HAVE_UINT64
typedef unsigned long long int uint64;
#endif
#else
/* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */
#error must have a working 64-bit integer datatype
#endif
-> [Error] #error must have a working 64-bit integer datatype
I don't know how to solve that problem, because clearly that there is a working 64 bit integer datatype that I can use.
Edit: I installed pgsql from binary. The C compiler I used for compile the C function file is MinGW GCC 4.7.2. (Using the path of Dev-cpp mingw gcc).
The command line is :
gcc -fpic -c "D:\trigf.c"
At the first time, it showed an error that in c.h: not found libintl.h (no such file or directory). Then I download the Lib Intl - 0.14.4 (library for native language support). The installation create a folder: C:\Program Files (x86)\GnuWin32.
I edited the environment variable CPATH, added C:\Program Files (x86)\GnuWin32\include folder, which contained libintl.h.
I ran the command again, and I met with the above error.

Update: It turns out not to be too hard to build extensions stand-alone with MSVC on Windows. I wrote a blog post detailing the process today.
The usual way to build extensions on Windows is to do it inside a working PostgreSQL build tree.
See these instructions on the PostgreSQL wiki.
You might be able to do it using MinGW and PGXS using a suitable Makefile instead.
Just trying to compile a standalone .c file is unlikely to work as there are a variety of paths and preprocessor definitions required.
It doesn't help that the current PostgreSQL packages don't include headers for public dependencies, which is really rather frustrating. You can safely compile without ENABLE_NLS defined even if the target PostgreSQL was built with ENABLE_NLS, though, and in this case libintl.h won't be required.

Related

Compiling against 64bits DLL cause segfault but works in 32bits

Context
On Windows, using mingw32 and its x86_64 version. In order to use a third-party library (within Unity), I'am trying to build a wrapper library (dll) around the native one (to simplify the integration in Unity). I need this library to be 64bits.
The problem arises when linking against the created wrapper library in a test program: the program crash on a segfault, whereas the 32bits version runs just fine.
Procedure
I am using the 32 and 64bits version of the dll provided by the third-party (see Dependencies analysis on Picture) to compile wrapping libraries.
The wrapper library is simply wrapping some functions of the native library. The header is:
#include <stdlib.h>
#include <stdio.h>
#include "ATC3DG.h"
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
__declspec(dllexport) int trakSTAR_Init();
__declspec(dllexport) int trakSTAR_GetMeasurement(double S1_X[3], double S1_A[3], double *S1_T, unsigned short * S1_Q, double S2_X[3], double S2_A[3], double *S2_T, unsigned short * S2_Q, double S3_X[3], double S3_A[3], double *S3_T, unsigned short * S3_Q);
__declspec(dllexport) int trakSTAR_Close();
__declspec(dllexport) void trakSTAR_ErrorName(int errorcode, char *errortxt);
#ifdef __cplusplus
}
#endif
It is compiling fine for both the 32 and 64bits versions respectively with:
mingw32-gcc.exe -shared -Iinclude -o bin\Release\libWrapper.dll WrapperLib.c lib\win32\nativelib.lib
and
x86_64-w64-mingw32-gcc.exe -shared -Iinclude -o bin\Release\libWrapper64.dll WrapperLib.c lib\win64\nativelib64.lib
Then, compiling test codes linking this Wrapper dll using respectively:
mingw32-gcc.exe -I.\include -L.\test -llibWrapper .\test\MainTest.c -o test\Test32
and
x86_64-w64-mingw32-gcc.exe -g -I.\include -L.\test .\test\MainTest.c -o test\Test64 -llibWrapper64
also works fine and produce the two executables.
Problem
Now, while the 32bits version (Test32.exe) runs fine, the 64bits version produce a Segfault straight ahead (no even first console print). The necessary dll (native and wrapper for both 32 and 64bits version are in the execution folder).
When inspecting the two Wrapper dlls with Dependencies, I can't see any major difference (see picture).
What could be the cause of the problem with the 64bits library?
What are my options to understand what is going wrong and debug/inspect further?
Note: Compiling a test code against the native dll works fine for both in 32 and 64 bits.
Note2: Running GDB on the faulty test program does not provide more information.

STM32 Cmake STM32Workbench project

I am trying to write a CMakeLists.txt file for my STM32 project. I am using cmake files from this repo: https://github.com/ObKo/stm32-cmake. Building from command line works fine. I am doing it in that way:
cmake -C "..\STM32F207ZCTx_config.cmake" -DCMAKE_BUILD_TYPE=DEBUG -G "Eclipse CDT4 - Unix Makefiles" ..
make.exe -j4
In cache file I have some variables set:
set(CMAKE_MAKE_PROGRAM "D:/STM32Workbench/plugins/fr.ac6.mcu.externaltools.arm-none.win32_1.16.0.201807130628/tools/make/make.exe" CACHE STRING "stm32 make")
set(CMAKE_TOOLCHAIN_FILE "stm32-cmake/gcc_stm32.cmake" CACHE STRING "stm32 toolchain")
set(TOOLCHAIN_PREFIX "D:/STM32Workbench/plugins/fr.ac6.mcu.externaltools.arm-none.win32_1.16.0.201807130628/tools/compiler" CACHE STRING "arm toolchain path")
When I import created project to STM32 Workbench it generates a lot of errors "unresolved external" regarding stdint.h types (e.g. uint8_t, int32_t).
After some debugging this problem I realized that there are missing some defines which are used by stdint.h header. I checked out the compiler with this command:
arm-none-eabi-gcc.exe -dM -E out.h
And got the list of defines in arm-none-eabi-gcc:
#define __UINTMAX_TYPE__ long long unsigned int
#define __INT_FAST16_TYPE__ int
#define __INT_FAST64_TYPE__ long long int
#define __INT_FAST32_TYPE__ int
#define __UINT_LEAST16_TYPE__ short unsigned int
#define __SIZE_TYPE__ unsigned int
#define __INT_LEAST16_TYPE__ short int
... and much more
These defines are needed by stdint.h to create correct uint8_t and other types.
I can add manually these defines to Eclipse project, but I am wondering if there is method to add these defines to Eclipse project automagically from CMake?
Any help will be appreciated.
Problem was in STM32Workbench. Sources were excluded from build and from indexer.
To fix it - right mouse click on source, Properties, C/C++ General, Preprocessor Include Paths, uncheck Exclude resource from build.
Now the indexer is able to find all sources and all "unresolved external" errors are gone!

VS 2015 C-header error C2039: 'int_least8_t': is not a member of '`global namespace''

I'm having header-related issues apparently new to VS2015 while trying to compile DOSBox SVN Daum in Windows 10. Examples:
Severity Code Description Project File Line Suppression State
Error (active) the global scope has no "int_least8_t" dosbox c:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\cstdint 23
Error C2039 'int_least8_t': is not a member of '`global namespace'' dosbox C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\cstdint 23
My search tells me this sort of problem has been happening to projects around, but I couldn't get it fixed.
In particular, I read VisualStudio 2015 RC Issue with Includes and https://blogs.msdn.microsoft.com/vcblog/2015/03/03/introducing-the-universal-crt/ , and then changed the contents of AppData\Local\Microsoft\MSBuild\v4.0\Microsoft.Cpp.Win32.user.props to:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets">
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<IncludePath>D:\dev\include;$(UniversalCRT_IncludePath);$(IncludePath)</IncludePath>
<LibraryPath>D:\dev\lib;$(UniversalCRT_LibraryPath_x86);$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup />
<ItemGroup />
</Project>
No luck though. :(
Images:
I'm far from being an experienced C programmer. Can anyone please tell me what's missing?
Thanks!
I had the same issue with a different program and after looking at the includes, I finally solved it.
If you look at a typical cstdint from a recent Visual Studio, you'll notice one include is stdint.h. This is where the actual definitions for the various types exist. What cstdint does is export the definitions to be members of the std namespace.
However, it appears here that while the first lines with intXX_t compiled fine, the int_least_xx_t don't. This is because it reads the wrong stdint.h file, that doesn't have some of the definitions needed. That file was written by people who wanted to use the named sizes before MSVC supported them (they came with C99, that MSVC never really got around to support, then in C++11, which at that point MSVC offered support for).
As they only needed the exact types, they didn't write the defines for the other types. Now that MSVC supports it, there is no need for this compatibility file. However, because the projects files were not updated, the compiler will find the bad compatibility header instead of the correct one, which leads to this error.
There are two ways to solve this: change the include folder order so that it will get the one you want, or delete the bad stdint.h file. It is easy to find as you can use Visual Studio to open #include files. For your case, the file is in the src/platform/visualc/ directory.
Addendum: this is my faulty stdint.h file
#pragma once
/* a minimal set of C99 types for use with MSVC */
typedef signed char int8_t;
typedef short int int16_t;
typedef int int32_t;
typedef __int64 int64_t;
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef unsigned __int64 uint64_t;

32 bit compilation failing on 64 bit Ubuntu 16.04

I have an application that requires the use of glib and a 32 bit library supplied by a third party.
When I compile on 32 bit Ubuntu the application builds and runs successfully.
However when I try the same on 64 bit Ubuntu it fails to build because of the following error:
/usr/include/glib-2.0/glib/gtypes.h: In function ‘_GLIB_CHECKED_ADD_U64’:
/usr/include/glib-2.0/glib/gmacros.h:217:53: error: size of array ‘_GStaticAssertCompileTimeAssertion_0’ is negative
#define G_STATIC_ASSERT(expr) typedef char G_PASTE (_GStaticAssertCompileTimeAssertion_, __COUNTER__)[(expr) ? 1 : -1] G_GNUC_UNUSED
^
/usr/include/glib-2.0/glib/gmacros.h:214:47: note: in definition of macro ‘G_PASTE_ARGS’
#define G_PASTE_ARGS(identifier1,identifier2) identifier1 ## identifier2
^
/usr/include/glib-2.0/glib/gmacros.h:217:44: note: in expansion of macro ‘G_PASTE’
#define G_STATIC_ASSERT(expr) typedef char G_PASTE (_GStaticAssertCompileTimeAssertion_, __COUNTER__)[(expr) ? 1 : -1] G_GNUC_UNUSED
^
/usr/include/glib-2.0/glib/gtypes.h:422:3: note: in expansion of macro ‘G_STATIC_ASSERT’
G_STATIC_ASSERT(sizeof (unsigned long long) == sizeof (guint64));
^
Note: I have gcc-multilib and g++-multilib.
I also tried changing the defines inside /usr/lib/x86_64-linux-gnu/glib-2.0/include/glibconfig.h from 8 to 4 with no success.
I also tried installing libglib2.0-dev:i686 but pkg config in cmake can not find glib. I am also using the appropriate -m32 flags for C, CXX and LD
Any help with this issue would be greatly appreciated.
No idea why glib wouldn't try to use int64_t instead of duplicating that. Seems silly to me. Maybe they do this on purpose to increase the chance of breaking if you do what you did, and try to compile 32-bit code using a 64-bit glib install.
To compile 32-bit apps, you need 32-bit library object files (.so). They will come with a glibconfig.h that has appropriate typedefs for -m32.
Installing libglib2.0-dev:i686 should be the right approach. I assume you eventually got that sorted out, so the app you're building finds the -I include paths and -L library paths for it.

Error compiling HDF5 with MinGW and CMake

I'm trying to compile HDF5 with MinGW's gcc 4.8.1 and CMake. I followed the instructions in the INSTALL_CMake documentation for Windows and read everything that I found on Google but I still get the following errors:
In file included from c:\mingw32-xy\include\fcntl.h:37:0,
from C:\Users\jicervan.NDC\Downloads\hdf5-1.8.13\hdf5-1.8.13\src\H5private.h:53,
from C:\Users\jicervan.NDC\Downloads\hdf5-1.8.13\hdf5-1.8.13\src\H5detect.c:57:
c:\mingw32-xy\include\io.h:301:1: error: unknown type name 'off64_t'
__CRT_INLINE off64_t lseek64 (int, off64_t, int);
^
c:\mingw32-xy\include\io.h:301:36: error: unknown type name 'off64_t'
__CRT_INLINE off64_t lseek64 (int, off64_t, int);
^
c:\mingw32-xy\include\io.h:302:1: error: unknown type name 'off64_t'
__CRT_INLINE off64_t lseek64 (int fd, off64_t offset, int whence) {
^
c:\mingw32-xy\include\io.h:302:39: error: unknown type name 'off64_t'
__CRT_INLINE off64_t lseek64 (int fd, off64_t offset, int whence) {
^
In file included from C:\Users\jicervan.NDC\Downloads\hdf5-1.8.13\hdf5-1.8.13\src\H5private.h:70:0,
from C:\Users\jicervan.NDC\Downloads\hdf5-1.8.13\hdf5-1.8.13\src\H5detect.c:57:
c:\mingw32-xy\include\unistd.h:65:20: error: unknown type name 'off_t'
int ftruncate(int, off_t);
The errors and warnings go on and on with a long list of warnings and undefines. Does anybody has any suggestions on how to solve this problem? Are there any other alternatives like using the Visual Studio binaries with MinGW maybe?
I finally got it working. My first attempt was to use configure and make according to the documentation in the /release_docs/INSTALL_MinGW.txt file, but it didn't work. I ended up using CMake. For documentation purposes, here's the procedure that I followed:
OPERATING SYSTEM: Windows 8.1 pro
COMPILER: CMake + MinGW gcc version 4.8.1
HDF5 VERSION: 1.8.13
STEPS:
Uncompress the hdf5-1.8.13.zip file.
Download CMake, and run the GUI.
Set the source folder to <hdf5-location>/hdf5-1.8.13 and the build folder to the folder where you want to place your Makefile.
Click on Configure, and a pop-up window will appear. Choose the MinGW Makefiles option as the generator for your project, and select the Use default native compilers option.
Once the list is populated with options, leave the default checkboxes selected, and also select BUILD_SHARED_LIBRARIES. Now the fun begins; compiling.
Locate the file H5pubconfig.h file in your HDF5 build folder and append the following lines:
// Define Windows 32
#ifndef H5_HAVE_WIN32_API
#ifdef WIN32 /* defined for all windows systems */
#define H5_HAVE_WIN32_API 1
#endif
#endif
// Define MinGW
#ifndef H5_HAVE_MINGW
#ifdef __MINGW32__ /*defined for all MinGW compilers */
#define H5_HAVE_MINGW 1
#endif
#endif
// Redefine _In_ and _Out_ to empty values
#define _In_
#define _Out_
// Redefine off_t and off64_t to match io.h and unistd.h
#define off_t _off_t
#define off64_t _off64_t
On the file io.hlocated in <MyFolder>/MinGW32/include/ change every instance of off64_t to _off64_t.
On the file unistd.hlocated in <MyFolder>/MinGW32/include/ change every instance of off_t to _off_t.
On the MinGW/MSYS command prompt, change directory to the location of your HDF5 Makefile (set on step 3).
Type the command Make and verify that it's compiled correctly.
Don't forget to include the flags -I/<your-HDF5-build-folder>/include/, -L/<your-HDF5-build-folder>/bin/, and -lhdf5 when you compile. Happy coding.

Resources