ProC complains about undefined symbols on Linux (CentOS 7.3) - linux

TLDR: Running ProC from Oracle instant client 12.2 on CentOS 7.3 doesn't seem to be able to properly process even a trivial input file.
Minimal input file demonstrating the problem:
EXEC SQL BEGIN DECLARE SECTION;
EXEC SQL INCLUDE oci.h;
EXEC SQL END DECLARE SECTION;
The real files obviously include my own project's header, but ultimately they pull in oci.h, which is one of the instant client SDK headers and this seems to be where the build issues are coming from.
Invocation of ProC:
The following script demonstrates the problem (again, a cut-down version of the real situation):
#!/bin/sh
export ORACLE_HOME=/some/path/instantclient_12_2
export ORACLE_SID=SomeSID
export PATH=/various/paths:${ORACLE_HOME}:${ORACLE_HOME}/sdk:${ORACLE_HOME}/bin:/some/more/paths/like:usr/bin:
export LD_LIBRARY_PATH=${ORACLE_HOME}:${ORACLE_HOME}/lib32:${ORACLE_HOME}/lib
${ORACLE_HOME}/sdk/proc \
LTYPE=LONG \
PARSE=PARTIAL \
MODE=ORACLE \
CODE=ANSI_C \
iname=foo.pc
Oracle configuration:
The contents of my pcscfg.cfg file look like this:
sys_include=/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include
sys_include=/usr/include
include=/some/path/instantclient_12_2/sdk/include
I've also tried various reordering, switching include and sys_include, but all seem to give the same behaviour. Adding define=__x86_64__ as seen in various online references makes no difference. I've chosen to expand out the $ORACLE_PATH in the above to make the example clearer.
Sample error output:
Using the input file defined above results in output with errors like the following (truncated to help focus the discussion):
Pro*C/C++: Release 12.2.0.1.0 - Production on Mon Sep 4 16:19:45 2017
Copyright (c) 1982, 2017, Oracle and/or its affiliates. All rights reserved.
System default option values taken from: /some/path/instantclient_12_2/precomp/admin/pcscfg.cfg
Syntax error at line 46, column 1, file /usr/include/bits/byteswap-16.h:
Error at line 46, column 1 in file /usr/include/bits/byteswap-16.h
{
1
PCC-S-02201, Encountered the symbol "{" when expecting one of the following:
; , = ( [
The contents around the line it is complaining about look like this:
static __inline unsigned short int
__bswap_16 (unsigned short int __bsx)
{ // <---- this is line 46
return __bswap_constant_16 (__bsx);
}
If I insert #include <stdlib.h> before the EXEC SQL BEGIN DECLARE SECTION line, the error message changes to this:
Syntax error at line 265, column 50, file /some/path/instantclient_12_2/sdk/include/ociextp.h:
Error at line 265, column 50 in file /some/path/instantclient_12_2/sdk/include/ociextp.h
void *ociepacm(OCIExtProcContext *with_context, size_t amount);
.................................................1
PCC-S-02201, Encountered the symbol "size_t" when expecting one of the following
:
... auto, char, const, double, enum, float, int, long,
ulong_varchar, OCIBFileLocator OCIBlobLocator,
OCIClobLocator, OCIDateTime, OCIExtProcContext, OCIInterval,
OCIRowid, OCIDate, OCINumber, OCIRaw, OCIString, register,
short, signed, sql_context, sql_cursor, static, struct,
union, unsigned, utext, uvarchar, varchar, void, volatile,
a typedef name, exec oracle, exec oracle begin, exec,
exec sql, exec sql begin, exec sql type, exec sql var,
The symbol "enum," was substituted for "size_t" to continue.
This one is more interesting because I've traced through the logic more carefully and even forcing size_t to be defined by various means, I still get the above error. But if I change the ProC invocation to use PARSE=FULL, it is successful. Unfortunately, that causes other problems with the real code and those problems have a similar nature to this one (i.e. chokes on compiler headers for things that should really have been defined by the compiler headers).
Further comments:
Looking at various solutions online, these issues are normally the result of having incorrectly set include search paths, but I've verified from the output listing that the correct headers are indeed being found. It is as though there are some compiler defines missing that GCC would normally provide but ProC isn't providing. There have been various other related examples which support this theory, giving errors on things like __INT_LEAST8_TYPE__ being unknown (which as far as I can tell GCC defines internally rather than explicitly in any of its headers).
Specific question:
ProC doesn't seem to be processing the system compiler headers correctly. Any idea why or even further things to try to help diagnose the underlying cause?

I have been able to get my application to compile correctly, I found that even though some compile problems were resolved by adding the output of the command "gcc -dM -E - < /dev/null" into a header file and including it in every Pro*C source file, new compile problems were introduced because of that and trying to resolve those new problems again introduced others so that approach was going nowhere.
In the end I started again from scratch and only included those #defines that were realy needed by the proc compiler. Also, I had to re-arrange the paths in the proc configuration file ${ORACLE_HOME}/precomp/admin/pcscfg.cfg
This is what it looks like now:
sys_include=$ORACLE_HOME/precomp/public
sys_include=/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include
sys_include=/usr/local/include
sys_include=/usr/include
sys_include=/usr/include/linux
ltype=short
define=__x86_64__
the reason for this is that there are several files located in the gcc include directory that are also present in some of the other directories, but those assume that all of those gcc internal defines are set as well. The system include files located in the gcc include directory sometimes differ significantly from the ones in the usual include directories that are listed below it and it would seem that proc has a lot less difficulties in parsing the ones located in the gcc 4.8.5 directory.
Next to this, the include file I created and #include into every source file proc choked on now looks this:
#ifndef __GCC4_INTERNAL_DEFINES_H__
#define __GCC4_INTERNAL_DEFINES_H__
/* Proceed only when using the Oracle Pro*C compiler on RHEL7 */
#ifdef DB_PRE_COMP
#ifdef OS_IS_RHEL7
/* These are some of the defines that gcc4 sets by itself. The Pro*C precompiler
does not know them and they are needed in order to correctly parse several
system header files. Full list of gcc4 internal defines may be obtained with
the following command: gcc -dM -E - < /dev/null */
#define __INT_LEAST8_TYPE__ signed char
#define __INT_LEAST16_TYPE__ short int
#define __INT_LEAST32_TYPE__ int
#define __INT_LEAST64_TYPE__ long int
#define __UINT_LEAST8_TYPE__ unsigned char
#define __UINT_LEAST16_TYPE__ short unsigned int
#define __UINT_LEAST32_TYPE__ unsigned int
#define __UINT_LEAST64_TYPE__ long unsigned int
#define __INT_FAST8_TYPE__ signed char
#define __INT_FAST16_TYPE__ long int
#define __INT_FAST32_TYPE__ long int
#define __INT_FAST64_TYPE__ long int
#define __UINT_FAST8_TYPE__ unsigned char
#define __UINT_FAST16_TYPE__ long unsigned int
#define __UINT_FAST32_TYPE__ long unsigned int
#define __UINT_FAST64_TYPE__ long unsigned int
#define __INTMAX_TYPE__ long int
#define __UINTMAX_TYPE__ long unsigned int
#include </usr/include/stdint.h>
#endif /* OS_IS_RHEL7 */
#endif /* DB_PRE_COMP */
#endif /* __GCC4_INTERNAL_DEFINES_H__ */
Much to my relief, I got everything to compile again with these updates. For completeness sake, proc is executed with the parse=full option, this is what I used to do under RHEL6 as well and what my application apparently needs; as part of my efforts to get it to compile I tried with partial option as well but that did not make a difference, it still choked.

This happens when you include your header with the same name as a system header, which includes stdint.h.
From Pro*C manual:
The precompiler searches directories in the following order:
the current directory
the system directory specified in a SYS_INCLUDE precompiler option
the directories specified by the INCLUDE option, in the order they are entered
the built-in directories for standard header files
For example, you may create header file db.h for your project.
If you have in your system Berkeley DB installed, then it supplies your system with it's own db.h.
As long as your db.h is situated in the same folder as preprocessed .pc file and you don't have to pass include=your_include_folder option to proc you will be ok.
If you do have separate folder for include files you are obliged to pass include=../include option to proc and Berkeley's db.h comes in place instead of db.h file from your project.

For me, I fixed this in either of these 2 ways:
Add define=ORASYS_TYPES to ${ORACLE_HOME}/precomp/admin/pcscfg.cfg
or
Add DEFINE=ORASYS_TYPES as an option to proc.
oci.h includes <oratypes.h>
And oratypes.h has:
#ifndef ORASYS_TYPES
# include <sys/types.h>
# define ORASYS_TYPES
#endif

Related

uint8_t, uint16_t and uint32_t not recognized in PCLint

When running PCLint on code base it seems that the data types uint8_t, uint16_t and uint32_t are not recognized.
For example:
uint8_t variable1 = 0;
The following errors are received from Lint:
129: declaration expected, indentifier 'uint8_t' ingnored
129: declaration expected, indentifier 'variable1' ingnored
10: Expecting identifier or other declarator
19: Useless declaration
Anything that uses 'variable1' the following errors are displayed:
40: Undeclared identifier 'variable1'
63: Expected an lvalue
Any ideas?
Possible reasons why PC-Lint fails to recognize uint8_t, uint16_t and uint32_t:
#include <stdint.h> is missing in your source code file
PC-Lint parses your code like the "dumbest" compiler. In order to know about the fixed-width integer types defined by C99 it requires an include of the appropriate header file. This can be either <stdint.h> or <inttypes.h>. Some compilers might know about the fixed-width integer types even without an include of these header files.
The header <stdint.h> cannot be found by PC-Lint
PC-Lint evaluates your code independently of your specific compiler. It does not bring along its own set of standard headers though. Therefore it needs to know where it will find system headers like <stdint.h> in your file system (usually the compiler installation path). This is usually done by providing a compiler-specific configuration file (e.g. co-gcc.lnt) at the command line. Gimpel Software (authors of PC-Lint) provide a large set of these files at their website: https://gimpel.com/html/ptch90.htm

Can't disable gcc warning - make pointer from integer without a cast

tried many methods, ex:
-fsyntax-only
-Wno-format
still got this warning:
xxxxx passing argument x of xxxx make pointer from integer without a cast
I want to disable this warning in any way.
//////////////////////
update:
in order to follow the rule here, I provide the specific code:
here is the source code I was testing:
https://github.com/vladermolaev/jam2ftdi
It can build successfully by Visual Studio.
However, I want to test it in Linux, I built it in Linux.
I saw the error log as I described in this issue.
Here is the problem code, the problem is the third input parameter, unsinged char *tdo.
because when calling this function in this project, it takes int as input parameter, not unsinged char*
https://github.com/vladermolaev/jam2ftdi/blob/master/FTDI_API.h#L5
int FTDI_WriteTMSandTDIandReadTDO(const unsigned char tms, const unsigned char tdi, unsigned char *tdo);
therefore, I already know it works since I built in Windows OS, I don't want to change code everywhere in linux platform.
Hope this is clear, and please unlock this issue.
Thanks.
///////////////////////
update:
for which line caused this error:
https://github.com/vladermolaev/jam2ftdi/blob/9af9c7a055707b178e5aa91ae4447686256a4790/JAMSTUB.C#L328
tdo = FTDI_WriteTMSandTDIandReadTDO(tms, tdi, read_tdo);
the usage in this project, read_tdo is int which generated this compiling warning.
Add this parameter for gcc as following:
-Wno-int-to-pointer-cast
it solves this issue.

wchar_t is not treated as built-in type even when the option is enabled

So here is the preprocessed output of a struct:
typedef struct RPT_Item
{
wchar_t *fullPath;
RPT_ItemFlags_t itemFlags;
int isComposite;
const void *reserved;
} RPT_Item_t;
Visual Studio complains because wchar_t is not defined, its own cryptic way:
error C2016: C requires that a struct or union has at least one member
I looked at the project files and also at the particular C file where the error appears and I can confirm that "Treat wchar_t as built-in type is set to YES".
If I define the type using a typedef it compiles fine.
I used the preprocessor output so I can exclude that some nasty preprocessor #define trick play the main role.
This project contains many low-level hacks, for example the CRT is not linked (/NODEFAULTLIB).
Most of the code is not written by me, and I'm tasked to remove reference to wchar.h from a public header that uses wchar_t, because VS treats it as a built in type default. (This particular module is built only on Windows.)
I totally ran out of ideas. Is there a compiler option or a pragma that can interfere? Or could it be even a compiler bug?
Microsoft didn't explicitly document this until VS 2013, but the docs for /Zc:wchar_t says
The wchar_t type is not supported when you compile C code.
It seems that including nearly any header from the runtime or from the SDK will typedef wchar_t tounsigned short using the following sequence:
#ifndef _WCHAR_T_DEFINED
typedef unsigned short wchar_t;
#define _WCHAR_T_DEFINED
#endif
you might want to do something similar in your file that uses wchar_t.
Note that when compiling a C++ file, if /Zc:wchar_t is in effect then the compiler pre-defines _WCHAR_T_DEFINED. If /Zc:wchar_t- is in effect it doesn't - so the above snippet should work nicely with C++ as well (for MSVC anyway - I don't know how other compilers might deal with this if you're looking for something portable).
The _WCHAR_T_DEFINED macro is documented:
MSVC Predefined Macros

How to calling R code from C++

I try to include R-code in C++ (Qt creator). To get familiar with the packages Rcpp, RInside and the R-source code R-3.0.1 I try to run the following example:
#include <QCoreApplication>
#include<iostream>
#include<Rcpp.h>
#include <RInside.h> // for the embedded R via RInside
int main(int argc, char *argv[]) {
RInside R(argc, argv); // create an embedded R instance
R["txt"] = "Hello, world!\n"; // assign a char* (string) to 'txt'
R.parseEvalQ("cat(txt)"); // eval the init string, ignoring any returns
exit(0);
}
First Question:
The file string.h comes from the package Rcpp, but it always generates a lots (130!) errors like:
'internal does not name a type'
'StringProxy does not name a type etc.
What is wrong with it?
Second Question:
In the .pro file I have to include all subfolder of the packages separatly like:
INCLUDEPATH += "W:\hesm\Private\Private\Qt files\ConnectToR\Rcpp\include\Rcpp\module"
Is it possible to include a folder (package) with all its subfolders in one quote?
Thanks
You are doing it wrong. The code you quote is verbatim from the examples/standards/rinside_sample0.cpp file of the RInside package.
It so happens that there is also a complete Qt example in examples/qt/ directory (albeit building a Qt application rather than a command-line one). You are expected to do
qmake && make
and the binary is built --- because all the required logic is in the .pro file.
Your question really is about how to use Qt Creator / Qt build tools, and has nothing to do with Rcpp or RInside per se.
Our supplied examples all work as documented and expected. Build them, look at what make executes and infer what you need for your use with Qt Creator (which is a fine tool, but not one supported by R out of the box). If you want to use it, you need to adapt to it locally.

suppress gcc warnings : "warning: this is the location of the previous definition"

I need a set of wrappers around the standard system calls-open,listen,etc.
For these i have a few "#define" as in:
#define open(a,b,c) JCL_Open(a,b,c)
But when i compile the header and associated .c files, i am getting the following warning:
/jcl_wrappers.h:114:1: warning: "open" redefined
/jcl_wrappers.h:113:1: warning: this is the location of the previous definition
How can i suppress these warnings?
Put include guards in your header file.
Basically you need to put these two lines at the beginning of your header file
#ifndef _yourincludefilename_h_
#define _yourincludefilename_h_
and
#endif /* _yourincludefilename_h_ */
at the end of you include file.
Edit:
rascher is right, that open is not a good name for a macro, as it will conflict with a library function. Usually it is good C convention to make macros all uppercase, so I would suggest to change your macro to
#define OPEN(a,b,c) JCL_Open(a,b,c)
or even better
#define XYZ_OPEN(a,b,c) JCL_Open(a,b,c)
where XYZ is a prefix specific to your code.
Leave the standard functions alone and rename the function:
#define myopen(a,b,c) JCL_Open(a,b,c)
Someone will thank you later.
You might try using compile guards. Like:
my_headers.h:
#ifndef __MY_HEADERS
#define __MY_HEADERS
#define open(a,b,c) JCL_Open(a,b,c)
#endif
This will only do do what is between the #ifndef and #endif if the '__MY_HEADERS' macro has been defined. So, everything in your .h file will only be declared once.
You could use the same construct to see if the "open" macro is already defined.
Also be aware that there is already a C function called open(): http://www.manpagez.com/man/2/open/ . May not be a great idea to use the same name for your macro!
Wrap the define in:
#ifndef JCL_WRAPPERS_H
#define JCL_WRAPPERS_H
... your macro's
#endif
This makes sure your macro's are only defined once if you including your header in multiple places.
It's generally a smart thing to do for all prototypes in headers also.

Resources