Repository: tensorflow
Issue: Monolithic build of libtensorflow_cc.so produces libtensorflow_framework.so, failing to run application
Labels: stat:awaiting tensorflower,type:build/install,comp:runtime,subtype: ubuntu/linux,TF 2.10

<details><summary>Click to expand!</summary> 
 
 ### Issue Type

Build/Install

### Have you reproduced the bug with TF nightly?

No

### Source

source

### Tensorflow Version

tf 2.10

### Custom Code

No

### OS Platform and Distribution

Linux Ubuntu 20.04

### Mobile device

_No response_

### Python version

3.8.10

### Bazel version

5.3.1

### GCC/Compiler version

9.4.0

### CUDA/cuDNN version

11.2.152

### GPU model and memory

NVIDIA RTX 3090 TI (24GB)

### Current Behaviour?

I am trying to build a monolithic version of the TensorFlow C++ library `libtensorflow_cc.so` from source for TensorFlow versions 2.10+.

I'm building inside a Docker container of the official `devel-gpu` image, which is [defined in devel-gpu.Dockerfile](https://github.com/tensorflow/tensorflow/blob/v2.10.0/tensorflow/tools/dockerfiles/dockerfiles/devel-gpu.Dockerfile).

For the build, I am calling the following. The build output is attached as the log in this issue. Note that I also had to incorporate [this patch](https://github.com/tensorflow/tensorflow/issues/57826#issuecomment-1328911560) to get the build to work at all. 

```
bazel build --jobs ${JOBS} --config=cuda --config=opt --config=monolithic --verbose_failures tensorflow:libtensorflow_cc.so tensorflow:install_headers
```

The library is built successfully, I did however notice that `libtensorflow_cc.so` seems to now be linking to `libtensorflow_framework.so`, which is also built in the process. That was not the case with v2.9.2 and below. Actually I thought that `--config=monolithic` should result in only `libtensorflow_cc.so`, but it looks like `libtensorflow_framework.so` is a dependency since https://github.com/tensorflow/tensorflow/commit/843c02fe06983ac0f4382a93fff9ffd07eb93d27? I didn't find where `--config=monolithic` is coming into play at the moment.

My main problem at the moment is that I cannot successfully compile and run a test C++ program. Previously this worked:

```
g++ -I /usr/local/include/tensorflow \
    hello_tensorflow.cpp \
    -ltensorflow_cc -lprotobuf \
    -o hello_tensorflow
```

With v2.10.0+ it is giving me the following error instead.

```
/usr/bin/ld: /tmp/ccVj5SwH.o: undefined reference to symbol '_ZN10tensorflow6TensorC1ENS_8DataTypeERKNS_11TensorShapeE'
/usr/bin/ld: /usr/local/lib//libtensorflow_framework.so.2: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
```

Now if I add `libtensorflow_framework.so` to the list of libs to link against, compilation works.

```
g++ -I /usr/local/include/tensorflow \
    hello_tensorflow.cpp \
    -ltensorflow_cc -ltensorflow_framework -lprotobuf \
    -o hello_tensorflow
```

This time however, I am getting the following runtime error:

```
[libprotobuf ERROR external/com_google_protobuf/src/google/protobuf/descriptor_database.cc:118] File already exists in database: google/protobuf/any.proto
[libprotobuf FATAL external/com_google_protobuf/src/google/protobuf/descriptor.cc:1379] CHECK failed: GeneratedDatabase()->Add(encoded_file_descriptor, size): 
terminate called after throwing an instance of 'google::protobuf::FatalException'
  what():  CHECK failed: GeneratedDatabase()->Add(encoded_file_descriptor, size): 
Aborted (core dumped)
```


### Standalone code to reproduce the issue

First build the official GPU devel image with [devel-gpu.Dockerfile](https://github.com/tensorflow/tensorflow/blob/v2.10.0/tensorflow/tools/dockerfiles/dockerfiles/devel-gpu.Dockerfile).

```
docker build -t tensorflow/tensorflow:2.10.0-devel-gpu -f devel-gpu.Dockerfile .
```

Then try to build the `libtensorflow_cc.so` with the following Dockerfile.

```docker
ARG TF_VERSION=2.10.0
FROM tensorflow/tensorflow:${TF_VERSION}-devel-gpu AS build

ARG TF_VERSION
ARG JOBS="auto"

# clone TensorFlow
RUN git clone --branch v${TF_VERSION} --depth=1 https://github.com/tensorflow/tensorflow.git /tensorflow
WORKDIR /tensorflow

# fix build issue in v2.10.0
# https://github.com/tensorflow/tensorflow/issues/57826
RUN if [ "${TF_VERSION}" = "2.10.0" ] || [ "${TF_VERSION}" = "2.10.1" ]; then \
        git fetch --depth=1 origin b1bd1d6beeac169ce669f81dcbf3c48899ca1ed0 && \
        git checkout FETCH_HEAD -- tensorflow/BUILD; \
    fi

# configure compilation
ENV PYTHON_BIN_PATH=/usr/bin/python3
ENV PYTHON_LIB_PATH=/usr/lib/python3/dist-packages
ENV TF_NEED_ROCM=0
ENV TF_CUDA_COMPUTE_CAPABILITIES=5.3,6.0,6.1,7.0,7.2,7.5,8.0,8.6
ENV TF_CUDA_CLANG=0
ENV GCC_HOST_COMPILER_PATH=/usr/bin/gcc
ENV CC_OPT_FLAGS="-march=native -Wno-sign-compare"
ENV TF_SET_ANDROID_WORKSPACE=0
RUN ./configure

# build C++ library
RUN bazel build --jobs ${JOBS} --config=cuda --config=opt --config=monolithic --verbose_failures tensorflow:libtensorflow_cc.so tensorflow:install_headers
```

```shell
docker build -t tensorflow/tensorflow:2.10.0-libtensorflow-cc .
```

Notice that both `libtensorflow_cc.so` and `libtensorflow_framework.so` are built.

Install the built libraries and headers to the system, e.g. in a Docker container of the built image. Try to build and run the following sample application.

```cpp
#include <iostream>
#include <vector>

#include <tensorflow/cc/client/client_session.h>
#include <tensorflow/cc/ops/standard_ops.h>
#include <tensorflow/core/framework/tensor.h>
#include <tensorflow/core/public/version.h>

using namespace std;


int main(int argc, char **argv) {

  // create new session
  auto scope = tensorflow::Scope::NewRootScope();
  tensorflow::ClientSession session(scope);

  // define graph of operations
  auto A = tensorflow::ops::Const(scope, {{1, 2}, {3, 4}});
  auto x = tensorflow::ops::Const(scope, {{1}, {2}});
  auto b = tensorflow::ops::MatMul(scope, A, x);

  // run graph and fetch outputs of A, x, and b
  vector<tensorflow::Tensor> outputs;
  session.Run({A, x, b}, &outputs);

  // print results
  cout << "Hello from TensorFlow C++ " << TF_VERSION_STRING << "!" << endl << endl;
  cout << "A = " << endl << outputs[0].tensor<int, 2>() << endl << endl;
  cout << "x = " << endl << outputs[1].tensor<int, 2>() << endl << endl;
  cout << "A * x = " << endl << outputs[2].tensor<int, 2>() << endl;

  return 0;
}
```

```
g++ -I /usr/local/include/tensorflow \
    hello_tensorflow.cpp \
    -ltensorflow_cc -ltensorflow_framework -lprotobuf \
    -o hello_tensorflow
```


### Relevant log output

```shell
[libprotobuf ERROR external/com_google_protobuf/src/google/protobuf/descriptor_database.cc:118] File already exists in database: google/protobuf/any.proto
[libprotobuf FATAL external/com_google_protobuf/src/google/protobuf/descriptor.cc:1379] CHECK failed: GeneratedDatabase()->Add(encoded_file_descriptor, size): 
terminate called after throwing an instance of 'google::protobuf::FatalException'
  what():  CHECK failed: GeneratedDatabase()->Add(encoded_file_descriptor, size): 
Aborted (core dumped)
```
</details>