forked from epics_driver_modules/require
support for exact version number match
This commit is contained in:
+47
-41
@@ -428,7 +428,7 @@ install build::
|
||||
# Loop over all architectures.
|
||||
install build debug::
|
||||
@+for ARCH in ${CROSS_COMPILER_TARGET_ARCHS}; do \
|
||||
umask 002; echo MAKING ARCH $$ARCH; ${MAKE} -f ${USERMAKEFILE} T_A=$$ARCH $@; \
|
||||
umask 002; echo MAKING ${EPICSVERSION} ARCH $$ARCH; ${MAKE} -f ${USERMAKEFILE} T_A=$$ARCH $@; \
|
||||
done
|
||||
|
||||
else # T_A
|
||||
@@ -438,29 +438,6 @@ ifeq ($(filter O.%,$(notdir ${CURDIR})),)
|
||||
# Target architecture defined.
|
||||
# Still in source directory, third run.
|
||||
|
||||
# Add include directory of other modules to include file search path.
|
||||
# By default use highest version of all other modules installed for
|
||||
# current EPICSVERSION and T_A.
|
||||
# The user can overwrite by defining <module>_VERSION=<version>.
|
||||
# This version can be incomplete (only <major> or <major>.<minor>).
|
||||
# In this case the hightest matching full version (<major>.<minor>.<patch>)
|
||||
# will be selected.
|
||||
|
||||
# The tricky part is to sort versions numerically.
|
||||
# Make can't but ls -v can.
|
||||
# Only accept numerical versions (needs extended glob).
|
||||
# This is slow, thus do it only once for each EPICSVERSION.
|
||||
|
||||
define ADD_OTHER_MODULE_INCLUDES
|
||||
$(eval $(1)_VERSION := $(patsubst ${EPICS_MODULES}/$(1)/%/R${EPICSVERSION}/lib/$(T_A)/../../include,%,$(firstword $(shell ls -dvr ${EPICS_MODULES}/$(1)/+([0-9]).+([0-9]).+([0-9])/R${EPICSVERSION}/lib/$(T_A)/../../include 2>/dev/null))))
|
||||
export $(1)_VERSION
|
||||
OTHER_MODULE_INCLUDES += $$(addprefix -I,$$(firstword $$(shell ls -dvr ${EPICS_MODULES}/$(1)/$$($(1)_VERSION)*(.+([0-9]))/R${EPICSVERSION}/include 2>/dev/null)))
|
||||
endef
|
||||
$(eval $(foreach m,$(filter-out $(PRJ) $(IGNORE_MODULES),$(notdir $(wildcard ${EPICS_MODULES}/*))),$(call ADD_OTHER_MODULE_INCLUDES,$m)))
|
||||
# Include path for old style modules.
|
||||
OTHER_MODULE_INCLUDES += $(addprefix -I,$(wildcard ${INSTBASE}/iocBoot/R${EPICSVERSION}/include))
|
||||
export OTHER_MODULE_INCLUDES
|
||||
|
||||
ifeq ($(filter ${OS_CLASS},${OS_CLASS_LIST}),)
|
||||
|
||||
install% build%: build
|
||||
@@ -479,6 +456,36 @@ install build:
|
||||
|
||||
else
|
||||
|
||||
# Add include directory of other modules to include file search path.
|
||||
# By default use highest version of all other modules installed for
|
||||
# current EPICSVERSION and T_A.
|
||||
# The user can overwrite by defining <module>_VERSION=<version>.
|
||||
# This version can be incomplete (only <major> or <major>.<minor>).
|
||||
# In this case the hightest matching full version (<major>.<minor>.<patch>)
|
||||
# will be selected.
|
||||
|
||||
# The tricky part is to sort versions numerically.
|
||||
# Make can't but ls -v can.
|
||||
# Only accept numerical versions (needs extended glob).
|
||||
# This is slow, thus do it only once for each EPICSVERSION.
|
||||
|
||||
define ADD_OTHER_MODULE_INCLUDES
|
||||
$(eval $(1)_VERSION = $(patsubst ${EPICS_MODULES}/$(1)/%/R${EPICSVERSION}/lib/$(T_A)/../../include,%,$(firstword $(shell ls -dvr ${EPICS_MODULES}/$(1)/+([0-9]).+([0-9]).+([0-9])/R${EPICSVERSION}/lib/$(T_A)/../../include 2>/dev/null))))
|
||||
export $(1)_VERSION
|
||||
OTHER_MODULE_INCLUDES += $$(addprefix -I,$$(firstword $$(shell ls -dvr ${EPICS_MODULES}/$(1)/$$($(1)_VERSION)*(.+([0-9]))/R${EPICSVERSION}/include 2>/dev/null)))
|
||||
endef
|
||||
$(eval $(foreach m,$(filter-out $(PRJ) $(IGNORE_MODULES),$(notdir $(wildcard ${EPICS_MODULES}/*))),$(call ADD_OTHER_MODULE_INCLUDES,$m)))
|
||||
# Include path for old style modules.
|
||||
OLD_INCLUDE = $(wildcard ${INSTBASE}/iocBoot/R${EPICSVERSION}/include)
|
||||
OTHER_MODULE_INCLUDES += $(addprefix -I,$(OLD_INCLUDE))
|
||||
export OTHER_MODULE_INCLUDES
|
||||
|
||||
# Manually required modules.
|
||||
define ADD_MANUAL_DEPENDENCIES
|
||||
$(eval $(1)_VERSION = $(or $(patsubst ${EPICS_MODULES}/$(1)/%/R${EPICSVERSION},%,$(firstword $(shell ls -dvr ${EPICS_MODULES}/$(1)/+([0-9]).+([0-9]).+([0-9])/R${EPICSVERSION} 2>/dev/null))),$(basename $(lastword $(subst -, ,$(basename $(realpath ${INSTBASE}/iocBoot/R${EPICSVERSION}/${T_A}/$(1).dep)))))))
|
||||
endef
|
||||
$(eval $(foreach m,${REQ},$(call ADD_MANUAL_DEPENDENCIES,$m)))
|
||||
|
||||
O.%:
|
||||
$(MKDIR) $@
|
||||
|
||||
@@ -520,7 +527,8 @@ export CFG
|
||||
|
||||
export IGNORE_MODULES
|
||||
|
||||
export API_MAY_CHANGE_BETWEEN_MINOR_VERSIONS
|
||||
export USE_EXACT_VERSION += $(ABI_MAY_CHANGE)
|
||||
export USE_EXACT_MINOR_VERSION += $(ABI_MAY_CHANGE_BETWEEN_MINOR_VERSIONS)
|
||||
|
||||
else # in O.*
|
||||
## RUN 4
|
||||
@@ -537,15 +545,9 @@ COMMON_DIR = ${COMMON_DIR_${EPICS_BASETYPE}}
|
||||
|
||||
# Remove include directory for this module from search path.
|
||||
# 3.13 and 3.14+ use different variables
|
||||
INSTALL_INCLUDES := $(strip $(OTHER_MODULE_INCLUDES))
|
||||
INSTALL_INCLUDES = $(strip $(OTHER_MODULE_INCLUDES))
|
||||
EPICS_INCLUDES =
|
||||
|
||||
# Manually required modules.
|
||||
define ADD_MANUAL_DEPENDENCIES
|
||||
$(eval $(1)_VERSION := $(or $(patsubst ${EPICS_MODULES}/$(1)/%/R${EPICSVERSION},%,$(firstword $(shell ls -dvr ${EPICS_MODULES}/$(1)/+([0-9]).+([0-9]).+([0-9])/R${EPICSVERSION} 2>/dev/null))),$(basename $(lastword $(subst -, ,$(basename $(realpath ${INSTBASE}/iocBoot/R${EPICSVERSION}/${T_A}/$(1).dep)))))))
|
||||
endef
|
||||
$(eval $(foreach m,${REQ},$(call ADD_MANUAL_DEPENDENCIES,$m)))
|
||||
|
||||
# EPICS 3.13 uses :: in some rules where 3.14 uses :
|
||||
ifeq (${EPICS_BASETYPE},3.13)
|
||||
INSTALLRULE=install::
|
||||
@@ -663,6 +665,7 @@ endif
|
||||
|
||||
endif # Both, 3.13 and 3.14+ from here.
|
||||
|
||||
ifndef USE_EXACT_VERSION
|
||||
# For backward compatibility:
|
||||
# Provide a global symbol for every version with the same
|
||||
# major and equal or smaller minor version number.
|
||||
@@ -674,7 +677,7 @@ MAJOR=$(word 1,${MAJOR_MINOR_PATCH})
|
||||
MINOR=$(word 2,${MAJOR_MINOR_PATCH})
|
||||
PATCH=$(word 3,${MAJOR_MINOR_PATCH})
|
||||
ifneq (${MINOR},)
|
||||
ifdef API_MAY_CHANGE_BETWEEN_MINOR_VERSIONS
|
||||
ifdef USE_EXACT_MINOR_VERSION
|
||||
ALLMINORS = ${MINOR}
|
||||
else
|
||||
ALLMINORS := $(shell for ((i=0;i<=${MINOR};i++));do echo $$i;done)
|
||||
@@ -687,6 +690,7 @@ PROVIDES = ${ALLMINORS:%=-Wl,--defsym,${PRJ}Lib_${MAJOR}.%=0}
|
||||
endif # Linux
|
||||
endif # MINOR
|
||||
LDFLAGS += ${PROVIDES} ${USR_LDFLAGS_${T_A}}
|
||||
endif # !USE_EXACT_VERSION
|
||||
|
||||
# Create and include dependency files.
|
||||
# 3.13 does not make those files at all.
|
||||
@@ -864,11 +868,17 @@ debug::
|
||||
|
||||
INSTALLS += ${INSTALL_CFGS} ${INSTALL_SCRS} ${INSTALL_HDRS} ${INSTALL_DBDS} ${INSTALL_DBS} ${INSTALL_LIBS} ${INSTALL_BINS} ${INSTALL_DEPS}
|
||||
|
||||
ifdef API_MAY_CHANGE_BETWEEN_MINOR_VERSIONS
|
||||
ifdef USE_EXACT_VERSION
|
||||
INSTALLS += ${EPICS_MODULES}/${PRJ}/use_exact_version
|
||||
%/use_exact_version:
|
||||
touch $@
|
||||
else
|
||||
ifdef USE_EXACT_MINOR_VERSION
|
||||
INSTALLS += ${EPICS_MODULES}/${PRJ}/use_exact_minor_version
|
||||
%/use_exact_minor_version:
|
||||
touch $@
|
||||
endif
|
||||
endif
|
||||
|
||||
${INSTALLRULE} ${INSTALLS}
|
||||
|
||||
@@ -1048,15 +1058,11 @@ ${DEPFILE}: ${LIBOBJS} $(USERMAKEFILE)
|
||||
@echo "Collecting dependencies"
|
||||
$(RM) $@
|
||||
@echo "# Generated file. Do not edit." > $@
|
||||
# Check dependencies on other module headers.
|
||||
cat *.d 2>/dev/null | sed 's/ /\n/g' | sed -n 's%${EPICS_MODULES}/*\([^/]*\)/\([0-9]*\.[0-9]*\)\.[0-9]*/.*%\1 \2%p;s%$(EPICS_MODULES)/*\([^/]*\)/\([^/]*\)/.*%\1 \2%p'| sort -u >> $@
|
||||
ifneq ($(strip ${REQ}),)
|
||||
# Manully added dependencies: ${REQ}
|
||||
@$(foreach m,${REQ},echo "$m $(or ${$m_VERSION},$(and $(wildcard ${EPICS_MODULES}/$m),$(error REQUIRED module $m has no numbered version. Set $m_VERSION)),$(warning REQUIRED module $m not found for ${T_A}.))" >> $@;)
|
||||
endif
|
||||
# Check dependencies on ${REQ} and other module headers.
|
||||
$(foreach m,$(sort ${REQ} $(shell cat *.d 2>/dev/null | sed 's/ /\n/g' | sed -n 's%${EPICS_MODULES}/*\([^/]*\)/.*%\1%p' | sort -u)),echo "$m $(or $(if $(wildcard ${EPICS_MODULES}/$m/use_exact_version),${$m_VERSION},$(basename ${$m_VERSION})),$(and $(wildcard ${EPICS_MODULES}/$m),$(error REQUIRED module $m has no numbered version. Set $m_VERSION)),$(warning REQUIRED module $m not found for ${T_A}.))" >> $@;)
|
||||
ifdef OLD_INCLUDE
|
||||
# Check dependencies on old style driver headers.
|
||||
@${MAKEHOME}/getPrerequisites.tcl -dep ${OLD_INCLUDE} | grep -vw -e ${PRJ} -e ^$$ >> $@ && echo "Warning: dependency on old style driver"; true;
|
||||
${MAKEHOME}/getPrerequisites.tcl -dep ${OLD_INCLUDE} | grep -vw -e ${PRJ} -e ^$$ >> $@ && echo "Warning: dependency on old style driver"; true;
|
||||
endif
|
||||
|
||||
# Remove MakefileInclude after we are done because it interfers with our way to build.
|
||||
|
||||
@@ -874,7 +874,7 @@ int libversionShow(const char* outfile)
|
||||
#define TESTVERS 2
|
||||
#define HIGHER 3
|
||||
|
||||
static int compareVersions(const char* found, const char* request, int exactMinorNeeded)
|
||||
static int compareVersions(const char* found, const char* request, int exactnessLevel)
|
||||
{
|
||||
int found_major, found_minor=0, found_patch=0, found_parts = 0;
|
||||
int req_major, req_minor, req_patch, req_parts;
|
||||
@@ -883,7 +883,7 @@ static int compareVersions(const char* found, const char* request, int exactMino
|
||||
int n;
|
||||
|
||||
if (requireDebug)
|
||||
printf("require: compareVersions(found=%s, request=%s, exactMinorNeeded=%d)\n", found, request, exactMinorNeeded);
|
||||
printf("require: compareVersions(found=%s, request=%s, exactnessLevel=%d)\n", found, request, exactnessLevel);
|
||||
|
||||
if (found == NULL || found[0] == 0) /* no version found: any requested? */
|
||||
{
|
||||
@@ -974,7 +974,7 @@ static int compareVersions(const char* found, const char* request, int exactMino
|
||||
}
|
||||
if (found_minor > req_minor) /* minor larger than required */
|
||||
{
|
||||
if (req_extra[0] == '+' && !exactMinorNeeded)
|
||||
if (req_extra[0] == '+' && exactnessLevel == 0)
|
||||
{
|
||||
if (requireDebug)
|
||||
printf("require: compareVersions: MATCH minor number higher than requested with +\n");
|
||||
@@ -1005,7 +1005,7 @@ static int compareVersions(const char* found, const char* request, int exactMino
|
||||
printf("require: compareVersions: MATCH patch level matches exactly requested\n");
|
||||
return MATCH;
|
||||
}
|
||||
if (req_extra[0] == '+')
|
||||
if (req_extra[0] == '+' && exactnessLevel <= 1)
|
||||
{
|
||||
if (requireDebug)
|
||||
printf("require: compareVersions: MATCH patch level higher than requested with +\n");
|
||||
@@ -1131,7 +1131,7 @@ static off_t fileSize(const char* filename)
|
||||
{
|
||||
case S_IFREG:
|
||||
if (requireDebug)
|
||||
printf("require: file %s exists, size %lld bytes\n",
|
||||
printf("require: file %s exists, size %llu bytes\n",
|
||||
filename, (unsigned long long)filestat.st_size);
|
||||
return filestat.st_size;
|
||||
case S_IFDIR:
|
||||
@@ -1247,7 +1247,7 @@ static int require_priv(const char* module, const char* version, const char* arg
|
||||
char* symbolname;
|
||||
char filename[PATH_MAX];
|
||||
|
||||
int exactMinorNeeded = 0;
|
||||
int exactnessLevel = 0;
|
||||
int someVersionFound = 0;
|
||||
int someArchFound = 0;
|
||||
|
||||
@@ -1301,11 +1301,19 @@ static int require_priv(const char* module, const char* version, const char* arg
|
||||
dirname = getLibLocation(module);
|
||||
if (requireDebug && dirname[0])
|
||||
printf("require: library found in %s\n", dirname);
|
||||
snprintf(filename, sizeof(filename), "%s%n.." OSI_PATH_SEPARATOR ".." OSI_PATH_SEPARATOR "use_exact_minor_version",
|
||||
snprintf(filename, sizeof(filename), "%s%n.." OSI_PATH_SEPARATOR ".." OSI_PATH_SEPARATOR "use_exact_version",
|
||||
dirname, &releasediroffs);
|
||||
if (fileExists(filename))
|
||||
exactMinorNeeded = 1;
|
||||
switch (compareVersions(loaded, version, exactMinorNeeded))
|
||||
{
|
||||
exactnessLevel = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(filename+releasediroffs, sizeof(filename)-releasediroffs, ".." OSI_PATH_SEPARATOR ".." OSI_PATH_SEPARATOR "use_exact_minor_version");
|
||||
if (fileExists(filename))
|
||||
exactnessLevel = 1;
|
||||
}
|
||||
switch (compareVersions(loaded, version, exactnessLevel))
|
||||
{
|
||||
case TESTVERS:
|
||||
if (version)
|
||||
@@ -1320,7 +1328,8 @@ static int require_priv(const char* module, const char* version, const char* arg
|
||||
int i = strlen(version);
|
||||
if (version[i-1] == '+') i--;
|
||||
printf("Conflict between required %s%s version %.*s and already loaded version %s.\n",
|
||||
exactMinorNeeded ? "exact " : "" , module, i, version, loaded);
|
||||
exactnessLevel > 1 ? "exact " : exactnessLevel > 0 ? "exact minor " : "" ,
|
||||
module, i, version, loaded);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1347,25 +1356,25 @@ static int require_priv(const char* module, const char* version, const char* arg
|
||||
end = strchr(end+2, OSI_PATH_LIST_SEPARATOR[0]);
|
||||
if (end) dirlen = (int)(end++ - dirname);
|
||||
else dirlen = (int)strlen(dirname);
|
||||
if (dirlen == 0) continue; /* ignore empty driverpath elements */
|
||||
|
||||
if (requireDebug)
|
||||
printf("require: trying %.*s\n", dirlen, dirname);
|
||||
if (dirlen == 0)
|
||||
continue; /* ignore empty driverpath elements */
|
||||
|
||||
if (!TRY_FILE(0, "%.*s" OSI_PATH_SEPARATOR, dirlen, dirname))
|
||||
continue; /* ignore non-existing driverpath elements */
|
||||
|
||||
snprintf(filename, sizeof(filename), "%.*s" OSI_PATH_SEPARATOR "%s" OSI_PATH_SEPARATOR "%n" OSI_PATH_SEPARATOR "use_exact_minor_version",
|
||||
dirlen, dirname, module, &modulediroffs);
|
||||
dirlen += strlen(OSI_PATH_SEPARATOR);
|
||||
/* filename = "<dirname>/[dirlen]<module>/[modulediroffs]/use_exact_minor_version" */
|
||||
|
||||
if (fileExists(filename))
|
||||
exactMinorNeeded = 1;
|
||||
/* filename = "<dirname>/[dirlen]" */
|
||||
|
||||
snprintf(filename+dirlen, sizeof(filename)-dirlen, "%s" OSI_PATH_SEPARATOR "%n", module, &modulediroffs);
|
||||
modulediroffs += dirlen;
|
||||
/* filename = "<dirname>/[dirlen]<module>/[modulediroffs]" */
|
||||
|
||||
/* Does the module directory exist? */
|
||||
filename[modulediroffs] = 0;
|
||||
IF_OPEN_DIR(filename)
|
||||
{
|
||||
if (requireDebug)
|
||||
printf("require: found directory %s\n", filename);
|
||||
if (TRY_FILE(modulediroffs, "use_exact_version")) exactnessLevel = 2;
|
||||
else if (TRY_FILE(modulediroffs, "use_exact_minor_version")) exactnessLevel = 1;
|
||||
|
||||
/* Now look for versions. */
|
||||
START_DIR_LOOP
|
||||
@@ -1379,10 +1388,10 @@ static int require_priv(const char* module, const char* version, const char* arg
|
||||
|
||||
/* Look for highest matching version. */
|
||||
if (requireDebug)
|
||||
printf("require: checking version %s against required %s\n",
|
||||
printf("require: comparing found version %s against required %s\n",
|
||||
currentFilename, version);
|
||||
|
||||
switch ((status = compareVersions(currentFilename, version, exactMinorNeeded)))
|
||||
switch ((status = compareVersions(currentFilename, version, exactnessLevel)))
|
||||
{
|
||||
case EXACT: /* exact match found */
|
||||
case MATCH: /* all given numbers match. */
|
||||
@@ -1418,10 +1427,10 @@ static int require_priv(const char* module, const char* version, const char* arg
|
||||
}
|
||||
|
||||
/* Is it higher than the one we found before? */
|
||||
if (found && requireDebug)
|
||||
if (requireDebug)
|
||||
printf("require: %s %s support for %s %s found, compare against previously found %s\n",
|
||||
module, currentFilename, epicsRelease, targetArch, found);
|
||||
if (!found || compareVersions(currentFilename, found, exactMinorNeeded) == HIGHER)
|
||||
if (!found || compareVersions(currentFilename, found, exactnessLevel) == HIGHER)
|
||||
{
|
||||
if (requireDebug)
|
||||
printf("require: %s %s looks promising\n", module, currentFilename);
|
||||
@@ -1565,7 +1574,7 @@ loadlib:
|
||||
/* check what we got */
|
||||
if (requireDebug)
|
||||
printf("require: compare requested version %s with loaded version %s\n", version, found);
|
||||
if (compareVersions(found, version, exactMinorNeeded) == MISMATCH)
|
||||
if (compareVersions(found, version, exactnessLevel) == MISMATCH)
|
||||
{
|
||||
fprintf(stderr, "Requested %s version %s not available, found only %s.\n",
|
||||
module, version, found);
|
||||
|
||||
Reference in New Issue
Block a user