[libc-dev] Header files, include paths and gtest

Petr Hosek via libc-dev libc-dev at lists.llvm.org
Sat Jan 11 13:23:40 PST 2020

I think that's fine given that libc testing is a special case where you
want to have strict control over your header dependencies. In Zircon, we've
similarly ended up creating zxtest
a googletest-like framework that's much simpler and thus usable for testing
kernel constructs. In GN, we're also using a custom
googletest-like framework that's much simpler and faster (and it was in
turn derived from Ninja's which is even simpler). These might be useful as
an inspiration.

On Sat, Jan 11, 2020 at 10:54 AM Siva Chandra via libc-dev <
libc-dev at lists.llvm.org> wrote:

> tl;dr - gtest is unittesting framework which uses the standard
> library. A circular dependency occurs when using gtest to test the
> standard library itself. [1] [2]
> To begin the long story, let me say a little about header files and
> include paths in llvm-libc. One of the implementation rules we want to
> follow is that header files should only be included using their local
> path in the implementation and test `.cpp` files. The same rule also
> is imposed on the internal header files like `src/sys/mman/mmap.h`.
> That is, the internal implementation header files like `mmap.h` should
> include `mman.h` using the full internal path `include/mmap.h` and not
> `<sys/mman.h>` or `"sys/mman.h"`. Likewise, the mmap unittest should
> include `sys/mman.h` using the full internal path `include/sys/mman.h`
> and not `<sys/mman.h>` or `"sys/mman.h"`. We need an implementation
> rule like this because we want to ensure that our implementations and
> tests only pick pieces from llvm-libc and not from the system-libc.
> I confess that I have accidentally, and also due to oversight in some
> cases, broken this rule in a few places. So, once I realized I had
> broken this rule, I tried fixing them. This attempt to fix is what
> brings us to the topic of this email.
> As far as the implementations in the `src` directory go, I did not
> face any problem fixing the places at which the rule was broken.
> However, as I started touching the tests, I ran into problems. The
> problem specifically was because of gtest. We use gtest for our
> unittests, but `gtest.h` includes string.h, time.h etc directly [3].
> As parts of a few standards require that some of the header files
> include other header files, llvm-libc's include paths are setup to
> lookup standard library headers from llvm-libc first. Because of this,
> gtest ends up getting llvm-libc's headers. We do not want gtest to be
> using llvm-libc's headers as it is not compiled against them. We
> cannot also change the include path order to enable gtest to get the
> system libc's headers because then, llvm-libc's public headers which
> include other public headers, will end up picking up systems libc
> headers.
> I could not come up with a clean solution to this problem other than
> disallowing gtest for unittests. Which means, we need a replacement
> which does not cause the problems I described above. For consistency,
> we want the interface of this replacement to be exactly like that of
> gtest. We do not however need this replacement to be as featureful as
> gtest (to begin with at least). As a demonstration, I have implemented
> a simple and lightweight framework and put it on my github account:
> https://github.com/sivachandra/unittest. I have also tested it with
> llvm-libc and verified that it solves the above header file problem
> and can be used as a drop-in replacement for gtest. Hence, I propose
> that we put this unittest framework in the llvm-libc tree (of course
> after a code review) and use it for setting up llvm-libc unittests. At
> the interface level, the experience will not be any different from
> using gtest (except that of including something different from
> `gtest/gtest.h`.)
> [1] At a fundamental level, gtest is not designed to test standard
> libraries.
> [2] Circular dependency can be of two kinds: header files and symbols.
> By ensuring that the tests call in to llvm-libc using internal names,
> we have avoided the circular dependeny wrt the symbols. So, when you
> link gtest with a test, we can be confident that gtest's library code
> does not call into llvm-libc.
> [3] To make our problem worse, LLVM's gtest pulls in headers from the
> LLVM Support library, which in turn pull in a large number of standard
> headers.
> Thanks,
> Siva Chandra
> _______________________________________________
> libc-dev mailing list
> libc-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/libc-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/libc-dev/attachments/20200111/21dc9248/attachment.html>

More information about the libc-dev mailing list