Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dependency visibility should be enforced #1987

Closed
david-german-tri opened this issue Apr 1, 2016 · 15 comments
Closed

Dependency visibility should be enforced #1987

david-german-tri opened this issue Apr 1, 2016 · 15 comments

Comments

@david-german-tri
Copy link
Contributor

Absent a concept of "visibility" in the build system, we should have a test that does a rudimentary sanity check of #include statements. To at least a first approximation, if CMake visits directory A before directory B, nothing in directory A should #include a file from directory B. (If you know of cases where such a dependency should be allowed, please chime in!)

The implementation of this test doesn't need to be rock-solid. One-off static analysis in Python would be pretty useful.

@jwnimmer-tri, I know this is also of interest to you.

@jwnimmer-tri
Copy link
Collaborator

For context, #1983 was the first example of fixing physical layering defects (c.f. Lakos).

@david-german-tri
Copy link
Contributor Author

@billhoffman Is there a standard way of doing this with CMake?

@jamiesnape
Copy link
Contributor

Not exactly what you want, but with regard to headers, as a start, we have include-what-you-use running on a nightly basis.

https://drake-jenkins.csail.mit.edu/job/linux-clang-nightly-include-what-you-use/

@liangfok
Copy link
Contributor

Nice! It looks like this tool enforces the "weak #include rule" which states that the transitive closure of all #include statements in a file should cover all symbols used in the file. Is this correct?

@david-german-tri
Copy link
Contributor Author

Great to know that IWYU is running, but it seems tangential to the visibility/physical-layering issue.

@jamiesnape
Copy link
Contributor

You need to include the correct headers first.

@david-german-tri
Copy link
Contributor Author

I'm not sure what you mean. To get started, all we really need is the ordered list of directories that CMake visits. Is that a thing we can make it output?

@jwnimmer-tri
Copy link
Collaborator

As a clarification, by way of example, here are three specific defects that we'd like to find with this kind of enforcement:

  • drake/drake/core/test/vector_test.cc should not be allowed to use drake/drake/util/testUtil.h (util can depend on core, but not the other way around)
  • drake/drake/util/yaml/yamlUtil.h should not be allowed to use drake/drake/systems/plants/RigidBodyTree.h (systems can depend on util, but not the other way around)
  • drake/drake/solvers/qpSpline/splineGeneration.h should not be allowed to use drake/drake/systems/trajectories/PiecewisePolynomial.h (systems can depend on solvers, but not the other way around)

@david-german-tri
Copy link
Contributor Author

Let's make some time to talk about this one when Kitware visits TRI next week.

@david-german-tri
Copy link
Contributor Author

From f2f discussion with @bradking and @jwnimmer-tri:

Part 1: Determining the physical ordering automatically. We can replace add_subdirectory with a drake_add_subdirectory macro, which will append to a global property with set_property(GLOBAL.... At the end of CMake execution, the contents of that property are the physical ordering that we want to enforce.

Alternative considered: Develop a separate notation for dependency declaration. Do a topological sort and cycle check on that notation in both CMake and our enforcement script. This may become a first-class feature in an upcoming version of CMake, in which case we can switch to it then.

Part 2: Enforcing the physical ordering. We can write the ordering to a file, and then run a Python script ctest that parses the #includes from every C++ source file and checks them against the physical ordering.

Alternative considered: Get the compiler to dump the #includes. This is more principled on the platforms that support it, but not portable and more work.

Alternative considered: Restructure the Drake tree so that the compiler can enforce physical ordering by only including a -I for permissible subtrees.

Alternative considered: Restructure the Drake libraries so that CMake can enforce physical encoding. This would require making all dependencies (even header-only ones) artificial link dependencies, using a Schwarz counter or similar.

@jwnimmer-tri
Copy link
Collaborator

I suggest WONTFIXing this, in lieu of #3129.

@jamiesnape
Copy link
Contributor

I would suggest it anyway. This is not a CMake issue per se.

@jwnimmer-tri
Copy link
Collaborator

Right, its not a CMake-specific issue.

However, my premise is that #3129 does not let us even write code that violates dependency layering, so creating a separate tool to enforce it would only be useful if #3129 was too long to wait for, and I don't think it is.

@jamiesnape
Copy link
Contributor

I think you are confusing dealing with legacy code with the build system.

@david-german-tri
Copy link
Contributor Author

Agree with @jwnimmer-tri, closing as wontfix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants