之前写了两个访问db的函数库,可是因为库里面使用到了同事们定义的一些结构体,之前代码一直能编译过,但是同事在他的代码中补充了很多其他内容,但是都统一的被头文件包含进来了,然后在编译库的时候傻眼了,一堆的错误,抽取一些如下显示:
proc def_sqlcode=yes line=true parse=full include=/new/src/include sqlcheck=syntax common_parser=no dynamic=ansi code=ansi_c mode=oracle dbms=v8 unsafe_null=yes release_cursor=yes iname=dbbase.pc
Pro*C/C++: Release 11.2.0.1.0 - Production on Thu Apr 10 18:08:46 2014
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
System default option values taken from: /diskarray/oracle7/precomp/admin/pcscfg.cfg
Error at line 2, column 12 in file /usr/include/asm/posix_types.h
# include "posix_types_32.h"
...........1
PCC-S-02015, unable to open include file
Syntax error at line 225, column 37, file /new/src/include/ax_base_log.h:
Error at line 225, column 37 in file /new/src/include/ax_base_log.h
#define mWriteLog(level,logcode,fmt,...) \
....................................1
PCC-S-02014, Encountered the symbol "..." when expecting one of the following:
an identifier, define, elif, else, endif, error, if, ifdef,
ifndef, include, line, pragma, undef, exec, sql, begin, end,
var, type, oracle, an immediate preprocessor command,
a C token, create, function, package, procedure, trigger, or,
replace,
Syntax error at line 229, column 78, file /new/src/include/ax_base_log.h:
Error at line 229, column 78 in file /new/src/include/ax_base_log.h
sprintf(head,"[%d] %s [%s:%d][%s]",getpid(),__FUNCTION__,__FILE__,__LINE
__,#logcode);\
.............................................................................1
PCC-S-02014, Encountered the symbol "logcode" when expecting one of the followin
g:
a numeric constant, newline, define, error, if, ifdef,
ifndef, include, line, pragma, undef,
an immediate preprocessor command, a C token,
The symbol "newline," was substituted for "logcode" to continue.
Syntax error at line 237, column 23, file /new/src/include/ax_base_log.h:
Error at line 237, column 23 in file /new/src/include/ax_base_log.h
LogOutput(level,head,##__VA_ARGS__);\
......................1
PCC-S-02014, Encountered the symbol "##" when expecting one of the following:
; { } , = : ( ) [ ] * ? | & < > + - / % ~ ! . # @ ^ *= /= %=
+= -= <<= >>= &&= ||= ^= ~= := | & == != <= >= << >> ++ -- ->
... .. <> ** => an identifier, a string, a numeric constant,
a sql string, misc. punctuation, newline, define, elif, else,
endif, error, if, ifdef, ifndef, include, line, pragma,
undef, exec, sql, begin, end, var, type, oracle,
an immediate preprocessor command, a C token, exec sql,
exec sql include, exec sql var, exec sql begin, exec sql end,
end-exec, exec sql type, exec oracle, exec oracle else,
exec oracle endif, exec oracle begin, a sql hint, create,
function, package, procedure, trigger, or, replace,
a C++ token,
Syntax error at line 270, column 2, file /new/src/include/ax_base_log.h:
Error at line 270, column 2 in file /new/src/include/ax_base_log.h
#endif /* BASE_LOG_H */
碰上这种问题,一般都不好定位,因为查代码,发现本身并没有错误,反而我认为是proc处理不了宏定义,但是说要是环境问题,那么之前代码都能编译过,现在却编译不过,结论有点不成立,但是问题到底出在哪,并且我的代码中只是使用对方很少一部分的结构定义,从这个编译结果可以看出,proc在预处理的时候,没能正确处理这些宏定义,有人说那将proc 编译参数parse=none就能不处理了吗? 但是请想想,如果proc代码中比如定义一个数组,数组的长度是用宏定义的,那么我相信用paser=none 是肯定编译不过的,none 就不去处理预编译宏,如果要想编译过,同时又要用proc编译器,那么必须让proc绕开预处理,设置parse=none,预处理步骤不能绕过,那么需要怎么操作呢?
1. 首先说,如果预处理不让proc程序来处理,那由编译器自己处理行不行,答案是可行的,由于是用gcc编译的,因此首先用gcc将pc文件做一次预处理,生成.i后缀文件, gcc选项 -E 就是只生成预处理文件,不生成对象文件, 由于是pc文件,我们需要自己指定它的语言,gcc -x选项可以指定语言, 那么gcc -E -x c input.pc -o input.i 是可以生成预处理后的文件的。
2. 利用生成的.i文件,再去使用proc来编译,由于程序中所有的宏定义都被gcc预处理器处理了,此时 proc 编译的时候,我们就可以不用 做全部解析了,因此 parse=none 就可以了,那么就有 proc parse=none iname=input.i ,proc编译完成就会生成 input.c文件。
3. 好了,有了.c文件就好办了,按照正常的c编译过程 gcc -o xxx input.c 就能编译通过了。
4. 最后看看编译结果
gcc -E -x c -I/new/src/include -o dbbase.i dbbase.pc
proc def_sqlcode=yes line=true parse=none include=/new/src/include sqlcheck=syntax common_parser=no dynamic=ansi code=ansi_c mode=oracle dbms=v8 unsafe_null=yes release_cursor=yes iname=dbbase.i
Pro*C/C++: Release 11.2.0.1.0 - Production on Thu Apr 10 18:35:20 2014
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
System default option values taken from: /diskarray/oracle7/precomp/admin/pcscfg.cfg
gcc -g -DOCCI_NO_WSTRING=1 -fPIC -I/new/src/include -L/new/src/lib/base -lax_base -I/diskarray/oracle7/precomp/public -c dbbase.c
ld -shared -fpic -o libdbbase.so dbbase.o -L/diskarray/oracle7/rdbms/lib -L/diskarray/oracle7/lib -lclntsh -L/new/src/lib/base -ldmhsbase
rm dbbase.i dbbase.c
当然这种方式编译,并不是说没有弊端的,由于我们直接用.i文件生成c文件的,如果在.i 文件生成.c文件过程中 有编译错误的时候,那查起错误就麻烦了,因为已经预处理,你不容易和源文件错误地址对应上,但是通过这种方法编译的确是可行的,一般情况下最好让proc来处理,遇到紧急问题处理的时候使用这种方法不迟。
阅读(2713) | 评论(0) | 转发(0) |