3

Folks,

I am trying to link .h and static libraries into my tensorflow program. My headers are in

/usr/local/include/lcm

And static/shared libraries (.so, etc.) in

/usr/local/lib

But Bazel complains they don't exist, or that it cannot find them. Here is my code on my BUILD file:

package(default_visibility = ["//tensorflow:internal"])
licenses(["notice"])  # Apache 2.0
exports_files(["LICENSE"])

# LCM shared libraries path
cc_library(
    name = "lcm_lib",
    srcs = glob([
        "*.so",
    ]),
    copts = ["-L/usr/local/lib"],
    linkopts = ["-pthread", "-shared"],
    visibility = ["//visibility:public"],
)

# LCM header libraries path
cc_library(
    name = "lcm_headers",
    hdrs = glob([
        "include/**/*.h",
    ]),
    copts = ["-L/usr/local/include"],
    linkopts = ["-pthread"],
    visibility = ["//visibility:public"],
)

cc_binary(
    name = "myProject",
    srcs = [
        "main.cc",
    ],
    linkopts = ["-lm"],
    deps = [
        "//tensorflow/cc:cc_ops",
        "//tensorflow/core:framework_internal",
        "//tensorflow/core:tensorflow",
    ],
)

filegroup(
    name = "all_files",
    srcs = glob(
        ["**/*"],
        exclude = [
            "**/METADATA",
            "**/OWNERS",
            "bin/**",
            "gen/**",
        ],
    ),
    visibility = ["//tensorflow:__subpackages__"],
)

If I remove LCM related code (from both BUILD and main.cc), then my program builds and runs. When I include LCM, then I get errors saying that lcm::LCM::~LCM() is undefined, and that it cannot find the liblcm.so. Now, my non-tensorflow code (or the majority of my project) is running cmake, and LCM and the rest of the libraries I need (openCV, etc.) can be found. I use commands in my CMakeList.txt like:

# search path for LCM header files
set(LCM_IncludeSearchPaths
  /usr/include/
  /usr/local/include/
  /opt/local/include
)
# search path for LCM static/dynamic libraries
set(LCM_LibrarySearchPaths
  /usr/lib/
  /usr/local/lib/
  /opt/local/lib/
)
find_path(LCM_INCLUDE_DIR
    NAMES lcm/lcm.h
    HINTS ${LCM_IncludeSearchPaths}
)   
FIND_LIBRARY(LCM_LIBS
  NAMES lcm
  HINTS ${LCM_LibrarySearchPaths}
  PATH_SUFFIXES lib
)

And it all works. But it does not work for tensorflow and Bazel

Here are my build and WORKSPACE files, located in the same directory:

This is my touched WORKSPACE file:

# LCM static libraries
new_local_repository(
    name = "lcm_libs",
    # pkg-config --variable=libdir x11
    path = "/usr/local/lib",
    build_file_content = """
cc_library(
    name = "liblcm",
    srcs = ["liblcm.so"],
    visibility = ["//visibility:public"],
)
""",
)

# LCM header files
new_local_repository(
    name = "lcm_headers",
    # pkg-config --variable=libdir x11
    path = "/usr/local/include",
    build_file_content = """
cc_library(
    name = "lcm",
    hdrs = glob([
        "lcm/*.h", "lcm/*.hpp",
    ]),
    visibility = ["//visibility:public"],
)
""",
)

# bind to a name to avoid using the "actual" format
#bind(
#    name = "liblcm",
#    actual = "@lcm_libs//:liblcm",
#)
#bind(
#    name = "lcm",
#    actual = "@lcm_headers//:lcm",
#)
#

And my BUILD:

# Description:
#   Tensorflow C++ inference example for labeling images.

package(default_visibility = ["//tensorflow:internal"])
licenses(["notice"])  # Apache 2.0
exports_files(["LICENSE"])

cc_binary(
    name = "facialFatigue",
    srcs = [
        "main.cc",
    ],
    linkopts = ["-lm"],
    deps = [
        "//tensorflow/cc:cc_ops",
        "//tensorflow/core:framework_internal",
        "//tensorflow/core:tensorflow",
        "@lcm_libs//:liblcm",
        "@lcm_headers//:lcm",
    ],
)

filegroup(
    name = "all_files",
    srcs = glob(
        ["**/*"],
        exclude = [
            "**/METADATA",
            "**/OWNERS",
            "bin/**",
            "gen/**",
        ],
    ),
    visibility = ["//tensorflow:__subpackages__"],
)

Sorry for the long question :-(

Ian Campbell
  • 23,484
  • 14
  • 36
  • 57
Pototo
  • 691
  • 1
  • 12
  • 27

1 Answers1

1

Bazel executes action (in your case C++ compile action) in a sandbox, to ensure the hermeticity. This is needed to be correct when inputs of the action change. Therefore you have to tell Bazel about all the inputs, including the system ones.

But of course you can depend on system libraries, take a look at local_repository rule. You might also find this example in bazel-discuss@ thread helpful.

hlopko
  • 3,100
  • 22
  • 27
  • I get errors:ERROR: /home/mario/tensorflow_HY/tensorflow/tensorflow/examples/MYPROJECT/cpp/BUILD:39:1: no such package '@lcm_headers//': error loading package 'external': The repository named 'lcm_headers' could not be resolved and referenced by '//tensorflow/examples/MYPROJECT/cpp:PROJECT'. – Pototo Apr 06 '17 at 19:42
  • see my WOKSPACE and new BUILD files above. Thanks in advance for your help – Pototo Apr 06 '17 at 19:46
  • Is the workspace file you pasted in the root of the repo? Maybe you have 2 workspace files, one in the root, one in the tensorflow/examples/MYPROJECT/. Try to edit the root one. Other than that it looks ok.. – hlopko Apr 13 '17 at 14:49