Skip to content

extedended main SConscript to support building executables of C++ cod…#375

Merged
iagaponenko merged 5 commits intomasterfrom
tickets/DM-13574
Feb 16, 2018
Merged

extedended main SConscript to support building executables of C++ cod…#375
iagaponenko merged 5 commits intomasterfrom
tickets/DM-13574

Conversation

@iagaponenko
Copy link
Contributor

e, added a demo application which tests if versions of the Gpoogle Protobuf headers and libraries match

…e, added a demo application which tests if versions of the Gpoogle Protobuf headers and libraries match
Copy link
Contributor

@andy-slac andy-slac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not what I expected 😑 Let me think about how to do it right, I'll probably make another commit on your branch tomorrow.

standardModule(env, exclude=exclude, unit_tests="")

Return('module_build_targets')
s
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops! I'll fix this.


standardModule(env, exclude=exclude, unit_tests="")

Return('module_build_targets')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use Return, everything is passed via env

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that a module's SConscript is a function which returns a value of a locally defined (within the called module) variable which is inspected by the main SConscript. That (returned) list is used on each iteration of the main SConscript's look over modules. Are you suggesting I should inject that variable into the global 'env'?

"protobuf",
"log",
"log4cxx"])
exclude.append(f)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should try to make this generic and move to standardModule()

Copy link
Contributor Author

@iagaponenko iagaponenko Feb 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hence, the idea is to add an optional parameter to "standardModule" to allow passing a list of module's binary products (along with their dependencies), someting like:
standardModule(binaries=[
{"tests_app.cc": ["qserv_common","util","log4cxx"]},
{"tests_somethingelse.cc":[...]),,,],

# SConscript. Also add the source file into a list of sources to be excluded
# from the shared library product.

env.Append(LIBPATH=['$build_dir'] + env['LIBPATH'])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That changes global environment which you don't want to do.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I then pass this as a parameter to the Program target when doing?
env.Program(...LIBPATH=['$build_dir'] + env['LIBPATH']...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I've deleted a line of code which modified LIBPATH in the global environment and passed it to each env.Program() invocation as a parameter. And this works.

…late code into function standardModule. This should simplify module-level SConscript file, and it will also make them more robust
@iagaponenko
Copy link
Contributor Author

iagaponenko commented Feb 16, 2018

@andy-slac okay, I've made an improved version of the build system as per your suggestion. NOw it should be trivial to add C++ binaries from the module's SConscriot files - just a dictionary of C++ file names (keys) and list of the corresponding libraries for dependencies It's also more robust compared with the prior version. Have a look at SConscript file of module "tests" as an example. Could you have a look at it please? Thanks!

Copy link
Contributor

@andy-slac andy-slac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks mostly OK, see comments below.

then use this parameter to pass list (or space-separated
string) of application names. Can be empty string or list to
not run any unit tests.
@param bin_cc_targets: a dictionary defining whgich binary products (not
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whgich -> which
Not shure targets has a meaning here. The key in dict is a name of the source, not target?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll come up with a better name

# library or unit tests
exclude_cc_files = []
if exclude is not None:
exclude_cc_files = exclude
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exclude_cc_files += exclude, otherwise you are potentially modifying exclude too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. My Python is rusty :-)

if exclude is not None:
exclude_cc_files = exclude
if bin_cc_targets is not None:
for f in bin_cc_targets: exclude_cc_files.append(f)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exclude_cc_files += bin_cc_targets.keys()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed

string) of application names. Can be empty string or list to
not run any unit tests.
@param bin_cc_targets: a dictionary defining whgich binary products (not
the unit tests should be built out of C/C++ files. Each key
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opening parenthesis on previous line is not closed, I guess it should go after "tests".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

# inject binary targets built of the optionally provided C/C++ files
if bin_cc_targets is not None:
for f,dependencies in bin_cc_targets.items():
source = os.path.basename(str(f))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need basename for source?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. No need. I will eliminate it.

target=target,
source=[source],
LIBS=dependencies,
LIBPATH=['$build_dir'] + env['LIBPATH'])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks a bit complicated, I'd think this should work:

for f, dependencies in bin_cc_targets.items():
    p = env.Program(f, LIBS=dependencies, LIBPATH=['$build_dir'] + env['LIBPATH'])

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will give it a try, and if it works then I'll make mods to the code.

bin_cc_targets = {}
path = "."
for f in env.Glob(os.path.join(path, "tests_*.cc"), source=True, strings=True):
bin_cc_targets[f] = ["qserv_common","util","protobuf","log","log4cxx"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't overdo it. Normally all "test*.cc" files are (unit) tests and we don't want their binaries installed so don't try to make all test_*.cc into true binaries. I'd probably give it different name, not starting with "test".

I believe you can also write:

bin_cc_targets[f] = "qserv_common util protobuf log log4cxx"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we should come up with some naming convention for the binaries. Something like: qserv--.cc. For instance my only app module tests should be renamed from "tests_protobuf_version.cc" into "qserv-tests-protobuf.cc". And I agree about avoiding using "test*" in apps names". I just wanted to see if my implementation of standardModule would work. And thanks for the advice to replace a list of dependencies with a string. I'll give it a try.

@iagaponenko
Copy link
Contributor Author

@andy-slac thank you for reviewing the code and making good suggestions! I've just committed a few more modification to the code as per your suggestions.

@iagaponenko iagaponenko merged commit df45244 into master Feb 16, 2018
@ktlim ktlim deleted the tickets/DM-13574 branch August 23, 2018 00:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants