使用 automake 构建 gSoap 应用程序时的不同行为
Different behavior when automake is used to build a gSoap application
我们使用 gSoap 开发了一个简单的 C++ 应用程序。当我们使用经典的 Makefile 时,一切正常,系统运行良好。但是当我们使用 GNU autotools 作为构建系统时,我们在调用服务时遇到了一个奇怪的约束违反验证错误:
( SOAP 1.1 fault: SOAP-ENV:Client [no subcode]
"Validation constraint violation: invalid value in element 'risk'"
Detail: [no detail]
我们检查了所有的编译和类似标志,两者看起来一样。
Makefile.am
ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4
AUTOMAKE_OPTIONS = subdir-objects
AM_CPPFLAGS = --pedantic -Wall -Wno-vla -Wno-unknown-pragmas -Wno-format
bin_PROGRAMS= Client Server
Client_SOURCES=card_soap_client.cpp envC.cpp stdsoap2.cpp cardProxy.cpp cardC.cpp
Client_CPPFLAGS= $(AM_CPPFLAGS) -DWITH_NONAMESPACES
Server_SOURCES=card_soap_server.cpp envC.cpp stdsoap2.cpp cardService.cpp cardC.cpp
Server_CPPFLAGS= $(AM_CPPFLAGS) -DWITH_NONAMESPACES
生成文件
CF=-c -Wall --pedantic -Wno-vla -Wno-unknown-pragmas -Wno-format -g -O2 -fPIC -DPIC -DWITH_NONAMESPACES
LF = -g -O2
all: card_soap_client.o card_soap_server.o cardProxy.o cardService.o cardC.o envC.o stdsoap2.o
g++ card_soap_client.o cardProxy.o cardC.o envC.o stdsoap2.o $(LF) -o Client
g++ card_soap_server.o cardService.o cardC.o envC.o stdsoap2.o $(LF) -o Server
cardC.o:cardC.cpp
g++ $(CF) cardC.cpp
cardService.o:cardService.cpp
g++ $(CF) cardService.cpp
cardProxy.o:cardProxy.cpp
g++ $(CF) cardProxy.cpp
envC.o: envC.cpp
g++ $(CF) envC.cpp
stdsoap2.o: stdsoap2.cpp
g++ $(CF) stdsoap2.cpp
card_soap_client.o:card_soap_client.cpp
g++ $(CF) card_soap_client.cpp
card_soap_server.o:card_soap_server.cpp
g++ $(CF) card_soap_server.cpp
我们使用 2.8.9 和 2.8.23 生成了服务,并使用 g++-4.7 编译。该服务是使用以下命令生成的:
soapcpp2 -i -n -qcard -I/usr/share/gsoap/import/ interface_v1.3.1.hpp
更新:完整的源代码可用here
罪恶的根源是 autoconf 工具生成的 config.h 文件。查看 CF
var of your
Makefile。如果您添加 -DHAVE_CONFIG_H -I. -I..
即您的 CF 将是
CF=-c -Wall -DHAVE_CONFIG_H -I. -I.. --pedantic -Wno-vla -Wno-unknown-pragmas -Wno-format -g -O2 -fPIC -DPIC -DWITH_NONAMESPACES
那么你将遇到与 automake 编译变体相同的错误
已编辑
查看 stdsoap2.cpp 文件中的 soap_s2double
函数。如果我们激活 HAVE_CONFIG_H
宏(通过 -DHAVE_CONFIG_H 选项),它又会停用 HAVE_STRTOD
宏(查看 stdsoap2.h 文件)。结果我们有 SOAP_TYPE 错误(因为我们不能将 risk
var 的字符串值转换为 double)。如果我们在没有 HAVE_CONFIG_H
宏的情况下工作,我们有 HAVE_STRTOD
个活动宏,因此 strtod
函数可以成功运行,我们没有任何错误。
已编辑 N1
如果您将 #define HAVE_STRTOD 1
字符串添加到您的 config.h 文件中,那么一切都会完美无缺。
我们使用 gSoap 开发了一个简单的 C++ 应用程序。当我们使用经典的 Makefile 时,一切正常,系统运行良好。但是当我们使用 GNU autotools 作为构建系统时,我们在调用服务时遇到了一个奇怪的约束违反验证错误:
( SOAP 1.1 fault: SOAP-ENV:Client [no subcode]
"Validation constraint violation: invalid value in element 'risk'"
Detail: [no detail]
我们检查了所有的编译和类似标志,两者看起来一样。
Makefile.am
ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4
AUTOMAKE_OPTIONS = subdir-objects
AM_CPPFLAGS = --pedantic -Wall -Wno-vla -Wno-unknown-pragmas -Wno-format
bin_PROGRAMS= Client Server
Client_SOURCES=card_soap_client.cpp envC.cpp stdsoap2.cpp cardProxy.cpp cardC.cpp
Client_CPPFLAGS= $(AM_CPPFLAGS) -DWITH_NONAMESPACES
Server_SOURCES=card_soap_server.cpp envC.cpp stdsoap2.cpp cardService.cpp cardC.cpp
Server_CPPFLAGS= $(AM_CPPFLAGS) -DWITH_NONAMESPACES
生成文件
CF=-c -Wall --pedantic -Wno-vla -Wno-unknown-pragmas -Wno-format -g -O2 -fPIC -DPIC -DWITH_NONAMESPACES
LF = -g -O2
all: card_soap_client.o card_soap_server.o cardProxy.o cardService.o cardC.o envC.o stdsoap2.o
g++ card_soap_client.o cardProxy.o cardC.o envC.o stdsoap2.o $(LF) -o Client
g++ card_soap_server.o cardService.o cardC.o envC.o stdsoap2.o $(LF) -o Server
cardC.o:cardC.cpp
g++ $(CF) cardC.cpp
cardService.o:cardService.cpp
g++ $(CF) cardService.cpp
cardProxy.o:cardProxy.cpp
g++ $(CF) cardProxy.cpp
envC.o: envC.cpp
g++ $(CF) envC.cpp
stdsoap2.o: stdsoap2.cpp
g++ $(CF) stdsoap2.cpp
card_soap_client.o:card_soap_client.cpp
g++ $(CF) card_soap_client.cpp
card_soap_server.o:card_soap_server.cpp
g++ $(CF) card_soap_server.cpp
我们使用 2.8.9 和 2.8.23 生成了服务,并使用 g++-4.7 编译。该服务是使用以下命令生成的:
soapcpp2 -i -n -qcard -I/usr/share/gsoap/import/ interface_v1.3.1.hpp
更新:完整的源代码可用here
罪恶的根源是 autoconf 工具生成的 config.h 文件。查看 CF
var of your
Makefile。如果您添加 -DHAVE_CONFIG_H -I. -I..
即您的 CF 将是
CF=-c -Wall -DHAVE_CONFIG_H -I. -I.. --pedantic -Wno-vla -Wno-unknown-pragmas -Wno-format -g -O2 -fPIC -DPIC -DWITH_NONAMESPACES
那么你将遇到与 automake 编译变体相同的错误
已编辑
查看 stdsoap2.cpp 文件中的 soap_s2double
函数。如果我们激活 HAVE_CONFIG_H
宏(通过 -DHAVE_CONFIG_H 选项),它又会停用 HAVE_STRTOD
宏(查看 stdsoap2.h 文件)。结果我们有 SOAP_TYPE 错误(因为我们不能将 risk
var 的字符串值转换为 double)。如果我们在没有 HAVE_CONFIG_H
宏的情况下工作,我们有 HAVE_STRTOD
个活动宏,因此 strtod
函数可以成功运行,我们没有任何错误。
已编辑 N1
如果您将 #define HAVE_STRTOD 1
字符串添加到您的 config.h 文件中,那么一切都会完美无缺。