Open dirk-zimoch opened 3 years ago
That seems like a nice idea, but I am not sure how to implement it.
$(EPICS_BASE_IOC_LIBS) is quite simple because it is never dependent on EPICS_HOST_ARCH nor on site-specific packages. It is just defined here:
/usr/local/epics-devel/base-7.0.6/configure/CONFIG_DATABASE_MODULE:EPICS_BASE_IOC_LIBS = dbRecStd dbCore ca Com
asyn on the other hand uses SYS_LIBS that are dependent on EPICS_HOST_ARCH and on whether certain packages are installed or not. It starts with the contents of CONFIG_SITE:
# If you have the local Linux GPIB support installed (http://sourceforge.net/projects/linux-gpib/)
# then set LINUX_GPIB=YES
LINUX_GPIB=NO
# If you have libusb-1.0 revision 16 or newer and want the USB TMC support set DRV_USBTMC=YES
#DRV_USBTMC=YES
# You can also define this on a per-architecture basis.
# In this example DRV_USBTMC would be built only for linux-x86_64, and not for other architectures
#ifeq (linux-x86_64, $(T_A))
# DRV_USBTMC=YES
#endif
# If you have libusb-1.0 and libftdi, and want FTDI support, set DRV_FTDI=YES
DRV_FTDI=NO
# If your system has libftdi1, set the following to YES. If it has libftdi, set it to NO
DRV_FTDI_USE_LIBFTDI1=NO
# If you want to build asyn so the only dependency on EPICS base is libCom then set the following flag
#EPICS_LIBCOM_ONLY=YES
# Some linux systems moved RPC related symbols to libtirpc
# To enable linking against this library, uncomment the following line
# TIRPC=YES
and then these variables are used in asyn/Makefile to define SYS_LIBS:
corvette:~/devel/asyn/asyn>grep -U10 SYS_LIBS Makefile
LIBRARY_IOC += asyn
asyn_SYS_LIBS_WIN32 = ws2_32 winmm
asyn_SYS_LIBS_cygwin32 = $(CYGWIN_RPC_LIB)
# Some linux systems moved RPC related symbols to libtirpc
# Define TIRPC in configure/CONFIG_SITE in this case
ifeq ($(TIRPC),YES)
USR_INCLUDES_Linux += -I/usr/include/tirpc
asyn_SYS_LIBS_Linux += tirpc
endif
--
ifneq (, $(findstring RTEMS, $(T_A)))
DRV_USBTMC = NO
endif
ifneq (, $(findstring vxWorks, $(T_A)))
DRV_USBTMC = NO
endif
ifeq ($(DRV_USBTMC),YES)
SRC_DIRS += $(ASYN)/drvAsynUSBTMC
asyn_SRCS += drvAsynUSBTMC.c
asyn_SYS_LIBS += usb-1.0
DBD += drvAsynUSBTMC.dbd
endif
ifeq ($(DRV_FTDI),YES)
SRC_DIRS += $(ASYN)/drvAsynFTDI
asyn_SRCS += ftdiDriver.cpp drvAsynFTDIPort.cpp
asyn_SYS_LIBS += usb-1.0
INC += drvAsynFTDIPort.h
ifeq ($(DRV_FTDI_USE_LIBFTDI1),YES)
asyn_SYS_LIBS += ftdi1
USR_CXXFLAGS += -DHAVE_LIBFTDI1
else
asyn_SYS_LIBS += ftdi
endif
DBD += drvAsynFTDIPort.dbd
endif
ifeq ($(LINUX_GPIB),YES)
SRC_DIRS += $(ASYN)/linuxGpib
asyn_SRCS_Linux += drvLinuxGpib.c
DBD += drvLinuxGpib.dbd
asyn_SYS_LIBS += gpib
endif
There would thus need to be a configuration file that defined these for each EPICS_HOST_ARCH, and that configuration file would need to available to other modules that depend on asyn.
Asyn can install a CFG file CONFIG_ASYN_MODULE
which every downstream application will include automatically when its RELEASE file contains a pointer to Asyn. Then for each target it builds, Asyn would also create a CFG file say ASYN.$(EPICS_HOST_ARCH).$(T_A)
which the first file would include like this:
# CONFIG_ASYN_MODULE
ifneq ($(T_A),)
include $(ASYN)/cfg/ASYN.$(EPICS_HOST_ARCH).$(T_A)
endif
The Asyn build knows how it has been configured for its specific host+target combination, so the ASYN.*
files that get created don't need any conditionals in them at all, they just set the variables that will be needed to build IOCs for that particular target, e.g:
# ASYN.centos8-x86_64.centos8-x86_64
asyn_IOC_LIBS += asyn
asyn_SYS_LIBS += tirpc
asyn_SYS_LIBS += usb-1.0
asyn_SYS_LIBS += ftdi1
Note that there's no need to set USR_INCLUDES
since that's only needed when compiling code inside Asyn. If you publish optional DBD files they should be added to something like asyn_DBD
; the idea is that the Makefile which builds the IOC must explicitly use the variables defined in the above file, since other targets might not want to link against those libraries.
I'm not clear on how having asyn_SYS_LIBS defined to include those system libraries helps when I am building an IOC. Do I do the following in my IOC Makefile?
PROD_SYS_LIBS += asyn_SYS_LIBS
Almost:
PROD_LIBS += $(asyn_IOC_LIBS)
PROD_LIBS += $(EPICS_BASE_IOC_LIBS)
PROD_SYS_LIBS += $(asyn_SYS_LIBS)
This can obviously be extended to other modules too, say
PROD_LIBS += $(modbus_IOC_LIBS)
PROD_LIBS += $(asyn_IOC_LIBS)
PROD_LIBS += $(EPICS_BASE_IOC_LIBS)
PROD_SYS_LIBS += $(asyn_SYS_LIBS)
I don't think modbus_IOC_LIBS
should include $(asyn_IOC_LIBS)
though, I think the IOC's Makefile should have to explicitly mention every module that it wants to be linked against.
One thing we have to be careful of with these names though is that the variable asyn_SYS_LIBS
is also the prod-specific *_SYS_LIBS
variable that would be used when linking a PROD called asyn
, which might cause problems. Maybe I should have suggested the upper-case ASYN_SYS_LIBS
for that variable, or the name asyn_IOC_SYS_LIBS
instead (or even combine the two to make ASYN_IOC_SYS_LIBS
).
Under some circumstances, drivers dependent on asyn seemingly require to link with the same SYS_LIBS as asyn. At least that‘s what some StreamDevice users tell me. But how should those drivers know when asyn_SYS_LIBS is only defined in the asyn Makefile? It would be nice to have some macro like $(EPICS_BASE_IOC_LIBS) for asyn too. Can asyn_SYS_LIBS be defined in a file that other Makefiles can include?