Set target architecture in the IOC environment

Bug #1553304 reported by Ralph Lange
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
EPICS Base
Fix Released
Wishlist
Unassigned

Bug Description

To simplify generation and deployment of IOC applications (e.g. examples) that work for multiple target architectures, it would be helpful if the IOC binary set its target architecture into an environment variable (preferably T_A?)

In that case, startup scripts (and their include files) could contain architecture dependent parts and paths in a generic way.

Related branches

summary: - Set $(T_A) in the IOC environment
+ Set target architecture in the IOC environment
Revision history for this message
mdavidsaver (mdavidsaver) wrote :

Seems obvious when you say it. Should be straight forward exercise with expandVars.pl. I'd start by adding a libCom function which returns a the target name string (and maybe some others as well). I think an environment variable should only be set for IOCs, so some static ctor in src/ioc/.

Changed in epics-base:
status: New → Triaged
importance: Undecided → Wishlist
Revision history for this message
Andrew Johnson (anj) wrote :

This definitely belongs in libCom, but I'm not sure that we need to add a new API for C code to get the architecture name; something like this works with the existing envDefs.h API, modulo an agreement on names:
    const char *T_A = envGetConfigParamPtr(EPICS_TARGET_ARCH);
I have already written the src/libCom/env changes necessary to set the EPICS_TARGET_ARCH parameter value.

User code can override the compiled-in default value if necessary by setting the EPICS_TARGET_ARCH environment variable. The ENV_PARAM value is not made available as an environment variable by default though. The softIoc main() function or the Registration() routine in the generated *_registerRecordDeviceDriver.cpp file could set a shorter environment variable such as ARCH (suggested for backwards compatibility) using the above call instead of the IOC loading it from the iocBoot/ioc/envPaths file. The name T_A seems too short for a global ENV_PARAM name, hence my longer one.

What other variables do you think we might need?

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

> What other variables do you think we might need?

Basically everything known to the build system would be of use to some target applications (excepting rtems/vxworks). And, again excepting rtems/vxworks the cost of doing so is negligible.

1. I'd like to get the Base version number components in numeric form (as in epicsVersion.h). No sense in having to parse this out.

2. CMPLR_CLASS and OS_CLASS for the same reason as T_A (or whatever you want to call it)

3. CROSS_COMPILER_TARGET_ARCHS and everything which goes into the pkg-config files. This would be helpful to downstream apps., particularly interpreters, using different build systems. Something along the same lines as https://docs.python.org/2.7/library/sysconfig.html

Revision history for this message
Ralph Lange (ralph-lange) wrote :

4. I'd like to have the timestamp of when the binary was created.

Revision history for this message
Ralph Lange (ralph-lange) wrote :

And I would like to have generic support in base (link support? device support?) to read and write environment variables from string type records.

Revision history for this message
Ralph Lange (ralph-lange) wrote :

And world peace.

Revision history for this message
Andrew Johnson (anj) wrote :

The only difference between the possible and the impossible is that the impossible takes a little longer.

Revision history for this message
Ben Franksen (bfrk) wrote : Re: [Bug 1553304] Re: Set target architecture in the IOC environment

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Am 07.03.2016 um 17:32 schrieb Ralph Lange:
> 4. I'd like to have the timestamp of when the binary was created.

Please don't do that. Binaries should *not* contain time or user
names, nor any paths that are specific to the place where the build
took place. In short: nothing that makes it impossible to get a
reproducible build result.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)

iF4EAREIAAYFAlbrNAgACgkQ025FMW5YzJe0BwD+KC4T8P62G0DrqCW+j3j4FtFx
JnHce/Co2q7f1gICOGcA/0PAoAcGj0BwbWqBpr6Fyth8tUZPWXX/A/885PbBWr6V
=pcrr
-----END PGP SIGNATURE-----

Revision history for this message
Ralph Lange (ralph-lange) wrote :

Pah!
Ben is right.

Revision history for this message
Andrew Johnson (anj) wrote :

