https://github.com/jwillikers/strlen
A sample implementation of the standard C library’s strlen function
https://github.com/jwillikers/strlen
c cmake cpp demo
Last synced: about 1 year ago
JSON representation
A sample implementation of the standard C library’s strlen function
- Host: GitHub
- URL: https://github.com/jwillikers/strlen
- Owner: jwillikers
- License: other
- Archived: true
- Created: 2020-11-23T15:51:09.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2024-10-12T14:23:27.000Z (over 1 year ago)
- Last Synced: 2025-04-06T21:52:14.361Z (over 1 year ago)
- Topics: c, cmake, cpp, demo
- Language: CMake
- Homepage: https://codeberg.org/jwillikers/strlen
- Size: 58.6 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.adoc
- License: LICENSE.adoc
- Code of conduct: CODE_OF_CONDUCT.adoc
Awesome Lists containing this project
README
= strlen
Jordan Williams
:experimental:
:icons: font
ifdef::env-github[]
:tip-caption: :bulb:
:note-caption: :information_source:
:important-caption: :heavy_exclamation_mark:
:caution-caption: :fire:
:warning-caption: :warning:
endif::[]
A sample implementation of the standard C library's https://en.cppreference.com/w/cpp/string/byte/strlen[`strlen`] function.
== Getting Started
This sections describes how to setup the build environment required by the project.
This project has been tested with the {cpp} compilers from GCC 10 and Clang 11 on https://ubuntu.com/[Ubuntu] 20.10.
Install at least one of these compilers with the following commands.
GCC 10::
+
[,sh]
----
sudo apt -y install gcc g++
----
Clang 11::
+
[,sh]
----
sudo apt -y install clang-11 lld
----
=== asdf
The preferred method of installing build dependencies is with https://asdf-vm.com/[asdf].
This ensures that the proper versions of the necessary tools are installed.
Pipenv is used to manage Python tools.
Combining asdf and Pipenv with https://direnv.net/[direnv] allows automatically configuring and loading a Python virtual environment upon entering the project directory.
The steps below will create an environment for building the project.
These steps assume you are on Ubuntu and familiar with the Linux command-line and https://git-scm.com/[Git].
Instructions are provided for the https://www.gnu.org/software/bash/[Bash], https://fishshell.com/[fish], and https://www.zsh.org/[ZSH] shells.
. Clone the project's repository from GitHub.
+
[,sh]
----
git clone https://codeberg.org/jwillikers/strlen.git
----
. Change into the project's directory.
+
[,sh]
----
cd strlen
----
. Install the dependencies needed for asdf.
+
[,sh]
----
sudo apt -y install curl git
----
. Pull down the https://github.com/asdf-vm/asdf[asdf repository] in to your home directory.
+
[,sh]
----
git clone https://github.com/asdf-vm/asdf.git ~/.asdf
Cloning into '/home/ubuntu/.asdf'...
remote: Enumerating objects: 145, done.
remote: Counting objects: 100% (145/145), done.
remote: Compressing objects: 100% (85/85), done.
remote: Total 5782 (delta 76), reused 93 (delta 59), pack-reused 5637
Receiving objects: 100% (5782/5782), 1.09 MiB | 6.01 MiB/s, done.
Resolving deltas: 100% (3293/3293), done.
----
. Checkout the latest version of asdf.
+
--
_fish_::
+
[,sh]
----
git -C ~/.asdf switch --detach (git -C ~/.asdf describe --abbrev=0 --tags)
HEAD is now at c6145d0 Update version to 0.8.0
----
_Bash / ZSH_::
+
[source,bash]
----
git -C ~/.asdf switch --detach $(git -C ~/.asdf describe --abbrev=0 --tags)
HEAD is now at c6145d0 Update version to 0.8.0
----
--
. Enable asdf in your shell.
+
--
_fish_::
+
[,sh]
----
mkdir -p ~/.config/fish/conf.d; and echo "source ~/.asdf/asdf.fish" > ~/.config/fish/conf.d/asdf.fish
----
_Bash_::
+
[source,bash]
----
echo '. $HOME/.asdf/asdf.sh' >> ~/.bashrc
----
_ZSH_::
+
[source,zsh]
----
echo '. $HOME/.asdf/asdf.sh' >> ~/.zshrc
----
--
. Install shell completions for asdf.
+
--
_fish_::
+
[,sh]
----
mkdir -p ~/.config/fish/completions; and ln -s ~/.asdf/completions/asdf.fish ~/.config/fish/completions
----
_Bash_::
+
[source,bash]
----
echo '. $HOME/.asdf/completions/asdf.bash' >> ~/.bashrc
----
_ZSH_::
+
[source,zsh]
----
echo -e 'fpath=(${ASDF_DIR}/completions $fpath)\nautoload -Uz compinit\ncompinit' >> ~/.zshrc
----
--
. Reload fish to make asdf available.
+
--
_fish_::
+
[,sh]
----
exec fish
----
_Bash_::
+
[source,bash]
----
source ~/.bashrc
----
_ZSH_::
+
[source,zsh]
----
source ~/.zshrc
----
--
. Add the https://github.com/danhper/asdf-python[Python plugin] to asdf.
+
[,sh]
----
asdf plugin add python
initializing plugin repository...
Cloning into '/home/ubuntu/.asdf/repository'...
remote: Enumerating objects: 2450, done.
remote: Total 2450 (delta 0), reused 0 (delta 0), pack-reused 2450
Receiving objects: 100% (2450/2450), 553.27 KiB | 3.57 MiB/s, done.
Resolving deltas: 100% (1140/1140), done.
----
. Install the necessary dependencies to build Python which are helpfully documented in the https://github.com/pyenv/pyenv/wiki#suggested-build-environment[Pyenv Wiki].
+
[,sh]
----
sudo apt -y install make build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils \
tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
----
. Before installing Pipenv, configure the default _global_ Python version for the user.
+
--
You can use the system version of Python by default or another version of your choice.
IMPORTANT: Whenever the user's global version of Python is updated, Pipenv must be reinstalled which may require that all virtual environments be rebuilt.
--
** Use the system's Python as the default.
... Ubuntu installs Python as either `python2` or `python3` on the system.
+
--
This means that asdf won't be able to detect the system version of python.
Install the Python package `python-is-python3` to install a `python` executable for the system which uses `python3`.
[,sh]
----
sudo apt -y install python-is-python3
----
--
... Install pip and venv because they are not installed by default on Ubuntu.
+
[,sh]
----
sudo apt -y install python3-pip python3-venv
----
... Set the user's Python to the system-wide version.
+
[,sh]
----
asdf global python system
----
** Or, you can use another version of Python for your user such as the latest and greatest version.
... Build and install the latest version of Python.
+
[,sh]
----
asdf install python latest
----
... Set the user's Python to the latest version available at this time.
+
--
_fish_::
+
[,sh]
----
asdf global python (asdf latest python)
----
_Bash / ZSH_::
+
[source,bash]
----
asdf global python $(asdf latest python)
----
--
. Install https://pipxproject.github.io/pipx/[pipx] for installing Pipenv in an isolated environment.
+
[,sh]
----
python -m pip install --user pipx
Collecting pipx
Downloading pipx-0.15.6.0-py3-none-any.whl (43 kB)
|████████████████████████████████| 43 kB 636 kB/s
Collecting argcomplete<2.0,>=1.9.4
Downloading argcomplete-1.12.1-py2.py3-none-any.whl (38 kB)
Collecting packaging>=20.0
Downloading packaging-20.4-py2.py3-none-any.whl (37 kB)
Collecting userpath>=1.4.1
Downloading userpath-1.4.1-py2.py3-none-any.whl (14 kB)
Collecting pyparsing>=2.0.2
Downloading pyparsing-2.4.7-py2.py3-none-any.whl (67 kB)
|████████████████████████████████| 67 kB 1.4 MB/s
Requirement already satisfied: six in /usr/lib/python3/dist-packages (from packaging>=20.0->pipx) (1.14.0)
Requirement already satisfied: click in /usr/lib/python3/dist-packages (from userpath>=1.4.1->pipx) (7.0)
Requirement already satisfied: distro; platform_system == "Linux" in /usr/lib/python3/dist-packages (from userpath>=1.4.1->pipx) (1.4.0)
Installing collected packages: argcomplete, pyparsing, packaging, userpath, pipx
WARNING: The script userpath is installed in '/home/ubuntu/.local/bin' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
WARNING: The script pipx is installed in '/home/ubuntu/.local/bin' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed argcomplete-1.12.1 packaging-20.4 pipx-0.15.6.0 pyparsing-2.4.7 userpath-1.4.1
----
. Add the directory where pip installs executables for the local user to `PATH`.
+
[,sh]
----
python -m pipx ensurepath
Success! Added /home/ubuntu/.local/bin to the PATH environment
variable.
/home/ubuntu/.local/bin has been been added to PATH, but you need to
open a new terminal or re-login for this PATH change to take
effect.
Consider adding shell completions for pipx. Run 'pipx completions' for
instructions.
You will need to open a new terminal or re-login for the PATH changes
to take effect.
Otherwise pipx is ready to go! ✨ 🌟 ✨
----
. To make executables installed by pipx available, reload your shell.
+
--
_fish_::
+
[,sh]
----
exec fish
----
_Bash_::
+
[source,bash]
----
source ~/.bashrc
----
_ZSH_::
+
[source,zsh]
----
source ~/.zshrc
----
--
. Install Pipenv.
+
[,sh]
----
python -m pipx install pipenv
installed package pipenv 2020.8.13, Python 3.8.5
These apps are now globally available
- pipenv
- pipenv-resolver
done! ✨ 🌟 ✨
----
. Add completions for Pipenv to your shell.
+
--
_fish_::
+
[,sh]
----
echo "eval (pipenv --completion)" > ~/.config/fish/completions/pipenv.fish
----
_Bash_::
+
[source,bash]
----
echo 'eval "$(pipenv --completion)"' >> ~/.bashrc
----
_ZSH_::
+
[source,zsh]
----
echo 'eval "$(pipenv --completion)"' >> ~/.zshrc
----
--
. Add the asdf ccache plugin.
+
[,sh]
----
asdf plugin add ccache
----
. Add the asdf CMake plugin.
+
[,sh]
----
asdf plugin add cmake
----
. Add the asdf direnv plugin.
+
[,sh]
----
asdf plugin add direnv
----
. Add the asdf Ninja plugin.
+
[,sh]
----
asdf plugin add ninja
----
. Integrate direnv with your shell.
+
--
_fish_::
+
[,sh]
----
mkdir -p ~/.config/fish/conf.d; \
and echo "asdf exec direnv hook fish | source" > ~/.config/fish/conf.d/direnv.fish
----
_Bash_::
+
[source,bash]
----
echo 'eval "$(asdf exec direnv hook bash)"' >> ~/.bashrc
----
_ZSH_::
+
[source,zsh]
----
echo 'eval "$(asdf exec direnv hook zsh)"' >> ~/.zshrc
----
--
. Make the asdf feature, i.e. the command `use asdf`, available in direnv.
+
--
_fish_::
+
[,sh]
----
mkdir -p ~/.config/direnv; \
and echo 'source "$(asdf direnv hook asdf)"' >> ~/.config/direnv/direnvrc
----
_Bash / ZSH_::
+
[source,bash]
----
mkdir -p ~/.config/direnv; \
echo 'source "$(asdf direnv hook asdf)"' >> ~/.config/direnv/direnvrc
----
NOTE: The `direnvrc` file should only use Bash syntax.
--
. Install the project's asdf dependencies.
+
[,sh]
----
asdf install
----
. Allow direnv to alter the environment for the project directory.
+
[,sh]
----
direnv allow
----
== Build
When using a single configuration generator with CMake, set the appropriate build type when configuring the build.
Likely, this build type will be either _Debug_ or _Release_, both of which are enumerated below in addition to using either GCC 10 or Clang 11.
These examples also enable several helpful options to improve performance of the build and the resulting binaries.
These examples assume you are in the top-level directory of the project.
Release::
+
--
Configure a release build in the aptly named _build_ directory like so.
GCC::
+
[,sh]
----
cmake \
-GNinja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_UNITY_BUILD=yes \
-DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=gold" \
-DCMAKE_MODULE_LINKER_FLAGS="-fuse-ld=gold" \
-DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=gold" \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=yes \
-B build -S .
----
Clang 11::
+
--
[,sh]
----
cmake \
-GNinja \
-DCMAKE_C_COMPILER=/usr/bin/clang-11 \
-DCMAKE_CXX_COMPILER=/usr/bin/clang++-11 \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_UNITY_BUILD=yes \
-DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" \
-DCMAKE_MODULE_LINKER_FLAGS="-fuse-ld=lld" \
-DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld" \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION:BOOL=yes \
-B build -S .
----
NOTE: On Ubuntu 20.10, Clang 11 compiler front-ends are installed with the suffix `-11`.
--
--
Debug::
+
--
To build in debug mode, set the build type appropriately, and enable `-gsplit-dwarf` while you're at it.
GCC::
+
[,sh]
----
cmake \
-GNinja \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_UNITY_BUILD=yes \
-DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=gold" \
-DCMAKE_MODULE_LINKER_FLAGS="-fuse-ld=gold" \
-DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=gold" \
-DCMAKE_C_FLAGS_DEBUG="-gsplit-dwarf" \
-DCMAKE_CXX_FLAGS_DEBUG="-gsplit-dwarf" \
-B build -S .
----
Clang 11::
+
[,sh]
----
cmake \
-GNinja \
-DCMAKE_C_COMPILER=/usr/bin/clang-11 \
-DCMAKE_CXX_COMPILER=/usr/bin/clang++-11 \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_UNITY_BUILD=yes \
-DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" \
-DCMAKE_MODULE_LINKER_FLAGS="-fuse-ld=lld" \
-DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld" \
-DCMAKE_C_FLAGS_DEBUG="-gsplit-dwarf" \
-DCMAKE_CXX_FLAGS_DEBUG="-gsplit-dwarf" \
-B build -S .
----
--
Then build.
[,sh]
----
cmake --build build
----
=== Google Sanitizers
Support for Google Sanitizers is provided by the https://github.com/StableCoder/cmake-scripts[cmake-scripts] project.
Set the `USE_SANITIZER` CMake variable to an appropriate value as documented https://github.com/StableCoder/cmake-scripts#sanitizer-builds-sanitizerscmake[here].
Use the Address sanitizer like so.
[,sh]
----
cmake -DUSE_SANITIZER=Address -B build -S .
----
== Test
Unit tests use https://github.com/boost-ext/ut[[Boost::ext\].μt] and are written in {cpp}.
The unit tests can be run with https://cmake.org/cmake/help/latest/module/CTest.html[CTest].
. Change in to the build directory.
+
[,sh]
----
cd build
----
. Run the tests by executing the `ctest` executable.
[,sh]
----
ctest
----
== Format
The https://clang.llvm.org/docs/ClangFormat.html[clang-format] and https://cmake-format.readthedocs.io/en/latest/cmake-format.html[cmake-format] tools are used to format the source code files.
The https://github.com/TheLartians/Format.cmake[Format.cmake] module provides build targets to simplify the use of these tools.
Format the all source files by building the CMake target `fix-format`.
[,sh]
----
cmake --build build --target fix-format
----
== Contributing
Contributions in the form of issues, feedback, and even pull requests are welcome.
Make sure to adhere to the project's link:CODE_OF_CONDUCT.adoc[Code of Conduct].
== Open Source Software
This project is built on the hard work of countless open source contributors.
Several of these projects are enumerated below.
* https://asciidoctor.org/[Asciidoctor]
* https://asdf-vm.com/#/[asdf]
* https://github.com/asdf-community/asdf-direnv[asdf-direnv]
* https://github.com/boost-ext/ut[[Boost::ext\].μt]
* https://ccache.dev/[ccache]
* https://github.com/TheLartians/Ccache.cmake[Ccache.cmake]
* https://clang.llvm.org/extra/clang-tidy/[Clang-Tidy]
* https://clang.llvm.org/docs/ClangFormat.html[ClangFormat]
* https://cmake.org/[CMake]
* https://cmake-format.readthedocs.io/en/latest/index.html[cmakelang]
* https://github.com/StableCoder/cmake-scripts[CMake Scripts]
* https://direnv.net/[direnv]
* https://git-scm.com/[Git]
* https://github.com/TheLartians/ModernCppStarter[ModernCppStarter]
* https://ninja-build.org/[Ninja]
* https://rouge.jneen.net/[Rouge]
* https://www.ruby-lang.org/en/[Ruby]
== Code of Conduct
The project's Code of Conduct is available in the link:CODE_OF_CONDUCT.adoc[] file.
== License
This repository is licensed under the https://www.gnu.org/licenses/gpl-3.0.html[GPLv3], available in the link:LICENSE.adoc[] file.
© 2020-2024 Jordan Williams
== Authors
mailto:{email}[{author}]