diff --git a/configure/RULES.ioc b/configure/RULES.ioc
index e868b02d9..5632bd758 100644
--- a/configure/RULES.ioc
+++ b/configure/RULES.ioc
@@ -17,16 +17,15 @@ ifneq ($(findstring $(ARCH),$(BUILD_ARCHS)),)
buildInstall: $(TARGETS)
clean:
- $(RM) cdCommands envPaths
+ $(RM) cdCommands envPaths dllPath.bat
else
buildInstall:
clean:
endif
-envPaths cdCommands: $(wildcard $(TOP)/configure/RELEASE*) \
+cdCommands envPaths dllPath.bat: $(wildcard $(TOP)/configure/RELEASE*) \
$(TOP)/configure/CONFIG $(INSTALL_BIN)
- @$(RM) $@
ifeq ($(IOCS_APPL_TOP),)
$(PERL) $(TOOLS)/convertRelease.pl -a $(ARCH) $@
else
@@ -34,5 +33,5 @@ else
endif
realclean:
- $(RM) cdCommands envPaths
+ $(RM) cdCommands envPaths dllPath.bat
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index 4386eb05f..bd2e54132 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -12,6 +12,15 @@
Changes between 3.14.9 and 3.14.10
+New ioc/dllPath.bat file for Win32
+
+When creating an IOC with one of the win32-x86 target architectures, a file
+dllPath.bat is now generated in the iocBoot/iocxxx directory which can
+be run to adjust the PATH variable to include all of the support application
+bin directories which might contain DLLs that the IOC uses. The PATH also
+includes the IOC application's own bin directory, which simplifies starting up
+the IOC as well.
+
New epicsEndian.h header
Any C or C++ code can #include "epicsEndian.h" which defines four
diff --git a/src/makeBaseApp/Makefile b/src/makeBaseApp/Makefile
index d59418c8e..76907a97f 100644
--- a/src/makeBaseApp/Makefile
+++ b/src/makeBaseApp/Makefile
@@ -53,6 +53,7 @@ TEMPLATES += top/exampleBoot/nfsCommands@vxWorks
TEMPLATES += top/exampleBoot/nfsCommands@RTEMS
TEMPLATES += top/exampleBoot/ioc/Makefile@Common
TEMPLATES += top/exampleBoot/ioc/Makefile@vxWorks
+TEMPLATES += top/exampleBoot/ioc/Makefile@win32
TEMPLATES += top/exampleBoot/ioc/st.cmd@Common
TEMPLATES += top/exampleBoot/ioc/st.cmd@vxWorks
TEMPLATES += top/exampleBoot/ioc/st.cmd@RTEMS
@@ -81,6 +82,7 @@ TEMPLATES += top/iocBoot/nfsCommands@vxWorks
TEMPLATES += top/iocBoot/nfsCommands@RTEMS
TEMPLATES += top/iocBoot/ioc/Makefile@Common
TEMPLATES += top/iocBoot/ioc/Makefile@vxWorks
+TEMPLATES += top/iocBoot/ioc/Makefile@win32
TEMPLATES += top/iocBoot/ioc/st.cmd@Common
TEMPLATES += top/iocBoot/ioc/st.cmd@Cross
TEMPLATES += top/iocBoot/ioc/st.cmd@vxWorks
diff --git a/src/makeBaseApp/top/exampleBoot/ioc/Makefile@win32 b/src/makeBaseApp/top/exampleBoot/ioc/Makefile@win32
new file mode 100644
index 000000000..59b32d734
--- /dev/null
+++ b/src/makeBaseApp/top/exampleBoot/ioc/Makefile@win32
@@ -0,0 +1,5 @@
+TOP = ../..
+include $(TOP)/configure/CONFIG
+ARCH = _ARCH_
+TARGETS = envPaths dllPath.bat
+include $(TOP)/configure/RULES.ioc
diff --git a/src/makeBaseApp/top/iocBoot/ioc/Makefile@win32 b/src/makeBaseApp/top/iocBoot/ioc/Makefile@win32
new file mode 100644
index 000000000..59b32d734
--- /dev/null
+++ b/src/makeBaseApp/top/iocBoot/ioc/Makefile@win32
@@ -0,0 +1,5 @@
+TOP = ../..
+include $(TOP)/configure/CONFIG
+ARCH = _ARCH_
+TARGETS = envPaths dllPath.bat
+include $(TOP)/configure/RULES.ioc
diff --git a/src/tools/convertRelease.pl@ b/src/tools/convertRelease.pl@
index 4d672c8f6..eb18104b0 100755
--- a/src/tools/convertRelease.pl@
+++ b/src/tools/convertRelease.pl@
@@ -33,14 +33,14 @@ my $cwd = UnixPath(cwd());
if ($opt_a) {
$arch = $opt_a;
-} else { # Look for O. in current path
+} else { # Look for O. in current path
$cwd =~ m{ / O. ([\w-]+) $}x;
$arch = $1;
}
if ($opt_T) {
$top = $opt_T;
-} else { # Find $top from current path
+} else { # Find $top from current path
# This approach only works inside iocBoot/* and configure/*
$top = $cwd;
$top =~ s{ / iocBoot .* $}{}x;
@@ -52,8 +52,8 @@ if ($opt_t) {
$iocroot = $opt_t;
$root = $top;
while (substr($iocroot, -1, 1) eq substr($root, -1, 1)) {
- chop $iocroot;
- chop $root;
+ chop $iocroot;
+ chop $root;
}
}
@@ -63,7 +63,7 @@ my $outfile = $ARGV[0];
# TOP refers to this application
my %macros = (TOP => LocalPath($top));
-my @apps = ('TOP'); # Records the order of definitions in RELEASE file
+my @apps = ('TOP'); # Records the order of definitions in RELEASE file
# Read the RELEASE file(s)
my $relfile = "$top/configure/RELEASE";
@@ -74,10 +74,11 @@ expandRelease(\%macros, \@apps);
# This is a perl switch statement:
for ($outfile) {
- m/releaseTops/ and do { &releaseTops; last; };
- m/cdCommands/ and do { &cdCommands; last; };
- m/envPaths/ and do { &envPaths; last; };
- m/checkRelease/ and do { &checkRelease; last; };
+ m/releaseTops/ and do { &releaseTops; last; };
+ m/dllPath\.bat/ and do { &dllPath; last; };
+ m/cdCommands/ and do { &cdCommands; last; };
+ m/envPaths/ and do { &envPaths; last; };
+ m/checkRelease/ and do { &checkRelease; last; };
die "Output file type \'$outfile\' not supported";
}
@@ -89,6 +90,7 @@ sub HELP_MESSAGE {
Usage: convertRelease.pl [-a arch] [-T top] [-t ioctop] outfile
where outfile is one of:
releaseTops - lists the module names defined in RELEASE*s
+ dllPath.bat - path changes for cmd.exe to find WIN32 DLLs
cdCommands - generate cd path strings for vxWorks IOCs
envPaths - generate epicsEnvSet commands for other IOCs
checkRelease - checks consistency with support modules
@@ -101,12 +103,35 @@ EOF
#
sub releaseTops {
my @includes = grep !/^(TOP|TEMPLATE_TOP)$/, @apps;
- foreach my $app (@includes) {
- print "$app ";
- }
- print "\n";
+ print join(' ', @includes), "\n";
}
+#
+# Generate Path files so Windows can find our DLLs
+#
+sub dllPath {
+ unlink $outfile;
+ open(OUT, ">$outfile") or die "$! creating $outfile";
+ print OUT "\@ECHO OFF\n";
+ print OUT "PATH %PATH%;", join(';', binDirs()), "\n";
+ close OUT;
+}
+
+sub binDirs {
+ my @includes = grep !/^TEMPLATE_TOP$/, @apps;
+ my @path;
+ foreach my $app (@includes) {
+ my $path = $macros{$app} . "/bin/$arch";
+ next unless -d $path;
+ $path =~ s/^$root/$iocroot/o if ($opt_t);
+ push @path, LocalPath($path);
+ }
+ return @path;
+}
+
+#
+# Generate cdCommands file with cd path strings for vxWorks IOCs
+#
sub cdCommands {
die "Architecture not set (use -a option)" unless ($arch);
my @includes = grep !/^TEMPLATE_TOP$/, @apps;
@@ -120,22 +145,25 @@ sub cdCommands {
print OUT "startup = \"$startup\"\n";
my $ioc = $cwd;
- $ioc =~ s/^.*\///; # iocname is last component of directory name
+ $ioc =~ s/^.*\///; # iocname is last component of directory name
print OUT "putenv \"ARCH=$arch\"\n";
print OUT "putenv \"IOC=$ioc\"\n";
foreach my $app (@includes) {
- my $iocpath = my $path = $macros{$app};
- $iocpath =~ s/^$root/$iocroot/o if ($opt_t);
- my $app_lc = lc($app);
- print OUT "$app_lc = \"$iocpath\"\n" if (-d $path);
- print OUT "putenv \"$app=$iocpath\"\n" if (-d $path);
- print OUT "${app_lc}bin = \"$iocpath/bin/$arch\"\n" if (-d "$path/bin/$arch");
+ my $iocpath = my $path = $macros{$app};
+ $iocpath =~ s/^$root/$iocroot/o if ($opt_t);
+ my $app_lc = lc($app);
+ print OUT "$app_lc = \"$iocpath\"\n" if (-d $path);
+ print OUT "putenv \"$app=$iocpath\"\n" if (-d $path);
+ print OUT "${app_lc}bin = \"$iocpath/bin/$arch\"\n" if (-d "$path/bin/$arch");
}
close OUT;
}
+#
+# Generate envPaths file with epicsEnvSet commands for other IOCs
+#
sub envPaths {
die "Architecture not set (use -a option)" unless ($arch);
my @includes = grep !/^TEMPLATE_TOP$/, @apps;
@@ -144,44 +172,47 @@ sub envPaths {
open(OUT,">$outfile") or die "$! creating $outfile";
my $ioc = $cwd;
- $ioc =~ s/^.*\///; # iocname is last component of directory name
+ $ioc =~ s/^.*\///; # iocname is last component of directory name
print OUT "epicsEnvSet(\"ARCH\",\"$arch\")\n";
print OUT "epicsEnvSet(\"IOC\",\"$ioc\")\n";
foreach my $app (@includes) {
- my $iocpath = my $path = $macros{$app};
- $iocpath =~ s/^$root/$iocroot/o if ($opt_t);
- print OUT "epicsEnvSet(\"$app\",\"$iocpath\")\n" if (-d $path);
+ my $iocpath = my $path = $macros{$app};
+ $iocpath =~ s/^$root/$iocroot/o if ($opt_t);
+ print OUT "epicsEnvSet(\"$app\",\"$iocpath\")\n" if (-d $path);
}
close OUT;
}
+#
+# Check RELEASE file consistency with support modules
+#
sub checkRelease {
my $status = 0;
delete $macros{TOP};
delete $macros{TEMPLATE_TOP};
while (my ($app, $path) = each %macros) {
- my %check = (TOP => $path);
- my @order = ();
- my $relfile = "$path/configure/RELEASE";
- readReleaseFiles($relfile, \%check, \@order, $arch);
- expandRelease(\%check, \@order);
- delete $check{TOP};
-
- while (my ($parent, $ppath) = each %check) {
- if (exists $macros{$parent} &&
- abs_path($macros{$parent}) ne abs_path($ppath)) {
- print "\n" unless ($status);
- print "Definition of $parent conflicts with $app support.\n";
- print "In this application configure/RELEASE defines\n";
- print "\t$parent = $macros{$parent}\n";
- print "but $app at $path has\n";
- print "\t$parent = $ppath\n";
- $status = 1;
- }
- }
+ my %check = (TOP => $path);
+ my @order = ();
+ my $relfile = "$path/configure/RELEASE";
+ readReleaseFiles($relfile, \%check, \@order, $arch);
+ expandRelease(\%check, \@order);
+ delete $check{TOP};
+
+ while (my ($parent, $ppath) = each %check) {
+ if (exists $macros{$parent} &&
+ abs_path($macros{$parent}) ne abs_path($ppath)) {
+ print "\n" unless ($status);
+ print "Definition of $parent conflicts with $app support.\n";
+ print "In this application configure/RELEASE defines\n";
+ print "\t$parent = $macros{$parent}\n";
+ print "but $app at $path has\n";
+ print "\t$parent = $ppath\n";
+ $status = 1;
+ }
+ }
}
print "\n" if ($status);
exit $status;