I am now calling epicsEnvSet("ARCH", targetArch) from the iocshRegisterCommon() routine in ioc/misc, but this is not a universal solution.

On VxWorks (and some RTEMS configurations) the startup script needs to know the architecture so it can load its .munch file from the right bin directory, and the iocshRegisterCommon() routine isn't executed until the .munch file is loaded (it's called from the C++ static constructor generated in the ioc_registerRecordDeviceDriver.cpp file). Thus for VxWorks IOCs the cdCommands file still needs to define topbin with the target-architecture included, so the iocBoot/ioc/Makefile must specify ARCH.

For Windows IOCs the user must have called/sourced the generated dllPath.bat or relPaths.sh (Cygwin) files before starting the IOC, thus the iocBoot/ioc/Makefile must have ARCH set to generate those files. We can't assume that the IOC architecture is the same as EPICS_HOST_ARCH, users may have cross-built for win32-x86-static for example.

The generated cdCommands and envPaths files no longer set ARCH though, and an iocBoot/ioc directory for a Unix-like OS can be architecture-independent. The makeBaseApp.pl script still needs the IOC architecture so it can expand the #! line which does contain _ARCH_, but the user could still run the IOC on a different architecture as long as they don't rely on the #! mechanism to find the IOC executable.

See the new branch lp:~epics-core/epics-base/ioc-arch for the current implementation.

Revision history for this message
Andrew Johnson (anj) wrote :

Do the other variables such as OS_CLASS and CMPLR_CLASS need to be available as environment variables in the IOC? I don't see the need...

Revision history for this message
Ralph Lange (ralph-lange) wrote :

Can't the IOC main binaries just set their target arch?
One compiler define for the softIOC main, and the target arch is set right from the beginning, on all host type architectures, including Windows.

Revision history for this message
Andrew Johnson (anj) wrote :

@Ralph: That's what I've done, the ARCH environment variable will be set when the C++ constructor in the ioc_registerRecordDeviceDriver.cpp file gets executed. For the Unix-like OSs that is sufficient to allow the iocBoot/ioc directory to be independent of the run-time architecture (except for the #! line in st.cmd). That is also true for Windows iff the ioc.exe was built statically, but for it to find DLLs we build the iocBoot/ioc/dllPath.bat file that sets PATH, so the build system must be told the IOC's target architecture in the Makefile.

I don't see any point in setting OS_CLASS and CMPLR_CLASS as environment variables in the IOC, but I have made those build variable values available as envParam default values like I did for the just-renamed EPICS_BUILD_TARGET_ARCH.

@Michael, can you explain more what you mean by "Base version number components in numeric form"? Are you asking for the Base version number to be provided as an environment variable for use in the IOC's st.cmd file? If not I don't see why your C code can't #include "epicsVersion.h" directly.

For saving all the build variables like Python's sysconfig or Perl's Config modules I would want to generate a different source file for libCom than envData.c so the embedded IOCs can exclude all that stuff from their link. This wouldn't actually be useful for cross-compiling though, since the host builds don't know what the variable values are for their cross-targets (you have to be building the cross-target to get those values out of GNUMake, and by then the host build has already finished). I'd want to see a more specific requirement before working on this.

Revision history for this message
Ralph Lange (ralph-lange) wrote :

OK, then I was mistaken.
I thought this was a issue of the env var not being set yet when the first lines of the st.cmd are executed. I would like them to be set from the beginning.

I've only ever used static builds on Windows, so I'm not familiar with the dllPath.bat thing at all.
Dave's use case was getting the same iocBoot to work for Windows and Linux, so I assume they set the PATH some place else, or use static builds.

Correct: the number components would be 3 14 12 and 5 for 3.14.12.5 - a possible application would be e.g. loading different db files or other st.cmd snippets for different EPICS versions.
If iocsh were able to do numerical expressions, a complete integer 03141205 would also be handy.

Andrew Johnson (anj)
Changed in epics-base:
status: Triaged → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.