diff --git a/libc/examples/README.md b/libc/examples/README.md --- a/libc/examples/README.md +++ b/libc/examples/README.md @@ -1 +1,79 @@ -Coming soon, stay tuned! +Examples +======== +This directory contains a few example programs which illustrate how one can set +up their own projects to use LLVM's libc, either as an overlay or as the only +libc in their projects. See the +[the usage mode document](https://libc.llvm.org/usage_modes.html) for more +information about the different modes in which one can build and use the libc. + +Building the Examples +===================== +Each example has its own directory which contain the source code and the CMake +build set up. To build an example, create a directory named `build` in the +example's directory: + +```bash +$> cd +$> mkdir build +$> cd build +``` + +Each example can be built to use the libc in either +[the overlay mode](https://libc.llvm.org/overlay_mode.html) or the +[full build mode](https://libc.llvm.org/fullbuild_mode.html). The CMake +configure step differs slightly depending on the mode you want to use the libc +in. + +Building against an overlay libc +-------------------------------- + +Before you can link an example against the overlay libc, you will have to +install it. See [the documentation of the overlay mode](https://libc.llvm.org/overlay_mode.html) +to learn how to install the libc's overlay static archive named `libllvmlibc.a`. +Once installed, to build an example against it, you have specify the directory +in which the static archive is installed with the option +`LIBC_OVERLAY_ARCHIVE_DIR`: + +```bash +$> cmake ../ -G \ + -DLIBC_OVERLAY_ARCHIVE_DIR= +``` + +Next, if `Ninja` is used for ``, you can build the example as follows: + +```bash +$> ninja +``` + +Building against a full libc +---------------------------- + +Before you can link an example against the full libc, you will have to first +install it. See [the documentation of the full build mode](https://libc.llvm.org/fullbuild_mode.html) +to learn how to install a full libc along with the other LLVM toolchain pieces +like `clang`, `lld` and `compiler-rt`. The CMake build for the examples will +assume that you have all of these components installed in a special sysroot +(see decription of the `--sysroot` option +[here](https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html).) Once you +have installed them, you have to inform CMake that we are linking against the +full libc as follows: + +```bash +$> cmake ../ -G -DLIBC_FULLBUILD=ON \ + -DCMAKE_SYSROOT= \ + -DCMAKE_C_COMPILER=/bin/clang \ + -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY +``` + +`` is the path to the sysroot directory you have set up while +installing the full libc. The option +`-DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY` tells CMake to not attempt +linking full executables against shared libraries. We have to use this as LLVM's +libc does not yet have support for shared libraries and dynamic linking. After +the above `cmake` command, assuming `Ninja` was used for ``, you can build +the example as follows: + + +```bash +$> ninja +``` diff --git a/libc/examples/examples.cmake b/libc/examples/examples.cmake new file mode 100644 --- /dev/null +++ b/libc/examples/examples.cmake @@ -0,0 +1,16 @@ +function(add_example name) + add_executable( + ${name} + ${ARGN} + ) + + if(LIBC_FULLBUILD) + target_link_options(${name} PRIVATE -static -rtlib=compiler-rt -fuse-ld=lld) + elseif(LIBC_OVERLAY_ARCHIVE_DIR) + target_link_directories(${name} PRIVATE ${LIBC_OVERLAY_ARCHIVE_DIR}) + target_link_options(${name} PRIVATE -l:libllvmlibc.a) + else() + message(FATAL_ERROR "Either LIBC_FULLBUILD should be on or " + "LIBC_OVERLAY_ARCHIVE_DIR should be set.") + endif() +endfunction() diff --git a/libc/examples/hello_world/.gitignore b/libc/examples/hello_world/.gitignore new file mode 100644 --- /dev/null +++ b/libc/examples/hello_world/.gitignore @@ -0,0 +1,10 @@ +#==============================================================================# +# This file specifies intentionally untracked files that git should ignore. +# See: http://www.kernel.org/pub/software/scm/git/docs/gitignore.html +# +# This file is intentionally different from the output of `git svn show-ignore`, +# as most of those are useless. +#==============================================================================# + +# Nested build directory +/build* diff --git a/libc/examples/hello_world/CMakeLists.txt b/libc/examples/hello_world/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/examples/hello_world/CMakeLists.txt @@ -0,0 +1,8 @@ +project(hello_world) +cmake_minimum_required(VERSION 3.13.4) +include(../examples.cmake) + +add_example( + hello_world + hello_world.c +) diff --git a/libc/examples/hello_world/hello_world.c b/libc/examples/hello_world/hello_world.c new file mode 100644 --- /dev/null +++ b/libc/examples/hello_world/hello_world.c @@ -0,0 +1,14 @@ +//===-- libc example - hello world ----------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include + +int main() { + printf("Hello, World\n"); + return 0; +}