Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve use-system-libc documentation #793

Closed
anarthal opened this issue Jan 14, 2025 · 4 comments · Fixed by #811
Closed

Improve use-system-libc documentation #793

anarthal opened this issue Jan 14, 2025 · 4 comments · Fixed by #811
Labels
Docs Related to program documentation

Comments

@anarthal
Copy link

Version:

$> mrdocs --version
MrDocs
    C++ Documentation Tool
    version: 0.0.3
    build: 
    built with LLVM 20.0.0git

Source file:

#include <boost/asio/detail/config.hpp>

Error:

/home/ruben/workspace/boost-root/libs/asio/include/boost/asio/detail/config.hpp:810:11: fatal error: 'linux/version.h' file not found
  810 | # include <linux/version.h>

Looks like __linux__ is defined, but the headers are not there. Changing use-system-stdlib: true fixes it.

@alandefreitas
Copy link
Collaborator

alandefreitas commented Jan 14, 2025

You need use-system-libc, because compilers enable all default system paths when you let it look for libc in the system.

use-system-stdlib is only for the C++ standard library

@alandefreitas
Copy link
Collaborator

Let me go ahead and expand on that a little (we'll need to explain this better in the docs anyway).

So, MrDocs has the advantage of seeing everything a real compiler (clang) sees. The "disadvantage" (depending on how you look at it) is that the code has to be valid. A corollary of that is that dependencies have to be available. We discuss regular dependencies in the documentation but not system dependencies.

For system dependencies, that's how the compiler works:

  • Implicit directories for the C++ standard library. When enabled, the compiler will look for specific paths according to the -stdlib option and include them as implicit -isystem paths. For instance, clang looks for different implementations of the C++ standard library depending on the platform (msvc on windows, libstdc++ on linux and libc++ otherwise). This can be disabled with -nostdinc++ -nostdlib++ or, in MrDocs, with use-system-stdlib=false.
  • Implicit directories for the C standard library. When enabled, the compiler will not look for specific paths but include all system paths, instead. A convenience related to the fact that it includes everything is you can include things like linux/version.h or Windows.h without explicitly including anything else even though they're not part of the C standard library. Unlike with libc++, LLVM+Clang does not provide an implementation of the C standard library and it always depends on the system for that. This can be disabled with -nostdinc or, in MrDocs, with use-system-libc=false.

So, in this context, MrDocs uses use-system-stdlib and use-system-libc as false by default. Of course, you'll still need access to the C and C++ standard libraries. For this reason, MrDocs bundles libc++ headers in <mrdocs-root>/share/mrdocs/headers/libcxx and <mrdocs-root>/share/mrdocs/headers/clang, and bundles libc stubs in <mrdocs-root>/share/mrdocs/headers/libc-stubs. These are used when stdlib-includes and libc-includes are false and they can be adjusted with stdlib-includes and libc-includes.

The reason for that is reproducibility. You want to be able to build your documentation and don't want it to stop working because some platform details have changed. You want it to keep working even if the platform changes (for instance, we don't want builds to break when there are slight changes in the boost release tools). Disabling these options by default also helps avoid conflicts where the same symbol or header is defined twice: the compilation database includes some system paths relevant to one compiler (say MSVC), but that then breaks things when MrDocs attempts to compile it with clang.

Although this gives us reproducibility, one inconvenience of this solution is that system headers (things like linux/version.h or Windows.h) are not available by default, which is a side effect of compilers including all system paths for LibC. MrDocs becomes a sandboxed environment where only the C and C++ standard libraries are available.

For many libraries, where there are no dependencies outside the standard libraries, the user won't even notice the difference. But code that depends on system libraries will need to handle that. So there are three solutions to this, and these solutions are in a continuum regarding use-system-stdlib/use-system-libc and the design of the code:

  • The first solution is to just enable use-system-libc. MrDocs will use the bundled LibC++ for the C++ standard library, use the system for the C standard library, and make system paths available. The trade-offs are the ones described above.
  • The second solution is to explicitly include the paths you need in your compilation database. For instance, you can get CMake to explicitly find linux/version.h and include that directory with -isystem or -I.
  • The third solution, depending on the design of your library, is to implement a different path for MrDocs where you don't need linux/version.h or Windows.h. Just like you have macros to decide what to include in these cases, you can use the __MRDOCS__ macro to include a new path. Because whatever comes from Linux/version.h or Windows.h is not being exposed in the public API of your library, you have to use replacements that make sense for the documentation. In some cases, this might require several stubs for the MrDocs path, but often not even that.

@anarthal
Copy link
Author

Well, that's coming from Asio, so ifdef-ing it out is not an option. use-system-libc is good for me. But I'm guessing this is going to happen to more than one person.

@alandefreitas
Copy link
Collaborator

But I'm guessing this is going to happen to more than one person.

Yes. There's no way around that. All we can do is document it.

@alandefreitas alandefreitas changed the title System headers not found when using use-system-stdlib: true Improve use-system-libc documentation Jan 15, 2025
@alandefreitas alandefreitas added the Docs Related to program documentation label Jan 15, 2025
alandefreitas added a commit to alandefreitas/mrdocs that referenced this issue Jan 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Docs Related to program documentation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants