Installing C/C++ headers

2,063 views
Skip to first unread message

Jason Zaman

unread,
Jun 22, 2018, 11:58:00 AM6/22/18
to bu...@tensorflow.org
Hey all,

I can't figure out how to correctly install the headers. When building
the pip_package it grabs the headers somehow and puts them in
site-pacakges/tensorflow/include/. I also need to be able to build the
C/C++ libraries and their header files and put them in /usr/include/
without building the python stuff. (ChromeOS wants to be able to build
without all the python parts, they only need the libs).

djenkins has been helping test the gentoo package and pointed out that I
was missing the *.pb.h files, but I am still not clear on the Eigen
headers.

I currently do roughly this (not exactly, we have helper methods):
# Install c c++ and core header files
for i in $(find tensorflow/{c,cc,core} -name "*.h"); do
mkdir -p /usr/include/tensorflow/${i%/*}
cp ${i} /usr/include/tensorflow/${i%/*}
done

# Installing generated headers
pushd bazel-genfiles/ > /dev/null || die
for i in $(find tensorflow/{cc,core} -name "*.h"); do
mkdir -p /usr/include/tensorflow/${i%/*}
cp ${i} /usr/include/tensorflow/${i%/*}
done
popd > /dev/null || die

# Installing Eigen headers
cp third_party/eigen3/{Eigen,unsupported}/* /usr/include/tensorflow/third_party/eigen3/

Doing all that gets me here:

g++ -o/dev/null -E -I/usr/include/tensorflow /usr/include/tensorflow/tensorflow/core/public/session.h
In file included from /usr/include/tensorflow/tensorflow/core/framework/tensor.h:19:0,
from /usr/include/tensorflow/tensorflow/core/public/session.h:24:
/usr/include/tensorflow/third_party/eigen3/unsupported/Eigen/CXX11/Tensor:1:10: fatal error: unsupported/Eigen/CXX11/Tensor: No such file or directory
#include "unsupported/Eigen/CXX11/Tensor"
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

I am missing the ones from external/eigen_archive.
The problem is the BUILD file for that has a target with what I need:
https://github.com/tensorflow/tensorflow/blob/master/third_party/eigen.BUILD
but I cant figure out how to get those files isolated so I can copy them
over. I can't just copy everything in external/eigen_archive because
they are licensed differently so I only want some. Copying the glob
patterns from the BUILD file is asking for a maintenance nightmare so
there has to be a better way.

$ bazel build --config=opt @eigen_archive//:eigen
INFO: Analysed target @eigen_archive//:eigen (7 packages loaded).
INFO: Found 1 target...
Target @eigen_archive//:eigen up-to-date (nothing to build)
INFO: Elapsed time: 2.102s, Critical Path: 0.01s
INFO: 0 processes.
INFO: Build completed successfully, 1 total action

Is there a way to make bazel put this stuff in a dir anywhere so I can
copy it? I've searched and grepped through the files but no dice :(.
Can someone thats better at bazel help?

-- Jason

Yun Peng

unread,
Jun 25, 2018, 4:00:26 AM6/25/18
to Jason Zaman, bu...@tensorflow.org
Hey Jason,

I think you can use a genrule to copy all necessary eigen files to a genfiles folder. Here's how to do it.

1. Add a filegroup in third_party/eigen.BUILD

filegroup(
    name = "all_eigen_files",
    srcs = EIGEN_MPL2_HEADER_FILES,
    visibility = ["//visibility:public"],
)

2. Define a genrule anywhere you want like this:

genrule(
    name = "gen_all_eigen_files",
    srcs = ["@eigen_archive//:all_eigen_files"],
    outs = ["eigen_files"],
    cmd = """
    mkdir $@
    for f in $(SRCS) ; do
      mkdir -p "$@/$$(dirname $${f})"
      cp "$${f}" "$@/$$(dirname $${f})/"
    done
    """
)

Then the eigen files will be available at ./bazel-genfiles/<package_path_of_genrule>/eigen_files/external/eigen_archive/

For example, I wrote the genrule in third_party/eigen3/BUILD (but not sure this is the right place). I got:
pcloudy@pcloudy0-w MSYS ~/workspace/tensorflow
$ ls ./bazel-genfiles/third_party/eigen3/eigen_files/external/eigen_archive/
Eigen/       unsupported/

Hope this could help!

Cheers,
Yun

--
You received this message because you are subscribed to the Google Groups "SIG Build" group.
To unsubscribe from this group and stop receiving emails from it, send an email to build+un...@tensorflow.org.
Visit this group at https://groups.google.com/a/tensorflow.org/group/build/.

Jason Zaman

unread,
Jun 25, 2018, 1:47:43 PM6/25/18
to Yun Peng, bu...@tensorflow.org
That worked really well, thanks!

I filed a PR here: https://github.com/tensorflow/tensorflow/pull/20281

-- Jason
Message has been deleted

flo...@infobaleen.com

unread,
Aug 14, 2018, 3:14:55 PM8/14/18
to SIG Build
Hi Jason and Yun,
 
> > I can't figure out how to correctly install the headers.
It seems a lot of people are struggling with similar problems, including me. There a number of github issues on the topic. Do you think you could upstream a rule or share instructions for generating the necessary contents of /usr/include/tensorflow? I'm sure a lot of people would appreciate it.

Best regards,
Florian

Jason Zaman

unread,
Aug 15, 2018, 1:48:27 AM8/15/18
to flo...@infobaleen.com, SIG Build
This is what you are looking for:
https://github.com/gentoo/gentoo/blob/20b3f8c041a450814e3e8c770302cbafc6bbc30d/sci-libs/tensorflow/tensorflow-1.10.0.ebuild#L397-L424

It is far from pretty and kind of bruteforce-ish. but it is correct in
that like everything you'd need is installed in the right places. It
probably includes too many but I have tested a real program that uses the
C++ API and it works so far.

I've made a helper for installing eigen headers since specific ones
should be included, not just all so find *.h doesnt work. I should just
make a rule for the rest of the headers too, you're right.

In the mean time, follow that. insinto and doins are gentoo ebuild
helpers, basically insinto sets the dir and doins copies the thing to
that dir (inside $DESTDIR for staging first) and sets the right modes
and whatnot so shouldnt be too hard to adapt for whatever your build
system is.

You can test it by doing something like this, most of them should
compile cleanly. There are a couple that wont depending on how you
configured and compiled TF.
for i in $(find /usr/include/tensorflow -iname "*.h"); do echo $i; g++ -o/dev/null -E -I/usr/include/tensorflow $i; done

-- Jason

On Tue, Aug 14, 2018 at 12:14:55PM -0700, flo...@infobaleen.com wrote:
> Hi Jason and Yun,
>
> > > I can't figure out how to correctly install the headers.
> It seems a lot of people are struggling with similar problems, including
> me. There a number of github issues
> <https://github.com/tensorflow/tensorflow/issues/18360> on the topic. Do
> you think you could upstream a rule or share instructions for generating
> the necessary contents of /usr/include/tensorflow? I'm sure a lot of people
> would appreciate it.
>
> Best regards,
> Florian
>

flo...@infobaleen.com

unread,
Aug 15, 2018, 8:03:13 AM8/15/18
to SIG Build
Thanks that helped a lot. I extracted this:
for i in $(find tensorflow/{c,cc,core} -name "*.h"); do
   mkdir -p ${dest}/${i%/*}
   cp ${i} ${dest}/${i}
done

for i in $(find bazel-genfiles/tensorflow/{cc,core} -name "*.h"); do
   j=${i#bazel-genfiles/}
   mkdir -p ${dest}/${j%/*}
   cp ${i} ${dest}/${j}
done

bazel build //third_party/eigen3:install_eigen_headers
cp -r bazel-genfiles/third_party/eigen3/include/* ${dest}

I seem to be missing some protocol buffer headers though:
g++ -std=c++11 example.cc -I tf/packaged_cc/
In file included from tf/packaged_cc/tensorflow/core/platform/protobuf.h:31:0,
                 from tf/packaged_cc/tensorflow/core/platform/default/string_coding.h:23,
                 from tf/packaged_cc/tensorflow/core/platform/tensor_coding.h:29,
                 from tf/packaged_cc/tensorflow/core/framework/resource_handle.h:19,
                 from tf/packaged_cc/tensorflow/core/framework/allocator.h:24,
                 from tf/packaged_cc/tensorflow/core/framework/tensor.h:20,
                 from tf/packaged_cc/tensorflow/cc/framework/ops.h:21,
                 from tf/packaged_cc/tensorflow/cc/client/client_session.h:24,
                 from example.cc:1:
tf/packaged_cc/tensorflow/core/platform/default/protobuf.h:22:35: fatal error: google/protobuf/arena.h: No such file or directory
 #include "google/protobuf/arena.h"

Compiling the same example using bazel works just fine, but I can't find the protobuf files in the tree, so I guees they are unpacked and then deleted by bazel during the build process. I see that you provide the corresponding archives to bazel (presumably because you can't let bazel download stuff. But I don't quite understand how get those headers out (some parts go a little over my head since I'm neither familiar with gentoo packaging nor bazel).

Jason Zaman

unread,
Aug 15, 2018, 9:28:28 AM8/15/18
to flo...@infobaleen.com, SIG Build
Hmm, I just looked through my machine and tensorflow itself doesnt
install those headers. I'd just install protobuf normally for your
distro through apt-get or however you normally would. My machine only
has protobuf headers in /usr/include/google/protobuf/ which are from the
protobuf package not from tensorflow.

-- Jason

flo...@infobaleen.com

unread,
Aug 15, 2018, 9:50:26 AM8/15/18
to SIG Build

Hmm, I just looked through my machine and tensorflow itself doesnt
install those headers. I'd just install protobuf normally for your
distro through apt-get or however you normally would. My machine only
has protobuf headers in /usr/include/google/protobuf/ which are from the
protobuf package not from tensorflow.


Thanks, I thought I was missing some magic in your scripts. The fun thing is that those libraries are too old in my distro (Debian stable) if I install them.

I ended up taking the purelib/tensorflow/include folder from the .whl for python and copy the results of the script I posted above over that one. Now I can compile successfully with "g++ -I mergedIncludeFolders".

I don't really understand this has had such a low priority for years, given that C++ isn't exactly an obscure choice. In any case, I hope this thread provides enough info for anyone else in this situation.

Thanks a lot for your help Jason.

Best regards,
Florian 

Jason Zaman

unread,
Aug 15, 2018, 10:08:57 AM8/15/18
to flo...@infobaleen.com, SIG Build
Good to hear its working! You're most welcome!

Yeah its definitely not as easy as it should be yet. Installing from pip
is definitely not as good as just apt-get install tensorflow. I've been
fixing things so its a bit easier to package now at least. The
unbundling stuff is a big part of it, distros generally dont allow
packages to bundle dependencies which is why no other distro has it in
the main tree yet. I really need to write more of this up on my blog too
or something.

You to need to be careful with the C++ API too for now tho. They have
not guaranteed a stable ABI for the C++ stuff, only the C library.
You'll likely have to rebuild everything using TF from scratch whenever
theres a new version of TF.

-- Jason

Jason Zaman

unread,
Sep 4, 2018, 2:48:49 PM9/4/18
to flo...@infobaleen.com, SIG Build
I added a //tensorflow:install_headers target:
https://github.com/tensorflow/tensorflow/pull/22061

-- Jason

On Wed, Aug 15, 2018 at 06:50:26AM -0700, flo...@infobaleen.com wrote:
>
> >
> >
Reply all
Reply to author
Forward
0 new messages