Closed MarkRivers closed 4 years ago
I should note that 2.8.8 builds OK on both windows-x64 and windows-x64-static after adding SSCAN to configure/RELEASE and uncommenting the line for sscan in streamApp/Makefile.
I'll have a look. Windows is always a pain in the ass for me.
I'm happy to test building when you make commits.
It seems to start with 'cat' not existing on Windows. That should already have been fixed in 2.8.10.
On both Linux and Windows the library files do not get installed into stream/lib, they get installed into stream/../lib. Is this intentional?
Probably not.
I missed 2.8.10. git tag shows them in alphabetical order, and so I thought 2.8.9 was the latest.
But the main problems are in master.
It looks like there may be a problem around here: https://github.com/paulscherrerinstitute/StreamDevice/blob/4180bbbdd9ef6f058f154a39bea19769739430cb/src/devStream.h#L74
This line:
is being included after you have switched to exporting shared symbols, but it should be before because it is in base, right?
Maybe. I don't understand why I have to switch on and off of the shared symbols stuff at all.
Andrew explained to me that the way you are doing it makes it safe against including your header file in the "wrong" order. I typically don't use that mechanism, I just include all header files for things defined in other libraries, then include epicsExport.h, then include header files for things defined in this library. Then I don't explicitly set the epicsExportSharedSymbols variable.
When you take out epicsStdioRedirect.h (which is not really essantial), does it link then?
I have pushed a change that moves epicsStdioRedirect.h inside the shared symbols switching. I hope that helps.
It's Thanksgiving holiday for the next 2 days, but I can work on it this weekend.
I tested the latest master branch which has your commit for devStream.h. It builds fine on Linux.
However, it stills fails on windows-x64-static with this error when building streamApp.exe.
link -nologo -incremental:no -opt:ref -release -MACHINE:X64 -out:streamApp.exe streamApp_registerRecordDeviceDriver.obj streamAppMain.obj ../../../lib/windows-x64-static/stream.lib J:/epics/devel/asyn-4-37/lib/windows-x64-static/asyn.lib J:/epics/devel/calc-3-7-3/lib/windows-x64-static/calc.lib J:/epics/devel/sscan-2-11-3/lib/windows-x64-static/sscan.lib H:/epics-devel/base-7.0.3.1/lib/windows-x64-static/dbRecStd.lib H:/epics-devel/base-7.0.3.1/lib/windows-x64-static/dbCore.lib H:/epics-devel/base-7.0.3.1/lib/windows-x64-static/ca.lib H:/epics-devel/base-7.0.3.1/lib/windows-x64-static/Com.lib netapi32.lib ws2_32.lib advapi32.lib user32.lib kernel32.lib winmm.lib dbghelp.lib
Creating library streamApp.lib and object streamApp.exp
stream.lib(StreamEpics.obj) : error LNK2019: unresolved external symbol "struct _iobuf * StreamDebugFile" (?StreamDebugFile@@3PEAU_iobuf@@EA) referenced in function "long __cdecl streamSetLogfile(char const *)" (?streamSetLogfile@@YAJPEBD@Z)
stream.lib(StreamEpics.obj) : error LNK2019: unresolved external symbol "char const * const StreamVersion" (?StreamVersion@@3QBDB) referenced in function "private: static void __cdecl Stream::initHook(enum initHookState)" (?initHook@Stream@@CAXW4initHookState@@@Z)
streamApp.exe : fatal error LNK1120: 2 unresolved externals
make[2]: *** [H:/epics-devel/base-7.0.3.1/configure/RULES_BUILD:213: streamApp.exe] Error 1120
make[2]: Leaving directory 'J:/epics/devel/StreamDevice/streamApp/O.windows-x64-static'
make[1]: *** [H:/epics-devel/base-7.0.3.1/configure/RULES_ARCHS:58: install.windows-x64-static] Error 2
make[1]: Leaving directory 'J:/epics/devel/StreamDevice/streamApp'
make: *** [H:/epics-devel/base-7.0.3.1/configure/RULES_DIRS:84: streamApp.install] Error 2
It fails on windows-x64 with this error when building stream.dll.
link -nologo -subsystem:windows -dll -LTCG -incremental:no -opt:ref -release -MACHINE:X64 -out:stream.dll -implib:stream.lib DebugInterface.obj DummyInterface.obj AsynDriverInterface.obj EnumConverter.obj BCDConverter.obj RawConverter.obj RawFloatConverter.obj BinaryConverter.obj ChecksumConverter.obj MantissaExponentConverter.obj TimestampConverter.obj devaoStream.obj devaiStream.obj devboStream.obj devbiStream.obj devmbboStream.obj devmbbiStream.obj devmbboDirectStream.obj devmbbiDirectStream.obj devlongoutStream.obj devlonginStream.obj devstringoutStream.obj devstringinStream.obj devwaveformStream.obj devaaiStream.obj devaaoStream.obj devcalcoutStream.obj devlsiStream.obj devlsoStream.obj devint64inStream.obj devint64outStream.obj devscalcoutStream.obj StreamVersion.obj StreamBuffer.obj StreamError.obj StreamProtocol.obj StreamFormatConverter.obj StreamCore.obj StreamBusInterface.obj StreamEpics.obj J:/epics/devel/asyn-4-37/lib/windows-x64/asyn.lib H:/epics-devel/base-7.0.3.1/lib/windows-x64/dbRecStd.lib H:/epics-devel/base-7.0.3.1/lib/windows-x64/dbCore.lib H:/epics-devel/base-7.0.3.1/lib/windows-x64/ca.lib H:/epics-devel/base-7.0.3.1/lib/windows-x64/Com.lib
Creating library stream.lib and object stream.exp
StreamEpics.obj : error LNK2001: unresolved external symbol "char const * const StreamVersion" (?StreamVersion@@3QBDB)
StreamEpics.obj : error LNK2001: unresolved external symbol "struct _iobuf * StreamDebugFile" (?StreamDebugFile@@3PEAU_iobuf@@EA)
stream.dll : fatal error LNK1120: 2 unresolved externals
make[2]: *** [H:/epics-devel/base-7.0.3.1/configure/RULES_BUILD:298: stream.dll] Error 1120
make[2]: Leaving directory 'J:/epics/devel/StreamDevice/src/O.windows-x64'
make[1]: *** [H:/epics-devel/base-7.0.3.1/configure/RULES_ARCHS:58: install.windows-x64] Error 2
make[1]: Leaving directory 'J:/epics/devel/StreamDevice/src'
make: *** [H:/epics-devel/base-7.0.3.1/configure/RULES_DIRS:84: src.install] Error 2
I have fixed the problems with these changes:
corvette:~/devel/StreamDevice/src>git diff .
diff --git a/src/StreamError.cc b/src/StreamError.cc
index 29757c5..8c200ee 100644
--- a/src/StreamError.cc
+++ b/src/StreamError.cc
@@ -24,15 +24,11 @@
#include <string.h>
#include <time.h>
#include <stdio.h>
+#include <epicsExport.h>
int streamDebug = 0;
int streamError = 1;
-extern "C" {
-#ifdef _WIN32
-__declspec(dllexport)
-#endif
-FILE *StreamDebugFile = NULL;
-}
+epicsShareExtern FILE *StreamDebugFile = NULL;
#ifndef va_copy
#ifdef __va_copy
diff --git a/src/devStream.h b/src/devStream.h
index 7b23676..0369486 100644
--- a/src/devStream.h
+++ b/src/devStream.h
@@ -89,13 +89,13 @@ typedef const struct format_s {
} format_t;
epicsShareExtern FILE* StreamDebugFile;
-extern const char StreamVersion [];
typedef long (*streamIoFunction) (dbCommon*, format_t*);
#ifdef __cplusplus
extern "C" {
#endif
+epicsShareExtern const char StreamVersion [];
long streamInit(int after);
long streamInitRecord(dbCommon *record,
StreamError.cc was unconditionally using __declspec(dllexport) for StreamDebugFile. That is not correct. I changed to use epicsShareExtern, which required including epicsExport.h.
devStream.h was declaring StreamVersion to have C++ linkage, but it is used in StreamVersion.c that has C linkage.
It now builds OK on Windows. I have tested all 8 combinations of
Hmm... I wanted to keep EPICS out of the generic parts of StreamDevice like StreamError.cc. I will set up a Windows machine and test what I can do.
StreamVersion is a variable, not a function. Can that have "C++ linkage"?
Hmm... I wanted to keep EPICS out of the generic parts of StreamDevice like StreamError.cc. I will set up a Windows machine and test what I can do.
You can test if it is a static build using #ifdef EPICS_BUILD_DLL and not use the __declspec(dllexport) if it is.
StreamVersion is a variable, not a function. Can that have "C++ linkage"?
Not sure. Moving it inside the extern C fixed the error.
Hi, i've pushed a possible fix in #47 - I removed the epicsShareExtern from streamDebugFile as it didn't look like it was needed anywhere outside streamdevice? If you need it visible outside the DLL then testing EPICS_BUILD_DLL as @MarkRivers suggests is one option. A slightly less reliable, but which usually works, option is to use
#if defined(_WIN32) && defined(_DLL)
The _DLL symbol is defined if the /MD[d] options are specified to the compiler, which they usually are for a DLL build. Static builds normally use /MT[d] and so do not set _DLL. I'm not sure what mingw or cygwin does, so it might fail there though.
Is this fixed? Can I close the issue?
I just pulled the master branch and built on linux-x86_64, windows-x64, and windows-x64-static. The only error was the following:
J:\epics\devel\stream>make -sj
make[2]: Circular StreamVersion.obj <- StreamVersion.obj dependency dropped.
calc.lib(editSseq.obj) : error LNK2019: unresolved external symbol seq_efClear referenced in function reconcilePVs
calc.lib(editSseq.obj) : error LNK2019: unresolved external symbol seq_efTestAndClear referenced in function reconcilePVs
calc.lib(editSseq.obj) : error LNK2019: unresolved external symbol seq_pvGetTmo referenced in function reconcilePVs
calc.lib(editSseq.obj) : error LNK2019: unresolved external symbol seq_pvPut referenced in function reconcilePVs
calc.lib(editSseq.obj) : error LNK2019: unresolved external symbol seq_pvPutTmo referenced in function reconcilePVs
calc.lib(editSseq.obj) : error LNK2019: unresolved external symbol seq_pvAssign referenced in function reconcilePVs
calc.lib(editSseq.obj) : error LNK2019: unresolved external symbol seqRegisterSequencerProgram referenced in function reconcilePVs
calc.lib(editSseq.obj) : error LNK2019: unresolved external symbol seqRegisterSequencerCommands referenced in function reconcilePVs
streamApp.exe : fatal error LNK1120: 8 unresolved externals
make[2]: *** [H:/epics-devel/base-7.0.3.1/configure/RULES_BUILD:213: streamApp.exe] Error 1120
make[1]: *** [H:/epics-devel/base-7.0.3.1/configure/RULES_ARCHS:58: install.windows-x64-static] Error 2
make: *** [H:/epics-devel/base-7.0.3.1/configure/RULES_DIRS:84: streamApp.install] Error 2
The reason for this is simple. calc can optionally depend on sncseq. I built calc with that optional sequencer support. In order to work with this configuration stream/configure/RELEASE should optionally define SNCSEQ and streamApp/Makefile should optionally include the sncseq libraries. This can be done the same way it optionally builds with CALC and SSCAN.
Note that I can also generate that error on Linux if I set STATIC_BUILD=YES in streamApp/Makefile:
/usr/bin/g++ -o streamApp -Wl,-Bstatic -L/home/epics/devel/lib/linux-x86_64 -L/home/epics/devel/asyn-4-39/lib/linux-x86_64 -L/home/epics/devel/calc-3-7-3/lib/linux-x86_64 -L/home/epics/devel/sscan-2-11-3/lib/linux-x86_64 -L/usr/local/epics-devel/base-7.0.3.1/lib/linux-x86_64 -Wl,-rpath,/home/epics/devel/lib/linux-x86_64 -Wl,-rpath,/home/epics/devel/asyn-4-39/lib/linux-x86_64 -Wl,-rpath,/home/epics/devel/calc-3-7-3/lib/linux-x86_64 -Wl,-rpath,/home/epics/devel/sscan-2-11-3/lib/linux-x86_64 -Wl,-rpath,/usr/local/epics-devel/base-7.0.3.1/lib/linux-x86_64 -rdynamic -m64 streamApp_registerRecordDeviceDriver.o streamAppMain.o -lstream -lasyn -lcalc -lsscan -ldbRecStd -ldbCore -lca -lCom -Wl,-Bdynamic -lpthread -lreadline -lm -lrt -ldl -lgcc
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o): In function `seqg_entry_editSseq_0_newCommand':
editSseq.c:(.text+0xbe): undefined reference to `seq_pvGetTmo'
editSseq.c:(.text+0xdc): undefined reference to `seq_pvGetTmo'
editSseq.c:(.text+0xfa): undefined reference to `seq_pvGetTmo'
editSseq.c:(.text+0x118): undefined reference to `seq_pvGetTmo'
editSseq.c:(.text+0x140): undefined reference to `seq_pvGetTmo'
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o):editSseq.c:(.text+0x15e): more undefined references to `seq_pvGetTmo' follow
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o): In function `seqg_entry_editSseq_0_newCommand':
editSseq.c:(.text+0x197): undefined reference to `seq_pvPutTmo'
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o): In function `seqg_entry_editSseq_0_newRecordName':
editSseq.c:(.text+0x347): undefined reference to `seq_pvPutTmo'
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o): In function `editSseqRegistrar':
editSseq.c:(.text+0x3d5): undefined reference to `seqRegisterSequencerCommands'
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o): In function `seqg_action_editSseq_0_waitForCmnd':
editSseq.c:(.text+0x419): undefined reference to `seq_pvPutTmo'
editSseq.c:(.text+0x439): undefined reference to `seq_pvPutTmo'
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o): In function `reconcilePVs.isra.1':
editSseq.c:(.text+0x4af): undefined reference to `seq_pvPut'
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o): In function `seqg_action_editSseq_0_newRecordName':
editSseq.c:(.text+0x66b): undefined reference to `seq_pvAssign'
editSseq.c:(.text+0x682): undefined reference to `seq_pvGetTmo'
editSseq.c:(.text+0x71a): undefined reference to `seq_pvAssign'
editSseq.c:(.text+0x779): undefined reference to `seq_pvAssign'
editSseq.c:(.text+0x7cc): undefined reference to `seq_pvAssign'
editSseq.c:(.text+0x81f): undefined reference to `seq_pvAssign'
editSseq.c:(.text+0x88b): undefined reference to `seq_pvAssign'
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o):editSseq.c:(.text+0x8ea): more undefined references to `seq_pvAssign' follow
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o): In function `seqg_entry_editSseq_0_waitForCmnd':
editSseq.c:(.text+0x989): undefined reference to `seq_efClear'
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o): In function `seqg_action_editSseq_0_init':
editSseq.c:(.text+0xa01): undefined reference to `seq_pvPutTmo'
editSseq.c:(.text+0xa21): undefined reference to `seq_pvPutTmo'
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o): In function `seqg_event_editSseq_0_waitForCmnd':
editSseq.c:(.text+0xa53): undefined reference to `seq_efTestAndClear'
editSseq.c:(.text+0xa81): undefined reference to `seq_efTestAndClear'
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o): In function `seqg_action_editSseq_0_newCommand':
editSseq.c:(.text+0xc55): undefined reference to `seq_pvPutTmo'
editSseq.c:(.text+0xded): undefined reference to `seq_pvPutTmo'
editSseq.c:(.text+0xe09): undefined reference to `seq_pvPutTmo'
editSseq.c:(.text+0xed0): undefined reference to `seq_pvPutTmo'
editSseq.c:(.text+0xef3): undefined reference to `seq_pvPutTmo'
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o):editSseq.c:(.text+0xf79): more undefined references to `seq_pvPutTmo' follow
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o): In function `seqg_action_editSseq_0_newCommand':
editSseq.c:(.text+0x1417): undefined reference to `seq_pvPut'
editSseq.c:(.text+0x1ae8): undefined reference to `seq_pvPutTmo'
editSseq.c:(.text+0x1b04): undefined reference to `seq_pvPutTmo'
editSseq.c:(.text+0x1b20): undefined reference to `seq_pvPutTmo'
editSseq.c:(.text+0x1b3c): undefined reference to `seq_pvPutTmo'
editSseq.c:(.text+0x1b58): undefined reference to `seq_pvPutTmo'
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o):editSseq.c:(.text+0x1b74): more undefined references to `seq_pvPutTmo' follow
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o): In function `seqg_action_editSseq_0_newCommand':
editSseq.c:(.text+0x36a7): undefined reference to `seq_pvPut'
editSseq.c:(.text+0x36ef): undefined reference to `seq_pvPut'
editSseq.c:(.text+0x373f): undefined reference to `seq_pvPut'
editSseq.c:(.text+0x3787): undefined reference to `seq_pvPut'
editSseq.c:(.text+0x37cf): undefined reference to `seq_pvPut'
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o):editSseq.c:(.text+0x3817): more undefined references to `seq_pvPut' follow
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o): In function `seqg_entry_editSseq_0_newCommand':
editSseq.c:(.text+0x1b8): undefined reference to `seq_pvPutTmo'
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o): In function `editSseqRegistrar':
editSseq.c:(.text+0x3e5): undefined reference to `seqRegisterSequencerProgram'
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o): In function `seqg_action_editSseq_0_waitForCmnd':
editSseq.c:(.text+0x45a): undefined reference to `seq_pvPutTmo'
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o): In function `seqg_action_editSseq_0_init':
editSseq.c:(.text+0xa2f): undefined reference to `seq_efClear'
/home/epics/devel/calc-3-7-3/lib/linux-x86_64/libcalc.a(editSseq.o): In function `seqg_action_editSseq_0_newCommand':
editSseq.c:(.text+0xc86): undefined reference to `seq_pvPutTmo'
collect2: error: ld returned 1 exit status
make[1]: *** [streamApp] Error 1
make[1]: Leaving directory `/home/epics/devel/stream-2-8-9/streamApp/O.linux-x86_64'
Also, configure/RELEASE no longer needs this line:
-include $(TOP)/../configure/SUPPORT.$(EPICS_HOST_ARCH)
That was there for Windows builds in the same tree as Linux, but now that is handled by this line, which is the accepted way of doing it:
-include $(TOP)/../RELEASE.$(EPICS_HOST_ARCH).local
I merged pull request #53. Does this solve the linker errors?
Re-open if the problem still exists.
I am trying to build stream on base with 7.0.3.1.
stream 2.8.9 fails to build on Windows static (windows-x64-static) with this error:
2.8.9 builds on Linux with these warnings:
On both Linux and Windows the library files do not get installed into stream/lib, they get installed into stream/../lib. Is this intentional?
The master branch fails to build on Windows with this error:
I can eliminate the error on StreamDebugFile with this change, removing the __declspec(dllexport), which should not be used for static builds.
However, I have not figured out how to eliminate the error on StreamVersion.
When building dynamically on Windows (windows-x64) the error shows up earlier, which building stream.lib, rather than streamApp.
k