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

gtest_main not linked correctly without srcs #20

Closed
skyw opened this issue Oct 6, 2022 · 5 comments
Closed

gtest_main not linked correctly without srcs #20

skyw opened this issue Oct 6, 2022 · 5 comments

Comments

@skyw
Copy link

skyw commented Oct 6, 2022

with exact same content, one in cu file, one in cpp file

//a.cpp
#include <gtest/gtest.h>
#include <iostream>

TEST(Dummy, CPP) {
  std::cout << "this is in cpp file" << std::endl;
}
// a.cu
#include <gtest/gtest.h>
#include <iostream>

TEST(Dummy, CU) {
  std::cout << "this is in cu file" << std::endl;
}

BUILD file

load("@rules_cuda//cuda:defs.bzl", "cuda_library")

package(default_visibility = ["//visibility:public"])

cuda_library(
    name = "a_cu",
    srcs = ["a.cu"]
)

cc_test(
    name = "dummy_test_cu",
    deps = [
        ":a_cu",
        "@com_google_googletest//:gtest_main",
    ]
 )
cc_test(
    name = "dummy_test",
    srcs = ["a.cpp"],
    deps = [
        "@com_google_googletest//:gtest_main",
    ],
)

If I run
bazel test --test_output=all //:dummy_test
1 test will run.

[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from Dummy
[ RUN      ] Dummy.CPP
this is in cpp file
[       OK ] Dummy.CPP (0 ms)
[----------] 1 test from Dummy (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[  PASSED  ] 1 test.

But if I run
bazel test --config=cuda --test_output=all //:dummy_test_cu
Everything will build and run "successfully". except no test is actually run

[==========] Running 0 tests from 0 test suites.
[==========] 0 tests from 0 test suites ran. (0 ms total)
[  PASSED  ] 0 tests.

I do need to define test as cu file because there will be CUDA code in it. Technically they can be wrapped in another lib and test file only contains pure c++ code, but that's extra work. Besides, a silent success without tests being actually run is dangerous. It can be easily missed in a bigger project.

Maybe explicitly support cuda_test and cuda_binary?

@cloudhan
Copy link
Collaborator

cloudhan commented Oct 7, 2022

This should be fixable by adding alwayslink=True to your cuda_library which has test impl must present in final binary.

cuda_test and cuda_binary will largely share the same logic with cc rules, it is not worth the effort. At the moment, it can be implemented as macro.

@skyw
Copy link
Author

skyw commented Oct 7, 2022

Thanks.

Adding alwayslink=True does the trick. Any low effort option to make it fail instead of running 0 tests?

@cloudhan
Copy link
Collaborator

cloudhan commented Oct 7, 2022

This boils down to you own customization problem. I think you can rollout your own version of test main and it should be quiet simple:

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  EXPECT_GT(::testing::UnitTest::GetInstance()->total_test_suite_count(), 0);
  return RUN_ALL_TESTS();
}

ref

@skyw
Copy link
Author

skyw commented Oct 7, 2022

This boils down to you own customization problem. I think you can rollout your own version of test main and it should be quiet simple:

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  EXPECT_GT(::testing::UnitTest::GetInstance()->total_test_suite_count(), 0);
  return RUN_ALL_TESTS();
}

ref

It can work. But I think the point gtest_main target exists is not to have the same main function in every test file. although not a huge deal to have them. In the mean time, cmake links gtest_main fine with .cu file in one of my project that I maintain both bazel and cmake build. So a little less motivation to do so.

@cloudhan
Copy link
Collaborator

cloudhan commented Oct 7, 2022

I mean, there is nothing prevent you from add a cc_library named as your_main and link it together with your cuda_librarys, since you want it signal you when no test is found. CMake can also suffer from this problem if you

add_library(a_cu_lib STATIC CU_FILES)
add_executable(dummy_test_cu a_cu_lib gtest_main)

The problems here is the a_cu_lib library is static and there is no symbol is referenced in the main function. Then you will need whole archive linking. And this is what alwayslink=True is doing. It is not a trick or walkaround in any form, it is how it should be. If the problem still present, then it is a bug in these rules.

I'd prefer the following macro, and you should not present a your_main

def cuda_test(name, srcs, deps, *args, *kwargs):
    cuda_library(name = name + "_cu", srcs = srcs, alwayslink=True)
    cc_test(name = name, deps = [name + "_cu"] + deps)

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

No branches or pull requests

2 participants