bazelbuild / bazel

a fast, scalable, multi-language and extensible build system
https://bazel.build
Apache License 2.0
22.77k stars 3.99k forks source link

Archive dependencies not used in the cc_test, but used in cc_binary #2944

Open gruszczy opened 7 years ago

gruszczy commented 7 years ago

Description of the problem / feature request / question:

WORKSPACE:

new_local_repository(
    name = "llvm",
    path = "/opt/local/libexec/llvm-4.0",
    build_file= "llvm.BUILD")

llvm.BUILD:

cc_library(
    name = "main",
    srcs = glob(["lib/*.a"]),
    hdrs = glob(["include/**/*.*"]),
    visibility = ["//visibility:public"],
    copts = ["-Iexternal/llvm/include"],
    alwayslink=1
)

cc_library(
    name = "jit",
    srcs = ["jit.cc"],
    hdrs = ["jit.h"],
    deps = [
        ":ast",
        ":common",
        "@llvm//:main"
    ],
    copts = GENERAL_COPTS)

Usage:

cc_test(
    name = "codegen_test",
    srcs = ["codegen_test.cc"],
    deps = [
        ":ast",
        ":jit",
        ":lexer",
        ":parser",
        ":codegen",
        "@gtest//:main",
        "@llvm//:main"
    ],
    copts = TEST_COPTS,
    data = [":examples"],
    size = "small",
    linkopts=["-force_load /opt/local/libexec/llvm-4.0/lib/libLLVMRuntimeDyld.a",
              "-force_load /opt/local/libexec/llvm-4.0/lib/libLLVMMCJIT.a"]
)

cc_binary(
    name = "compiler",
    srcs = ["compiler.cc"],
    deps = [
        ":ast",
        ":classes",
        ":codegen",
        ":functions",
        ":jit",
        ":lexer",
        ":parser"
    ],
    copts = GENERAL_COPTS
)

cc_binary works no matter what. For cc_test, if I remove the linkopts, it will stop working, complaining during execution of the test about:

dyld: Symbol not found: __ZN4llvm11RuntimeDyld13MemoryManager6anchorEv
  Referenced from: /private/var/tmp/_bazel_gruszczy/f47cf37dc1ed5953a8d3118b36522f59/bazel-sandbox/7f0b2366-44a6-45be-93bd-271304d4b483-28/execroot/shwifty/bazel-out/local-fastbuild/bin/codegen_test.runfiles/__main__/_solib_darwin//liblibjit.so
  Expected in: flat namespace
 in /private/var/tmp/_bazel_gruszczy/f47cf37dc1ed5953a8d3118b36522f59/bazel-sandbox/7f0b2366-44a6-45be-93bd-271304d4b483-28/execroot/shwifty/bazel-out/local-fastbuild/bin/codegen_test.runfiles/__main__/_solib_darwin//liblibjit.so
external/bazel_tools/tools/test/test-setup.sh: line 159: 23179 Abort trap: 6           "${TEST_PATH}" "$@"

It doesn't complain about this in the compiler binary, even though it depends on ":jit" target.

If possible, provide a minimal example to reproduce the problem:

Environment info

Have you found anything relevant by searching the web?

My own question: http://stackoverflow.com/questions/43786877/llvm-dyld-symbol-not-found-zn4llvm11runtimedyld13memorymanager6anchorev

Anything else, information or logs or outputs that would be helpful?

(If they are large, please upload as attachment or provide link).

damienmg commented 7 years ago

C++ so marcel to look at it.

hlopko commented 7 years ago

Hello @gruszczy, The source of confusion is that Bazel by default links binaries statically, but tests dynamically. This makes the test-code-refactor loop faster, because changes to the test code only trigger the rebuild of the test, not the whole application. It can be disabled by setting linkstatic = 1 on codegen_test target.

As to why the symbols are not present in codegen_test when built as a shared library, that's much harder question and would need more project-specific information. But a possible solution might be to mark targets producing VMRuntimeDyld.a and VMMCJit.a as alwayslink = 1.

hlopko commented 7 years ago

I'll close this issue now, feel free to reopen if you think this is a Bazel issue. If you have further questions feel free to continue on your StackOverflow question.

gruszczy commented 7 years ago

Hi Marcel,

Thanks for the tip, it's good to know the difference (and rationale) about the linking. linkstatic indeed fixes the issues an allows me to avoid listing files, so it's an acceptable solution.

However, I did try to use alwayslink = 1 on the target that is producing the VMRuntimeDyld.a and VMMCJit.a, it's in the snippet I included above:

cc_library( name = "main", srcs = glob(["lib/*.a"]), hdrs = glob(["include/*/.*"]), visibility = ["//visibility:public"], copts = ["-Iexternal/llvm/include"], alwayslink=1 )

That's why I think this is a bug, because I would expect the alwayslink to propagate to the cc_test, no matter what is the difference in linking between these two.

hlopko commented 7 years ago

I guess this is really a bug. The issue here is that Bazel treats .a files in srcs as dependencies, not a real sources. And alwayslink only affects the .a library made from sources (in your last snippet that would be libmain.a, but since there are no real sources there, it's not built). Alwayslink is not transitive, so dependencies are not enclosed in --whole-archive block.

hlopko commented 7 years ago

I've shared a really ugly unsupported hack on StackOverflow if you need a fix quickly. As the answer says, it can break any time without warning, but we have plans for more disciplined solution.

sgowroji commented 1 year ago

Hi there! We're doing a clean up of old issues and will be closing this one. Please reopen if you’d like to discuss anything further. We’ll respond as soon as we have the bandwidth/resources to do so.

gregoryT5 commented 1 year ago

@sgowroji this still happens, please reopen

github-actions[bot] commented 2 weeks ago

Thank you for contributing to the Bazel repository! This issue has been marked as stale since it has not had any activity in the last 1+ years. It will be closed in the next 90 days unless any other activity occurs. If you think this issue is still relevant and should stay open, please post any comment here and the issue will no longer be marked as stale.