1

Today I am facing a strange SCons behaviour.

My problem is the following (in case there is a better workaround, I am pretty new to SCons) : My SCons script is building .cu cuda files and .cpp c++ files. For the c++ files, I need the -std=c++0x flag since we are doing c++11 but nvcc doesn't really like that flag.

So what I need to do is adding temporary the flag while I am compiling C++ files, and removing it while I am compiling cuda files.

I tried something like this :

    def defaultLibConstructObjs(self,targetName,env,avoided=[]):
      constructedObjects=[]
      oldcppflags=env["CPPFLAGS"]
      print(env["CPPFLAGS"])
      for ext in ["cu","c","cpp"]:
         if ext == "cu":
              prefix = ext
          else:
              prefix = ""
          if ext == "cpp":
              env["CPPFLAGS"]+=env["CPPONLYFLAGS"]
        constructedObjects.append(self.constructObjs(targetName,env,ext,prefix,avoided))
        env["CPPFLAGS"]=oldcppflags
      return constructedObjects

So I would expect env["CPPFLAGS"] to be unchanged at each loop turn, but instead of this every time my cpponlyflags (-std=c++0x in this case) is appended so I end up with a list with number of times I call defaultLibConstructObjs -std=c++0x.

wRAR
  • 25,009
  • 4
  • 84
  • 97
MisterJ
  • 919
  • 1
  • 9
  • 24

1 Answers1

2

This looks a bit as if you're not only new to SCons, but to Python as well. ;) With

oldcppflags=env["CPPFLAGS"]

you're storing a "reference" to the environment in your variable, but don't create a full copy of its contents. That's why your environment gets changed anyway...

About your actual problem: the more SConsish way would be to setup two environments in your top-level SConstruct:

cuda_env = Environment(...) # default, without the offending flags
std_env = cuda_env.Clone()  # create a copy
std_env.Append(CPPFLAGS=['-std=c++0x'])

Then you can pass these down to your subfolder SConscripts (see Export/Import methods) and there use

cuda_env.Program('foo', Glob('*.cu'))

or,

std_env.Library('bar', Glob('*.cpp'))

just as you need it. Note, how you can freely mix which files get created by which environment, even within the same SConscript! There are no folder-wise boundaries imposed on your build environments, as with the autotools for example. Good luck with your project, and if you have further question you might consider to come over to the SCons user mailing list at scons-users@scons.org .

dirkbaechle
  • 3,984
  • 14
  • 17
  • Hi, You guessed right, I have not that much experience in python. My bad. If some is looking at this topic with my original problem (cf reference VS copy, here is an useful link : http://stackoverflow.com/questions/2612802/how-to-clone-or-copy-a-list-in-python) Many thanks to you. – MisterJ Sep 22 '14 at 07:18
  • Edit : none of the solution mentionned in the link I added are working. Is that related to SCons? – MisterJ Sep 22 '14 at 07:26
  • And even by having a step after the object building with : `if(ext == cpp): env["CPPFLAGS"]=env["CPPFLAGS"][:-1]` On my debug output when I should build cpp files, I see the std=c++0x flags, but at real building time, it has dissapeared.... So I guess your multi env solutions is the only viable – MisterJ Sep 22 '14 at 07:38
  • Regard, that the SConstructs are declarative...which means that a env.Program(...) doesn't build the application right away. It only schedules the Program builder for the actual build phase. And for the build phase, the last status of your environment (variables) counts. If the last command in the last SConscript that gets parsed is env['CPPFLAGS'] = '', you won't see any flags during the build...independent of what you configured before. – dirkbaechle Sep 22 '14 at 16:55
  • Ok, that's what I thought, so the multiple env structures is mandatory. Btw it is still strange than even doing what I mentionned above the c++11 flag is added multiple times. Thank you very much! – MisterJ Sep 23 '14 at 07:13