CPPDEFINES not evaluating value
Related: https://stackoverflow.com/questions/58985097/scons-dynamic-construction-variable/58999495#58999495
Required information
- Link to SCons Users thread discussing your issue. n/a. Discussed on Discord and was told I could post here
- Version of SCons 3.1.1
- Version of Python 3.7.3
- Which python distribution if applicable (python.org, cygwin, anaconda, macports, brew,etc) brew, pyenv
- How you installed SCons brew
- What Platform are you on? (Linux/Windows and which version) macOS
- How to reproduce your issue? Please include a small self contained reproducer. Likely a SConstruct should do for most issues.
Example project: Simply main.c that just prints Hello World and a SConstruct file below
Issue
env = Environment()
env.Append(CPPDEFINES='THETARGET=${TARGET}')
env.Append(CPPDEFINES='SOURCEHASH=${SOURCE.get_csig()}')
env.Program('main', ['main.c'])
Issue output
$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
gcc -o main.o -c -DTHETARGET= -DSOURCEHASH= main.c
gcc -o main main.o
scons: done building targets.
As you can see $TARGET and $SOUREC.get_csig() aren't returning the correct value.
The workaround @bdbaddog proposed is below:
Solution
env = Environment()
env.Append(CPPFLAGS=['-DTHETARGET=${TARGET}'])
env.Append(CPPFLAGS=['-DSOURCEHASH=${SOURCE.get_csig()}'])
env.Program('main', ['main.c'])
Solution output
$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
gcc -o main.o -c -DTHETARGET=main.o -DSOURCEHASH=97eb88ec8573ff4b8a242a5e619fef72 main.c
gcc -o main main.o
scons: done building targets.
I presume it's just a transcription/paste problem, but the lines in your "issue" chunk are wrong, since CPPDEFINES builds the right syntax for the compilation environment in question, you can't include the '-D' part (your SO post didn't have it this way which is why the transcription problem is the guess)
@mwichmann You presumed correctly. Updated the report.
@bdbaddog does CPPDEFINES get substituted in the right context to interpolate TARGETS/SOURCES?
It should be also. I think this should really be:
env.Append(CPPDEFINES=('SOURCEHASH','${SOURCE.get_csig()}'))
That doesn't help, in fact makes it odder looking:
gcc -o main.o -c "-D('THETARGET', '', 'SOURCEHASH', '')" main.c
This latter form may be falling into the special-case handling Append has for CPPDEFINES only.
This is what I'm using internally with fileHashGenerator being the function to generate my custom hashes.
self["FILE_HASH"] = "${fileHashGenerator(__env__,TARGET,SOURCE)}"
self.Append(CPPFLAGS=["-DFILE_HASH=$FILE_HASH"])
self["fileHashGenerator"] = fileHashGenerator
~~For linkage purposes - this is similar to #3790. _concat_ixes which is used here pays no attention to source and target args, unlike, say _concat:~~
def _concat(prefix, list, suffix, env, f=lambda x: x, target=None, source=None):
def _concat_ixes(prefix, list, suffix, env):
def _defines(prefix, defs, suffix, env, c=_concat_ixes):
return c(prefix, env.subst_path(processDefines(defs)), suffix, env)
EDIT: misread: the above doesn't matter. Substitution happens before _concat_ixes is called during the expansion of CPPDEFINES. Basically, this is how CPPDEFINES is expanded:
concat_ixes(prefix, env.subst_list(processDefines(defs), target=target, source=source), suffix, env)
Adding this to 4.2 milestone for now - we should be able to implement whatever the decision is fairly easily, but do need a decision.
So now that this seems to work, can we close?
Here's the build output now: ``` [issue3477]$ scons -n scons: Reading SConscript files ... scons: done reading SConscript files. scons: Building targets ... gcc -o main.o -c -DTHETARGET=main.o -DSOURCEHASH=d41d8cd98f00b204e9800998ecf8427e main.c gcc -o main main.o scons: done building targets.
Closing as fixed.