xref: /aosp_15_r20/external/pigweed/pw_unit_test/public/pw_unit_test/static_library_support.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2022 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 #pragma once
15 
16 #include "pw_unit_test/framework.h"
17 
18 /// Ensures tests in a static library are linked and executed. Provide the test
19 /// suite name and test name for one test in the file linked into a static
20 /// library. Any test in the file may be used, but it's recommended to use the
21 /// first for consistency. The test must be in a static library that's a
22 /// dependency of this target. Referring to a test that does not exist causes a
23 /// linker error.
24 ///
25 /// The linker usually ignores tests linked through a static library
26 /// because test registration relies on the test instance's static constructor
27 /// adding itself to a global list of tests. When linking against a static
28 /// library, static constructors in an object file will be ignored unless at
29 /// least one entity in that object file is linked.
30 ///
31 /// This macro works by passing the internal ``TestInfo`` instance to a
32 /// constructor defined in a source file. This guarantees that the ``TestInfo``
33 /// instance is referenced, so the linker will link it and the other tests in
34 /// that file.
35 #define PW_UNIT_TEST_LINK_FILE_CONTAINING_TEST(suite, name) \
36   _PW_UNIT_TEST_LINK_TESTS(_pw_unit_test_Info_##suite##_##name)
37 
38 #define _PW_UNIT_TEST_LINK_TESTS(info)                              \
39   extern "C" {                                                      \
40                                                                     \
41   extern ::pw::unit_test::internal::TestInfo info;                  \
42                                                                     \
43   [[maybe_unused]] const ::pw::unit_test::internal::ReferToTestInfo \
44       _pw_unit_test_reference_to_ensure_link_##info(info);          \
45                                                                     \
46   } /* extern "C" */                                                \
47                                                                     \
48   static_assert(true, "Macros must end with a semicolon")
49 
50 namespace pw::unit_test::internal {
51 
52 // Refers to the TestInfo to ensure it is linked in.
53 class ReferToTestInfo {
54  public:
55   explicit ReferToTestInfo(const TestInfo& info);
56 };
57 
58 }  // namespace pw::unit_test::internal
59