2af18704fd Merge branch 'backport-3.16-link-libs-config-case'
3f976bf201 target_link_libraries: Fix regression in case of $<CONFIG> genex
5a95b5e091 target_link_libraries: Fix regression in case of $<CONFIG> genex
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !4544
This script was added by commit 0f150b69d3 (AIX: Explicitly compute
shared object exports for both XL and GNU, 2019-07-11,
v3.16.0-rc1~418^2~2) but does not have a `.sh` extension so our existing
install rules neglect to give it execute permission. Our test suite
works on AIX in the build tree but the script is broken without execute
permission on installation.
Fixes: #20520
Since commit b8626261e9 (Precompile headers: Add methods to generate PCH
sources, 2019-07-13, v3.16.0-rc1~182^2~4) we look up source files for a
target using an upper-case configuration even though an original-case
name is sufficient. Since commit 36ded610af (PCH: Generate sources
during Compute step, 2019-10-05, v3.16.0-rc1~2^2) the source file lookup
is the first time we compute many on-demand structures that depend on
the configuration name. This caused the `$<CONFIG>` generator
expression to evaluate to the upper-case configuration name in some
cases where we used original-case before.
Fix this by switching the source file lookup to the original-case config
name. Add a test covering the symptom that led to the discovery of this
problem.
Fixes: #20517
Since commit b8626261e9 (Precompile headers: Add methods to generate PCH
sources, 2019-07-13, v3.16.0-rc1~182^2~4) we look up source files for a
target using an upper-case configuration even though an original-case
name is sufficient. Since commit 36ded610af (PCH: Generate sources
during Compute step, 2019-10-05, v3.16.0-rc1~2^2) the source file lookup
is the first time we compute many on-demand structures that depend on
the configuration name. This caused the `$<CONFIG>` generator
expression to evaluate to the upper-case configuration name in some
cases where we used original-case before.
Fix this by switching the source file lookup to the original-case config
name. Add a test covering the symptom that led to the discovery of this
problem.
Fixes: #20517
PRE_TEST makes it possible to properly distinguish between test cases
that exist only in certain configurations.
In the new test scenario, debug tests are disabled in release builds,
and release tests are disabled in debug builds
when a multi config generator is used.
Note, this is a bit of a hack and *only* works for PRE_TEST mode.
POST_BUILD makes no attempt to get this right. It preserves the status quo
and you obtain the tests that were last discovered.
See further discussion in !4078
Ideally, the POST_BUILD behavior could be fixed
by using generator expressions in OUTPUT and BYPRODUCT expressions.
Then you could do something like:
set(ctest_include_file "${ctest_file_base}_include-$<CONFIG>.cmake")
set(ctest_tests_file "${ctest_file_base}_tests-$<CONFIG>.cmake")
Once #12877 lands, maybe this can be revisited.
Co-authored-by: Ryan Thornton <ThorntonRyan@JohnDeere.com>
Co-authored-by: Kevin Puetz <PuetzKevinA@JohnDeere.com>
Now, the unit tests are ran twice -- once with POST_BUILD (i.e. default mode)
and again with PRE_TEST (i.e. new discovery mode).
Both modes of setting gtest discovery mode are also tested:
1. Using the global override (i.e. CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE)
2. Explicitly passing DISCOVERY_MODE in calls to gtest_discover_tests (in GoogleTestDiscoveryTimeout.cmake)
The goal is to show that the new PRE_TEST discovery mode does not break existing behavior
(i.e. should not break POST_BUILD mode) and should also pass the same tests
in the same way.
A few non trivial implementation details worth noting:
1. Refactoring discovery_timeout_test into own project
Originally, I tried doing:
```
run_GoogleTest(POST_BUILD)
run_GoogleTest(PRE_TEST)
```
Without changing the internal structure of run_GoogleTest.
But since discovery_timeout_test is part of the same project as the other tests,
and CTest include files always get evaluated and that's where test discovery occurs,
this means every other test now notices the timeout problem when running in PRE_TEST mode.
As a result, keeping the existing test structure meant that each existing test
(and any new test) would need to have its own PRE_TEST / POST_BUILD variant for stderr and stdout
in order to handle the case where discovery_timeout_test timed out.
This exponential increase in test output files introduced unnecessary complexity
and made it more cumbersome to work on test cases.
Why should an unrelated test case care about discovery_timeout_test?
So, to fix that issue, the tests were broken apart into two main groups:
1. run_GoogleTest_discovery_timeout (the test dealing with discovery_timeout_test)
2. run_GoogleTest (everything else)
This isolates the PRE_TEST / POST_BUILD timeout variants to a single test case.
And the other test cases remain unchanged -- further driving home the point that
DISCOVERY_MODE shouldn't change existing behavior.
2. Different number of PRE_TEST / POST_BUILD file variants
On the PRE_TEST path, different build systems / compilers (i.e. MSBuild and ninja/gcc)
produces different build output when building discovery_timeout_test,
but we don't actually care what it is, just as long as it builds
successfully.
This the fundamental difference in behavior between POST_BUILD (which would have failed)
and PRE_TEST (which doesn't) and is the reason why we don't need
a GoogleTest-discovery-build-result.txt or GoogleTest-discovery-build-stdout.txt
3. Fix flaky discovery timeout test
The test expects to see:
> Output:
> timeout
> case.
But sometimes, the test would only produce:
> Output:
> timout
In certain environments, specifically when built with OpenWatcom 1.4,
and while the build server was under heavy load (i.e. running many tests in parallel),
std::endl behaves inconsistently and doesn't completely
flush std::cout when the program is terminated due to timeout.
This results in inconsistent test failures because the actual output
doesn't fully match what's expected.
At first we tried adding an additional:
std::cout << std::flush
That didn't work. But using C-style printf() and fflush() appears to do
the trick:
> This time I managed to get on the machine while it was still busy doing other nightly builds
> and could reproduce the problem reliably. With that I was finally able to find a fix.
> It turns out my earlier hypothesis that C++ stream flushing was not working on the old compiler was correct,
> but even .flush() is not enough.
> I changed it to use C-style printf() and fflush() and now the test passes on that build.
> -- Brad King <brad.king@kitware.com>
Co-authored-by: Ryan Thornton <ThorntonRyan@JohnDeere.com>
Co-authored-by: Kevin Puetz <PuetzKevinA@JohnDeere.com>