cmake icon indicating copy to clipboard operation
cmake copied to clipboard

Added the tests from cmake-d project

Open dcarp opened this issue 10 years ago • 7 comments

There are still two omissions:

  • test Tests/DOnly/app_5 actually should detected automatically the a.d dependency, but I could not found such a functionality in the current implementation.
  • test Tests/UseD/app_1 is commented out. I cannot figure it out how to use add_d_unittests.

dcarp avatar Aug 07 '14 00:08 dcarp

  • test Tests/DOnly/app_5 actually should detected automatically the a.d dependency, but I could not found such a functionality in the current implementation.

If I understand correctly, you want to be able to do

add_executable(app_5 app_5.d)

and have it automatically add a.d to app_5's sources, right? A while ago, I had a function that could do that sort of thing in UseD.cmake, but it was slow and a potential source of bugs. I am open to re-adding such a functionality, but you'll have to convince @mathstuf (and eventually the rest of Kitware). One of the reasons it was removed was to get the D support more in line with CMake's C/C++/Fortran support, none of which have such a feature.

  • test Tests/UseD/app_1 is commented out. I cannot figure it out how to use add_d_unittests

I'll need to improve its documentation (or perhaps implementation?), then. It should work if you drop the SOURCES parameter, which is there to allow you to add unittest-only sources that weren't in the non-unittest target.

A couple of other notes:

  • Don't use file(GLOB) to name sources. This may actually be the source of the problem in using add_d_unittests
  • Some of these (DOnly/app_4 sticks out) seem to be testing the D (compiler / standard library / runtime) rather than CMake functionality. Is this something we want? Granted, there is value in making sure my lexer/parser actually work, and I'm working on some tests to that end, but the named test seems to just test if fibers and threads work. This could be useful to make sure pthreads (or equivalent) is linked when needed, but the D compiler handles that on its own.

Only other thing I'm seeing right now is that the names could stand improvement, but I need to rename some tests and improve my changes to Tests/CMakeLists.txt anyway, so I can rename things to be more descriptive when I do that.

trentforkert avatar Aug 07 '14 02:08 trentforkert

On Wed, Aug 06, 2014 at 19:33:44 -0700, trentforkert wrote:

  • test Tests/DOnly/app_5 actually should detected automatically the a.d dependency, but I could not found such a functionality in the current implementation.

If I understand correctly, you want to be able to do

add_executable(app_5 app_5.d)

and have it automatically add a.d to app_5's sources, right? A while ago, I had a function that could do that sort of thing in UseD.cmake, but it was slow and a potential source of bugs. I am open to re-adding such a functionality, but you'll have to convince @mathstuf (and eventually the rest of Kitware). One of the reasons it was removed was to get the D support more in line with CMake's C/C++/Fortran support, none of which have such a feature.

The problem with such a thing is that now running CMake depends on every source file which will only make your build that much slower. I've never seen a project where files came and went so often that manual (or using something like Vim's ":r!ls *.cxx") is such a burden that a feature like this is wanted (such features feel like very strong YAGNI to me). Counterexamples welcome.

  • test Tests/UseD/app_1 is commented out. I cannot figure it out how to use add_d_unittests

I'll need to improve its documentation (or perhaps implementation?), then. It should work if you drop the SOURCES parameter, which is there to allow you to add unittest-only sources that weren't in the non-unittest target.

A couple of other notes:

  • Don't use file(GLOB) to name sources. This may actually be the source of the problem in using add_d_unittests

Globbing is worse than detecting files during configure time because at least the latter can add the required "rerun CMake" dependency rules whereas globbing depends on "this directory changing" which is not expressible in any build system I know of (other than Tup, but Tup is already a completely different beast).

  • Some of these (DOnly/app_4 sticks out) seem to be testing the D (compiler / standard library / runtime) rather than CMake functionality. Is this something we want? Granted, there is value in making sure my lexer/parser actually work, and I'm working on some tests to that end, but the named test seems to just test if fibers and threads work. This could be useful to make sure pthreads (or equivalent) is linked when needed, but the D compiler handles that on its own.

Testing that the compiler works is good (it checks that flags are valid, that the linker is invoked correctly, etc.). It'd be nice if we could run the test for multiple D compilers in one test run, but that may require some more infrastructure.

mathstuf avatar Aug 07 '14 02:08 mathstuf

The problem with such a thing is that now running CMake depends on every source file which will only make your build that much slower. I've never seen a project where files came and went so often that manual (or using something like Vim's ":r!ls *.cxx") is such a burden that a feature like this is wanted (such features feel like very strong YAGNI to me). Counterexamples welcome.

Actually this is quite used, rdmd --build-only does exactly this. You know the reference D compiler is quite fast.

