-1

I use scons to build a large project and finally found a line in the SConstruct file that caused a compilation error that I posted here previously: sstream redeclared with public access compiler error

Here is the line in the SConctruct file:

jailbreak_env = env.Clone(CPPDEFINES=[('protected','public'),('private','public')])

If you look at the link for the error message that complains redefining access specifiers in the sstream library, that error no longer comes up when I edited the SConstruct line like so:

jailbreak_env = env.Clone(CPPDEFINES=[])

However I cannot figure out how exactly this fix worked, or even how is it possible to change access specifiers in c++? I spent some time researching around SCons and I learned that Clone() simply creates a new "jailbreak version" of the program but by drastically changing the c++ compiler environment using the CPP_DEFINES variable. But the scons documentation (http://www.scons.org/doc/0.96.90/HTML/scons-user/a3061.html) for CPP_DEFINES does not mention being used to change access specifiers as shown above?

Any ideas or pointers for where I should look for an explanation are welcome.

miro_x
  • 201
  • 3
  • 8
  • Doing so is an incredibly bad idea! – user0042 Dec 19 '17 at 18:32
  • Doing what is a bad idea? Doing the edit I did or the first line of code? Can you tell me why or what exactly is the effect of such a change? I should point out that I am not the one who wrote this SCons file or the main project, I am just trying to get it to compile and the above is the fix that made it work for me. – miro_x Dec 19 '17 at 18:33
  • _"Doing what is a bad idea?"_ Redefining `private` and `protected` as `public` using a macro definition. Why do you really need that? – user0042 Dec 19 '17 at 18:34
  • As I mention in my question that is what I'm trying to figure out. I never even realized that this was ever possible in c++. I'm surprised that older compilers allow you to get away with such a thing. I think it is needed because the C++ project is designed in such a way so that many functions can be reused in python and python "apparently" needs everything set as public? Although this may be completely wrong... – miro_x Dec 19 '17 at 18:35
  • @miro_x Not only is it completely wrong. But compiling it one way to build the object files then changing it to another for python may result in slightly different ABI and thus break the integration layer between the languages. – Martin York Dec 19 '17 at 20:02
  • This is clearly completely beyond me. I've not even come across the term ABI before, just reading up about it now. So I take it that the edit I made is for the better? Since I no longer redefine the C++ access specifiers during compilation? Can someone tell me how scons even accomplishes such a thing? The CPP_DEFINES variable has nothing like that mentioned in the scons documentation. – miro_x Dec 19 '17 at 20:57
  • 1
    @miro_x I'd suggest you go do some reading about how the preprocessor works. In simple terms -Dsomething=somethingelse will change every occurrence of something in any text file to somethingelse. You can try this on the command line if you want to experiment. SCons is not changing the access specifiers, it is just building the command line for the compiler. In this case because of the requested CPPDEFINES it has the effect listed in the above reply from user0042. – bdbaddog Dec 21 '17 at 20:48
  • I am not sure for the negative feedback on my question, but thank you for the answers. It is slightly clearer now. – miro_x Dec 26 '17 at 21:10

1 Answers1

1

The link into SCons' documentation that you mention above, does explicitly state (search for the CPPDEFINE keyword):

If $CPPDEFINES is a list, the values of the $CPPDEFPREFIX and $CPPDEFSUFFIX construction variables will be appended to the beginning and end of each element in the list. If any element is a list or tuple, then the first item is the name being defined and the second item is its value.

Your tuple

('protected','public')

will simply be passed to the preprocessor/compiler as

-Dprotected=public

, which will work with any strings given. There is nothing special for access specifiers about this and you should actually see the defines as given to your compiler in the output of your build (unless you have redefined the standard output for SCons' build steps).

You can create the following two simple files

SConstruct
==========

env = Environment(CPPDEFINES=[('foo','bar')])
env.Program('main', 'main.cxx')

main.cxx
========

int main(void)
{
  return 0;
}

and when calling "scons" on them, you get the expected output (under Linux):

scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o main.o -c -Dfoo=bar main.cxx
g++ -o main main.o
scons: done building targets.
dirkbaechle
  • 3,984
  • 14
  • 17
  • So Dprotected=public, essentially changes all text in the source files from protected to public? OK in that case it seems this is allowed only up to c++11 judging from my experience. – miro_x Dec 26 '17 at 21:12