diff --git a/libc/examples/README.md b/libc/examples/README.md new file mode 100644 --- /dev/null +++ b/libc/examples/README.md @@ -0,0 +1,92 @@ +Examples +======== +This directory contains 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: + +``` +$> cd # example $> cd hello_world +$> 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 [this](https://libc.llvm.org/overlay_mode.html) to learn how to +install the libc's overlay static archive name `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`: + +``` +$> cmake ../ -G \ + -DLIBC_OVERLAY_ARCHIVE_DIR= +``` + +`` in the generator of your choice, typically `Unix Makefiles` or `Ninja` on Linux +like platforms. Once configured with `cmake` as above, you can build the example +as follows: + +``` +$> make # If is "Unix Makefiles" +``` + +or + +``` +$> ninja # If is "Ninja" +``` + +Building against a full libc +---------------------------- + +Before you can link an example against the full libc, you will have to first +install it. See [this](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: + +``` +$> cmake ../ -G -DLIBC_FULLBUILD=ON \ + -DCMAKE_SYSROOT= \ + -DCMAKE_C_COMPILER=/bin/clang \ + -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY +``` + +In the above `cmake` command, `` is the generator of your choice, typically +`Unix Makefiles` or `Ninja` on Linux like platforms. `` 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 a shared libraries and dynamic linking and +loading. After the `cmake` command, you can build the example as follows: + + +``` +$> make # If is "Unix Makefiles" +``` + +or + +``` +$> ninja # If is "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; +}