Closed princessirabor closed 3 years ago
EPICS_BASE=/opt/develop/epics/base
Was Base built on the same host, with the same compiler version options? The symbols mentioned as undefined should be provided by libpvAccess.so
. Code using this library must be compiled with the same C++ language options used to build the library itself.
$ nm -g -C lib/linux-x86_64/libpvAccess.so|grep createChannelProcess
00000000000642a0 T epics::pvAccess::Channel::createChannelProcess(std::shared_ptr<epics::pvAccess::ChannelProcessRequester> const&, std::shared_ptr<epics::pvData::PVStructure> const&)
As can be seen in this example from my laptop, the symbol names are slightly different when built with -std=c++11
, as opposed to -std=c++98
which appears in your build of P4P.
fyi. you could also try to install my pre-built binaries from pypi.org with pip install p4p
.
Thank you for your prompt feedback. Base was built on the same host with same version (g++ (GCC) 8.3.1 20190507 (Red Hat 8.3.1-4)). Base and p4p were built without any compiler flags. I still got the same error when I tried to build p4p with -std=c++11.
$ nm -g -C /opt/_develop/epics/base-7.0.4/lib/linux-x86_64/libpvAccess.so.7.1.1|grep createChannelProcess
000000000009c030 T epics::pvAccess::Channel::createChannelProcess(std::shared_ptr
How do I ensure p4p is built correctly with -std=c++11,?
Also attaching output for completeness output.txt
from you output.txt
/usr/bin/g++ ... -std=c++14 ... -std=c++98
It looks like -std=c++98
is still sneaking in somehow, and overriding the earlier -std=c++14
.
grep -R 'c++98' /opt/develop/test_p4p /opt/_develop/epics/base-7.0.4
will hopefully find this.
I set the cxxflags and cppflags to explicitly use c++14 (so c++98 no longer shows up) but I got the error below even when I recompiled with -fPIC. The *.o files exist under /opt/develop/test_p4p/p4p/src/O.linux-x86_64. The output is the same when I use c++11 and c++98. (Also see attached output when I attempt to run it with -no-pie flag)
/usr/bin/ld: p4p_top.o: relocation R_X86_64_32 against .rodata' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: p4p_type.o: relocation R_X86_64_32S against
.rodata' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: p4p_value.o: relocation R_X86_64_32 against .rodata' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: p4p_array.o: relocation R_X86_64_32 against symbol
_ZN14PyClassWrapperIN5epics6pvData13shared_vectorIKvvEELb0EE4typeE' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: p4p_server.o: relocation R_X86_64_32 against .rodata' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: p4p_server_provider.o: relocation R_X86_64_32 against
.rodata' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: p4p_server_sharedpv.o: relocation R_X86_64_32 against .rodata' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: p4p_client.o: relocation R_X86_64_32 against
.rodata' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
make[2]: [/opt/develop/epics/base-7.0.4//configure/RULES_BUILD:311: _p4p.so] Error 1
make[2]: Leaving directory '/opt/develop/test_p4p/p4p/src/O.linux-x86_64'
make[1]: [/opt/develop/epics/base-7.0.4//configure/RULES_ARCHS:58: install.linux-x86_64] Error 2
make[1]: Leaving directory '/opt/develop/test_p4p/p4p/src'
make: *** [/opt/develop
Have you done a full clean (make distclean
) and rebuild of both Base and P4P after changing build flags? (-std=*
or otherwise)
I was able to build after doing a full clean and rebuild of Base. However, I get an undefined symbol error when I run pvvagw. I was previously getting an ImportError: libpvAccess.so.7.0.4.99.0: cannot open shared object file: No such file or directory
so I added epocscorelibs/lib to my library path. Thanks for your help
$ pvagw -v ~/gwconfig
Traceback (most recent call last):
File "/home/user1/miniconda3/envs/p4p/bin/pvagw", line 33, in
What changes to Base (under configure/
or otherwise) are you making?
I added epocscorelibs/lib to my library path.
The default uses -rpath
to encoded this path automatically, which makes setting $LD_LIBRARY_PATH
unnecessary.
As a test. Could you please unset all $EPICS_*
environment variables and try to run the following:
install -d /tmp/p4pbuild
cd /tmp/p4pbuild
virtualenv -p python3 env
. env/bin/activate
git clone --depth 1 --recursive https://github.com/epics-base/epics-base
git clone --depth 1 --recursive https://github.com/mdavidsaver/p4p
cat <<EOF > p4p/configure/RELEASE.local
EPICS_BASE=\$(TOP)/../epics-base
EOF
pip install -r p4p/requirements-latest.txt
make -C epics-base
make -C p4p
./p4p/bin/linux-x86_64/pvagw p4p/loopback.conf
This being one of the variants described in https://mdavidsaver.github.io/p4p/building.html#build-as-epics-module
I was able to run the test successfully. No changes were made to Base. I think the issue was the path the required packages were installed to when I used conda install. It works now. Thanks for your help.
The build logs you shared don't show any sign, but maybe you've picked up a conda packaged build of epics-base as well? Having multiple versions in play is a good way to get confused.
I get the following error when I build p4p as an EPICS module .
Steps followed
Install python dependencies conda activate p4p export EPICS_HOST_ARCH=linux-x86_64 export EPICS_BASE=/opt/develop/epics/base conda install numpy nose Cython ply
Set Location of EPICS module(base-7.0.4) cat < configure/RELEASE.local
EPICS_BASE=/opt/develop/epics/base
EOF
make
python ../bootgw.py -P "../../python3.8/linux-x86_64" pvagw Installing created executable ../../bin/linux-x86_64/pvagw mkdir ../../bin mkdir ../../bin/linux-x86_64 make[2]: Leaving directory '/opt/develop/test_p4p/p4p/src/O.linux-x86_64' make[1]: Leaving directory '/opt/develop/test_p4p/p4p/src' make -C ./testing install make[1]: Entering directory '/opt/develop/test_p4p/p4p/testing' perl -CSD /opt/develop/epics/base-7.0.4/bin/linux-x86_64/makeMakefile.pl O.linux-x86_64 ../.. mkdir -p O.Common make -C O.linux-x86_64 -f ../Makefile TOP=../.. \ T_A=linux-x86_64 install make[2]: Entering directory '/opt/develop/test_p4p/p4p/testing/O.linux-x86_64' /usr/bin/g++ -D_GNU_SOURCE -D_DEFAULT_SOURCE -D_X8664 -DUNIX -Dlinux -O3 -Wall -mtune=generic -m64 -Werror=pointer-arith -fvisibility=hidden -std=c++98 -fvisibility-inlines-hidden -I. -I../O.Common -I. -I. -I.. -I../../include/compiler/gcc -I../../include/os/Linux -I../../include -I/opt/develop/epics/base-7.0.4//include/compiler/gcc -I/opt/develop/epics/base-7.0.4//include/os/Linux -I/opt/develop/epics/base-7.0.4//include -MM -MF odometer.d ../odometer.cpp /usr/bin/g++ -D_GNU_SOURCE -D_DEFAULT_SOURCE -D_X8664 -DUNIX -Dlinux -O3 -Wall -mtune=generic -m64 -Werror=pointer-arith -fvisibility=hidden -std=c++98 -fvisibility-inlines-hidden -I. -I../O.Common -I. -I. -I.. -I../../include/compiler/gcc -I../../include/os/Linux -I../../include -I/opt/develop/epics/base-7.0.4//include/compiler/gcc -I/opt/develop/epics/base-7.0.4//include/os/Linux -I/opt/develop/epics/base-7.0.4//include -c ../odometer.cpp /usr/bin/g++ -o odometer -L/opt/develop/test_p4p/p4p/lib/linux-x86_64 -L/opt/develop/epics/base-7.0.4/lib/linux-x86_64 -Wl,-rpath,/opt/develop/test_p4p/p4p/lib/linux-x86_64 -Wl,-rpath,/opt/develop/epics/base-7.0.4/lib/linux-x86_64 -rdynamic -m64 odometer.o -lpvAccess -lpvData -ldbRecStd -ldbCore -lca -lCom const&)'
odometer.o:(.rodata+0x530): undefined reference to , std::allocator > const&, std::tr1::shared_ptr const&, short)'
odometer.o:(.rodata+0x788): undefined reference to `epics::pvAccess::Channel::getField(std::tr1::shared_ptr const&, std:: cxx11::basic_string<char, std::char_traits, std::allocator > const&)'
odometer.o:(.rodata+0x790): undefined reference to const&, std::tr1::shared_ptr const&)'
odometer.o:(.rodata+0x7a8): undefined reference to const&, std::tr1::shared_ptr const&)'
odometer.o:(.rodata+0x7b8): undefined reference to const&, std::tr1::shared_ptr const&)'
odometer.o:(.rodata+0x7c8): undefined reference to `epics::pvAccess::Channel::createChannelArray(std::tr1::shared_ptr const&, std::tr1::shared_ptr const&)'
collect2: error: ld returned 1 exit status
make[2]: [/opt/develop/epics/base-7.0.4//configure/RULES_BUILD:213: odometer] Error 1
make[2]: Leaving directory '/opt/develop/test_p4p/p4p/testing/O.linux-x86_64'
make[1]: [/opt/develop/epics/base-7.0.4//configure/RULES_ARCHS:58: install.linux-x86_64] Error 2
make[1]: Leaving directory '/opt/develop/test_p4p/p4p/testing'
make: *** [/opt/develop/epics/base-7.0.4//configure/RULES_DIRS:85: testing.install] Error 2
odometer.o: In function
(anonymous namespace)::CounterProvider::channelFind(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::tr1::shared_ptr<epics::pvAccess::ChannelFindRequester> const&)': odometer.cpp:(.text+0x452): undefined reference to
epics::pvAccess::ChannelFind::buildDummy(std::tr1::shared_ptrepics::pvAccess::ChannelProvider::channelList(std::tr1::shared_ptr<epics::pvAccess::ChannelListRequester> const&)' odometer.o:(.rodata+0x538): undefined reference to
epics::pvAccess::ChannelProvider::createChannel(std::cxx11::basic_string<char, std::char_traitsepics::pvAccess::Channel::getAccessRights(std::tr1::shared_ptr<epics::pvData::PVField> const&)' odometer.o:(.rodata+0x798): undefined reference to
epics::pvAccess::Channel::createChannelProcess(std::tr1::shared_ptrepics::pvAccess::Channel::createChannelPut(std::tr1::shared_ptr<epics::pvAccess::ChannelPutRequester> const&, std::tr1::shared_ptr<epics::pvData::PVStructure> const&)' odometer.o:(.rodata+0x7b0): undefined reference to
epics::pvAccess::Channel::createChannelPutGet(std::tr1::shared_ptrepics::pvAccess::Channel::createChannelRPC(std::tr1::shared_ptr<epics::pvAccess::ChannelRPCRequester> const&, std::tr1::shared_ptr<epics::pvData::PVStructure> const&)' odometer.o:(.rodata+0x7c0): undefined reference to
epics::pvAccess::Channel::createMonitor(std::tr1::shared_ptr