I wanted to suggest to @trentforkert that it will be very very useful to have an option, where you specify to the compiler all .d files at once. In my company we use it by default. It allows the compiler to read less files from the disc (imports loaded once) and produces much less output for linker, the linker being anyway the slowest step in the build process. We have projects where a clean build runs 2-3 times faster this way. We speak about 15 seconds instead of 50.

Globbing is worse than detecting files during configure time because at least the latter can add the required "rerun CMake" dependency rules whereas globbing depends on "this directory changing" which is not expressible in any build system I know of (other than Tup, but Tup is already a completely different beast).

I will rework this test.

dcarp avatar Aug 08 '14 13:08 dcarp

The problem with build-it-all-at-once builds is that incremental builds are slower (since changing one line forces building all files again). I suppose D doesn't have it quite as good without an API/implementation file split like C/C++ does, but then again, that's pretty much the only such place that happens. One shot builds, IME, mainly care about the order of magnitude for build times rather than absolutes. Development builds care more about build times given a set of changed files. What is dmd's performance there (preferably for large and small sets of files, but I guess interconnectedness matter a lot more there)?

mathstuf avatar Aug 09 '14 01:08 mathstuf

The problem with build-it-all-at-once builds is that incremental builds are slower (since changing one line forces building all files again). I suppose D doesn't have it quite as good without an API/implementation file split like C/C++ does, but then again, that's pretty much the only such place that happens.

Actually D is designed to compiled code very fast [1]. The compiler reads the sources in one step (it has no trigraphs or macros). The heavy templated code is slower, but the templated C++ code also have no API/implementation split.

[1] http://www.drdobbs.com/cpp/increasing-compiler-speed-by-over-75/240158941

One shot builds, IME, mainly care about the order of magnitude for build times rather than absolutes. Development builds care more about build times given a set of changed files. What is dmd's performance there (preferably for large and small sets of files, but I guess interconnectedness matter a lot more there)?

By providing the absolutes I wanted to show that compiling all-at-once can bring build times of a project, ca. 100k LOC in my case, to an acceptable range to be used even as development build. Another example Phobos, the D standard library, compiles in 6 seconds using dmd with build all-at-once. I need to mention that, gdc and ldc2 are sensible slower. Btw. AFAIK go uses the same procedure.

Of course, the incremental build is necessary and can be active by default. Build all-at-once would be ideally activated with a cached variable. CMake makes it very easy for the user to manage such an option.

dcarp avatar Aug 09 '14 21:08 dcarp

Of course, the incremental build is necessary and can be active by default. Build all-at-once would be ideally activated with a cached variable. CMake makes it very easy for the user to manage such an option.

AFAIK, some build systems (e.g., Ninja) can't/won't do non-incremental builds. If a user asks for Ninja+AllAtOnce, should we just lie to the user, give a warning, or what? Not to mention, such a flag would need to apply to C, C++, and Fortran as well, probably with the addition of language-specific overrides for those flags (and documentation and tests).

I'd also be curious if you've done tests of incremental multi-threaded compilation vs all-at-once single-threaded. I just set up a quick test with LDC and Phobos, and it took ~25secs on my machine to do all-at-once compilation. Compare that to ~16secs when using 4 cores and incremental compilation.

trentforkert avatar Aug 09 '14 23:08 trentforkert

On Sat, Aug 09, 2014 at 14:17:09 -0700, Dragos Carp wrote:

Actually D is designed to compiled code very fast [1]. The compiler reads the sources in one step (it has no trigraphs or macros).

That's great if it's fast, but I really doubt it's faster than 8 parallel single-source compilations going at the same time. The D compiler is not threaded AFAIK (GDC and LDC certainly aren't).

The heavy templated code is slower, but the templated C++ code also have no API/implementation split.

This can be avoided by putting the template implementation code in .txx files and shipping them. Instantiations include the txx file while everything else gets just the .h like everything else.

[1] http://www.drdobbs.com/cpp/increasing-compiler-speed-by-over-75/240158941

Site seems to be broken; I get an infinite redirect here.

By providing the absolutes I wanted to show that compiling all-at-once can bring build times of a project, ca. 100k LOC in my case, to an acceptable range to be used even as development build.

Are you running the build in parallel? -j1 will certainly be slower with .d -> .o transformations versus *.d -> .so transformations.

Another example Phobos, the D standard library, compiles in 6 seconds using dmd with build all-at-once. I need to mention that, gdc and ldc2 are sensible slower.

And what happens with a single touch foo.d for build times?

Of course, the incremental build is necessary and can be active by default. Build all-at-once would be ideally activated with a cached variable. CMake makes it very easy for the user to manage such an option.

The problem is that if there are any source file-specific options (version, includes, whatever), then what do we do? Refuse to accept the variable set to ON?

mathstuf avatar Aug 10 '14 00:08 mathstuf