1

I have a binary in Android that links to a static library A. Static library libA depends on multiple shared libraries. The binary does not do anything except it imports a class from the static library and executes a simple function.

However, the binary fails to build except I link against the same shared libraries to which the static library A is linked because the compiler tries to recompile libA with the build config of the binary.

Here is my Android.bp of the static library:

cc_library_static {
name: "libA",
relative_install_path: "hw",
vendor: true,
rtti: true,
cflags: [
    "-Wall",
    "-Wextra",
    "-g",
    "-DUNIT_TEST",
    "-fexceptions"
],
srcs: [
    "libA.cpp",
],
shared_libs: [
    "libhidlbase",
    "libhidltransport",
    "libutils",
    "liblog"
],
header_libs: [
    "lib_a_stub_headers",
],
whole_static_libs: [
    "lib_a_stub",
],
export_include_dirs: ["."]
}

Here is my Android.bp for the binary:

cc_binary{
name: "simplebinary",
relative_install_path: "hw",
vendor: true,
cflags: [
    "-fexceptions"
],
whole_static_libs: [
    "libA"
],
shared_libs: [
    "vendor.test.hal@1.0",
],
srcs: [
    "simplebinary.cpp",
],
}

The build of the binary fails with:

libA.hpp:4:10: fatal error: 'lib/lib.hpp' file not found

I'm building using the command mm

Moaaz Ali
  • 93
  • 15

1 Answers1

1

According to the error message, the compiler cannot find a header file in its header search path. Header includes are resolved during the preprocessor stage, therefore this is not a linking problem. The preprocessor runs at the beginning of compilation, the linking is done at the end.

From your description, I understand that the code for simplebinary includes the header libA.hpp, provided by libA. I understand that libA.hpp is contained in the same directory as the Android.bp that defines the libA module. Because of the export_include_dirs: ["."], this directory is added to the header search path for the compilation of simplebinary. Therefore, the compiler can find libA.hpp when compiling simplebinary.

Now libA.hpp includes CommonAPI/CommonAPI.hpp. I do not know to which library this header belongs. I assume the header belongs to some library libB, and libA links against libB. I further assume that libB has export_include_dirs set to point to the folder containing CommonAPI/CommonAPI.hpp. You can then make libA re-export this header by adding export_shared_lib_headers: ["libB"] to the module declaration of libA. If libB is not a shared library, you would have to use export_static_lib_headers or export_header_lib_headers instead (reference).

  • Thank you for the detailed answer! However, there is a small detail I don't understand, if a static library is linking to a shared library, is it obligatory that any binary linking to the static library to link to the shared library? – Moaaz Ali Jul 06 '20 at 09:28
  • 1
    Right, static libraries do not hold linking information, so when you have a binary that links against a static library, and the static library uses symbols provided by another shared library, then your binary has to also link against the shared library. Technically speaking there is no such thing as a static library linking against a shared library. In my answer I was focusing on the header problem, I now see that in your question `libA` is a static library. So in my answer when I say "`libA` links against `libB`", this would have been worded better as "`libA` uses symbols provided by `libB`". – f9c69e9781fa194211448473495534 Jul 10 '20 at 23:51
  • Or to put it in other words - Android.bp does not have transistive dependencies, so each module must more explicit about them than in CMake. Especially re-exporting include paths is missing, so easy to end up with repeating all dependencies many times if intermediate ones are not carefully exporting what they use in headers. – kwesolowski Jan 19 '21 at 12:32