├── .ackrc ├── .gitattributes ├── .github └── workflows │ ├── mulle-sde-ci.yml │ └── semgrep.yml ├── .gitignore ├── .mulle ├── .gitignore ├── README.md ├── etc │ ├── env │ │ ├── auxscope │ │ ├── environment-global.sh │ │ ├── environment-host-ci-prerelease.sh │ │ ├── environment-project.sh │ │ ├── environment-user-mulle-kybernetik-tv.sh │ │ ├── environment-user-nat-os-linux.sh │ │ └── tool.linux │ ├── match │ │ └── ignore.d │ │ │ ├── 00-directories--none │ │ │ ├── 10-boring--none │ │ │ └── 20-generated--none │ ├── project │ │ └── version-info.sh │ └── sourcetree │ │ └── config └── share │ ├── env │ ├── auxscope │ ├── environment-extension.sh │ ├── environment-plugin-os-darwin.sh │ ├── environment-plugin.sh │ ├── environment-post-extension.sh │ ├── environment.sh │ ├── include-environment.sh │ ├── motd │ ├── style │ ├── tool-extension │ ├── tool-extension.darwin │ ├── tool-extension.windows │ ├── tool-plugin │ └── version │ ├── match │ ├── ignore.d │ │ └── 10-boring--none │ └── match.d │ │ ├── 10-sourcetree--all │ │ ├── 70-header--private-generated-headers │ │ ├── 70-header--public-generated-headers │ │ ├── 75-header--private-generic-headers │ │ ├── 75-header--public-generic-headers │ │ ├── 80-header--private-headers │ │ ├── 85-header--public-headers │ │ ├── 86-header--project-only-headers │ │ ├── 90-source--standalone-sources │ │ ├── 95-cmakefile--all │ │ └── 95-source--sources │ ├── monitor │ ├── bin │ │ ├── cmakefile-callback │ │ ├── filesystem-callback │ │ ├── header-callback │ │ ├── resource-callback │ │ ├── source-callback │ │ └── sourcetree-callback │ └── libexec │ │ ├── craft-task.sh │ │ ├── filesystem-task.sh │ │ └── sourcetree-task.sh │ ├── sde │ ├── extension │ └── version │ │ ├── mulle-c │ │ ├── c │ │ ├── c-cmake │ │ ├── c-demo │ │ ├── c-developer │ │ └── github-actions │ │ └── mulle-sde │ │ ├── c │ │ ├── c-cmake │ │ ├── c-demo │ │ ├── cmake │ │ └── sde │ └── sourcetree │ └── config ├── .touch ├── CMakeLists.txt ├── LICENSE ├── README.md ├── RELEASENOTES.md ├── clib.json ├── cmake ├── Headers.cmake ├── README.md ├── Sources.cmake ├── reflect │ ├── _Dependencies.cmake │ ├── _Headers.cmake │ ├── _Libraries.cmake │ ├── _Resources.cmake │ └── _Sources.cmake └── share │ ├── AllLoadC.cmake │ ├── CMakeTweaksC.cmake │ ├── CompilerDetectionC.cmake │ ├── CompilerFlagsC.cmake │ ├── CompilerWarningsC.cmake │ ├── Dependencies.cmake │ ├── DependenciesAndLibraries.cmake │ ├── Environment.cmake │ ├── Executable.cmake │ ├── ExecutableAux.cmake │ ├── Files.cmake │ ├── FinalOutput.cmake │ ├── Framework.cmake │ ├── FrameworkAux.cmake │ ├── Headers.cmake │ ├── IDESupport.cmake │ ├── InstallCMakeInclude.cmake │ ├── InstallCMakePackage.cmake │ ├── InstallExecutable.cmake │ ├── InstallFramework.cmake │ ├── InstallLibrary.cmake │ ├── InstallRpath.cmake │ ├── Library.cmake │ ├── LibraryAux.cmake │ ├── MacOSXFrameworkInfo.plist.in.sample │ ├── Motd.cmake │ ├── MultiPhase.cmake │ ├── PostExecutable.cmake │ ├── PostFiles.cmake │ ├── PostFramework.cmake │ ├── PostLibrary.cmake │ ├── PostSharedLibrary.cmake │ ├── PreExecutable.cmake │ ├── PreFiles.cmake │ ├── PreLibrary.cmake │ ├── README.md │ ├── Resources.cmake │ ├── Sources.cmake │ ├── StandaloneC.cmake │ ├── StringCase.cmake │ ├── mulle-thread-config.cmake.in │ └── mulle-thread-config.h.in ├── cola ├── api.md.bud ├── description.md.bud ├── info.md.bud └── properties.plist ├── dox ├── API_ATOMIC.md ├── API_MUTEX.md ├── API_THREAD.md ├── API_TSS.md ├── BUILD.md └── CONVENIENT_BOUNCE.md ├── mulle-thread.sublime-project ├── overview.dot.svg ├── run-on-ipad ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── ViewController.h ├── ViewController.m └── main.m ├── src ├── generic │ ├── include-private.h │ └── include.h ├── mintomic-empty.c ├── mulle-atomic-c11.h ├── mulle-atomic-mintomic.h ├── mulle-atomic.h ├── mulle-thread-c11.h ├── mulle-thread-linkage.c ├── mulle-thread-pthreads.h ├── mulle-thread-standalone.c ├── mulle-thread-windows.c ├── mulle-thread-windows.h ├── mulle-thread.h └── reflect │ ├── _mulle-thread-include-private.h │ ├── _mulle-thread-include.h │ ├── _mulle-thread-provide.h │ └── _mulle-thread-versioncheck.h └── test ├── .mulle-test └── etc │ └── environment.sh ├── .mulle ├── .gitignore ├── README.md ├── etc │ ├── env │ │ ├── auxscope │ │ ├── environment-global.sh │ │ ├── environment-host-ci-prerelease.sh │ │ └── environment-project.sh │ └── sourcetree │ │ └── config └── share │ ├── env │ ├── auxscope │ ├── environment-plugin-os-darwin.sh │ ├── environment-plugin.sh │ ├── environment.sh │ ├── include-environment.sh │ ├── style │ ├── tool-plugin │ └── version │ ├── sde │ └── extension │ └── test │ └── mulle-test ├── atomic ├── README.md ├── add.c ├── bench.c ├── bench.stdout ├── cas.c └── default.stdout ├── mutex ├── mutex-do.c ├── mutex-do.stdout ├── mutex-stress.c ├── mutex-stress.stdout ├── mutex.c └── mutex.stdout ├── threads ├── threads.c └── threads.stdout └── tss ├── tss.c └── tss.stdout /.ackrc: -------------------------------------------------------------------------------- 1 | --ignore-dir=addiction 2 | --ignore-dir=build 3 | --ignore-dir=dependency 4 | --ignore-dir=kitchen 5 | --ignore-dir=stash 6 | --ignore-dir=.mulle/var 7 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # ### > generated by mulle-sde (extensions/mulle-sde/sde/init) 2 | # Tweak GitHub language statistics 3 | 4 | # .inc is generally C 5 | 6 | *.h linguist-language=C 7 | *.inc linguist-language=C 8 | 9 | # remove boring files 10 | .mulle/** linguist-generated 11 | .vscode/** linguist-generated 12 | cmake/** linguist-generated 13 | 14 | # ### < generated by mulle-sde (extensions/mulle-sde/sde/init) 15 | 16 | -------------------------------------------------------------------------------- /.github/workflows/mulle-sde-ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | workflow_dispatch: 9 | 10 | env: 11 | BUILD_TYPE: release 12 | OTHER_PROJECTS: "mulle-c/mulle-c-developer;" 13 | 14 | jobs: 15 | build: 16 | runs-on: ${{ matrix.os }} 17 | strategy: 18 | matrix: 19 | os: [ ubuntu-latest] # macos-latest, 20 | 21 | steps: 22 | - name: Set MULLE_HOSTNAME 23 | run: | 24 | name="${GITHUB_REF##*/}" 25 | MULLE_HOSTNAME="${MULLE_HOSTNAME:-ci-${name##*-}}" 26 | echo "MULLE_HOSTNAME=${MULLE_HOSTNAME}" >> $GITHUB_ENV 27 | 28 | - name: Add to path 29 | run: echo "$HOME/bin" >> $GITHUB_PATH 30 | 31 | - name: Dump Environment 32 | run: env | sort 33 | 34 | - uses: actions/checkout@v4 35 | 36 | - uses: mulle-sde/github-ci@v2 37 | 38 | - name: Dump Project Environment 39 | run: | 40 | [ ! -d .mulle/etc/env ] || ls -l .mulle/etc/env/environment*.sh 41 | mulle-sde environment 42 | 43 | - name: Mulle-SDE Fetch 44 | run: mulle-sde fetch 45 | 46 | - name: Mulle-SDE Craft 47 | run: mulle-sde craft --${BUILD_TYPE:-release} 48 | 49 | - name: Mulle-SDE Test 50 | run: | 51 | [ ! -d test ] || mulle-sde test 52 | -------------------------------------------------------------------------------- /.github/workflows/semgrep.yml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_dispatch: {} 3 | pull_request: {} 4 | push: 5 | branches: 6 | - main 7 | - master 8 | paths: 9 | - .github/workflows/semgrep.yml 10 | # schedule: 11 | # random HH:MM to avoid a load spike on GitHub Actions at 00:00 12 | # - cron: 5 8 * * * 13 | name: Semgrep 14 | jobs: 15 | semgrep: 16 | name: semgrep/ci 17 | runs-on: ubuntu-20.04 18 | env: 19 | SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} 20 | container: 21 | image: returntocorp/semgrep 22 | steps: 23 | - uses: actions/checkout@v4 24 | - run: semgrep ci 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | ._.DS_Store 3 | .idea/ 4 | 5 | var/ 6 | *.dSYM/ 7 | *.exe 8 | *.exe.debug 9 | *.old 10 | *.bak 11 | 12 | environment-os-*.sh 13 | environment-host-*.sh 14 | !environment-host-ci-*.sh 15 | 16 | # various cruft 17 | 18 | bin/tap-info.sh 19 | tap-info.sh 20 | 21 | # ### > generated by mulle-sde (extensions/mulle-sde/sde/init) 22 | 23 | # generally /var directories are not interesting 24 | .mulle/var/ 25 | 26 | # .mulle-env /bin and /libexec are not interesting 27 | 28 | .mulle/bin/ 29 | .mulle/libexec/ 30 | 31 | # style is "fluctuating" on a per-user level so not interesting 32 | .mulle/etc/env/style 33 | 34 | 35 | 36 | # ### < generated by mulle-sde (extensions/sde/init) 37 | 38 | stash/ 39 | build/ 40 | kitchen/ 41 | dependency/ 42 | mintomic 43 | 44 | .mulle-sourcetree-fix 45 | *.sublime-workspace 46 | .mulle-make-build-dir 47 | version.old 48 | .gdb_history 49 | .ackrc 50 | wilted/ 51 | mulle-template-composer-* 52 | mulle-markdown-preview-*.html 53 | coverage*.html 54 | *.gcda 55 | *.gcno 56 | cola/wilted/ 57 | CMakeLists.txt.bak 58 | .mulle/etc/make/build-dir 59 | vgcore.* 60 | -------------------------------------------------------------------------------- /.mulle/.gitignore: -------------------------------------------------------------------------------- 1 | var/ 2 | environment-host-*.sh 3 | !environment-host-ci-*.sh 4 | -------------------------------------------------------------------------------- /.mulle/README.md: -------------------------------------------------------------------------------- 1 | # .mulle 2 | 3 | This `.mulle` folder is used by [mulle-sde](//mulle-sde.github.io) to 4 | store project information. 5 | 6 | ## Structure 7 | 8 | * `etc` is user editable, changes will be preserved. 9 | * `share` is read only, changes will be lost on the next upgrade. 10 | * `var` is ephemeral. You can delete and it will get recreated. 11 | 12 | Every mulle-sde tool may have its own subfolder within those three folders. 13 | It's name will be the name of the tool without the "mulle-" prefix. 14 | 15 | You can edit the files in `etc` with any editor, but for consistency and 16 | ease of use, it's usually better to use the appropriate mulle-sde tool. 17 | 18 | ## Remove .mulle 19 | 20 | The share folder is often write protected, to prevent accidental user edits. 21 | 22 | ``` 23 | chmod -R ugo+rwX .mulle && rm -rf .mulle 24 | ``` 25 | 26 | -------------------------------------------------------------------------------- /.mulle/etc/env/auxscope: -------------------------------------------------------------------------------- 1 | project;20 2 | -------------------------------------------------------------------------------- /.mulle/etc/env/environment-global.sh: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # 4 | export MULLE_MATCH_TO_CMAKE_SOURCES_FILE="NONE" 5 | 6 | 7 | # 8 | # 9 | # 10 | export MULLE_SOURCETREE_RESOLVE_TAG="NO" 11 | 12 | 13 | -------------------------------------------------------------------------------- /.mulle/etc/env/environment-host-ci-prerelease.sh: -------------------------------------------------------------------------------- 1 | # 2 | # mulle-c11 nodetype: ${MULLE__C11_NODETYPE:-tar} 3 | # 4 | export MULLE__C11_NODETYPE="git" 5 | 6 | 7 | # 8 | # mulle-c11 url: ${MULLE__C11_URL:-https://github.com/mulle-c/mulle-c11/archive/${MULLE_TAG}.tar.gz} 9 | # 10 | export MULLE__C11_URL="https://github.com/mulle-c/mulle-c11.git" 11 | 12 | 13 | # 14 | # mulle-c11 branch: ${MULLE__C11_BRANCH} 15 | # 16 | export MULLE__C11_BRANCH="prerelease" 17 | 18 | 19 | -------------------------------------------------------------------------------- /.mulle/etc/env/environment-project.sh: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # 4 | export PROJECT_TYPE="library" 5 | 6 | 7 | # 8 | # 9 | # 10 | export PROJECT_NAME="mulle-thread" 11 | 12 | 13 | # 14 | # 15 | # 16 | export PROJECT_SOURCE_DIR="src" 17 | 18 | 19 | # 20 | # 21 | # 22 | export PROJECT_LANGUAGE="c" 23 | 24 | 25 | # 26 | # 27 | # 28 | export PROJECT_DIALECT="c" 29 | 30 | 31 | # 32 | # 33 | # 34 | export PROJECT_EXTENSIONS="c" 35 | 36 | 37 | # 38 | # 39 | # 40 | 41 | 42 | 43 | # 44 | # 45 | # 46 | 47 | 48 | 49 | # 50 | # 51 | # 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /.mulle/etc/env/environment-user-mulle-kybernetik-tv.sh: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # 4 | export MULLE_CRAFT_POST_PROJECT="/home/mulle-kybernetik-tv/bin/reamalgamate-mulle-core" 5 | 6 | 7 | -------------------------------------------------------------------------------- /.mulle/etc/env/environment-user-nat-os-linux.sh: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # 4 | export MULLE_CRAFT_POST_PROJECT="/home/mulle-kybernetik-tv/bin/reamalgamate-mulle-core" 5 | 6 | 7 | # 8 | # 9 | # 10 | export MULLE_CRAFT_CCACHE="sccache" 11 | 12 | 13 | -------------------------------------------------------------------------------- /.mulle/etc/env/tool.linux: -------------------------------------------------------------------------------- 1 | sccache 2 | -------------------------------------------------------------------------------- /.mulle/etc/match/ignore.d/00-directories--none: -------------------------------------------------------------------------------- 1 | # Everything is boring 2 | * 3 | 4 | # Except for src, src is interesting 5 | !src/ 6 | !tests/ 7 | 8 | # Except for mulle-sourcetree where we like the etc directory... 9 | # 10 | # If we specifically exclude !.mulle-sourcetree/etc only, that's no good for 11 | # mulle-find, which collects top-level directories only. So we specifcally 12 | # ignore some known boring subfolders only 13 | # 14 | !.mulle-sourcetree/ 15 | .mulle-sourcetree/var/ 16 | .mulle-sourcetree/share/ 17 | 18 | -------------------------------------------------------------------------------- /.mulle/etc/match/ignore.d/10-boring--none: -------------------------------------------------------------------------------- 1 | ../../../share/match/ignore.d/10-boring--none -------------------------------------------------------------------------------- /.mulle/etc/match/ignore.d/20-generated--none: -------------------------------------------------------------------------------- 1 | src/_mulle-aba-dependencies.h" 2 | -------------------------------------------------------------------------------- /.mulle/etc/project/version-info.sh: -------------------------------------------------------------------------------- 1 | # -- Version Info -- 2 | # 3 | # Keep these commented out, if the automatic detection works well 4 | # enough for you. If you don't have this file, there will be 5 | # not git operations. 6 | # 7 | # VERSIONFILE= 8 | # VERSIONNAME= 9 | -------------------------------------------------------------------------------- /.mulle/etc/sourcetree/config: -------------------------------------------------------------------------------- 1 | mulle-c11;${MULLE__C11_NODETYPE:-tar};no-all-load,no-cmake-inherit,no-import,no-link,no-recurse,no-singlephase;97F390B6-FA26-4BAC-BB87-90A654AAB3B6;${MULLE__C11_URL:-https://github.com/mulle-c/mulle-c11/archive/${MULLE_TAG}.tar.gz};${MULLE__C11_BRANCH};${MULLE__C11_TAG:-latest};; 2 | mintomic;${MINTOMIC_NODETYPE:-tar};no-all-load,no-build,no-header,no-import,no-link,no-recurse,no-share,no-symlink-windows;74cd2077-3124-4083-be6a-c643393aee69;${MINTOMIC_URL:-https://github.com/mulle-concurrent/mintomic/archive/${MULLE_TAG}.tar.gz};${MINTOMIC_BRANCH};${MINTOMIC_TAG:-mulle-objc};; 3 | stdthreads;none;no-all-load,no-build,no-cmake-inherit,no-delete,no-dependency,no-fs,no-import,no-update,only-platform-freebsd;91a3a06c-669f-4cd4-9060-562b3d0b6315;;;;; 4 | pthread;none;no-all-load,no-build,no-delete,no-dependency,no-fs,no-import,no-platform-android,no-platform-mingw,no-require,no-update;8fd8130b-1d75-4633-89b4-57e61467847e;;;;;aliases=pthreads,pthread 5 | -------------------------------------------------------------------------------- /.mulle/share/env/auxscope: -------------------------------------------------------------------------------- 1 | extension;30 2 | post-extension;210 3 | -------------------------------------------------------------------------------- /.mulle/share/env/environment-extension.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Reset to empty 3 | # 4 | export MULLE_SDE_REFLECT_CALLBACKS="sourcetree:filesystem" 5 | 6 | 7 | # 8 | # Used by `mulle-match find` to speed up the search. 9 | # 10 | export MULLE_MATCH_FILENAMES="config*:*.h:*.inc:*.c:CMakeLists.txt:*.cmake" 11 | 12 | 13 | # 14 | # Used by `mulle-match find` to locate files 15 | # 16 | export MULLE_MATCH_PATH=".mulle/etc/sourcetree:${PROJECT_SOURCE_DIR}:CMakeLists.txt:cmake" 17 | 18 | 19 | # 20 | # Used by `mulle-match find` to ignore boring subdirectories like .git 21 | # 22 | export MULLE_MATCH_IGNORE_PATH="" 23 | 24 | 25 | # 26 | # mulle-c and mulle-objc projects have an actual latest tag, so don't resolve 27 | # 28 | export MULLE_SOURCETREE_RESOLVE_TAG="NO" 29 | 30 | 31 | # 32 | # tell mulle-sde to keep files protected from read/write changes 33 | # 34 | export MULLE_SDE_PROTECT_PATH="cmake/share" 35 | 36 | 37 | -------------------------------------------------------------------------------- /.mulle/share/env/environment-plugin-os-darwin.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Git mirror and Zip/TGZ cache to conserve bandwidth 3 | # 4 | export MULLE_FETCH_MIRROR_DIR="${HOME:-/tmp}/Library/Caches/mulle-fetch/git-mirror" 5 | 6 | # 7 | # Git mirror and Zip/TGZ cache to conserve bandwidth 8 | # 9 | export MULLE_FETCH_ARCHIVE_DIR="${HOME:-/tmp}/Library/Caches/mulle-fetch/archive" 10 | -------------------------------------------------------------------------------- /.mulle/share/env/environment-plugin.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Git mirror and Zip/TGZ cache to conserve bandwidth 3 | # Memo: Will often be overridden in an os-specific environment file 4 | # Can be overridden with -DMULLE_FETCH_ARCHIVE_DIR on the commandline 5 | # 6 | export MULLE_FETCH_MIRROR_DIR="${HOME:-/tmp}/.cache/mulle-fetch/git-mirror" 7 | 8 | # 9 | # Git mirror and Zip/TGZ cache to conserve bandwidth 10 | # 11 | export MULLE_FETCH_ARCHIVE_DIR="${HOME:-/tmp}/.cache/mulle-fetch/archive" 12 | 13 | # 14 | # PATH to search for git repositories locally. 15 | # 16 | export MULLE_FETCH_SEARCH_PATH="${MULLE_VIRTUAL_ROOT}/.." 17 | 18 | # 19 | # Prefer symlinks to clones of git repos found in MULLE_FETCH_SEARCH_PATH 20 | # 21 | export MULLE_SOURCETREE_SYMLINK='YES' 22 | # 23 | # 24 | # 25 | export MULLE_SDE_INSTALLED_VERSION="3.4.2" 26 | 27 | 28 | -------------------------------------------------------------------------------- /.mulle/share/env/environment-post-extension.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Used to be hardcoded in mulle-sde plugin, now part of the environment. 3 | # pick first as default (if any) 4 | # 5 | export _MULLE_SDK_DIR="${DEPENDENCY_DIR:-${MULLE_VIRTUAL_ROOT}/dependency}/${MULLE_CRAFT_SDKS%%:*}" 6 | 7 | 8 | # 9 | # 10 | # 11 | export MULLE_SDK_DIR="${_MULLE_SDK_DIR%%/}" 12 | 13 | 14 | # 15 | # 16 | # 17 | export PATH="${MULLE_SDK_DIR}/Debug/bin:${MULLE_SDK_DIR}/Release/bin:${MULLE_SDK_DIR}/bin:${PATH}" 18 | 19 | 20 | -------------------------------------------------------------------------------- /.mulle/share/env/environment.sh: -------------------------------------------------------------------------------- 1 | ####### 2 | ### none startup 3 | ####### 4 | [ "${TRACE}" = 'YES' -o "${ENVIRONMENT_SH_TRACE}" = 'YES' ] && set -x && : "$0" "$@" 5 | 6 | # 7 | # If mulle-env is broken, sometimes its nice just to source this file. 8 | # If you're sourcing this manually on a regular basis, you're doing it wrong. 9 | # 10 | if [ -z "${MULLE_VIRTUAL_ROOT}" ] 11 | then 12 | MULLE_VIRTUAL_ROOT="`PATH=/bin:/usr/bin pwd -P`" 13 | echo "Using ${MULLE_VIRTUAL_ROOT} as MULLE_VIRTUAL_ROOT for \ 14 | your convenience" >&2 15 | fi 16 | 17 | if [ -z "${MULLE_UNAME}" ] 18 | then 19 | MULLE_UNAME="`PATH=/bin:/usr/bin uname -s 2> /dev/null | tr '[:upper:]' '[:lower:]'`" 20 | MULLE_UNAME="${MULLE_UNAME:-unknown}" 21 | echo "Using ${MULLE_UNAME} as MULLE_UNAME for your convenience" >&2 22 | fi 23 | 24 | # 25 | # now read in custom envionment (required) 26 | # 27 | . "${MULLE_VIRTUAL_ROOT}/.mulle/share/env/include-environment.sh" 28 | 29 | # 30 | # basic setup for interactive shells 31 | # 32 | case "${MULLE_SHELL_MODE}" in 33 | *INTERACTIVE*) 34 | # 35 | # Set PS1 so that we can see, that we are in a mulle-env 36 | # 37 | envname="`PATH=/bin:/usr/bin basename -- "${MULLE_VIRTUAL_ROOT}"`" 38 | 39 | case "${PS1}" in 40 | *\\h\[*) 41 | ;; 42 | 43 | *\\h*) 44 | PS1="$( PATH=/bin:/usr/bin sed 's/\\h/\\h\['${envname}'\]/' <<< "${PS1}" )" 45 | ;; 46 | 47 | *) 48 | PS1='\u@\h['${envname}'] \W$ ' 49 | ;; 50 | esac 51 | export PS1 52 | 53 | unset envname 54 | 55 | # install cd catcher 56 | if [ ! -z "${MULLE_ENV_LIBEXEC_DIR}" ] 57 | then 58 | . "${MULLE_ENV_LIBEXEC_DIR}/mulle-env-cd.sh" 59 | unset MULLE_ENV_LIBEXEC_DIR 60 | fi 61 | 62 | # install mulle-env-reload 63 | 64 | alias mulle-env-reload='. "${MULLE_VIRTUAL_ROOT}/.mulle/share/env/include-environment.sh"' 65 | 66 | # 67 | # source in any bash completion files 68 | # 69 | # memo: nullglob not easily done on both bash and zsh 70 | for filename in "${MULLE_VIRTUAL_ROOT}/.mulle/share/env/libexec"/*-bash-completion.sh 71 | do 72 | if [ -f "${filename}" ] 73 | then 74 | . "${filename}" 75 | fi 76 | done 77 | 78 | unset filename 79 | 80 | vardir="${MULLE_VIRTUAL_ROOT}/.mulle/var/${MULLE_HOSTNAME:-unknown-host}" 81 | [ -d "${vardir}" ] || PATH=/bin:/usr/bin mkdir -p "${vardir}" 82 | 83 | HISTFILE="${vardir}/bash_history" 84 | export HISTFILE 85 | 86 | unset vardir 87 | 88 | # 89 | # show motd, if any 90 | # 91 | if [ -z "${NO_MOTD}" ] 92 | then 93 | if [ -f "${MULLE_VIRTUAL_ROOT}/.mulle/etc/env/motd" ] 94 | then 95 | cat "${MULLE_VIRTUAL_ROOT}/.mulle/etc/env/motd" 96 | else 97 | if [ -f "${MULLE_VIRTUAL_ROOT}/.mulle/share/env/motd" ] 98 | then 99 | cat "${MULLE_VIRTUAL_ROOT}/.mulle/share/env/motd" 100 | fi 101 | fi 102 | fi 103 | ;; 104 | esac 105 | 106 | # remove some uglies 107 | unset NO_MOTD 108 | unset TRACE 109 | 110 | ####### 111 | ### mulle startup 112 | ####### 113 | 114 | case "${MULLE_SHELL_MODE}" in 115 | *INTERACTIVE*) 116 | if [ -z "${MULLE_SDE_NO_ALIAS}" ] 117 | then 118 | alias clean="mulle-sde clean" 119 | alias craft="mulle-sde craft" 120 | alias craftorder="mulle-sde craftorder" 121 | alias dependency="mulle-sde dependency" 122 | alias environment="mulle-sde environment" 123 | alias extension="mulle-sde extension" 124 | alias fetch="mulle-sde fetch" 125 | alias library="mulle-sde library" 126 | alias list="mulle-sde list" 127 | alias log="mulle-sde log" 128 | alias match="mulle-sde match" 129 | alias monitor="mulle-sde monitor" 130 | alias patternfile="mulle-sde patternfile" 131 | alias reflect="mulle-sde reflect" 132 | alias run="mulle-sde run" 133 | alias show="mulle-sde show" 134 | alias subproject="mulle-sde subproject" 135 | fi 136 | 137 | if [ -z "${MULLE_SDE_NO_QUICK_ALIAS}" ] 138 | then 139 | alias C="mulle-sde clean; mulle-sde craft" 140 | alias c="mulle-sde craft" 141 | alias CC="mulle-sde clean all; mulle-sde craft" 142 | alias l="mulle-sde list --files" 143 | alias r="mulle-sde reflect" 144 | alias T="mulle-sde test craft ; mulle-sde test" 145 | alias t="mulle-sde test rerun --serial" 146 | alias TT="mulle-sde test clean all; mulle-sde test" 147 | alias tt="mulle-sde test craft ; mulle-sde test rerun --serial" 148 | fi 149 | ;; 150 | esac 151 | -------------------------------------------------------------------------------- /.mulle/share/env/include-environment.sh: -------------------------------------------------------------------------------- 1 | [ -z "${MULLE_VIRTUAL_ROOT}" -o -z "${MULLE_UNAME}" ] && \ 2 | echo "Your script needs to setup MULLE_VIRTUAL_ROOT \ 3 | and MULLE_UNAME properly" >&2 && exit 1 4 | 5 | MULLE_ENV_SHARE_DIR="${MULLE_VIRTUAL_ROOT}/.mulle/share/env" 6 | MULLE_ENV_ETC_DIR="${MULLE_VIRTUAL_ROOT}/.mulle/etc/env" 7 | # Top/down order of inclusion. 8 | # Keep these files (except environment-custom.sh) clean off manual edits so 9 | # that mulle-env can read and set environment variables. 10 | # 11 | # .mulle/etc/env | .mulle/share/env 12 | # --------------------------------------|-------------------- 13 | # | environment-plugin.sh 14 | # | environment-plugin-os-${MULLE_UNAME}.sh 15 | # environment-project.sh | 16 | # environment-global.sh | 17 | # environment-os-${MULLE_UNAME}.sh | 18 | # environment-host-${MULLE_HOSTNAME}.sh | 19 | # environment-user-${MULLE_USERNAME}.sh | 20 | # environment-custom.sh | 21 | # environment-post-global.sh | 22 | # 23 | scopes="s:plugin;5 24 | s:plugin-os-${MULLE_UNAME};15 25 | e:global;40 26 | e:os-${MULLE_UNAME};60 27 | e:host-${MULLE_HOSTNAME};80 28 | e:user-${MULLE_USERNAME};100 29 | e:user-${MULLE_USERNAME}-os-${MULLE_UNAME};120 30 | e:user-${MULLE_USERNAME}-host-${MULLE_HOSTNAME};140 31 | e:custom;1000 32 | e:post-global;2000" 33 | 34 | if [ -f "${MULLE_ENV_ETC_DIR}/auxscope" ] 35 | then 36 | auxscopes="`PATH=/bin:/usr/bin sed -e 's/^/e:/' \ 37 | -e "s/\${MULLE_UNAME}/${MULLE_UNAME}/" \ 38 | -e "s/\${MULLE_HOSTNAME}/${MULLE_HOSTNAME}/" \ 39 | -e "s/\${MULLE_USERNAME}/${MULLE_USERNAME}/" \ 40 | "${MULLE_ENV_ETC_DIR}/auxscope"`" 41 | scopes="${scopes}"$'\n'"${auxscopes}" 42 | fi 43 | 44 | if [ -f "${MULLE_ENV_SHARE_DIR}/auxscope" ] 45 | then 46 | auxscopes="`PATH=/bin:/usr/bin sed -e 's/^/s:/' \ 47 | -e "s/\${MULLE_UNAME}/${MULLE_UNAME}/" \ 48 | -e "s/\${MULLE_HOSTNAME}/${MULLE_HOSTNAME}/" \ 49 | -e "s/\${MULLE_USERNAME}/${MULLE_USERNAME}/" \ 50 | "${MULLE_ENV_SHARE_DIR}/auxscope"`" 51 | scopes="${scopes}"$'\n'"${auxscopes}" 52 | fi 53 | 54 | # 55 | # Load scopes according to priority now 56 | # put in local var for crazy old bashes 57 | # 58 | prioscopes=`printf "%s\n" "${scopes}" \ 59 | | PATH=/bin:/usr/bin sort -t';' -k2n -k1 \ 60 | | PATH=/bin:/usr/bin sed -n -e 's/\(.*\);.*$/\1/p'` 61 | 62 | for scope in ${prioscopes} 63 | do 64 | case "${scope}" in 65 | e:*) 66 | includefile="${MULLE_ENV_ETC_DIR}/environment-${scope#?:}.sh" 67 | ;; 68 | 69 | s:*) 70 | includefile="${MULLE_ENV_SHARE_DIR}/environment-${scope#?:}.sh" 71 | ;; 72 | 73 | *) 74 | continue; 75 | ;; 76 | esac 77 | 78 | if [ -f "${includefile}" ] 79 | then 80 | . "${includefile}" 81 | fi 82 | done 83 | 84 | unset scope 85 | unset scopes 86 | unset auxscopes 87 | unset includefile 88 | 89 | unset MULLE_ENV_ETC_DIR 90 | unset MULLE_ENV_SHARE_DIR 91 | -------------------------------------------------------------------------------- /.mulle/share/env/motd: -------------------------------------------------------------------------------- 1 | Run external commands with mudo 2 | Project is ready to craft 3 | -------------------------------------------------------------------------------- /.mulle/share/env/style: -------------------------------------------------------------------------------- 1 | mulle/relax 2 | -------------------------------------------------------------------------------- /.mulle/share/env/tool-extension: -------------------------------------------------------------------------------- 1 | mulle-cmake-graphviz-include 2 | mulle-create-build-motd 3 | clib 4 | clib-configure 5 | clib-install 6 | clib-uninstall 7 | clib-upgrade 8 | clib-build 9 | clib-init 10 | clib-search 11 | clib-update 12 | git 13 | gzip 14 | id 15 | inotifywait 16 | ssh 17 | tar 18 | zip 19 | xz 20 | bzip2 21 | mulle-sourcetree-to-c 22 | mulle-sourcetree-to-cmake 23 | mulle-sourcetree-graph 24 | ar 25 | as 26 | cc 27 | clang 28 | scan-build 29 | diff 30 | gcc 31 | ld 32 | nm 33 | valgrind 34 | vgdb 35 | valgrind.bin 36 | mulle-match-to-cmake 37 | mulle-match-to-c 38 | cmake;script 39 | -------------------------------------------------------------------------------- /.mulle/share/env/tool-extension.darwin: -------------------------------------------------------------------------------- 1 | inotifywait;remove 2 | fswatch 3 | dsymutil 4 | install_name_tool 5 | otool 6 | ranlib 7 | -------------------------------------------------------------------------------- /.mulle/share/env/tool-extension.windows: -------------------------------------------------------------------------------- 1 | lib.exe 2 | cl.exe 3 | link.exe 4 | ifc.exe 5 | ml.exe 6 | bscmake.exe 7 | ml64.exe 8 | cvtres.exe 9 | msbuild.exe 10 | dumpbin.exe 11 | editbin.exe 12 | pgomgr.exe 13 | pgocvt.exe 14 | pgosweep.exe 15 | xdcmake.exe 16 | cmake;remove 17 | cmake.exe 18 | ninja.exe 19 | nmake.exe 20 | -------------------------------------------------------------------------------- /.mulle/share/env/tool-plugin: -------------------------------------------------------------------------------- 1 | autoconf 2 | autoreconf 3 | awk;required 4 | base64 5 | basename;required 6 | bash 7 | bash;optional 8 | cat;required 9 | chgrp;required 10 | chmod;required 11 | chown;required 12 | clear 13 | column 14 | cp;required 15 | curl 16 | cut;required 17 | date;required 18 | dd 19 | df 20 | dirname;required 21 | dmesg 22 | echo;required 23 | ed 24 | egrep 25 | emacs 26 | env;required 27 | expr;required 28 | false;required 29 | fgrep 30 | file 31 | find;required 32 | grep;required 33 | head;required 34 | hostname 35 | kill;required 36 | less 37 | ln;required 38 | login 39 | ls;required 40 | make 41 | meson 42 | mkdir;required 43 | mknod 44 | more 45 | mount 46 | mulle-column 47 | mv;required 48 | nano 49 | ninja 50 | ps 51 | pwd;required 52 | readlink;required 53 | rmdir;required 54 | rm;required 55 | sed;required 56 | shasum 57 | sh;required 58 | sleep;required 59 | sort;required 60 | stat;required 61 | stty 62 | su 63 | sw_vers 64 | sync 65 | sysctl 66 | tail;required 67 | tee;required 68 | test;required 69 | touch;required 70 | tree 71 | tr;required 72 | true;required 73 | tty 74 | umount 75 | uname;required 76 | uptime 77 | uuidgen 78 | vi 79 | wc;required 80 | wget 81 | which;required 82 | xargs 83 | xcodebuild 84 | xcrun 85 | zsh 86 | zsh;optional 87 | -------------------------------------------------------------------------------- /.mulle/share/env/version: -------------------------------------------------------------------------------- 1 | 5.4.2 2 | -------------------------------------------------------------------------------- /.mulle/share/match/ignore.d/10-boring--none: -------------------------------------------------------------------------------- 1 | *.old 2 | *.old/ 3 | old/ 4 | 5 | # certain old nibs :) 6 | *~.*/ 7 | 8 | # vi backup files or somesuch 9 | *~ 10 | 11 | # good old 12 | *.bak 13 | 14 | # not too much more as .o and such things shouldn't even be in the search space 15 | -------------------------------------------------------------------------------- /.mulle/share/match/match.d/10-sourcetree--all: -------------------------------------------------------------------------------- 1 | .mulle/etc/sourcetree/config* 2 | -------------------------------------------------------------------------------- /.mulle/share/match/match.d/70-header--private-generated-headers: -------------------------------------------------------------------------------- 1 | # private generated headers, are not installed ever 2 | src/reflect/*-private.h 3 | -------------------------------------------------------------------------------- /.mulle/share/match/match.d/70-header--public-generated-headers: -------------------------------------------------------------------------------- 1 | # these are installed, but aren't published in the envelope. Will be used 2 | # after 70-source--private due to ASCII sort order 3 | 4 | src/reflect/*.h 5 | -------------------------------------------------------------------------------- /.mulle/share/match/match.d/75-header--private-generic-headers: -------------------------------------------------------------------------------- 1 | # these are installed and the envelope header includes them directly 2 | include-private.h 3 | -------------------------------------------------------------------------------- /.mulle/share/match/match.d/75-header--public-generic-headers: -------------------------------------------------------------------------------- 1 | # these are installed and the envelope header includes them directly 2 | include.h 3 | -------------------------------------------------------------------------------- /.mulle/share/match/match.d/80-header--private-headers: -------------------------------------------------------------------------------- 1 | # these are installed as private headers only, they don't appear in the 2 | # envelope header 3 | 4 | *[_-]private.h 5 | private.h 6 | -------------------------------------------------------------------------------- /.mulle/share/match/match.d/85-header--public-headers: -------------------------------------------------------------------------------- 1 | # This is the fallback if patterns file with smaller numbers fail. 2 | # These are public headers, that are auto-included in the envelope header 3 | 4 | *.h 5 | -------------------------------------------------------------------------------- /.mulle/share/match/match.d/86-header--project-only-headers: -------------------------------------------------------------------------------- 1 | # This is the fallback if patterns file with smaller numbers fail. 2 | # These are project headers, that are not included anywhere so far 3 | # and not even exported as private! 4 | 5 | *.inc 6 | 7 | -------------------------------------------------------------------------------- /.mulle/share/match/match.d/90-source--standalone-sources: -------------------------------------------------------------------------------- 1 | # Likely to be obsolete soon 2 | *-standalone.c 3 | -------------------------------------------------------------------------------- /.mulle/share/match/match.d/95-cmakefile--all: -------------------------------------------------------------------------------- 1 | # cmake files that can have user edits 2 | CMakeLists.txt 3 | CMakePackage.cmake 4 | cmake/[^_]*.cmake 5 | -------------------------------------------------------------------------------- /.mulle/share/match/match.d/95-source--sources: -------------------------------------------------------------------------------- 1 | # This is the fallback if patternfiles with smaller numbers fail 2 | # 3 | *.c 4 | -------------------------------------------------------------------------------- /.mulle/share/monitor/bin/cmakefile-callback: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # Copyright (c) 2018 Nat! - Mulle kybernetiK 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 9 | # Redistributions of source code must retain the above copyright notice, this 10 | # list of conditions and the following disclaimer. 11 | # 12 | # Redistributions in binary form must reproduce the above copyright notice, 13 | # this list of conditions and the following disclaimer in the documentation 14 | # and/or other materials provided with the distribution. 15 | # 16 | # Neither the name of Mulle kybernetiK nor the names of its contributors 17 | # may be used to endorse or promote products derived from this software 18 | # without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | # POSSIBILITY OF SUCH DAMAGE. 31 | # 32 | [ "${TRACE}" = 'YES' ] && set -x && : "$0" "$@" 33 | 34 | 35 | main() 36 | { 37 | # local callback="$1" 38 | # local action="$2" # unused 39 | # local filename="$3" 40 | # local category="$4" 41 | 42 | echo "none" # this selects the **task** to run 43 | } # none means no task 44 | 45 | main "$@" 46 | -------------------------------------------------------------------------------- /.mulle/share/monitor/bin/filesystem-callback: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # Copyright (c) 2018 Nat! - Mulle kybernetiK 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 9 | # Redistributions of source code must retain the above copyright notice, this 10 | # list of conditions and the following disclaimer. 11 | # 12 | # Redistributions in binary form must reproduce the above copyright notice, 13 | # this list of conditions and the following disclaimer in the documentation 14 | # and/or other materials provided with the distribution. 15 | # 16 | # Neither the name of Mulle kybernetiK nor the names of its contributors 17 | # may be used to endorse or promote products derived from this software 18 | # without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | # POSSIBILITY OF SUCH DAMAGE. 31 | # 32 | [ "${TRACE}" = 'YES' ] && set -x && : "$0" "$@" 33 | 34 | 35 | # 36 | # if action is empty, assume it means we are inside mulle-sde monitor update 37 | # 38 | main() 39 | { 40 | # local callback="$1" 41 | # local action="$2" # unused 42 | # local filename="$3" 43 | # local category="$4" 44 | 45 | echo "filesystem" # this selects the **task** to run 46 | } # see mulle-sde task list for whats available 47 | 48 | main "$@" 49 | -------------------------------------------------------------------------------- /.mulle/share/monitor/bin/header-callback: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # Copyright (c) 2018 Nat! - Mulle kybernetiK 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 9 | # Redistributions of source code must retain the above copyright notice, this 10 | # list of conditions and the following disclaimer. 11 | # 12 | # Redistributions in binary form must reproduce the above copyright notice, 13 | # this list of conditions and the following disclaimer in the documentation 14 | # and/or other materials provided with the distribution. 15 | # 16 | # Neither the name of Mulle kybernetiK nor the names of its contributors 17 | # may be used to endorse or promote products derived from this software 18 | # without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | # POSSIBILITY OF SUCH DAMAGE. 31 | # 32 | [ "${TRACE}" = 'YES' ] && set -x && : "$0" "$@" 33 | 34 | 35 | # 36 | # this script is used by mulle-monitor in monitor mode so that source changes 37 | # trigger rebuilds. It usually won't be executed during a `mulle-sde reflect` 38 | # 39 | 40 | main() 41 | { 42 | # local callback="$1" 43 | # local action="$2" # unused 44 | local filename="$3" 45 | local category="$4" 46 | 47 | case "-${category}-" in 48 | *-generated-*) 49 | return 0 50 | ;; 51 | esac 52 | 53 | echo "craft" # this selects the **task** to run 54 | } # none means no task 55 | 56 | main "$@" 57 | -------------------------------------------------------------------------------- /.mulle/share/monitor/bin/resource-callback: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # Copyright (c) 2018 Nat! - Mulle kybernetiK 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 9 | # Redistributions of source code must retain the above copyright notice, this 10 | # list of conditions and the following disclaimer. 11 | # 12 | # Redistributions in binary form must reproduce the above copyright notice, 13 | # this list of conditions and the following disclaimer in the documentation 14 | # and/or other materials provided with the distribution. 15 | # 16 | # Neither the name of Mulle kybernetiK nor the names of its contributors 17 | # may be used to endorse or promote products derived from this software 18 | # without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | # POSSIBILITY OF SUCH DAMAGE. 31 | # 32 | [ "${TRACE}" = 'YES' ] && set -x && : "$0" "$@" 33 | 34 | 35 | # 36 | # this script is used by mulle-monitor in monitor mode so that source changes 37 | # trigger rebuilds. It usually won't be executed during a `mulle-sde reflect` 38 | # 39 | 40 | 41 | main() 42 | { 43 | # local callback="$1" 44 | # local action="$2" # unused 45 | local filename="$3" 46 | local category="$4" 47 | 48 | case "-${category}-" in 49 | *-generated-*) 50 | return 0 51 | ;; 52 | esac 53 | 54 | echo "craft" # this selects the **task** to run 55 | } # none means no task 56 | 57 | main "$@" 58 | -------------------------------------------------------------------------------- /.mulle/share/monitor/bin/source-callback: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # Copyright (c) 2018 Nat! - Mulle kybernetiK 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 9 | # Redistributions of source code must retain the above copyright notice, this 10 | # list of conditions and the following disclaimer. 11 | # 12 | # Redistributions in binary form must reproduce the above copyright notice, 13 | # this list of conditions and the following disclaimer in the documentation 14 | # and/or other materials provided with the distribution. 15 | # 16 | # Neither the name of Mulle kybernetiK nor the names of its contributors 17 | # may be used to endorse or promote products derived from this software 18 | # without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | # POSSIBILITY OF SUCH DAMAGE. 31 | # 32 | [ "${TRACE}" = 'YES' ] && set -x && : "$0" "$@" 33 | 34 | 35 | # 36 | # this script is used by mulle-monitor in monitor mode so that source changes 37 | # trigger rebuilds. It usually won't be executed during a `mulle-sde reflect` 38 | # 39 | 40 | 41 | main() 42 | { 43 | # local callback="$1" 44 | # local action="$2" # unused 45 | local filename="$3" 46 | local category="$4" 47 | 48 | case "-${category}-" in 49 | *-generated-*) 50 | return 0 51 | ;; 52 | esac 53 | 54 | echo "craft" # this selects the **task** to run 55 | } # none means no task 56 | 57 | main "$@" 58 | 59 | -------------------------------------------------------------------------------- /.mulle/share/monitor/bin/sourcetree-callback: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # Copyright (c) 2018 Nat! - Mulle kybernetiK 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 9 | # Redistributions of source code must retain the above copyright notice, this 10 | # list of conditions and the following disclaimer. 11 | # 12 | # Redistributions in binary form must reproduce the above copyright notice, 13 | # this list of conditions and the following disclaimer in the documentation 14 | # and/or other materials provided with the distribution. 15 | # 16 | # Neither the name of Mulle kybernetiK nor the names of its contributors 17 | # may be used to endorse or promote products derived from this software 18 | # without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | # POSSIBILITY OF SUCH DAMAGE. 31 | # 32 | [ "${TRACE}" = 'YES' ] && set -x && : "$0" "$@" 33 | 34 | 35 | # 36 | # if action is empty, assume it means we are inside mulle-sde monitor update 37 | # 38 | main() 39 | { 40 | # local callback="$1" 41 | # local action="$2" 42 | # local filename="$3" 43 | # local category="$4" 44 | 45 | echo "sourcetree" # this selects the **task** to run 46 | } # see mulle-sde task list for whats available 47 | 48 | main "$@" 49 | -------------------------------------------------------------------------------- /.mulle/share/monitor/libexec/craft-task.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | # 3 | # Copyright (c) 2018 Nat! - Mulle kybernetiK 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 9 | # Redistributions of source code must retain the above copyright notice, this 10 | # list of conditions and the following disclaimer. 11 | # 12 | # Redistributions in binary form must reproduce the above copyright notice, 13 | # this list of conditions and the following disclaimer in the documentation 14 | # and/or other materials provided with the distribution. 15 | # 16 | # Neither the name of Mulle kybernetiK nor the names of its contributors 17 | # may be used to endorse or promote products derived from this software 18 | # without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | # POSSIBILITY OF SUCH DAMAGE. 31 | # 32 | craft_task_run() 33 | { 34 | log_entry "mulle-sde/sde:: craft_task_run" "$@" 35 | 36 | log_fluff "==> Craft" 37 | 38 | # 39 | # remove running test jobs, as they are invalid now 40 | # but only if we restart them 41 | # 42 | if [ "${MULLE_SDE_TEST_AFTER_CRAFT}" = 'YES' ] 43 | then 44 | monitor::task::remove_job "test" 45 | fi 46 | 47 | if ! eval_exekutor mulle-sde "${MULLE_TECHNICAL_FLAGS}" \ 48 | "${MULLE_CRAFT_TASK_FLAGS}" \ 49 | craft "$@" \ 50 | "${MULLE_CRAFT_TASK_ARGS}" 51 | then 52 | return 1 53 | fi 54 | 55 | if [ "${MULLE_SDE_TEST_AFTER_CRAFT}" = 'YES' ] 56 | then 57 | monitor::task::run "test" 58 | fi 59 | } 60 | 61 | 62 | -------------------------------------------------------------------------------- /.mulle/share/monitor/libexec/filesystem-task.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | # 3 | # Copyright (c) 2020 Nat! - Mulle kybernetiK 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 9 | # Redistributions of source code must retain the above copyright notice, this 10 | # list of conditions and the following disclaimer. 11 | # 12 | # Redistributions in binary form must reproduce the above copyright notice, 13 | # this list of conditions and the following disclaimer in the documentation 14 | # and/or other materials provided with the distribution. 15 | # 16 | # Neither the name of Mulle kybernetiK nor the names of its contributors 17 | # may be used to endorse or promote products derived from this software 18 | # without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | # POSSIBILITY OF SUCH DAMAGE. 31 | # 32 | 33 | filesystem_task_run() 34 | { 35 | log_entry "mulle-sde/c-cmake::filesystem_task_run" "$@" 36 | 37 | log_info "Reflecting ${C_MAGENTA}${C_BOLD}${PROJECT_NAME:-.}${C_INFO} filesystem" 38 | 39 | local rval 40 | 41 | rval=0 42 | case "${MULLE_MATCH_TO_CMAKE_RUN}" in 43 | NO|DISABLE*|OFF) 44 | ;; 45 | 46 | *) 47 | exekutor mulle-match-to-cmake ${MULLE_TECHNICAL_FLAGS} "$@" 48 | rval=$? 49 | ;; 50 | esac 51 | 52 | if [ $rval -ne 0 ] 53 | then 54 | log_error "mulle-match-to-cmake ${MULLE_TECHNICAL_FLAGS} $* failed ($rval)" 55 | fi 56 | 57 | local rval2 58 | 59 | rval2=0 60 | case "${MULLE_MATCH_TO_C_RUN}" in 61 | NO|DISABLE*|OFF) 62 | ;; 63 | 64 | *) 65 | exekutor mulle-match-to-c ${MULLE_TECHNICAL_FLAGS} "$@" 66 | rval2=$? 67 | ;; 68 | esac 69 | 70 | if [ $rval2 -ne 0 ] 71 | then 72 | log_error "mulle-match-to-c ${MULLE_TECHNICAL_FLAGS} $* failed ($rval2)" 73 | fi 74 | 75 | local rval3 76 | 77 | rval3=0 78 | case "${MULLE_PROJECT_CLIB_JSON_RUN}" in 79 | YES|ENABLE*|ON) 80 | case "${PROJECT_DIALECT}" in 81 | objc) 82 | exekutor mulle-project-clib-json ${MULLE_TECHNICAL_FLAGS} \ 83 | -a src/reflect/objc-loader.inc \ 84 | -o "clib.json" 85 | rval3=$? 86 | ;; 87 | 88 | *) 89 | exekutor mulle-project-clib-json ${MULLE_TECHNICAL_FLAGS} \ 90 | -o "clib.json" 91 | rval3=$? 92 | ;; 93 | esac 94 | ;; 95 | esac 96 | 97 | if [ $rval3 -ne 0 ] 98 | then 99 | log_error "mulle-project-clib-json ${MULLE_TECHNICAL_FLAGS} failed ($rval3)" 100 | fi 101 | 102 | 103 | [ $rval -eq 0 -a $rval2 -eq 0 -o $rval3 -eq 0 ] 104 | } 105 | -------------------------------------------------------------------------------- /.mulle/share/monitor/libexec/sourcetree-task.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | # 3 | # Copyright (c) 2018 Nat! - Mulle kybernetiK 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 9 | # Redistributions of source code must retain the above copyright notice, this 10 | # list of conditions and the following disclaimer. 11 | # 12 | # Redistributions in binary form must reproduce the above copyright notice, 13 | # this list of conditions and the following disclaimer in the documentation 14 | # and/or other materials provided with the distribution. 15 | # 16 | # Neither the name of Mulle kybernetiK nor the names of its contributors 17 | # may be used to endorse or promote products derived from this software 18 | # without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | # POSSIBILITY OF SUCH DAMAGE. 31 | # 32 | 33 | # 34 | # Overwrite inherited task and add mulle-mulle-sourcetree-to-c. 35 | # It would be nice to inherit this properly instead of clobbering it. 36 | # Also mulle-sourcetree-to-c doesn't really require cmake to exist, this 37 | # is another bug. 38 | # 39 | sourcetree_task_run() 40 | { 41 | log_entry "mulle-sde/c-cmake::sourcetree_task_run" "$@" 42 | 43 | local runs 44 | 45 | case "${MULLE_SOURCETREE_TO_CMAKE_RUN}" in 46 | NO|DISABLE*|OFF) 47 | ;; 48 | 49 | *) 50 | runs="cmake" 51 | ;; 52 | esac 53 | 54 | case "${MULLE_SOURCETREE_TO_C_RUN}" in 55 | NO|DISABLE*|OFF) 56 | ;; 57 | 58 | *) 59 | r_comma_concat "${runs}" "c" 60 | runs="${RVAL}" 61 | ;; 62 | esac 63 | 64 | if [ -z "${runs}" ] 65 | then 66 | return 67 | fi 68 | 69 | log_info "Reflecting ${C_MAGENTA}${C_BOLD}${PROJECT_NAME:-.}${C_INFO} sourcetree ${C_RESET_BOLD}${MULLE_SOURCETREE_CONFIG_NAME:-config}" 70 | 71 | local rval 72 | 73 | rval=0 74 | case ",${runs}," in 75 | *,cmake,*) 76 | exekutor mulle-sourcetree-to-cmake ${MULLE_TECHNICAL_FLAGS} "$@" 77 | rval=$? 78 | if [ $rval -ne 0 ] 79 | then 80 | log_error "mulle-sourcetree-to-cmake ${MULLE_TECHNICAL_FLAGS} $* failed ($rval)" 81 | fi 82 | ;; 83 | esac 84 | 85 | local rval2 86 | 87 | rval2=0 88 | case ",${runs}," in 89 | *,c,*) 90 | exekutor mulle-sourcetree-to-c ${MULLE_TECHNICAL_FLAGS} "$@" 91 | rval2=$? 92 | if [ $rval2 -ne 0 ] 93 | then 94 | log_error "mulle-sourcetree-to-c ${MULLE_TECHNICAL_FLAGS} $* failed ($rval2)" 95 | fi 96 | ;; 97 | esac 98 | 99 | [ $rval -eq 0 -a $rval2 -eq 0 ] 100 | } 101 | -------------------------------------------------------------------------------- /.mulle/share/sde/extension: -------------------------------------------------------------------------------- 1 | mulle-c/c-developer;meta 2 | mulle-c/c;runtime 3 | mulle-sde/c;runtime 4 | mulle-sde/sde;extra 5 | mulle-c/c-cmake;buildtool 6 | mulle-sde/c-cmake;buildtool 7 | mulle-sde/cmake;buildtool 8 | mulle-c/c-demo;extra 9 | mulle-sde/c-demo;extra 10 | mulle-c/github-actions;extra 11 | -------------------------------------------------------------------------------- /.mulle/share/sde/version/mulle-c/c: -------------------------------------------------------------------------------- 1 | 0.17.1 2 | -------------------------------------------------------------------------------- /.mulle/share/sde/version/mulle-c/c-cmake: -------------------------------------------------------------------------------- 1 | 0.18.1 2 | -------------------------------------------------------------------------------- /.mulle/share/sde/version/mulle-c/c-demo: -------------------------------------------------------------------------------- 1 | 0.17.0 2 | -------------------------------------------------------------------------------- /.mulle/share/sde/version/mulle-c/c-developer: -------------------------------------------------------------------------------- 1 | 0.14.0 2 | -------------------------------------------------------------------------------- /.mulle/share/sde/version/mulle-c/github-actions: -------------------------------------------------------------------------------- 1 | 0.18.0 2 | -------------------------------------------------------------------------------- /.mulle/share/sde/version/mulle-sde/c: -------------------------------------------------------------------------------- 1 | 0.27.0 2 | -------------------------------------------------------------------------------- /.mulle/share/sde/version/mulle-sde/c-cmake: -------------------------------------------------------------------------------- 1 | 0.27.0 2 | -------------------------------------------------------------------------------- /.mulle/share/sde/version/mulle-sde/c-demo: -------------------------------------------------------------------------------- 1 | 0.27.0 2 | -------------------------------------------------------------------------------- /.mulle/share/sde/version/mulle-sde/cmake: -------------------------------------------------------------------------------- 1 | 0.29.1 2 | -------------------------------------------------------------------------------- /.mulle/share/sde/version/mulle-sde/sde: -------------------------------------------------------------------------------- 1 | 0.27.0 2 | -------------------------------------------------------------------------------- /.mulle/share/sourcetree/config: -------------------------------------------------------------------------------- 1 | mulle-c11;${MULLE__C11_NODETYPE:-tar};no-all-load,no-cmake-inherit,no-import,no-link,no-recurse,no-singlephase;735DBE4E-A36C-44FA-8BAD-C193737E4D65;${MULLE__C11_URL:-https://github.com/mulle-c/mulle-c11/archive/${MULLE_TAG}.tar.gz};${MULLE__C11_BRANCH};${MULLE__C11_TAG:-latest};; 2 | -------------------------------------------------------------------------------- /.touch: -------------------------------------------------------------------------------- 1 | 18cd1860-7226-456a-9ca8-64590f0488e1 2 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.13...99.99) 2 | 3 | project( mulle-thread VERSION 4.6.2 LANGUAGES C) 4 | 5 | 6 | 7 | 8 | ### mulle-sde environment 9 | 10 | # add cmake module paths to search path 11 | list( INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}/cmake/share") 12 | list( INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}/cmake/reflect") 13 | list( INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 14 | 15 | include( Environment) 16 | 17 | include( Files) 18 | 19 | ### Library 20 | 21 | if( HEADERS_PHASE) 22 | install( FILES ${INSTALL_PUBLIC_HEADERS} DESTINATION "include/mulle-thread") 23 | install( FILES ${INSTALL_PRIVATE_HEADERS} DESTINATION "include/mulle-thread") 24 | install( FILES ${INSTALL_CMAKE_INCLUDES} DESTINATION "include/mulle-thread/cmake") 25 | # manually maintained! 26 | install( FILES ${MINTOMIC_PUBLIC_HEADERS} DESTINATION "include/mintomic") 27 | # NOTE: it's really private subdir! 28 | install( FILES ${MINTOMIC_PRIVATE_HEADERS} DESTINATION "include/mintomic/private") 29 | 30 | # short cut out 31 | if( NOT COMPILE_PHASE AND NOT LINK_PHASE) 32 | return() 33 | endif() 34 | endif() 35 | 36 | if( LINK_PHASE) 37 | include( Dependencies OPTIONAL) 38 | endif() 39 | 40 | include( Library) 41 | 42 | # use LIBRARY_COMPILE_TARGET for compiler options 43 | target_compile_definitions( "${LIBRARY_COMPILE_TARGET}" PUBLIC) 44 | target_compile_options( "${LIBRARY_COMPILE_TARGET}" PUBLIC) 45 | if( NOT MSVC) 46 | target_compile_options( "${LIBRARY_COMPILE_TARGET}" PUBLIC -Wunused) 47 | endif() 48 | 49 | # use LIBRARY_LINK_TARGET for linker options 50 | if( LINK_PHASE) 51 | target_link_options( "${LIBRARY_LINK_TARGET}" PUBLIC) 52 | endif() 53 | 54 | include( InstallLibrary) 55 | 56 | if( LINK_PHASE) 57 | include( InstallCMakeInclude) 58 | include( InstallCMakePackage) 59 | endif() 60 | 61 | include( FinalOutput OPTIONAL) 62 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is a BSD-3 style license 2 | ----------------------------- 3 | 4 | Copyright (c) 2015 Nat! - Mulle kybernetiK 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | Neither the name of Mulle kybernetiK nor the names of its contributors 18 | may be used to endorse or promote products derived from this software 19 | without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | POSSIBILITY OF SUCH DAMAGE. 32 | 33 | ------------------------------ 34 | mulle-thread (Library) uses mintomic https://mintomic.github.io/ 35 | which is governed by a modified BSD 3 License. See its LICENSE file 36 | http://directory.fsf.org/wiki/License:BSD_3Clause 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mulle-thread 2 | 3 | #### 🔠 Cross-platform thread/mutex/tss/atomic operations in C 4 | 5 | 6 | # mulle-thread 7 | 8 | #### 🔠 Cross-platform thread/mutex/tss/atomic operations in C 9 | 10 | **mulle-thread** is a set of **C** wrapper headers for a simplified 11 | subset of thread functions and for a limited range of atomic operations that 12 | strongly mimics the thread standard, even if thread is not available. On Windows it 13 | has to do a bit more work. 14 | 15 | mulle-threads main advantages are **simplicity**, **portability**, **sanity**. 16 | 17 | * basic atomic operations CAS, ++, -- on void pointers. 18 | * basic thread operations 19 | * mutex functionality 20 | * thread local storage, with proper destruction 21 | 22 | Since thread has `` and ``, eventually this project 23 | could become superflous. In the meantime though it's a convenient abstraction 24 | on threads and atomic operations. 25 | 26 | ### Warning 27 | 28 | `mulle_thread_once` doesn't guarantee, that exceptions or thread cancellation 29 | within the init function will clear the once flag for a second run. In fact 30 | it will not. 31 | 32 | 33 | | Release Version 34 | |----------------------------------- 35 | | [![Build Status](https://github.com/mulle-concurrent/mulle-thread/workflows/CI/badge.svg?branch=release)](//github.com/mulle-concurrent/mulle-thread) ![Mulle kybernetiK tag](https://img.shields.io/github/tag/mulle-concurrent/mulle-thread/workflows/CI/badge.svg?branch=release) 36 | 37 | 38 | 39 | 40 | | Release Version | Release Notes | AI Documentation 41 | |-------------------------------------------------------|----------------|--------------- 42 | | ![Mulle kybernetiK tag](https://img.shields.io/github/tag/mulle-concurrent/mulle-thread.svg) [![Build Status](https://github.com/mulle-concurrent/mulle-thread/workflows/CI/badge.svg)](//github.com/mulle-concurrent/mulle-thread/actions) | [RELEASENOTES](RELEASENOTES.md) | [DeepWiki for mulle-thread](https://deepwiki.com/mulle-concurrent/mulle-thread) 43 | 44 | 45 | ## API 46 | 47 | * [Atomic Operations](dox/API_ATOMIC.md) 48 | * [Threads](dox/API_THREAD.md) 49 | * [Mutex](dox/API_MUTEX.md) 50 | * [Thread Local Storage](dox/API_TSS.md) 51 | 52 | 53 | 54 | 55 | ## Convenience macro for mutex 56 | 57 | An easy way to get a locked code region is to use: 58 | 59 | ``` c 60 | void foo( mulle_thread_mutex_t *mutex) 61 | { 62 | mulle_thread_mutex_do( mutex) 63 | { 64 | // code block is now executed with mutex locked 65 | } 66 | // mutex is unlocked again 67 | } 68 | ``` 69 | 70 | `break` and `continue` will exit the block and unlock the mutex. But when you 71 | use `return` the function exists and the mutex remains locked. 72 | 73 | 74 | 75 | ### You are here 76 | 77 | ![Overview](overview.dot.svg) 78 | 79 | 80 | 81 | 82 | 83 | ## Add 84 | 85 | **This project is a component of the [mulle-core](//github.com/mulle-core/mulle-core) library. As such you usually will *not* add or install it 86 | individually, unless you specifically do not want to link against 87 | `mulle-core`.** 88 | 89 | 90 | ### Add as an individual component 91 | 92 | Use [mulle-sde](//github.com/mulle-sde) to add mulle-thread to your project: 93 | 94 | ``` sh 95 | mulle-sde add github:mulle-concurrent/mulle-thread 96 | ``` 97 | 98 | To only add the sources of mulle-thread with dependency 99 | sources use [clib](https://github.com/clibs/clib): 100 | 101 | 102 | ``` sh 103 | clib install --out src/mulle-concurrent mulle-concurrent/mulle-thread 104 | ``` 105 | 106 | Add `-isystem src/mulle-concurrent` to your `CFLAGS` and compile all the sources that were downloaded with your project. 107 | 108 | 109 | ## Install 110 | 111 | Use [mulle-sde](//github.com/mulle-sde) to build and install mulle-thread and all dependencies: 112 | 113 | ``` sh 114 | mulle-sde install --prefix /usr/local \ 115 | https://github.com/mulle-concurrent/mulle-thread/archive/latest.tar.gz 116 | ``` 117 | 118 | ### Legacy Installation 119 | 120 | Install the requirements: 121 | 122 | | Requirements | Description 123 | |----------------------------------------------|----------------------- 124 | | [mulle-c11](https://github.com/mulle-c/mulle-c11) | 🔀 Cross-platform C compiler glue (and some cpp conveniences) 125 | 126 | Download the latest [tar](https://github.com/mulle-concurrent/mulle-thread/archive/refs/tags/latest.tar.gz) or [zip](https://github.com/mulle-concurrent/mulle-thread/archive/refs/tags/latest.zip) archive and unpack it. 127 | 128 | Install **mulle-thread** into `/usr/local` with [cmake](https://cmake.org): 129 | 130 | ``` sh 131 | PREFIX_DIR="/usr/local" 132 | cmake -B build \ 133 | -DMULLE_SDK_PATH="${PREFIX_DIR}" \ 134 | -DCMAKE_INSTALL_PREFIX="${PREFIX_DIR}" \ 135 | -DCMAKE_PREFIX_PATH="${PREFIX_DIR}" \ 136 | -DCMAKE_BUILD_TYPE=Release && 137 | cmake --build build --config Release && 138 | cmake --install build --config Release 139 | ``` 140 | 141 | 142 | ## Author 143 | 144 | [Nat!](https://mulle-kybernetik.com/weblog) for Mulle kybernetiK 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /clib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "mulle-thread", 3 | "version" : "4.6.2", 4 | "description" : "🔠 Cross-platform thread/mutex/tss/atomic operations in C", 5 | "keywords" : [], 6 | "license" : "BSD-3-Clause", 7 | "repo" : "mulle-concurrent/mulle-thread", 8 | "src" : [ 9 | "src/generic/include-private.h", 10 | "src/generic/include.h", 11 | "src/mintomic-empty.c", 12 | "src/mulle-atomic-c11.h", 13 | "src/mulle-atomic-mintomic.h", 14 | "src/mulle-atomic.h", 15 | "src/mulle-thread-c11.h", 16 | "src/mulle-thread-linkage.c", 17 | "src/mulle-thread-pthreads.h", 18 | "src/mulle-thread-standalone.c", 19 | "src/mulle-thread-windows.c", 20 | "src/mulle-thread-windows.h", 21 | "src/mulle-thread.h", 22 | "src/reflect/_mulle-thread-include-private.h", 23 | "src/reflect/_mulle-thread-include.h", 24 | "src/reflect/_mulle-thread-provide.h", 25 | "src/reflect/_mulle-thread-versioncheck.h" 26 | ], 27 | "dependencies" : { 28 | "mulle-c/mulle-c11": "*", 29 | "mulle-concurrent/mintomic": "*" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /cmake/Headers.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # The following includes include definitions generated 3 | # during `mulle-sde update`. Don't edit those files. They are 4 | # overwritten frequently. 5 | # 6 | # === MULLE-SDE START === 7 | 8 | include( _Headers) 9 | 10 | # === MULLE-SDE END === 11 | # 12 | 13 | # 14 | # If you don't like the "automatic" way of generating _Headers 15 | # 16 | # MULLE_MATCH_TO_CMAKE_HEADERS_FILE="DISABLE" # or NONE 17 | # 18 | 19 | # 20 | # Add ignored headers back in so that the generators pick them up 21 | # 22 | set( PUBLIC_HEADERS 23 | "src/reflect/_mulle-thread-include.h" 24 | ${PUBLIC_HEADERS} 25 | ) 26 | 27 | # keep headers to install separate to make last minute changes 28 | set( INSTALL_PUBLIC_HEADERS 29 | ${PUBLIC_HEADERS} 30 | ${PUBLIC_GENERIC_HEADERS} 31 | ) 32 | 33 | 34 | # 35 | # Do not install generated private headers and include-private.h 36 | # which aren't valid outside of the project scope. 37 | # 38 | set( INSTALL_PRIVATE_HEADERS ${PRIVATE_HEADERS}) 39 | list( REMOVE_ITEM INSTALL_PRIVATE_HEADERS "src/include-private.h") 40 | 41 | # add ignored headers back in so that the generators pick them up 42 | set( PRIVATE_HEADERS 43 | "src/reflect/_mulle-thread-include-private.h" 44 | ${PRIVATE_HEADERS} 45 | ) 46 | 47 | # 48 | # You can put more source and resource file definitions here. 49 | # 50 | # add ignored header back in 51 | # add ignored headers back in 52 | 53 | set( MINTOMIC_PUBLIC_HEADERS 54 | mintomic/include/mintomic/core.h 55 | mintomic/include/mintomic/mintomic.h 56 | mintomic/include/mintomic/platform_detect.h) 57 | 58 | 59 | set( MINTOMIC_PRIVATE_HEADERS 60 | mintomic/include/mintomic/private/core_gcc.h 61 | mintomic/include/mintomic/private/core_msvc.h 62 | mintomic/include/mintomic/private/mintomic_gcc_arm.h 63 | mintomic/include/mintomic/private/mintomic_gcc_x86-64.h 64 | mintomic/include/mintomic/private/mintomic_msvc.h 65 | mintomic/include/mintomic/private/mintomic_stdint.h 66 | ) 67 | 68 | include_directories( 69 | AFTER SYSTEM mintomic/include 70 | ) 71 | 72 | -------------------------------------------------------------------------------- /cmake/README.md: -------------------------------------------------------------------------------- 1 | # cmake 2 | 3 | Files in this folder can be included in your "CMakeLists.txt". They are 4 | included ahead of files with the same name in `reflect` or `share`. 5 | 6 | 7 | 13 | -------------------------------------------------------------------------------- /cmake/Sources.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # The following includes include definitions generated 3 | # during `mulle-sde update`. Don't edit those files. They are 4 | # overwritten frequently. 5 | # 6 | # === MULLE-SDE START === 7 | 8 | include( _Sources) 9 | 10 | # === MULLE-SDE END === 11 | # 12 | # 13 | # If you don't like the "automatic" way of generating _Sources 14 | # 15 | # MULLE_MATCH_TO_CMAKE_SOURCES_FILE="DISABLE" # or NONE 16 | # 17 | 18 | # 19 | # You can put more source and resource file definitions here. 20 | # 21 | 22 | set( SOURCES 23 | src/mulle-thread-linkage.c 24 | ) 25 | 26 | set( STANDALONE_SOURCES 27 | src/mulle-thread-standalone.c 28 | ) 29 | 30 | 31 | if( MSVC) 32 | set( SOURCES 33 | ${SOURCES} 34 | src/mulle-thread-windows.c 35 | ) 36 | endif() 37 | 38 | -------------------------------------------------------------------------------- /cmake/reflect/_Dependencies.cmake: -------------------------------------------------------------------------------- 1 | # This file will be regenerated by `mulle-sourcetree-to-cmake` via 2 | # `mulle-sde reflect` and any edits will be lost. 3 | # 4 | # This file will be included by cmake/share/Files.cmake 5 | # 6 | # Disable generation of this file with: 7 | # 8 | # mulle-sde environment set MULLE_SOURCETREE_TO_CMAKE_DEPENDENCIES_FILE DISABLE 9 | # 10 | if( MULLE_TRACE_INCLUDE) 11 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 12 | endif() 13 | 14 | # 15 | # Generated from sourcetree: 97F390B6-FA26-4BAC-BB87-90A654AAB3B6;mulle-c11;no-all-load,no-cmake-inherit,no-import,no-link,no-recurse,no-singlephase; 16 | # Disable with : `mulle-sourcetree mark mulle-c11 no-header` 17 | # Disable for this platform: `mulle-sourcetree mark mulle-c11 no-cmake-platform-${MULLE_UNAME}` 18 | # Disable for a sdk: `mulle-sourcetree mark mulle-c11 no-cmake-sdk-` 19 | # 20 | if( NOT MULLE__C11_HEADER) 21 | find_file( MULLE__C11_HEADER NAMES mulle-c11.h mulle-c11/mulle-c11.h) 22 | message( STATUS "MULLE__C11_HEADER is ${MULLE__C11_HEADER}") 23 | 24 | # 25 | # Add MULLE__C11_HEADER to HEADER_ONLY_LIBRARIES list. 26 | # Disable with: `mulle-sourcetree mark mulle-c11 no-cmake-add` 27 | # 28 | set( HEADER_ONLY_LIBRARIES 29 | ${MULLE__C11_HEADER} 30 | ${HEADER_ONLY_LIBRARIES} 31 | ) 32 | if( MULLE__C11_HEADER) 33 | # intentionally left blank 34 | else() 35 | # Disable with: `mulle-sourcetree mark mulle-c11 no-require` 36 | message( SEND_ERROR "MULLE__C11_HEADER was not found") 37 | endif() 38 | endif() 39 | -------------------------------------------------------------------------------- /cmake/reflect/_Headers.cmake: -------------------------------------------------------------------------------- 1 | # This file will be regenerated by `mulle-match-to-cmake` via 2 | # `mulle-sde reflect` and any edits will be lost. 3 | # 4 | # This file will be included by cmake/share/Headers.cmake 5 | # 6 | if( MULLE_TRACE_INCLUDE) 7 | MESSAGE( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 8 | endif() 9 | 10 | # 11 | # contents are derived from the file locations 12 | 13 | set( INCLUDE_DIRS 14 | src/reflect 15 | src/generic 16 | src 17 | ) 18 | 19 | # 20 | # contents selected with patternfile ??-header--private-generated-headers 21 | # 22 | set( PRIVATE_GENERATED_HEADERS 23 | src/reflect/_mulle-thread-include-private.h 24 | ) 25 | 26 | # 27 | # contents selected with patternfile ??-header--private-generic-headers 28 | # 29 | set( PRIVATE_GENERIC_HEADERS 30 | src/generic/include-private.h 31 | ) 32 | 33 | # 34 | # contents selected with patternfile ??-header--public-generated-headers 35 | # 36 | set( PUBLIC_GENERATED_HEADERS 37 | src/reflect/_mulle-thread-include.h 38 | src/reflect/_mulle-thread-provide.h 39 | src/reflect/_mulle-thread-versioncheck.h 40 | ) 41 | 42 | # 43 | # contents selected with patternfile ??-header--public-generic-headers 44 | # 45 | set( PUBLIC_GENERIC_HEADERS 46 | src/generic/include.h 47 | ) 48 | 49 | # 50 | # contents selected with patternfile ??-header--public-headers 51 | # 52 | set( PUBLIC_HEADERS 53 | src/mulle-atomic-c11.h 54 | src/mulle-atomic.h 55 | src/mulle-atomic-mintomic.h 56 | src/mulle-thread-c11.h 57 | src/mulle-thread.h 58 | src/mulle-thread-pthreads.h 59 | src/mulle-thread-windows.h 60 | ) 61 | 62 | -------------------------------------------------------------------------------- /cmake/reflect/_Libraries.cmake: -------------------------------------------------------------------------------- 1 | # This file will be regenerated by `mulle-sourcetree-to-cmake` via 2 | # `mulle-sde reflect` and any edits will be lost. 3 | # 4 | # This file will be included by cmake/share/Files.cmake 5 | # 6 | # Disable generation of this file with: 7 | # 8 | # mulle-sde environment set MULLE_SOURCETREE_TO_CMAKE_LIBRARIES_FILE DISABLE 9 | # 10 | if( MULLE_TRACE_INCLUDE) 11 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 12 | endif() 13 | 14 | # 15 | # Generated from sourcetree: 91a3a06c-669f-4cd4-9060-562b3d0b6315;stdthreads;no-all-load,no-build,no-cmake-inherit,no-delete,no-dependency,no-fs,no-import,no-update,only-platform-freebsd; 16 | # Disable with : `mulle-sourcetree mark stdthreads ` 17 | # Disable for this platform: `mulle-sourcetree mark stdthreads no-cmake-platform-${MULLE_UNAME}` 18 | # Disable for a sdk: `mulle-sourcetree mark stdthreads no-cmake-sdk-` 19 | # 20 | if( ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") 21 | if( COLLECT_OS_SPECIFIC_LIBRARIES_AS_NAMES) 22 | list( APPEND OS_SPECIFIC_LIBRARIES "stdthreads") 23 | else() 24 | if( NOT STDTHREADS_LIBRARY) 25 | find_library( STDTHREADS_LIBRARY NAMES 26 | stdthreads 27 | ) 28 | message( STATUS "STDTHREADS_LIBRARY is ${STDTHREADS_LIBRARY}") 29 | # 30 | # The order looks ascending, but due to the way this file is read 31 | # it ends up being descending, which is what we need. 32 | # 33 | if( STDTHREADS_LIBRARY) 34 | # 35 | # Add STDTHREADS_LIBRARY to OS_SPECIFIC_LIBRARIES list. 36 | # Disable with: `mulle-sourcetree mark stdthreads no-cmake-add` 37 | # 38 | list( APPEND OS_SPECIFIC_LIBRARIES ${STDTHREADS_LIBRARY}) 39 | # intentionally left blank 40 | else() 41 | # Disable with: `mulle-sourcetree mark stdthreads no-require-link` 42 | message( SEND_ERROR "STDTHREADS_LIBRARY was not found") 43 | endif() 44 | endif() 45 | endif() 46 | endif() 47 | 48 | 49 | # 50 | # Generated from sourcetree: 8fd8130b-1d75-4633-89b4-57e61467847e;pthread;no-all-load,no-build,no-delete,no-dependency,no-fs,no-import,no-platform-android,no-platform-mingw,no-require,no-update;pthreads,pthread 51 | # Disable with : `mulle-sourcetree mark pthread ` 52 | # Disable for this platform: `mulle-sourcetree mark pthread no-cmake-platform-${MULLE_UNAME}` 53 | # Disable for a sdk: `mulle-sourcetree mark pthread no-cmake-sdk-` 54 | # 55 | if( NOT (${CMAKE_SYSTEM_NAME} MATCHES "Android" OR ${CMAKE_SYSTEM_NAME} MATCHES "Windows")) 56 | if( COLLECT_OS_SPECIFIC_LIBRARIES_AS_NAMES) 57 | list( APPEND OS_SPECIFIC_LIBRARIES "pthreads") 58 | else() 59 | if( NOT PTHREAD_LIBRARY) 60 | find_library( PTHREAD_LIBRARY NAMES 61 | pthreads 62 | pthread 63 | ) 64 | message( STATUS "PTHREAD_LIBRARY is ${PTHREAD_LIBRARY}") 65 | # 66 | # The order looks ascending, but due to the way this file is read 67 | # it ends up being descending, which is what we need. 68 | # 69 | if( PTHREAD_LIBRARY) 70 | # 71 | # Add PTHREAD_LIBRARY to OS_SPECIFIC_LIBRARIES list. 72 | # Disable with: `mulle-sourcetree mark pthread no-cmake-add` 73 | # 74 | list( APPEND OS_SPECIFIC_LIBRARIES ${PTHREAD_LIBRARY}) 75 | # 76 | # Inherit information from dependency. 77 | # Encompasses: no-cmake-searchpath,no-cmake-dependency,no-cmake-loader 78 | # Disable with: `mulle-sourcetree mark pthread no-cmake-inherit` 79 | # 80 | # temporarily expand CMAKE_MODULE_PATH 81 | get_filename_component( _TMP_PTHREAD_ROOT "${PTHREAD_LIBRARY}" DIRECTORY) 82 | get_filename_component( _TMP_PTHREAD_ROOT "${_TMP_PTHREAD_ROOT}" DIRECTORY) 83 | # 84 | # 85 | # Search for "Definitions.cmake" and "DependenciesAndLibraries.cmake" to include. 86 | # Disable with: `mulle-sourcetree mark pthread no-cmake-dependency` 87 | # 88 | foreach( _TMP_PTHREAD_NAME "pthreads" "pthread") 89 | set( _TMP_PTHREAD_DIR "${_TMP_PTHREAD_ROOT}/include/${_TMP_PTHREAD_NAME}/cmake") 90 | # use explicit path to avoid "surprises" 91 | if( IS_DIRECTORY "${_TMP_PTHREAD_DIR}") 92 | list( INSERT CMAKE_MODULE_PATH 0 "${_TMP_PTHREAD_DIR}") 93 | # we only want top level INHERIT_OBJC_LOADERS, so disable them 94 | if( NOT NO_INHERIT_OBJC_LOADERS) 95 | set( NO_INHERIT_OBJC_LOADERS OFF) 96 | endif() 97 | list( APPEND _TMP_INHERIT_OBJC_LOADERS ${NO_INHERIT_OBJC_LOADERS}) 98 | set( NO_INHERIT_OBJC_LOADERS ON) 99 | # 100 | include( "${_TMP_PTHREAD_DIR}/DependenciesAndLibraries.cmake" OPTIONAL) 101 | # 102 | list( GET _TMP_INHERIT_OBJC_LOADERS -1 NO_INHERIT_OBJC_LOADERS) 103 | list( REMOVE_AT _TMP_INHERIT_OBJC_LOADERS -1) 104 | list( REMOVE_ITEM CMAKE_MODULE_PATH "${_TMP_PTHREAD_DIR}") 105 | # 106 | unset( PTHREAD_DEFINITIONS) 107 | include( "${_TMP_PTHREAD_DIR}/Definitions.cmake" OPTIONAL) 108 | list( APPEND INHERITED_DEFINITIONS ${PTHREAD_DEFINITIONS}) 109 | break() 110 | else() 111 | message( STATUS "${_TMP_PTHREAD_DIR} not found") 112 | endif() 113 | endforeach() 114 | else() 115 | # Enable with: `mulle-sourcetree mark pthread require` 116 | message( STATUS "PTHREAD_LIBRARY is missing but it is marked as \"no-require\"") 117 | endif() 118 | endif() 119 | endif() 120 | endif() 121 | -------------------------------------------------------------------------------- /cmake/reflect/_Resources.cmake: -------------------------------------------------------------------------------- 1 | # This file will be regenerated by `mulle-match-to-cmake` via 2 | # `mulle-sde reflect` and any edits will be lost. 3 | # 4 | # This file will be included by cmake/share/resources.cmake 5 | # 6 | if( MULLE_TRACE_INCLUDE) 7 | MESSAGE( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 8 | endif() 9 | 10 | message( STATUS "No resources found. `mulle-sde environment set MULLE_MATCH_TO_CMAKE_RESOURCES_FILE NONE`, to avoid this (harmless) warning") 11 | -------------------------------------------------------------------------------- /cmake/reflect/_Sources.cmake: -------------------------------------------------------------------------------- 1 | # This file will be regenerated by `mulle-match-to-cmake` via 2 | # `mulle-sde reflect` and any edits will be lost. 3 | # 4 | # This file will be included by cmake/share/sources.cmake 5 | # 6 | if( MULLE_TRACE_INCLUDE) 7 | MESSAGE( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 8 | endif() 9 | 10 | # Source generation disabled by MULLE_MATCH_TO_CMAKE_SOURCES_FILE=NONE 11 | -------------------------------------------------------------------------------- /cmake/share/AllLoadC.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | if( NOT __ALL_LOAD_C_CMAKE__) 6 | set( __ALL_LOAD_C_CMAKE__ ON) 7 | 8 | if( MULLE_TRACE_INCLUDE) 9 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 10 | endif() 11 | 12 | # 13 | # Get the linker to not strip away "unused" symbols during 14 | # a link 15 | # 16 | # This is either done by prefixing a library or enclosing 17 | # link statements. Sometimes it seemed as if Apple needed 18 | # -lx -force_load x though. ? 19 | # 20 | if( APPLE) 21 | set( FORCE_LOAD_PREFIX "-force_load ") 22 | set( BEGIN_ALL_LOAD) 23 | set( END_ALL_LOAD) 24 | else() 25 | if( WIN32) 26 | set( FORCE_LOAD_PREFIX "-WHOLEARCHIVE:") 27 | set( BEGIN_ALL_LOAD) 28 | set( END_ALL_LOAD) 29 | else() 30 | set( BEGIN_ALL_LOAD "-Wl,--whole-archive -Wl,--no-as-needed") 31 | set( END_ALL_LOAD "-Wl,--as-needed -Wl,--no-whole-archive") 32 | set( FORCE_LOAD_PREFIX) 33 | endif() 34 | endif() 35 | 36 | 37 | # 38 | # For APPLE we mention the library twice. That's because if it happens to 39 | # be a shared library, for some reason, that cmake still picks it up 40 | # to generate an RPATH. 41 | # 42 | # ALL_LOAD_PREFIX can be set to "-Xlinker -reexport_library " and then 43 | # symbols will be reexported. 44 | # 45 | function( CreateForceAllLoadList listname outputname) 46 | set( list "") 47 | if( ${listname}) 48 | set( list ${BEGIN_ALL_LOAD}) 49 | foreach( library ${${listname}}) 50 | if( APPLE) 51 | list( APPEND list "${ALL_LOAD_PREFIX}${library}") 52 | # if FORCE_LOAD_PREFIX is empty, we can skip the output 53 | # which is handy sometimes when we have dynamic frameworks 54 | # (hacque). But only on APPLE, where we emitted something 55 | # already... 56 | if( FORCE_LOAD_PREFIX) 57 | list( APPEND list "${FORCE_LOAD_PREFIX}${library}") 58 | endif() 59 | else() 60 | list( APPEND list "${FORCE_LOAD_PREFIX}${library}") 61 | endif() 62 | endforeach() 63 | list( APPEND list ${END_ALL_LOAD}) 64 | endif() 65 | set( ${outputname} "${list}" PARENT_SCOPE) 66 | endfunction() 67 | 68 | include( AllLoadAuxC OPTIONAL) 69 | 70 | endif() 71 | -------------------------------------------------------------------------------- /cmake/share/CMakeTweaksC.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | if( NOT __CMAKE_TWEAKS_C_CMAKE__) 6 | set( __CMAKE_TWEAKS_C_CMAKE__ ON) 7 | 8 | if( MULLE_TRACE_INCLUDE) 9 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 10 | endif() 11 | 12 | # https://cmake.org/cmake/help/v3.1/policy/CMP0054.html 13 | cmake_policy( SET CMP0054 NEW) 14 | 15 | # makes nicer Xcode projects, I see no detriment 16 | set_property( GLOBAL PROPERTY USE_FOLDERS ON) 17 | 18 | if( APPLE) 19 | # actually 3.0 but cmake gets pissy then nowadays 20 | # cmake_minimum_required (VERSION 3.15) 21 | 22 | # CMAKE_OSX_SYSROOT must be set for CMAKE_OSX_DEPLOYMENT_TARGET (cmake bug) 23 | if( NOT CMAKE_OSX_SYSROOT) 24 | set( CMAKE_OSX_SYSROOT "/" CACHE STRING "SDK for OSX" FORCE) # means current OS X 25 | endif() 26 | 27 | # baseline set to OSX_VERSION for rpath (is this still needed?) 28 | if( NOT CMAKE_OSX_DEPLOYMENT_TARGET AND NOT $ENV{MACOSX_DEPLOYMENT_TARGET} ) 29 | execute_process( COMMAND sw_vers -productVersion 30 | OUTPUT_VARIABLE OSX_VERSION_FULL 31 | OUTPUT_STRIP_TRAILING_WHITESPACE) 32 | string( REGEX REPLACE "\\.[^.]*$" "" OSX_VERSION ${OSX_VERSION_FULL} ) 33 | 34 | set( CMAKE_OSX_DEPLOYMENT_TARGET "${OSX_VERSION}" CACHE STRING "Deployment target for OSX" FORCE) 35 | endif() 36 | 37 | set( CMAKE_POSITION_INDEPENDENT_CODE OFF) 38 | 39 | else() 40 | if( WIN32) 41 | # may not be enough though... 42 | # cmake_minimum_required( VERSION 3.13...99.99) 43 | else() 44 | # UNIXy gcc based 45 | # cmake_minimum_required( VERSION 3.13...99.99) 46 | endif() 47 | # 48 | # so we build static libs, but they might be linked into code 49 | # that needs -fPIC, but on some platforms (MUSL, COSMOPOLITAN) 50 | # we don't want PIC/PIE executables (why?) 51 | # 52 | # https://github.com/jart/cosmopolitan/issues/703 53 | # 54 | if( COSMOPOLITAN OR MUSL_STATIC_ONLY) 55 | set( CMAKE_SKIP_RPATH ON) 56 | # (230213) turn this on for mulle-objc-optimize 57 | set( CMAKE_POSITION_INDEPENDENT_CODE ON) 58 | # but don't link as such 59 | set( CMAKE_EXE_LINKER_FLAGS "-no-pie ${CMAKE_EXE_LINKER_FLAGS}") 60 | else() 61 | set( CMAKE_POSITION_INDEPENDENT_CODE ON) 62 | endif() 63 | endif() 64 | 65 | include( CMakeTweaksAuxC OPTIONAL) 66 | 67 | endif() 68 | -------------------------------------------------------------------------------- /cmake/share/CompilerDetectionC.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | if( NOT __COMPILER_DETECTION_C_CMAKE__) 6 | set( __COMPILER_DETECTION_C_CMAKE__ ON) 7 | 8 | if( MULLE_TRACE_INCLUDE) 9 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 10 | endif() 11 | 12 | # 13 | # for windows want a MSVC prefix 14 | # 15 | # CMAKE_C_COMPILER_ID, doesn't detect mulle-clang necessarily, so fallback 16 | # on -DCMAKE_C_COMPILER 17 | # 18 | if( NOT MULLE_C_COMPILER_ID) 19 | string( TOUPPER "${CMAKE_C_COMPILER_ID}" TMP_NAME) 20 | string( REGEX REPLACE "[^A-Za-z0-9]" "" TMP_NAME "${TMP_NAME}") 21 | if( ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") AND ( "${TMP_NAME}" MATCHES "CLANG") ) 22 | set( MULLE_C_COMPILER_ID "MSVC-${TMP_NAME}") 23 | else() 24 | get_filename_component( TMP_NAME2 "${CMAKE_C_COMPILER}" NAME_WE) 25 | string( TOUPPER "${TMP_NAME2}" TMP_NAME2) 26 | string( REGEX REPLACE "[^A-Za-z0-9]" "" TMP_NAME2 "${TMP_NAME2}") 27 | if( "${TMP_NAME2}" MATCHES "MULLECLANG") 28 | set( MULLE_C_COMPILER_ID "${TMP_NAME2}") 29 | else() 30 | set( MULLE_C_COMPILER_ID "${TMP_NAME}") 31 | endif() 32 | endif() 33 | endif() 34 | 35 | if( NOT MULLE_CXX_COMPILER_ID) 36 | string( TOUPPER "${CMAKE_CXX_COMPILER_ID}" TMP_NAME) 37 | string( REGEX REPLACE "[^A-Za-z0-9]" "" TMP_NAME "${TMP_NAME}") 38 | if( ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") AND ( "${TMP_NAME}" MATCHES "CLANG") ) 39 | set( MULLE_CXX_COMPILER_ID "MSVC-${TMP_NAME}") 40 | else() 41 | get_filename_component( TMP_NAME2 "${CMAKE_CXX_COMPILER}" NAME_WE) 42 | string( TOUPPER "${TMP_NAME2}" TMP_NAME2) 43 | string( REGEX REPLACE "[^A-Za-z0-9]" "" TMP_NAME2 "${TMP_NAME2}") 44 | if( "${TMP_NAME2}" MATCHES "MULLECLANG") 45 | set( MULLE_CXX_COMPILER_ID "${TMP_NAME2}") 46 | else() 47 | set( MULLE_CXX_COMPILER_ID "${TMP_NAME}") 48 | endif() 49 | endif() 50 | endif() 51 | 52 | include( CompilerDetectionAuxC OPTIONAL) 53 | 54 | endif() 55 | -------------------------------------------------------------------------------- /cmake/share/CompilerFlagsC.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | if( NOT __COMPILER_FLAGS_C_CMAKE__) 6 | set( __COMPILER_FLAGS_C_CMAKE__ ON) 7 | 8 | if( MULLE_TRACE_INCLUDE) 9 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 10 | endif() 11 | 12 | set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OTHER_C_FLAGS} ${WANTED_C_WARNINGS} ${UNWANTED_C_WARNINGS}") 13 | set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OTHER_C_FLAGS} ${WANTED_C_WARNINGS} ${UNWANTED_C_WARNINGS}") 14 | 15 | if( CMAKE_BUILD_TYPE) 16 | string( TOUPPER "${CMAKE_BUILD_TYPE}" TMP_CONFIGURATION_NAME) 17 | add_definitions( "-D${TMP_CONFIGURATION_NAME}" ) 18 | if( NOT (TMP_CONFIGURATION_NAME STREQUAL "DEBUG")) 19 | add_definitions( "-DNDEBUG" ) 20 | endif() 21 | endif() 22 | 23 | if( MULLE_TEST) 24 | add_definitions( "-DMULLE_TEST=1" ) 25 | endif() 26 | 27 | # set this as the default, as we expect shared libs to be included too 28 | # if this is not the case you need to change this on a case per case 29 | # basis 30 | # 31 | if( BUILD_SHARED_LIBS) 32 | add_definitions( "-DMULLE_INCLUDE_DYNAMIC=1" ) 33 | endif() 34 | 35 | # 36 | # MEMO: mulle-clang is currently too old for "mold", it doesn't know about 37 | # that linker yet. 38 | # 39 | # if( "${CMAKE_C_COMPILER_ID}" MATCHES "^(Clang|MulleClang)$") 40 | # find_program( MOLD_LINKER "mold") 41 | # if( MOLD_LINKER) 42 | # set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=mold") 43 | # endif() 44 | # endif() 45 | 46 | # load in flags defined by other plugins, presumably Objective-C 47 | include( CompilerFlagsAuxC OPTIONAL) 48 | 49 | endif() 50 | -------------------------------------------------------------------------------- /cmake/share/CompilerWarningsC.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | if( NOT __UNWANTED_WARNINGS_C_CMAKE__) 6 | set( __UNWANTED_WARNINGS_C_CMAKE__ ON) 7 | 8 | if( MULLE_TRACE_INCLUDE) 9 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 10 | endif() 11 | 12 | if( NOT DEFINED UNWANTED_WARNINGS) 13 | option( UNWANTED_WARNINGS "Squelch some unwanted compiler warnings" ON) 14 | endif() 15 | 16 | if( UNWANTED_WARNINGS) 17 | # 18 | # move this to ObjC 19 | # 20 | if( "${MULLE_C_COMPILER_ID}" MATCHES "^(Clang|AppleClang|MulleClang|GNU)$") 21 | set( UNWANTED_C_WARNINGS "-Wno-parentheses") 22 | else() 23 | if( "${MULLE_C_COMPILER_ID}" MATCHES "^(Intel|MSVC|MSVC-Clang|MSVC-MulleClang)$") 24 | # C4068: unwanted pragma 25 | set( UNWANTED_C_WARNINGS "/D_CRT_SECURE_NO_WARNINGS /wd4068 /wd4113") 26 | endif() 27 | endif() 28 | 29 | if( "${MULLE_C_COMPILER_ID}" MATCHES "^(MSVC-Clang|MSVC-MulleClang)$") 30 | # set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") 31 | # 4211 is for classes.. 32 | set( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /ignore:4221") 33 | set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4221") 34 | set( CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221") 35 | endif() 36 | endif() 37 | 38 | if( NOT DEFINED WANTED_WARNINGS) 39 | option( WANTED_WARNINGS "Enable some desirable compiler warnings" ON) 40 | endif() 41 | 42 | if( WANTED_WARNINGS) 43 | # 44 | # move this to ObjC 45 | # 46 | if( "${MULLE_C_COMPILER_ID}" MATCHES "^(Clang|AppleClang|MulleClang|GNU)$") 47 | set( WANTED_C_WARNINGS "-Wuninitialized -Wunused") 48 | endif() 49 | endif() 50 | 51 | endif() 52 | -------------------------------------------------------------------------------- /cmake/share/Dependencies.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | ### Dependencies 6 | 7 | 8 | if( NOT __DEPENDENCIES___CMAKE__) 9 | set( __DEPENDENCIES___CMAKE__ ON) 10 | 11 | if( MULLE_TRACE_INCLUDE) 12 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 13 | endif() 14 | 15 | include( PreDependencies OPTIONAL) 16 | 17 | include( DependenciesAndLibraries OPTIONAL) 18 | 19 | # 20 | # So the generated dependency code stores the result of each find_library 21 | # in a cached variable, this means we also have to cache the 22 | # accmulated lists. We can't do it in DependenciesAndLibraries because 23 | # that file is inherited in other projects and we don't want to 24 | # clobber their cache. But "Dependencies.cmake" is only included by the 25 | # main project 26 | # 27 | if( NOT DEFINED CACHE{INHERITED_INCLUDE_DIRS}) 28 | # remove some duplicates (can happen, if we alias to an amalgamated library) 29 | list( REMOVE_DUPLICATES INHERITED_INCLUDE_DIRS) 30 | list( REMOVE_DUPLICATES INHERITED_DEFINITIONS) 31 | 32 | list( REMOVE_DUPLICATES HEADER_ONLY_LIBRARIES) 33 | 34 | list( REMOVE_DUPLICATES DEPENDENCY_LIBRARIES) 35 | list( REMOVE_DUPLICATES DEPENDENCY_FRAMEWORKS) 36 | list( REMOVE_DUPLICATES OS_SPECIFIC_LIBRARIES) 37 | list( REMOVE_DUPLICATES OS_SPECIFIC_FRAMEWORKS) 38 | 39 | list( REMOVE_DUPLICATES ALL_LOAD_OS_SPECIFIC_LIBRARIES) 40 | list( REMOVE_DUPLICATES ALL_LOAD_OS_SPECIFIC_FRAMEWORKS) 41 | list( REMOVE_DUPLICATES ALL_LOAD_DEPENDENCY_LIBRARIES) 42 | list( REMOVE_DUPLICATES ALL_LOAD_DEPENDENCY_FRAMEWORKS) 43 | 44 | list( REMOVE_DUPLICATES ALL_LOAD_OPTIONAL_DEPENDENCY_LIBRARIES) 45 | list( REMOVE_DUPLICATES ALL_LOAD_OPTIONAL_DEPENDENCY_FRAMEWORKS) 46 | list( REMOVE_DUPLICATES STARTUP_ALL_LOAD_DEPENDENCY_LIBRARIES) 47 | list( REMOVE_DUPLICATES STARTUP_ALL_LOAD_DEPENDENCY_FRAMEWORKS) 48 | 49 | set( INHERITED_INCLUDE_DIRS ${INHERITED_INCLUDE_DIRS} CACHE INTERNAL "cache these") 50 | set( INHERITED_DEFINITIONS ${INHERITED_DEFINITIONS} CACHE INTERNAL "cache these") 51 | 52 | set( HEADER_ONLY_LIBRARIES ${HEADER_ONLY_LIBRARIES} CACHE INTERNAL "cache these") 53 | 54 | set( DEPENDENCY_LIBRARIES ${DEPENDENCY_LIBRARIES} CACHE INTERNAL "cache these") 55 | set( DEPENDENCY_FRAMEWORKS ${DEPENDENCY_FRAMEWORKS} CACHE INTERNAL "cache these") 56 | set( OS_SPECIFIC_LIBRARIES ${OS_SPECIFIC_LIBRARIES} CACHE INTERNAL "cache these") 57 | set( OS_SPECIFIC_FRAMEWORKS ${OS_SPECIFIC_FRAMEWORKS} CACHE INTERNAL "cache these") 58 | 59 | set( ALL_LOAD_OS_SPECIFIC_LIBRARIES ${ALL_LOAD_OS_SPECIFIC_LIBRARIES} CACHE INTERNAL "cache these") 60 | set( ALL_LOAD_OS_SPECIFIC_FRAMEWORKS ${ALL_LOAD_OS_SPECIFIC_FRAMEWORKS} CACHE INTERNAL "cache these") 61 | set( ALL_LOAD_DEPENDENCY_LIBRARIES ${ALL_LOAD_DEPENDENCY_LIBRARIES} CACHE INTERNAL "cache these") 62 | set( ALL_LOAD_DEPENDENCY_FRAMEWORKS ${ALL_LOAD_DEPENDENCY_FRAMEWORKS} CACHE INTERNAL "cache these") 63 | 64 | set( ALL_LOAD_OPTIONAL_DEPENDENCY_LIBRARIES ${ALL_LOAD_OPTIONAL_DEPENDENCY_LIBRARIES} CACHE INTERNAL "cache these") 65 | set( ALL_LOAD_OPTIONAL_DEPENDENCY_FRAMEWORKS ${ALL_LOAD_OPTIONAL_DEPENDENCY_FRAMEWORKS} CACHE INTERNAL "cache these") 66 | set( STARTUP_ALL_LOAD_DEPENDENCY_LIBRARIES ${STARTUP_ALL_LOAD_DEPENDENCY_LIBRARIES} CACHE INTERNAL "cache these") 67 | set( STARTUP_ALL_LOAD_DEPENDENCY_FRAMEWORKS ${STARTUP_ALL_LOAD_DEPENDENCY_FRAMEWORKS} CACHE INTERNAL "cache these") 68 | endif() 69 | 70 | # 71 | # MEMO: Do not cache anything here. It will affect projects that include 72 | # this file as part of the inheritance scheme 73 | # 74 | option( INHERIT_DEPENDENCY_INCLUDES "Make headers of dependencies available as local headers" OFF) 75 | 76 | if( INHERIT_DEPENDENCY_INCLUDES) 77 | # message( STATUS "INHERITED_INCLUDE_DIRS=\"${INHERITED_INCLUDE_DIRS}\"" ) 78 | 79 | # these generate -I arguments, that add to the user search path 80 | include_directories( ${INHERITED_INCLUDE_DIRS}) 81 | endif() 82 | 83 | 84 | option( INHERIT_DEPENDENCY_DEFINITIONS "Inherit compiler flags from dependencies" ON) 85 | 86 | if( INHERIT_DEPENDENCY_INCLUDES) 87 | add_compile_definitions( ${INHERITED_DEFINITIONS}) 88 | endif() 89 | 90 | endif() 91 | -------------------------------------------------------------------------------- /cmake/share/DependenciesAndLibraries.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | if( MULLE_TRACE_INCLUDE) 6 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 7 | endif() 8 | 9 | # 10 | # Get Libraries first. That way local library definitions override those 11 | # we might inherit from dependencies. The link order should not be affected by 12 | # this. 13 | # 14 | include( _Libraries OPTIONAL) 15 | 16 | # 17 | # If we are in an IDE like CLion and the dependencies haven't been made yet 18 | # cmake is unhappy, try to avoid that. 19 | # 20 | if( IS_DIRECTORY "${DEPENDENCY_DIR}") 21 | include( _Dependencies OPTIONAL) 22 | else() 23 | message( STATUS "DEPENDENCY_DIR \"${DEPENDENCY_DIR}\" is missing, so no dependencies") 24 | endif() 25 | -------------------------------------------------------------------------------- /cmake/share/ExecutableAux.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | if( MULLE_TRACE_INCLUDE) 6 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 7 | endif() 8 | 9 | 10 | include( AllLoadC) 11 | 12 | include( ExecutableAuxC OPTIONAL) 13 | 14 | # 15 | # Currently we have no distinction for static and dynamic frameworks 16 | # all frameworks are dynamic, so we don't really force load them. 17 | # But we keep the code as is otherwise, because static frameworks are likely 18 | # to arrive sooner or later. 19 | # 20 | # --- this probably fixed something but its disastrous for plain 21 | # mulle-objc-developer/objc-developer with static libraries 22 | # 23 | # if( APPLE) 24 | # unset( FORCE_LOAD_PREFIX) 25 | # endif() 26 | 27 | 28 | if( NOT DEFINED EXECUTABLE_LIBRARY_LIST) 29 | # MEMO: frameworks are always shared so we don't force them 30 | 31 | # CreateForceAllLoadList( ALL_LOAD_DEPENDENCY_FRAMEWORKS FORCE_ALL_LOAD_DEPENDENCY_FRAMEWORKS) 32 | # CreateForceAllLoadList( ALL_LOAD_OPTIONAL_DEPENDENCY_FRAMEWORKS FORCE_ALL_LOAD_OPTIONAL_DEPENDENCY_FRAMEWORKS) 33 | # CreateForceAllLoadList( ALL_LOAD_OS_SPECIFIC_FRAMEWORKS FORCE_ALL_LOAD_OS_SPECIFIC_FRAMEWORKS) 34 | # CreateForceAllLoadList( STARTUP_ALL_LOAD_DEPENDENCY_FRAMEWORKS FORCE_STARTUP_ALL_LOAD_DEPENDENCY_FRAMEWORKS) 35 | 36 | CreateForceAllLoadList( ALL_LOAD_DEPENDENCY_LIBRARIES FORCE_ALL_LOAD_DEPENDENCY_LIBRARIES) 37 | CreateForceAllLoadList( ALL_LOAD_OPTIONAL_DEPENDENCY_LIBRARIES FORCE_ALL_LOAD_OPTIONAL_DEPENDENCY_LIBRARIES) 38 | CreateForceAllLoadList( ALL_LOAD_OS_SPECIFIC_LIBRARIES FORCE_ALL_LOAD_OS_SPECIFIC_LIBRARIES) 39 | CreateForceAllLoadList( STARTUP_ALL_LOAD_DEPENDENCY_LIBRARIES FORCE_STARTUP_ALL_LOAD_DEPENDENCY_LIBRARIES) 40 | 41 | set( EXECUTABLE_LIBRARY_LIST 42 | ${FORCE_ALL_LOAD_DEPENDENCY_LIBRARIES} 43 | ${ALL_LOAD_DEPENDENCY_FRAMEWORKS} 44 | ${DEPENDENCY_LIBRARIES} 45 | ${DEPENDENCY_FRAMEWORKS} 46 | 47 | ${FORCE_ALL_LOAD_OPTIONAL_DEPENDENCY_LIBRARIES} 48 | ${ALL_LOAD_OPTIONAL_DEPENDENCY_FRAMEWORKS} 49 | ${OPTIONAL_DEPENDENCY_LIBRARIES} 50 | ${OPTIONAL_DEPENDENCY_FRAMEWORKS} 51 | 52 | ${FORCE_STARTUP_ALL_LOAD_DEPENDENCY_LIBRARIES} 53 | ${STARTUP_ALL_LOAD_DEPENDENCY_FRAMEWORKS} 54 | ${STARTUP_DEPENDENCY_LIBRARIES} 55 | ${STARTUP_DEPENDENCY_FRAMEWORKS} 56 | 57 | ${FORCE_ALL_LOAD_OS_SPECIFIC_LIBRARIES} 58 | ${ALL_LOAD_OS_SPECIFIC_FRAMEWORKS} 59 | ${OS_SPECIFIC_LIBRARIES} 60 | ${OS_SPECIFIC_FRAMEWORKS} 61 | ) 62 | endif() 63 | -------------------------------------------------------------------------------- /cmake/share/Files.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | ### Files 6 | if( NOT __FILES__CMAKE__) 7 | set( __FILES___CMAKE__ ON) 8 | 9 | if( MULLE_TRACE_INCLUDE) 10 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 11 | endif() 12 | 13 | message( STATUS "CMAKE_CURRENT_SOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\"") 14 | 15 | include( PreFiles OPTIONAL) 16 | 17 | include( Headers OPTIONAL) 18 | include( Sources OPTIONAL) 19 | include( Resources OPTIONAL) 20 | 21 | 22 | # 23 | # PROJECT_FILES (GUI Support) 24 | # 25 | if( NOT DEFINED CACHE{INSTALL_CMAKE_INCLUDES}) 26 | if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Definitions.cmake") 27 | list( APPEND INSTALL_CMAKE_INCLUDES "cmake/Definitions.cmake") 28 | endif() 29 | if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/DependenciesAndLibraries.cmake") 30 | list( APPEND INSTALL_CMAKE_INCLUDES "cmake/DependenciesAndLibraries.cmake") 31 | else() 32 | list( APPEND INSTALL_CMAKE_INCLUDES "cmake/share/DependenciesAndLibraries.cmake") 33 | endif() 34 | if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/_Dependencies.cmake") 35 | list( APPEND INSTALL_CMAKE_INCLUDES "cmake/_Dependencies.cmake") 36 | else() 37 | list( APPEND INSTALL_CMAKE_INCLUDES "cmake/reflect/_Dependencies.cmake") 38 | endif() 39 | if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/_Libraries.cmake") 40 | list( APPEND INSTALL_CMAKE_INCLUDES "cmake/_Libraries.cmake") 41 | else() 42 | list( APPEND INSTALL_CMAKE_INCLUDES "cmake/reflect/_Libraries.cmake") 43 | endif() 44 | set( INSTALL_CMAKE_INCLUDES ${INSTALL_CMAKE_INCLUDES} CACHE INTERNAL "cache these") 45 | endif() 46 | 47 | 48 | if( NOT DEFINED CACHE{PROJCT_CMAKE_EDITABLE_FILES}) 49 | 50 | # IDE visible cmake files, Headers etc. are no longer there by default 51 | if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt") 52 | list( APPEND PROJCT_CMAKE_EDITABLE_FILES "CMakeLists.txt") 53 | endif() 54 | 55 | FILE( GLOB TMP_CMAKE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/*.cmake) 56 | list( APPEND PROJCT_CMAKE_EDITABLE_FILES ${TMP_CMAKE_FILES}) 57 | set( PROJCT_CMAKE_EDITABLE_FILES ${PROJCT_CMAKE_EDITABLE_FILES} CACHE INTERNAL "cache these") 58 | endif() 59 | 60 | include( PostFiles OPTIONAL) 61 | 62 | set( PROJECT_FILES 63 | ${PROJECT_FILES} 64 | ${SOURCES} 65 | ${PUBLIC_HEADERS} 66 | ${PUBLIC_GENERIC_HEADERS} 67 | ${PUBLIC_GENERATED_HEADERS} 68 | ${PRIVATE_HEADERS} 69 | ${PRIVATE_GENERATED_HEADERS} 70 | ${PROJCT_CMAKE_EDITABLE_FILES} 71 | ${RESOURCES} 72 | ) 73 | 74 | include_directories( ${INCLUDE_DIRS}) 75 | 76 | endif() 77 | -------------------------------------------------------------------------------- /cmake/share/FinalOutput.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | if( NOT __FINAL_OUTPUT_C_CMAKE__) 6 | set( __FINAL_OUTPUT_C_CMAKE__ ON) 7 | 8 | if( MULLE_TRACE_INCLUDE) 9 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 10 | endif() 11 | 12 | # 13 | # 14 | # 15 | message( STATUS "CMAKE_MODULE_PATH is ${CMAKE_MODULE_PATH}") 16 | message( STATUS "CMAKE_BUILD_TYPE is ${CMAKE_BUILD_TYPE}") 17 | message( STATUS "CMAKE_SYSTEM_NAME is ${CMAKE_SYSTEM_NAME}") 18 | message( STATUS "BUILD_SHARED_LIBS is ${BUILD_SHARED_LIBS}") 19 | 20 | if( APPLE) 21 | message( STATUS "CMAKE_OSX_SYSROOT is ${CMAKE_OSX_SYSROOT}") 22 | message( STATUS "CMAKE_OSX_DEPLOYMENT_TARGET is ${CMAKE_OSX_DEPLOYMENT_TARGET}") 23 | message( STATUS "CMAKE_FRAMEWORK_PATH is ${CMAKE_FRAMEWORK_PATH}") 24 | endif() 25 | 26 | message( STATUS "CMAKE_INCLUDE_PATH is ${CMAKE_INCLUDE_PATH}") 27 | message( STATUS "CMAKE_LIBRARY_PATH is ${CMAKE_LIBRARY_PATH}") 28 | 29 | message( STATUS "MULLE_LANGUAGE is ${MULLE_LANGUAGE}") 30 | message( STATUS "MULLE_C_COMPILER_ID is ${MULLE_C_COMPILER_ID}") 31 | message( STATUS "MULLE_CXX_COMPILER_ID is ${MULLE_C_COMPILER_ID}") 32 | 33 | message( STATUS "CMAKE_C_COMPILER_ID is ${CMAKE_C_COMPILER_ID}") 34 | message( STATUS "CMAKE_C_FLAGS is ${CMAKE_C_FLAGS}") 35 | 36 | message( STATUS "CMAKE_CXX_COMPILER_ID is ${CMAKE_C_COMPILER_ID}") 37 | message( STATUS "CMAKE_CXX_FLAGS is ${CMAKE_CXX_FLAGS}") 38 | 39 | message( STATUS "CMAKE_EXE_LINKER_FLAGS is ${CMAKE_EXE_LINKER_FLAGS}") 40 | message( STATUS "CMAKE_SHARED_LINKER_FLAGS is ${CMAKE_SHARED_LINKER_FLAGS}") 41 | message( STATUS "CMAKE_STATIC_LINKER_FLAGS is ${CMAKE_STATIC_LINKER_FLAGS}") 42 | message( STATUS "CMAKE_INSTALL_RPATH=\"${CMAKE_INSTALL_RPATH}\"" ) 43 | 44 | include( FinalOutputAuxC OPTIONAL) 45 | 46 | endif() 47 | -------------------------------------------------------------------------------- /cmake/share/Framework.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | # This in theory can be included multiple times 6 | 7 | if( MULLE_TRACE_INCLUDE) 8 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 9 | endif() 10 | 11 | # 12 | # FRAMEWORKS do not support three-phase build 13 | # 14 | if( NOT FRAMEWORK_NAME) 15 | set( FRAMEWORK_NAME "${PROJECT_NAME}") 16 | endif() 17 | if( NOT FRAMEWORK_VERSION) 18 | set( FRAMEWORK_VERSION "A") 19 | endif() 20 | 21 | include( StringCase) 22 | 23 | if( NOT FRAMEWORK_IDENTIFIER) 24 | snakeCaseString( "${FRAMEWORK_NAME}" FRAMEWORK_IDENTIFIER) 25 | endif() 26 | if( NOT FRAMEWORK_UPCASE_IDENTIFIER) 27 | string( TOUPPER "${FRAMEWORK_IDENTIFIER}" FRAMEWORK_UPCASE_IDENTIFIER) 28 | endif() 29 | if( NOT FRAMEWORK_DOWNCASE_IDENTIFIER) 30 | string( TOLOWER "${FRAMEWORK_IDENTIFIER}" FRAMEWORK_DOWNCASE_IDENTIFIER) 31 | endif() 32 | 33 | # if( NOT FRAMEWORK_DOWNCASE_IDENTIFIER) 34 | # string( TOLOWER "${FRAMEWORK_IDENTIFIER}" FRAMEWORK_DOWNCASE_IDENTIFIER) 35 | # endif() 36 | 37 | if( NOT FRAMEWORK_FILES) 38 | set( FRAMEWORK_FILES "${PROJECT_FILES}") 39 | set( __FRAMEWORK_FILES_UNSET ON) 40 | endif() 41 | 42 | 43 | include( PreFramework OPTIONAL) 44 | 45 | if( NOT FRAMEWORK_FILES) 46 | message( SEND_ERROR "There are no sources to compile for framework ${FRAMEWORK_NAME}. Did mulle-sde reflect run yet ?") 47 | endif() 48 | 49 | add_library( "${FRAMEWORK_NAME}" SHARED 50 | ${FRAMEWORK_FILES} 51 | ) 52 | 53 | include( FrameworkAux OPTIONAL) 54 | 55 | # frameworks are Apple only, so we don't really need to force load 56 | # if we set -ObjC or ? 57 | if( NOT SHARED_LIBRARY_LIST) 58 | set( SHARED_LIBRARY_LIST 59 | ${DEPENDENCY_LIBRARIES} 60 | ${DEPENDENCY_FRAMEWORKS} 61 | ${OPTIONAL_DEPENDENCY_LIBRARIES} 62 | ${OPTIONAL_DEPENDENCY_FRAMEWORKS} 63 | ${OS_SPECIFIC_LIBRARIES} 64 | ${OS_SPECIFIC_FRAMEWORKS} 65 | ) 66 | endif() 67 | 68 | include( PostSharedLibrary OPTIONAL) # additional hook 69 | 70 | target_link_libraries( "${FRAMEWORK_NAME}" 71 | ${SHARED_LIBRARY_LIST} # use SHARED_LIBRARY_LIST because of PostSharedLibrary 72 | ) 73 | 74 | set_target_properties( "${FRAMEWORK_NAME}" PROPERTIES 75 | FRAMEWORK TRUE 76 | FRAMEWORK_VERSION "${FRAMEWORK_VERSION}" 77 | # headers must be part of ${FRAMEWORK_NAME} target else it don't work 78 | PUBLIC_HEADER "${INSTALL_PUBLIC_HEADERS}" 79 | PRIVATE_HEADER "${INSTALL_PRIVATE_HEADERS}" 80 | RESOURCE "${INSTALL_RESOURCES}" 81 | # XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer" 82 | ) 83 | 84 | # 85 | # -ObjC to force link all static libraries with Objective-C code in them 86 | # and dynamic_lookup to keep those symbols "open" to later linking from 87 | # executable. Especially with multiple Frameworks you don't want the static 88 | # libraries duplicated in all of them, so you mark them "no-link". 89 | # 90 | if( LINK_PHASE) 91 | target_link_options( "${FRAMEWORK_NAME}" PRIVATE 92 | -ObjC 93 | -undefined dynamic_lookup 94 | ) 95 | endif() 96 | 97 | # message( STATUS "INSTALL_PUBLIC_HEADERS=${INSTALL_PUBLIC_HEADERS}") 98 | # message( STATUS "INSTALL_PRIVATE_HEADERS=${INSTALL_PRIVATE_HEADERS}") 99 | # message( STATUS "INSTALL_RESOURCES=${INSTALL_RESOURCES}") 100 | message( STATUS "SHARED_LIBRARY_LIST=${SHARED_LIBRARY_LIST}") 101 | 102 | set( INSTALL_FRAMEWORK_TARGETS 103 | "${FRAMEWORK_NAME}" 104 | ${INSTALL_FRAMEWORK_TARGETS} 105 | ) 106 | 107 | include( PostFramework OPTIONAL) 108 | 109 | 110 | # clean FRAMEWORK_FILES for the next run, if set by this script 111 | if( __FRAMEWORK_FILES_UNSET ) 112 | unset( FRAMEWORK_FILES) 113 | unset( __FRAMEWORK_FILES_UNSET) 114 | endif() 115 | -------------------------------------------------------------------------------- /cmake/share/FrameworkAux.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | # This in theory can be included multiple times 6 | 7 | if( MULLE_TRACE_INCLUDE) 8 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 9 | endif() 10 | 11 | 12 | option( REEXPORT_ALL_LOAD "Reexport linked static Objective-C libraries (all-load) of framework" ON) 13 | 14 | if( REEXPORT_ALL_LOAD) 15 | set( ALL_LOAD_PREFIX "-Xlinker -reexport_library ") # space important 16 | endif() 17 | 18 | 19 | include( AllLoadC) 20 | include( StandaloneC) 21 | 22 | include( FrameworkAuxC OPTIONAL) 23 | -------------------------------------------------------------------------------- /cmake/share/Headers.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | if( MULLE_TRACE_INCLUDE) 6 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 7 | endif() 8 | 9 | option( RESOLVE_INSTALLABLE_HEADER_SYMLINKS "Resolve PROJECT_INSTALLABLE_HEADERS symlinks" OFF) 10 | message( STATUS "RESOLVE_INSTALLABLE_HEADER_SYMLINKS is ${RESOLVE_INSTALLABLE_HEADER_SYMLINKS}") 11 | 12 | 13 | # 14 | # The following includes include definitions generated 15 | # during `mulle-sde reflect`. Don't edit those files. They are 16 | # overwritten frequently. 17 | # 18 | # === MULLE-SDE START === 19 | 20 | include( _Headers OPTIONAL) 21 | 22 | # === MULLE-SDE END === 23 | # 24 | 25 | # 26 | # If you don't like the "automatic" way of generating _Headers 27 | # 28 | # MULLE_MATCH_TO_CMAKE_HEADERS_FILE="DISABLE" # or NONE 29 | # 30 | 31 | 32 | function( ResolveFileSymlinksIfNeeded listname outputname) 33 | unset( list) 34 | if( RESOLVE_INSTALLABLE_HEADER_SYMLINKS) 35 | foreach( TMP_HEADER ${${listname}}) 36 | file( REAL_PATH "${TMP_HEADER}" TMP_RESOLVED_HEADER) 37 | list( APPEND list "${TMP_RESOLVED_HEADER}") 38 | endforeach() 39 | message( STATUS "Resolved symlinks of ${outputname}=${list}") 40 | else() 41 | set( list ${${listname}}) 42 | endif() 43 | set( ${outputname} ${list} PARENT_SCOPE) 44 | endfunction() 45 | 46 | 47 | # 48 | # PROJECT_INSTALLABLE_HEADERS 49 | # INSTALL_PUBLIC_HEADERS 50 | # INSTALL_PRIVATE_HEADERS 51 | # 52 | 53 | # keep headers to install separate to make last minute changes 54 | set( TMP_HEADERS ${PUBLIC_HEADERS} 55 | ${PUBLIC_GENERIC_HEADERS} 56 | ${PUBLIC_GENERATED_HEADERS} 57 | ) 58 | ResolveFileSymlinksIfNeeded( TMP_HEADERS INSTALL_PUBLIC_HEADERS) 59 | 60 | # 61 | # Do not install generated private headers and include-private.h 62 | # which aren't valid outside of the project scope. 63 | # 64 | set( TMP_HEADERS ${PRIVATE_HEADERS}) 65 | if( TMP_HEADERS) 66 | list( REMOVE_ITEM TMP_HEADERS "include-private.h") 67 | endif() 68 | ResolveFileSymlinksIfNeeded( TMP_HEADERS INSTALL_PRIVATE_HEADERS) 69 | 70 | # let's not cache headers, as they are bound to fluctuate. when we change 71 | # dependencies we expect a clean 72 | set( PROJECT_INSTALLABLE_HEADERS 73 | ${INSTALL_PUBLIC_HEADERS} 74 | ${INSTALL_PRIVATE_HEADERS} 75 | ) 76 | 77 | # 78 | # You can put more source and resource file definitions here. 79 | # 80 | -------------------------------------------------------------------------------- /cmake/share/IDESupport.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | ### Files 6 | if( NOT __IDE_SUPPORT_START__CMAKE__) 7 | set( __IDE_SUPPORT_START__CMAKE__ ON) 8 | 9 | if( MULLE_TRACE_INCLUDE) 10 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 11 | endif() 12 | 13 | #default to ON for a while 14 | option( IDE_SUPPORT "Enable IDE support for Clion" ON) 15 | 16 | if( IDE_SUPPORT) 17 | find_program( MULLE_SDE mulle-sde) 18 | if( NOT MULLE_SDE) 19 | message( WARNING "The folder \"dependency\" is not ready.\nInstall mulle-sde and run `mulle-sde craft craftorder`") 20 | else() 21 | if( NOT DEFINED ENV{MULLE_VIRTUAL_ROOT}) # sic! NOT ${ENV} 22 | # 23 | # If there is (likely) a sourcetree, we need to build dependencies now 24 | # because otherwise the include( DEPENDENCIES) fails. 25 | # IDE support in subdirectoy makes no sense (IMO) therefore 26 | # not CMAKE_CURRENT_SOURCE_DIR 27 | if( IS_DIRECTORY "${PROJECT_SOURCE_DIR}/.mulle/etc/sourcetree" OR 28 | IS_DIRECTORY "${PROJECT_SOURCE_DIR}/.mulle/share/sourcetree") 29 | # 30 | # If we have a dependency folder, check for the .state-complete 31 | # 32 | if( NOT EXISTS "${DEPENDENCY_DIR}/.state-complete") 33 | execute_process( COMMAND "${MULLE_SDE}" craft --build-type "${CMAKE_BUILD_TYPE}" craftorder 34 | WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} 35 | COMMAND_ERROR_IS_FATAL ANY) 36 | endif() 37 | endif() 38 | 39 | # 40 | # In an IDE like CLion use these target to clean all. The immediate 41 | # rebuild is needed, because the above code won't run again. 42 | # mulle_sde_craft_craftorder: just rebuild. Can be useful if "clean all" 43 | # failed. 44 | add_custom_target( mulle_sde_craft_craftorder 45 | COMMENT "Craft dependency folder" 46 | COMMAND "${MULLE_SDE}" craft --build-type "${CMAKE_BUILD_TYPE}" craftorder 47 | VERBATIM 48 | ) 49 | set_target_properties( mulle_sde_craft_craftorder PROPERTIES EXCLUDE_FROM_ALL ON) 50 | 51 | add_custom_target( mulle_sde_reflect 52 | COMMENT "Reflect files and sourcetree" 53 | COMMAND "${MULLE_SDE}" reflect 54 | VERBATIM 55 | ) 56 | set_target_properties( mulle_sde_reflect PROPERTIES EXCLUDE_FROM_ALL ON) 57 | 58 | add_custom_target( mulle_sde_clean_target 59 | COMMENT "Clean a specific target and then craft dependency folder" 60 | COMMAND "${MULLE_SDE}" clean --gui && "${MULLE_SDE}" craft 61 | VERBATIM 62 | ) 63 | set_target_properties( mulle_sde_clean_target PROPERTIES EXCLUDE_FROM_ALL ON) 64 | 65 | add_custom_target( mulle_sde_clean_all 66 | COMMENT "Clean all and craft dependency folder" 67 | COMMAND "${MULLE_SDE}" craft -C 68 | VERBATIM 69 | ) 70 | set_target_properties( mulle_sde_clean_all PROPERTIES EXCLUDE_FROM_ALL ON) 71 | 72 | add_custom_target( mulle_sde_clean_tidy 73 | COMMENT "Clean stash and craft dependency folder" 74 | COMMAND "${MULLE_SDE}" craft -g 75 | VERBATIM 76 | ) 77 | set_target_properties( mulle_sde_clean_tidy PROPERTIES EXCLUDE_FROM_ALL ON) 78 | 79 | add_custom_target( mulle_sde_upgrade 80 | COMMENT "Upgrade project to current mulle-sde version" 81 | COMMAND "${MULLE_SDE}" upgrade 82 | VERBATIM 83 | ) 84 | set_target_properties( mulle_sde_upgrade PROPERTIES EXCLUDE_FROM_ALL ON) 85 | else() 86 | message( STATUS "Skipping IDE Support as we are in a mulle-sde environment") 87 | endif() 88 | endif() 89 | endif() 90 | 91 | endif() 92 | 93 | # extension : mulle-sde/cmake 94 | # directory : project/all 95 | # template : .../IDESupport.cmake 96 | # Suppress this comment with `export MULLE_SDE_GENERATE_FILE_COMMENTS=NO` 97 | -------------------------------------------------------------------------------- /cmake/share/InstallCMakeInclude.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | if( NOT __INSTALL_CMAKE_INCLUDE__CMAKE__) 6 | set( __INSTALL_CMAKE_INCLUDE__CMAKE__ ON) 7 | 8 | 9 | if( MULLE_TRACE_INCLUDE) 10 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 11 | endif() 12 | 13 | # 14 | # convenient way to figure out, if we are added as a subdirectory 15 | # if we aren't, there is no point in doing this or ? 16 | if( NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) 17 | 18 | list( APPEND INSTALL_TMP_HEADERS ${INSTALL_PUBLIC_HEADERS} ${INSTALL_PRIVATE_HEADERS}) 19 | 20 | # 21 | # we copy our headers into a build directory, so we don't have to gum 22 | # up our project with a root /include, that duplicates the headers (as 23 | # we did in the code below) 24 | # 25 | if( INSTALL_TMP_HEADERS) 26 | add_custom_target( ${LIBRARY_NAME}-headers ALL 27 | COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/include/${LIBRARY_NAME}" 28 | COMMAND ${CMAKE_COMMAND} -E copy_if_different ${INSTALL_TMP_HEADERS} "${CMAKE_BINARY_DIR}/include/${LIBRARY_NAME}" 29 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 30 | SOURCES ${INSTALL_TMP_HEADERS} 31 | ) 32 | 33 | add_dependencies( ${LIBRARY_NAME} ${LIBRARY_NAME}-headers) 34 | 35 | target_include_directories(${LIBRARY_NAME} INTERFACE 36 | $ 37 | $ 38 | ) 39 | endif() 40 | 41 | endif() 42 | endif() 43 | 44 | 45 | # function( unprotect_cmake_include_directory dir) 46 | # if( NOT EXISTS "${dir}") 47 | # file( MAKE_DIRECTORY "${dir}") 48 | # else() 49 | # if( WIN32) 50 | # execute_process(COMMAND attrib -R "${dir}\\*.*" /S) 51 | # else() 52 | # execute_process(COMMAND chmod -R ugo+w "${dir}") 53 | # endif() 54 | # endif() 55 | # endfunction() 56 | # 57 | # function( protect_cmake_include_directory dir) 58 | # if( WIN32) 59 | # execute_process(COMMAND attrib +R "${dir}\\*.*" /S) 60 | # else() 61 | # execute_process(COMMAND chmod -R ugo-w "${dir}") 62 | # endif() 63 | # endfunction() 64 | # 65 | # # 66 | # # This can run at anytime really, targets must not rely on these headers 67 | # # 68 | # if( INSTALL_CMAKE_INCLUDE_ENABLED) 69 | # set( SOURCE_ROOT_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include") 70 | # set( SOURCE_PUBLIC_INCLUDE_DIR "${SOURCE_ROOT_INCLUDE_DIR}/${PROJECT_NAME}") 71 | # set( SOURCE_PRIVATE_INCLUDE_DIR "${SOURCE_ROOT_INCLUDE_DIR}/${PROJECT_NAME}") 72 | ## 73 | ## noone's gonna look there anyway 74 | ## set( SOURCE_CMAKE_INCLUDE_DIR "${SOURCE_ROOT_INCLUDE_DIR}/${PROJECT_NAME}/cmake") 75 | # 76 | # unprotect_cmake_include_directory( "${SOURCE_ROOT_INCLUDE_DIR}") 77 | # 78 | # file( MAKE_DIRECTORY "${SOURCE_PUBLIC_INCLUDE_DIR}") 79 | # file( MAKE_DIRECTORY "${SOURCE_PRIVATE_INCLUDE_DIR}") 80 | ## file( MAKE_DIRECTORY "${SOURCE_CMAKE_INCLUDE_DIR}") 81 | # 82 | # # Copy public headers 83 | # foreach( HEADER ${INSTALL_PUBLIC_HEADERS}) 84 | # file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/${HEADER}" 85 | # DESTINATION "${SOURCE_PUBLIC_INCLUDE_DIR}") 86 | # endforeach() 87 | # 88 | # # Copy private headers 89 | # foreach( HEADER ${INSTALL_PRIVATE_HEADERS}) 90 | # file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/${HEADER}" 91 | # DESTINATION "${SOURCE_PRIVATE_INCLUDE_DIR}") 92 | # endforeach() 93 | ## 94 | ## # Copy cmake headers 95 | ## foreach( HEADER ${INSTALL_CMAKE_INCLUDES}) 96 | ## file( COPY "${CMAKE_CURRENT_SOURCE_DIR}/${HEADER}" 97 | ## DESTINATION "${SOURCE_CMAKE_INCLUDE_DIR}") 98 | ## endforeach() 99 | # 100 | # protect_cmake_include_directory( "${SOURCE_ROOT_INCLUDE_DIR}") 101 | # endif() 102 | -------------------------------------------------------------------------------- /cmake/share/InstallCMakePackage.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | # could conceivably be used multiple times for each library 6 | 7 | if( MULLE_TRACE_INCLUDE) 8 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 9 | endif() 10 | 11 | set( CONFIG_CMAKE_IN_FILENAME "${CMAKE_CURRENT_SOURCE_DIR}/cmake/${PROJECT_NAME}-config.cmake.in") 12 | if( NOT EXISTS "${CONFIG_CMAKE_IN_FILENAME}") 13 | set( CONFIG_CMAKE_IN_FILENAME "${CMAKE_CURRENT_SOURCE_DIR}/cmake/share/${PROJECT_NAME}-config.cmake.in") 14 | endif() 15 | 16 | set( HEADER_CMAKE_IN_FILENAME "${CMAKE_CURRENT_SOURCE_DIR}/cmake/${PROJECT_NAME}-config.h.in") 17 | if( NOT EXISTS "${HEADER_CMAKE_IN_FILENAME}") 18 | set( HEADER_CMAKE_IN_FILENAME "${CMAKE_CURRENT_SOURCE_DIR}/cmake/share/${PROJECT_NAME}-config.h.in") 19 | endif() 20 | 21 | 22 | # can do this multiple times 23 | install( TARGETS ${LIBRARY_NAME} 24 | EXPORT ${LIBRARY_NAME}-targets) 25 | 26 | target_include_directories( ${LIBRARY_NAME} PUBLIC 27 | $ 28 | $) 29 | 30 | # Set target properties 31 | set_target_properties( ${LIBRARY_NAME} PROPERTIES 32 | VERSION ${PROJECT_VERSION} 33 | SOVERSION ${PROJECT_VERSION_MAJOR} 34 | EXPORT_NAME ${LIBRARY_NAME}) 35 | 36 | # Create and install config files 37 | include( CMakePackageConfigHelpers) 38 | 39 | configure_package_config_file( 40 | "${CONFIG_CMAKE_IN_FILENAME}" 41 | "${CMAKE_CURRENT_BINARY_DIR}/${LIBRARY_NAME}-config.cmake" 42 | INSTALL_DESTINATION lib/cmake/${LIBRARY_NAME}) 43 | 44 | configure_file( "${HEADER_CMAKE_IN_FILENAME}" "${LIBRARY_NAME}-config.h") 45 | 46 | install( EXPORT ${LIBRARY_NAME}-targets 47 | FILE ${LIBRARY_NAME}-targets.cmake 48 | NAMESPACE ${LIBRARY_NAME}:: 49 | DESTINATION lib/cmake/${LIBRARY_NAME}) 50 | 51 | write_basic_package_version_file( 52 | "${CMAKE_CURRENT_BINARY_DIR}/${LIBRARY_NAME}-config-version.cmake" 53 | VERSION ${PROJECT_VERSION} 54 | COMPATIBILITY SameMajorVersion) 55 | 56 | install(FILES 57 | "${CMAKE_CURRENT_BINARY_DIR}/${LIBRARY_NAME}-config.cmake" 58 | "${CMAKE_CURRENT_BINARY_DIR}/${LIBRARY_NAME}-config-version.cmake" 59 | DESTINATION lib/cmake/${LIBRARY_NAME} 60 | ) 61 | -------------------------------------------------------------------------------- /cmake/share/InstallExecutable.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | # This can be included multiple times 6 | 7 | if( MULLE_TRACE_INCLUDE) 8 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 9 | endif() 10 | 11 | 12 | if( LINK_PHASE) 13 | ### Install 14 | 15 | include( PreInstallExecutable OPTIONAL) 16 | 17 | install( TARGETS ${INSTALL_EXECUTABLE_TARGETS} DESTINATION "bin") 18 | foreach( TMP_NAME ${INSTALL_EXECUTABLE_TARGETS}) 19 | string( MAKE_C_IDENTIFIER "${TMP_NAME}" TMP_IDENTIFIER) 20 | string( TOUPPER "${TMP_IDENTIFIER}" TMP_IDENTIFIER) 21 | # avoid empty share subdir 22 | if( (${INSTALL_${TMP_IDENTIFIER}_RESOURCE_DIRS}) OR (${INSTALL_${TMP_IDENTIFIER}_RESOURCES})) 23 | install( DIRECTORY ${INSTALL_${TMP_IDENTIFIER}_RESOURCE_DIRS} DESTINATION "share/${TMP_NAME}") 24 | install( FILES ${INSTALL_${TMP_IDENTIFIER}_RESOURCES} DESTINATION "share/${TMP_NAME}") 25 | endif() 26 | endforeach() 27 | 28 | 29 | include( PostInstallExecutable OPTIONAL) 30 | 31 | endif() 32 | -------------------------------------------------------------------------------- /cmake/share/InstallFramework.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | # This in theory can be included multiple times 6 | 7 | if( MULLE_TRACE_INCLUDE) 8 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 9 | endif() 10 | 11 | 12 | if( LINK_PHASE) 13 | 14 | include( PreInstallFramework OPTIONAL) 15 | 16 | install( TARGETS ${INSTALL_FRAMEWORK_TARGETS} DESTINATION "Frameworks") 17 | 18 | include( PostInstallFramework OPTIONAL) 19 | 20 | endif() 21 | -------------------------------------------------------------------------------- /cmake/share/InstallLibrary.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | # This in theory can be included multiple times 6 | 7 | if( MULLE_TRACE_INCLUDE) 8 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 9 | endif() 10 | 11 | 12 | if( LINK_PHASE) 13 | include( PreInstallLibrary OPTIONAL) 14 | 15 | install( TARGETS ${INSTALL_LIBRARY_TARGETS} DESTINATION "lib") 16 | foreach( TMP_NAME ${INSTALL_LIBRARY_TARGETS}) 17 | string( MAKE_C_IDENTIFIER "${TMP_NAME}" TMP_IDENTIFIER) 18 | string( TOUPPER "${TMP_IDENTIFIER}" TMP_IDENTIFIER) 19 | # avoid empty share subdir 20 | if( (${INSTALL_${TMP_IDENTIFIER}_RESOURCE_DIRS}) OR (${INSTALL_${TMP_IDENTIFIER}_RESOURCES})) 21 | install( DIRECTORY ${INSTALL_${TMP_IDENTIFIER}_RESOURCE_DIRS} DESTINATION "share/${TMP_NAME}") 22 | install( FILES ${INSTALL_${TMP_IDENTIFIER}_RESOURCES} DESTINATION "share/${TMP_NAME}") 23 | endif() 24 | endforeach() 25 | 26 | include( PostInstallLibrary OPTIONAL) 27 | 28 | endif() 29 | -------------------------------------------------------------------------------- /cmake/share/InstallRpath.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | # This can be included multiple times 6 | 7 | if( MULLE_TRACE_INCLUDE) 8 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 9 | endif() 10 | 11 | # 12 | # https://stackoverflow.com/questions/32469953/why-is-cmake-designed-so-that-it-removes-runtime-path-when-installing/32470070#32470070 13 | # 14 | # MULLE_NO_CMAKE_INSTALL_RPATH can be used to kill this codepath 15 | # This is not used during a regular craft, but only when "install" is run. 16 | # One could enable CMAKE_INSTALL_RPATH for build by setting 17 | # set( CMAKE_BUILD_WITH_INSTALL_RPATH ON) 18 | # but this is usually counterproductive, since lib will be really in 19 | # ../../dependency/lib 20 | # 21 | # CMAKE_INSTALL_RPATH must be defined before add_executable or add_library 22 | # 23 | # https://cmake.org/cmake/help/latest/prop_tgt/INSTALL_RPATH.html#prop_tgt:INSTALL_RPATH 24 | # 25 | if( MULLE_NO_CMAKE_INSTALL_RPATH) 26 | # for cosmopolitan and musl static builds RPATH can be a hindrance 27 | set( CMAKE_SKIP_BUILD_RPATH ON) 28 | else() 29 | if( APPLE) 30 | # Modern CMake handles lib path automatically (at least for libraries 31 | # it seems, for executable apparently not and there it is handled 32 | # with a separate target property install) 33 | if( CMAKE_VERSION VERSION_LESS 3.20) 34 | set(CMAKE_INSTALL_RPATH 35 | "@loader_path/../lib/" 36 | "@loader_path/../Frameworks/" 37 | ) 38 | endif() 39 | else() 40 | set( CMAKE_INSTALL_RPATH "\$ORIGIN/../lib") 41 | endif() 42 | endif() 43 | -------------------------------------------------------------------------------- /cmake/share/LibraryAux.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | # This in theory can be included multiple times 6 | 7 | if( MULLE_TRACE_INCLUDE) 8 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 9 | endif() 10 | 11 | include( AllLoadC) 12 | include( StandaloneC) 13 | 14 | include( LibraryAuxC OPTIONAL) 15 | -------------------------------------------------------------------------------- /cmake/share/MacOSXFrameworkInfo.plist.in.sample: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${MACOSX_FRAMEWORK_NAME} 9 | CFBundleIconFile 10 | ${MACOSX_FRAMEWORK_ICON_FILE} 11 | CFBundleIdentifier 12 | ${MACOSX_FRAMEWORK_IDENTIFIER} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | ${MACOSX_FRAMEWORK_BUNDLE_VERSION} 21 | CFBundleShortVersionString 22 | ${MACOSX_FRAMEWORK_SHORT_VERSION_STRING} 23 | CSResourcesFileMapped 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /cmake/share/Motd.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | # this can be included multiple times 6 | 7 | if( MULLE_TRACE_INCLUDE) 8 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 9 | endif() 10 | 11 | # 12 | # Output message of a day to locate output. 13 | # Only run in link phase, which should be defined for singlephase builds too 14 | # 15 | if( EXECUTABLE_NAME AND LINK_PHASE) 16 | 17 | # But if create-build-motd doesn't exist, it's no biggy 18 | # 19 | if( NOT CREATE_MOTD_EXE) 20 | if( MSVC) 21 | # TODO: adapt search path 22 | find_program( CREATE_MOTD_EXE mulle-create-build-motd.bat 23 | PATHS "${MULLE_VIRTUAL_ROOT}/.mulle/var/$ENV{MULLE_HOSTNAME}/$ENV{MULLE_USERNAME}/env/bin" 24 | ) 25 | else() 26 | # will fail on WSL if .mulle/var is elsewhere`. should get 27 | # location from `mulle-env vardir env` 28 | find_program( CREATE_MOTD_EXE mulle-create-build-motd 29 | PATHS "${MULLE_VIRTUAL_ROOT}/.mulle/var/$ENV{MULLE_HOSTNAME}/$ENV{MULLE_USERNAME}/env/bin" 30 | ) 31 | endif() 32 | message( STATUS "CREATE_MOTD_EXE is ${CREATE_MOTD_EXE}") 33 | endif() 34 | 35 | # 36 | # there is no real order, in which these motds are generated 37 | # as they are hooked into the cmake dependency system 38 | # 39 | if( CREATE_MOTD_EXE) 40 | if( NOT TARGET "__cleanmotd__") 41 | add_custom_target( "__cleanmotd__" 42 | COMMAND env "PATH=/usr/bin:/bin" "test" "!" "-f" "${CMAKE_CURRENT_BINARY_DIR}/.motd" 43 | "||" "rm" "${CMAKE_CURRENT_BINARY_DIR}/.motd" 44 | COMMENT "Remove old motd file for mulle-craft" 45 | VERBATIM 46 | ) 47 | endif() 48 | 49 | add_custom_target( "_${EXECUTABLE_NAME}__motd__" ALL 50 | COMMAND ${CMAKE_COMMAND} -E env "MULLE_VIRTUAL_ROOT=${MULLE_VIRTUAL_ROOT}" 51 | "${CREATE_MOTD_EXE}" 52 | $ENV{CREATE_BUILD_MOTD_FLAGS} 53 | "--append" 54 | "executable" 55 | "${CMAKE_CURRENT_BINARY_DIR}" 56 | "${EXECUTABLE_NAME}" 57 | COMMENT "Append to motd file for mulle-craft" 58 | VERBATIM 59 | ) 60 | 61 | add_dependencies( "_${EXECUTABLE_NAME}__motd__" ${EXECUTABLE_NAME}) 62 | add_dependencies( "_${EXECUTABLE_NAME}__motd__" "__cleanmotd__") 63 | else() 64 | message( WARNING "Tool \"mulle-create-build-motd\" not found") 65 | endif() 66 | 67 | include( MotdAux OPTIONAL) 68 | endif() 69 | -------------------------------------------------------------------------------- /cmake/share/MultiPhase.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | if( MULLE_TRACE_INCLUDE) 6 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 7 | endif() 8 | 9 | ### MultiPhase 10 | if( NOT __MULTI_PHASE__CMAKE__) 11 | set( __MULTI_PHASE__CMAKE__ ON) 12 | 13 | # 14 | # Parallel build support. run all "participating" projects once for 15 | # HEADER_PHASE in parallel. 16 | # Now run all "participating" projects for COMPILE_PHASE in parallel. 17 | # Finally run all participating and non-participating projects in craftorder 18 | # serially together with the LINK_PHASE. What is tricky is that the 19 | # sequential projects may need to run first. 20 | # 21 | # 22 | # MEMO: as cmake caches the ON flags, this will slowly progress 23 | # from ON OFF OFF to ON ON OFF to ON ON ON during a three 24 | # phase build 25 | # 26 | option( HEADER_PHASE "Install headers only phase (1)" OFF) 27 | option( COMPILE_PHASE "Compile sources only phase (2)" OFF) 28 | option( LINK_PHASE "Link and install only phase (3)" OFF) 29 | 30 | if( MULLE_MAKE_PHASE STREQUAL "HEADERS" OR MULLE_MAKE_PHASE STREQUAL "HEADER") 31 | set( HEADER_PHASE ON) 32 | endif() 33 | if( MULLE_MAKE_PHASE STREQUAL "COMPILE") 34 | set( COMPILE_PHASE ON) 35 | endif() 36 | if( MULLE_MAKE_PHASE STREQUAL "LINK") 37 | set( LINK_PHASE ON) 38 | endif() 39 | 40 | if( NOT HEADER_PHASE AND 41 | NOT COMPILE_PHASE AND 42 | NOT LINK_PHASE) 43 | set( HEADER_PHASE ON) 44 | set( COMPILE_PHASE ON) 45 | set( LINK_PHASE ON) 46 | endif() 47 | 48 | if( COMPILE_PHASE AND NOT HEADER_PHASE) 49 | set( HEADER_PHASE ON) 50 | endif() 51 | if( LINK_PHASE AND NOT COMPILE_PHASE) 52 | set( COMPILE_PHASE ON) 53 | endif() 54 | 55 | # backwards compatibility 56 | if( HEADER_PHASE) 57 | set( HEADERS_PHASE ON) 58 | endif() 59 | 60 | message( STATUS "HEADER_PHASE=${HEADER_PHASE}") 61 | message( STATUS "COMPILE_PHASE=${COMPILE_PHASE}") 62 | message( STATUS "LINK_PHASE=${LINK_PHASE}") 63 | endif() 64 | -------------------------------------------------------------------------------- /cmake/share/PostExecutable.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | # can be included multiple times 6 | 7 | if( MULLE_TRACE_INCLUDE) 8 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 9 | endif() 10 | 11 | include( PostExecutableAuxC OPTIONAL) 12 | -------------------------------------------------------------------------------- /cmake/share/PostFiles.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | if( NOT __POST_FILES__CMAKE__) 6 | set( __POST_FILES__CMAKE__ ON) 7 | 8 | if( MULLE_TRACE_INCLUDE) 9 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 10 | endif() 11 | 12 | include( PostFilesAuxC OPTIONAL) 13 | 14 | endif() 15 | -------------------------------------------------------------------------------- /cmake/share/PostFramework.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | # can be included multiple times 6 | 7 | if( MULLE_TRACE_INCLUDE) 8 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 9 | endif() 10 | 11 | include( PostFrameworkAuxC OPTIONAL) 12 | -------------------------------------------------------------------------------- /cmake/share/PostLibrary.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | # can be included multiple times 6 | 7 | if( MULLE_TRACE_INCLUDE) 8 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 9 | endif() 10 | 11 | include( PostLibraryAuxC OPTIONAL) 12 | -------------------------------------------------------------------------------- /cmake/share/PostSharedLibrary.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | # can be included multiple times is shared by Library.cmake and Framework.cmake 6 | 7 | if( MULLE_TRACE_INCLUDE) 8 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 9 | endif() 10 | 11 | # Frameworks aren't forced 12 | CreateForceAllLoadList( ALL_LOAD_DEPENDENCY_LIBRARIES FORCE_ALL_LOAD_DEPENDENCY_LIBRARIES) 13 | #CreateForceAllLoadList( ALL_LOAD_DEPENDENCY_FRAMEWORKS FORCE_ALL_LOAD_DEPENDENCY_FRAMEWORKS) 14 | CreateForceAllLoadList( ALL_LOAD_OPTIONAL_DEPENDENCY_LIBRARIES FORCE_ALL_LOAD_OPTIONAL_DEPENDENCY_LIBRARIES) 15 | #CreateForceAllLoadList( ALL_LOAD_OPTIONAL_DEPENDENCY_FRAMEWORKS FORCE_ALL_LOAD_OPTIONAL_DEPENDENCY_FRAMEWORKS) 16 | CreateForceAllLoadList( ALL_LOAD_OS_SPECIFIC_LIBRARIES FORCE_ALL_LOAD_OS_SPECIFIC_LIBRARIES) 17 | #CreateForceAllLoadList( ALL_LOAD_OS_SPECIFIC_FRAMEWORKS FORCE_ALL_LOAD_OS_SPECIFIC_FRAMEWORKS) 18 | # 19 | # message( STATUS "DEPENDENCY_LIBRARIES=${DEPENDENCY_LIBRARIES}") 20 | # message( STATUS "DEPENDENCY_FRAMEWORKS=${DEPENDENCY_FRAMEWORKS}") 21 | # message( STATUS "OPTIONAL_DEPENDENCY_LIBRARIES=${OPTIONAL_DEPENDENCY_LIBRARIES}") 22 | # message( STATUS "OPTIONAL_DEPENDENCY_FRAMEWORKS=${OPTIONAL_DEPENDENCY_FRAMEWORKS}") 23 | # message( STATUS "OS_SPECIFIC_LIBRARIES=${OS_SPECIFIC_LIBRARIES}") 24 | # message( STATUS "OS_SPECIFIC_FRAMEWORKS=${OS_SPECIFIC_FRAMEWORKS}") 25 | # 26 | # message( STATUS "SHARED_LIBRARY_LIST=${SHARED_LIBRARY_LIST}") 27 | # message( STATUS "FORCE_ALL_LOAD_DEPENDENCY_LIBRARIES=${FORCE_ALL_LOAD_DEPENDENCY_LIBRARIES}") 28 | # message( STATUS "ALL_LOAD_DEPENDENCY_FRAMEWORKS=${ALL_LOAD_DEPENDENCY_FRAMEWORKS}") 29 | # message( STATUS "FORCE_ALL_LOAD_OPTIONAL_DEPENDENCY_LIBRARIES=${FORCE_ALL_LOAD_OPTIONAL_DEPENDENCY_LIBRARIES}") 30 | # message( STATUS "ALL_LOAD_OPTIONAL_DEPENDENCY_FRAMEWORKS=${ALL_LOAD_OPTIONAL_DEPENDENCY_FRAMEWORKS}") 31 | # message( STATUS "FORCE_ALL_LOAD_OS_SPECIFIC_LIBRARIES=${FORCE_ALL_LOAD_OS_SPECIFIC_LIBRARIES}") 32 | # message( STATUS "ALL_LOAD_OS_SPECIFIC_FRAMEWORKS=${ALL_LOAD_OS_SPECIFIC_FRAMEWORKS}") 33 | 34 | set( SHARED_LIBRARY_LIST 35 | ${FORCE_ALL_LOAD_DEPENDENCY_LIBRARIES} 36 | ${ALL_LOAD_DEPENDENCY_FRAMEWORKS} 37 | ${FORCE_ALL_LOAD_OPTIONAL_DEPENDENCY_LIBRARIES} 38 | ${ALL_LOAD_OPTIONAL_DEPENDENCY_FRAMEWORKS} 39 | ${FORCE_ALL_LOAD_OS_SPECIFIC_LIBRARIES} 40 | ${ALL_LOAD_OS_SPECIFIC_FRAMEWORKS} 41 | ${SHARED_LIBRARY_LIST} 42 | ) 43 | 44 | include( PostSharedLibraryAuxC OPTIONAL) 45 | -------------------------------------------------------------------------------- /cmake/share/PreExecutable.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | # can be included multiple times 6 | 7 | if( MULLE_TRACE_INCLUDE) 8 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 9 | endif() 10 | 11 | include( CompilerDetectionC) 12 | include( CompilerWarningsC) # after detection, before flags 13 | include( CompilerFlagsC) 14 | 15 | include( PreExecutableAuxC OPTIONAL) 16 | -------------------------------------------------------------------------------- /cmake/share/PreFiles.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | if( NOT __PRE_FILES__CMAKE__) 6 | set( __PRE_FILES__CMAKE__ ON) 7 | 8 | if( MULLE_TRACE_INCLUDE) 9 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 10 | endif() 11 | 12 | include( CMakeTweaksC) 13 | 14 | # a place to add stuff for ObjC or C++ 15 | include( PreFilesAuxC OPTIONAL) 16 | 17 | endif() 18 | -------------------------------------------------------------------------------- /cmake/share/PreLibrary.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | # can be included multiple times 6 | 7 | if( MULLE_TRACE_INCLUDE) 8 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 9 | endif() 10 | 11 | include( CompilerDetectionC) 12 | include( CompilerWarningsC) # after detection, before flags 13 | include( CompilerFlagsC) 14 | 15 | include( PreLibraryAuxC OPTIONAL) 16 | -------------------------------------------------------------------------------- /cmake/share/README.md: -------------------------------------------------------------------------------- 1 | # DO NOT EDIT THIS FOLDER 2 | 3 | Files changes will be lost with the next `mulle-sde upgrade` execution. 4 | 5 | If you want to edit any of the files copy them "up" and edit them there. 6 | 7 | ``` 8 | cp share/Environment.cmake . 9 | vi Environment.cmake 10 | ``` 11 | -------------------------------------------------------------------------------- /cmake/share/Resources.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | if( MULLE_TRACE_INCLUDE) 6 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 7 | endif() 8 | 9 | # 10 | # The following includes include definitions generated 11 | # during `mulle-sde reflect`. Don't edit those files. They are 12 | # overwritten frequently. 13 | # 14 | # === MULLE-SDE START === 15 | 16 | include( _Resources OPTIONAL) 17 | 18 | # === MULLE-SDE END === 19 | # 20 | # 21 | # If you don't like the "automatic" way of generating _Resources 22 | # 23 | # MULLE_MATCH_TO_CMAKE_RESOURCES_FILE="DISABLE" # or NONE 24 | # 25 | 26 | # 27 | # You can put more source and resource file definitions here. 28 | # 29 | set( INSTALL_RESOURCES ${RESOURCES}) 30 | -------------------------------------------------------------------------------- /cmake/share/Sources.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | if( MULLE_TRACE_INCLUDE) 6 | message( STATUS "# Include \"${CMAKE_CURRENT_LIST_FILE}\"" ) 7 | endif() 8 | 9 | # 10 | # The following includes include definitions generated 11 | # during `mulle-sde reflect`. Don't edit those files. They are 12 | # overwritten frequently. 13 | # 14 | # === MULLE-SDE START === 15 | 16 | include( _Sources OPTIONAL) 17 | 18 | # === MULLE-SDE END === 19 | # 20 | # 21 | # If you don't like the "automatic" way of generating _Sources 22 | # 23 | # MULLE_MATCH_TO_CMAKE_SOURCES_FILE="DISABLE" # or NONE 24 | # 25 | 26 | # 27 | # You can put more source and resource file definitions here. 28 | # 29 | -------------------------------------------------------------------------------- /cmake/share/StringCase.cmake: -------------------------------------------------------------------------------- 1 | ### If you want to edit this, copy it from cmake/share to cmake. It will be 2 | ### picked up in preference over the one in cmake/share. And it will not get 3 | ### clobbered with the next upgrade. 4 | 5 | 6 | # Original: 7 | # 8 | # https://github.com/ros2/rosidl/blob/master/rosidl_cmake/cmake/string_camel_case_to_lower_case_underscore.cmake 9 | # Apache License, Version 2. 10 | # 11 | if( NOT __STRING_CASE__CMAKE__) 12 | set( __STRING_CASE__CMAKE__ ON) 13 | function( snakeCaseString str var) 14 | # convert this to one word If present 15 | string( REGEX REPLACE "ObjC" "Objc" value "${str}") 16 | 17 | # turns mulle-scion into MULLE__SCION to distinguish from 18 | # MulleScion -> MULLE_SCION 19 | string( REGEX REPLACE "-" "__" value "${value}") 20 | 21 | # insert an underscore before any upper case letter 22 | # which is not followed by another upper case letter 23 | string( REGEX REPLACE "(.)([A-Z][a-z]+)" "\\1_\\2" value "${value}") 24 | 25 | # insert an underscore before any upper case letter 26 | # which is preseded by a lower case letter or number 27 | string( REGEX REPLACE "([a-z0-9])([A-Z])" "\\1_\\2" value "${value}") 28 | 29 | # replace non-identifier characters with an '_', for UTF8 this 30 | # may produce multiple _s we can't get easily rid off 31 | string( REGEX REPLACE "[^A-Za-z0-9$_]" "_" value "${value}") 32 | 33 | set( ${var} "${value}" PARENT_SCOPE) 34 | endfunction() 35 | endif() 36 | -------------------------------------------------------------------------------- /cmake/share/mulle-thread-config.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | include( CMakeFindDependencyMacro) 4 | 5 | set( COLLECT_DEPENDENCY_LIBRARIES_AS_NAMES ON) 6 | set( TMP_DEPENDENCY_LIBRARIES "${DEPENDENCY_LIBRARIES}") 7 | unset( DEPENDENCY_LIBRARIES) 8 | 9 | include( "${CMAKE_CURRENT_LIST_DIR}/reflect/_Dependencies.cmake" OPTIONAL) 10 | 11 | 12 | foreach( TMP_NAME ${DEPENDENCY_LIBRARIES}) 13 | find_dependency( ${TMP_NAME}) 14 | endforeach() 15 | 16 | # restore 17 | set( COLLECT_DEPENDENCY_LIBRARIES_AS_NAMES OFF) 18 | set( DEPENDENCY_LIBRARIES "${TMP_DEPENDENCY_LIBRARIES}") 19 | 20 | include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake") 21 | 22 | check_required_components(@PROJECT_NAME@) 23 | -------------------------------------------------------------------------------- /cmake/share/mulle-thread-config.h.in: -------------------------------------------------------------------------------- 1 | #define MULLE_ALLOCATOR_VERSION "@PROJECT_VERSION@" 2 | #define MULLE_ALLOCATOR_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ 3 | #define MULLE_ALLOCATOR_VERSION_MINOR @PROJECT_VERSION_MINOR@ 4 | #define MULLE_ALLOCATOR_VERSION_PATCH @PROJECT_VERSION_PATCH@ 5 | -------------------------------------------------------------------------------- /cola/api.md.bud: -------------------------------------------------------------------------------- 1 | ## API 2 | 3 | * [Atomic Operations](dox/API_ATOMIC.md) 4 | * [Threads](dox/API_THREAD.md) 5 | * [Mutex](dox/API_MUTEX.md) 6 | * [Thread Local Storage](dox/API_TSS.md) 7 | 8 | -------------------------------------------------------------------------------- /cola/description.md.bud: -------------------------------------------------------------------------------- 1 | 2 | # mulle-thread 3 | 4 | #### 🔠 Cross-platform thread/mutex/tss/atomic operations in C 5 | 6 | **mulle-thread** is a set of **C** wrapper headers for a simplified 7 | subset of thread functions and for a limited range of atomic operations that 8 | strongly mimics the thread standard, even if thread is not available. On Windows it 9 | has to do a bit more work. 10 | 11 | mulle-threads main advantages are **simplicity**, **portability**, **sanity**. 12 | 13 | * basic atomic operations CAS, ++, -- on void pointers. 14 | * basic thread operations 15 | * mutex functionality 16 | * thread local storage, with proper destruction 17 | 18 | Since thread has `` and ``, eventually this project 19 | could become superflous. In the meantime though it's a convenient abstraction 20 | on threads and atomic operations. 21 | 22 | ### Warning 23 | 24 | `mulle_thread_once` doesn't guarantee, that exceptions or thread cancellation 25 | within the init function will clear the once flag for a second run. In fact 26 | it will not. 27 | 28 | 29 | | Release Version 30 | |----------------------------------- 31 | | [![Build Status](https://github.com/mulle-concurrent/mulle-thread/workflows/CI/badge.svg?branch=release)](//github.com/mulle-concurrent/mulle-thread) ![Mulle kybernetiK tag](https://img.shields.io/github/tag/mulle-concurrent/mulle-thread/workflows/CI/badge.svg?branch=release) 32 | 33 | -------------------------------------------------------------------------------- /cola/info.md.bud: -------------------------------------------------------------------------------- 1 | ## Convenience macro for mutex 2 | 3 | An easy way to get a locked code region is to use: 4 | 5 | ``` c 6 | void foo( mulle_thread_mutex_t *mutex) 7 | { 8 | mulle_thread_mutex_do( mutex) 9 | { 10 | // code block is now executed with mutex locked 11 | } 12 | // mutex is unlocked again 13 | } 14 | ``` 15 | 16 | `break` and `continue` will exit the block and unlock the mutex. But when you 17 | use `return` the function exists and the mutex remains locked. 18 | 19 | 20 | -------------------------------------------------------------------------------- /cola/properties.plist: -------------------------------------------------------------------------------- 1 | { 2 | project = 3 | { 4 | description="🔠 Cross-platform thread/mutex/tss/atomic operations in C"; 5 | domain="github"; 6 | language="c"; 7 | dialect="c"; 8 | name="mulle-thread"; 9 | user="mulle-concurrent"; 10 | repo="mulle-thread"; 11 | homepage="https://github.com/mulle-concurrent/mulle-thread"; 12 | license="BSD-3-Clause"; 13 | }; 14 | dependencies = 15 | ( 16 | { 17 | description="🔀 Cross-platform C compiler glue (and some cpp conveniences)"; 18 | domain="github"; 19 | name="mulle-c11"; 20 | repo="mulle-c11"; 21 | url="https://github.com/mulle-c/mulle-c11"; 22 | user="mulle-c"; 23 | } 24 | ); 25 | embedded = 26 | ( 27 | { 28 | description="For more information, see [the documentation](http://mintomic.github.io/) or the accompanying blog post, [Introducing Mintomic](http://preshing.com/20130505/introducing-mintomic-a-small-portable-lock-free-api)."; 29 | domain="github"; 30 | name="mintomic"; 31 | repo="mintomic"; 32 | url="https://github.com/mulle-concurrent/mintomic"; 33 | user="mulle-concurrent"; 34 | } 35 | ); 36 | } 37 | -------------------------------------------------------------------------------- /dox/API_MUTEX.md: -------------------------------------------------------------------------------- 1 | # Mutex API 2 | 3 | The mutex API is almost identical to the pthreads mutex API, but a bit simplified. A mutex is local to the process and it's threads. 4 | 5 | 6 | ## Types 7 | 8 | Type | Description 9 | -----------------------|------------------------------------------------ 10 | `mulle_thread_mutex_t` | mutex type (when using **pthreads** a typedef of `pthread_mutex_t`) 11 | 12 | 13 | ## Functions 14 | 15 | #### mulle_thread_mutex_init 16 | 17 | ``` 18 | int mulle_thread_mutex_init( mulle_thread_mutex_t *lock) 19 | ``` 20 | 21 | Initialize a mutex. You must call this before using it. You can not 22 | statically initialize a `mulle_thread_mutex_t`. 23 | 24 | Returns 0 on success. 25 | 26 | 27 | #### mulle_thread_mutex_lock 28 | 29 | ``` 30 | int mulle_thread_mutex_lock( mulle_thread_mutex_t *lock) 31 | ``` 32 | 33 | Lock the mutex. A thread will deadlock if it tries to lock the mutex again. 34 | 35 | Returns 0 on success. A negative value indicates that you set up the mutex wrong. 36 | 37 | See: [pthread_mutex_lock](https://linux.die.net/man/3/pthread_mutex_lock) 38 | 39 | 40 | #### mulle_thread_mutex_trylock 41 | 42 | ``` 43 | int mulle_thread_mutex_trylock( mulle_thread_mutex_t *lock) 44 | ``` 45 | 46 | Returns 0 on success. Returns 1 if busy. Returns -1 on failure. 47 | 48 | See: [pthread_mutex_trylock](https://linux.die.net/man/3/pthread_mutex_trylock) 49 | 50 | 51 | #### mulle_thread_mutex_unlock 52 | 53 | ``` 54 | int mulle_thread_mutex_unlock( mulle_thread_mutex_t *lock) 55 | ``` 56 | Unlock the mutex. Unlocking a non-locked mutex is wrong. Unlocking a mutex, that was locked by a different thread, is wrong. 57 | 58 | Returns 0 on success. 59 | 60 | See: [pthread_mutex_unlock](https://linux.die.net/man/3/pthread_mutex_unlock) 61 | 62 | 63 | #### mulle_thread_mutex_done 64 | 65 | ``` 66 | int mulle_thread_mutex_done( mulle_thread_mutex_t *lock) 67 | ``` 68 | 69 | Destroy the mutex. You should not destroy a locked mutex. 70 | 71 | Returns 0 on success. 72 | 73 | See: [pthread_mutex_done](https://linux.die.net/man/3/pthread_mutex_done) 74 | 75 | -------------------------------------------------------------------------------- /dox/API_THREAD.md: -------------------------------------------------------------------------------- 1 | # Thread API 2 | 3 | The thread API is like pthreads, except where noted. Please consult the pthread 4 | man pages for more extensive help. 5 | 6 | * Main differences to be aware of: There is no such thing as a return value from a thread. 7 | * You must execute `mulle_thread_exit` at the end of your thread. 8 | 9 | 10 | ## Types 11 | 12 | Type | Description 13 | ----------------------|------------------------------------------------ 14 | `mulle_thread_t` | thread type, with **pthreads** a typedef of `pthread_t` 15 | `mulle_thread_rval_t` | the return value of a thread. Assume this being **void**! 16 | 17 | 18 | #### mulle_thread_self 19 | 20 | ``` 21 | mulle_thread_t mulle_thread_self( void) 22 | ``` 23 | 24 | Returns the current thread, just like `pthread_self` 25 | 26 | 27 | #### mulle_thread_create 28 | 29 | ``` 30 | mulle_thread_create( mulle_thread_rval_t (*f)(void *), 31 | void *arg, 32 | mulle_thread_t *thread) 33 | ``` 34 | 35 | > Note: Parameters are differently ordered than in pthread 36 | 37 | **f** is the thread function with **arg** as its argument. 38 | The created thread is returned in **thread**. Obviously **arg** should not 39 | be a pointer to stack memory. `mulle_thread_rval_t` can be `void` or `int` 40 | depending on platform. The return value will be ignored though. Use 41 | `mulle_thread_return()` in your code to avoid warnings. 42 | 43 | A return value of 0 indicates success. 44 | 45 | 46 | #### mulle_thread_join 47 | 48 | ``` 49 | int mulle_thread_join( mulle_thread_t thread) 50 | ``` 51 | 52 | Join with a terminated thread (wait for a thread to exit) 53 | 54 | 55 | See: [pthread_join](//man7.org/linux/man-pages/man3/pthread_join.3.html) 56 | 57 | 58 | #### mulle_thread_detach 59 | 60 | ``` 61 | int mulle_thread_detach( mulle_thread_t thread) 62 | ``` 63 | 64 | Detach a thread, frees caller from having to join it later. 65 | 66 | See: [pthread_detach](//man7.org/linux/man-pages/man3/pthread_detach.3.html) 67 | 68 | 69 | #### mulle_thread_exit 70 | 71 | ``` 72 | void mulle_thread_exit( void) 73 | ``` 74 | 75 | Terminate calling thread. Your thread **must** call this to exit, 76 | so that thread local storage destructors are run. 77 | 78 | See: [pthread_exit](//man7.org/linux/man-pages/man3/pthread_exit.3.html) 79 | 80 | 81 | 82 | #### mulle_thread_yield 83 | 84 | ``` 85 | void mulle_thread_yield( void) 86 | ``` 87 | 88 | Initiate a context switch. 89 | 90 | See: [sched_yield](//man7.org/linux/man-pages/man2/sched_yield.2.html) 91 | 92 | -------------------------------------------------------------------------------- /dox/API_TSS.md: -------------------------------------------------------------------------------- 1 | # TSS API 2 | 3 | The thread specific storage API is like the [pthreads](//en.wikipedia.org/wiki/POSIX_Threads) 4 | thread local storage API, except where noted. 5 | 6 | On Windows the destructor facility of pthreads is emulated to provide a saner experience. 7 | 8 | Think of thread specific storage as a hashtable/dictionary that belongs to every 9 | thread, where the keys are globally defined (with `mulle_thread_tss_create`). 10 | 11 | 12 | ## Types 13 | 14 | Type | Description 15 | ---------------------|------------------------------------------------ 16 | `mulle_thread_tss_t` | thread local storage key type (when using **pthreads** a typedef of `pthread_key_t`) 17 | 18 | 19 | ## Functions 20 | 21 | 22 | #### mulle_thread_tss_create 23 | 24 | ``` 25 | int mulle_thread_tss_create( void (*f)( void *), 26 | mulle_thread_tss_t *key) 27 | ``` 28 | 29 | Create a thread local storage key, with a destructor function. This key is 30 | common to all threads. TSS storage keys are very limited. Do not create too 31 | many for your application. Less than 100 I would expect to work evertime. 32 | The destructor function will be called, whenever a thread terminates properly 33 | with `mulle_thread_exit`. The key can be zero value! 34 | 35 | Returns 0 on success. 36 | 37 | See: [pthread_key_create](//linux.die.net/man/3/pthread_key_create) 38 | 39 | 40 | #### mulle_thread_tss_free 41 | 42 | ``` 43 | void mulle_thread_tss_free( mulle_thread_tss_t key) 44 | ``` 45 | 46 | Free a thread local storage key. Be sure that you do not free a key, when it 47 | is still in use by other threads. In general applications don't need to call this 48 | function. 49 | 50 | See: [pthread_key_delete](//linux.die.net/man/3/pthread_key_delete) 51 | 52 | 53 | #### mulle_thread_tss_get 54 | 55 | ``` 56 | void *mulle_thread_tss_get( mulle_thread_tss_t key) 57 | ``` 58 | 59 | Get value from thread local storage with key. 60 | 61 | 62 | See: [pthread_getspecific](//linux.die.net/man/3/pthread_getspecific) 63 | 64 | 65 | #### mulle_thread_tss_set 66 | 67 | ``` 68 | int mulle_thread_tss_set( mulle_thread_tss_t key, 69 | void *value) 70 | ``` 71 | 72 | Set value in thread local storage with key. Obviously **value** should not 73 | be a pointer to memory writable by other threads or stack memory. If you want 74 | to write an integer use `mulle_thread_tss_set( key, (void *) 1848)`. 75 | 76 | See: [pthread_setspecific](//linux.die.net/man/3/pthread_setspecific) 77 | -------------------------------------------------------------------------------- /dox/BUILD.md: -------------------------------------------------------------------------------- 1 | # How to build mulle-thread 2 | 3 | 4 | ## What you get 5 | 6 | * `libmulle_thread.a`, the mulle-thread static library along with a bunch of 7 | headers. You can often get by not linking with libmulle_thread.a, except on 8 | windows, where you absolutely do need it. 9 | 10 | 11 | ## Prerequisites 12 | 13 | #### mintomic 14 | 15 | If your compiler does not support C11 atomics, then `mulle-thread` needs 16 | [mintomic](//mintomic.github.io/) as a prerequisite. This is expected to 17 | exist in the project directory root. 18 | 19 | #### mulle-c11 20 | 21 | [mulle-c11](//www.mulle-kybernetik.com/software/git/mulle-c11/) is a header 22 | that abstracts a small set of non-standardized compiler features. 23 | 24 | #### mulle-configuration 25 | 26 | [mulle-configuration](//www.mulle-kybernetik.com/software/git/mulle-configuration/) are 27 | configuration files for building with Xcode or cmake. This is expected to 28 | exist in the project directory root. 29 | 30 | #### mulle-tests 31 | 32 | [mulle-tests](//www.mulle-kybernetik.com/software/git/mulle-tests/) are 33 | scripts to provide an environment for running the tests. This is expected to 34 | exist in the project directory root if you want to run tests. 35 | 36 | #### mulle-build 37 | 38 | [mulle-build](//www.mulle-kybernetik.com/software/git/mulle-build) will 39 | painlessly assemble the dependencies and build the library. 40 | 41 | 42 | ### Windows: Installing further prerequisites 43 | 44 | Check the [mulle-build README.md](//www.mulle-kybernetik.com/software/git/mulle-build/README.md) 45 | for instrutions how to get the "Git for Windows" bash going. 46 | 47 | 48 | ## Install mulle-thread using mulle-build 49 | 50 | Grab the latest **mulle-thread** release and go into the project directory: 51 | 52 | ``` 53 | git clone https://github.com/mulle-objc/mulle-thread 54 | cd mulle-thread 55 | ``` 56 | 57 | Then let **mulle-build** fetch the dependencies and build **mulle-thread** in 58 | debug mode: 59 | 60 | ``` 61 | mulle-build --debug 62 | ``` 63 | 64 | Run some tests: 65 | 66 | ``` 67 | mulle-test 68 | ``` 69 | 70 | Build library in release mode and install into `tmp` : 71 | 72 | ``` 73 | mulle-clean ; 74 | mulle-install --prefix /tmp 75 | ``` 76 | 77 | 78 | ### Compile Flags 79 | 80 | For production use NDEBUG 81 | -------------------------------------------------------------------------------- /dox/CONVENIENT_BOUNCE.md: -------------------------------------------------------------------------------- 1 | 2 | # Automatically call mulle_thread_exit on thread function exit 3 | 4 | If you are prone to forget calling `mulle_thread_exit` or want to easily 5 | interface with functions, that are not aware, that they are running as a 6 | thread. I've got some code for you: 7 | 8 | 9 | `thread_bounceinfo.h`: 10 | 11 | ``` 12 | #include 13 | #include 14 | 15 | struct thread_bounceinfo 16 | { 17 | mulle_thread_rval_t (*f)( void *arg); 18 | void *arg; 19 | }; 20 | 21 | 22 | struct thread_bounceinfo *thread_bounceinfo_create( mulle_thread_rval_t (*f)( void *), 23 | void *arg); 24 | 25 | 26 | static inline void thread_bounceinfo_free( struct thread_bounceinfo *info) 27 | { 28 | free( info); 29 | } 30 | 31 | void thread_bounceinfo_bounce( void *_info); 32 | 33 | ``` 34 | 35 | `thread_bounceinfo.c`: 36 | 37 | ``` 38 | #include "thread_bounceinfo.h" 39 | 40 | 41 | struct thread_bounceinfo *thread_bounceinfo_create( mulle_thread_rval_t (*f)( void *), 42 | void *arg) 43 | { 44 | struct thread_bounceinfo *info; 45 | 46 | info = calloc( 1, sizeof( struct thread_bounceinfo)); 47 | if( ! info) 48 | return( NULL); 49 | 50 | info->f = f; 51 | info->arg = arg; 52 | return( info); 53 | } 54 | 55 | 56 | void thread_bounceinfo_bounce( void *_info) 57 | { 58 | mulle_thread_rval_t rval; 59 | struct thread_bounceinfo *info; 60 | void (*f)( void *); 61 | void *arg; 62 | 63 | info = _info; 64 | f = info->f; 65 | arg = info->arg; 66 | free( _info); 67 | 68 | rval = (*f)( arg); 69 | 70 | mulle_thread_exit( (mulle_thread_native_rval_t) rval); 71 | assert( 0 && "mulle_thread_exit must not return"); 72 | } 73 | ``` 74 | 75 | 76 | And the call 77 | 78 | `thread.c`: 79 | 80 | ``` 81 | #include "thread_bounceinfo.h" 82 | 83 | static inline int thread_create( mulle_thread_rval_t (*f)( void *), 84 | void *arg, 85 | mulle_thread_t *thread) 86 | { 87 | struct thread_bounceinfo *info; 88 | 89 | info = thread_bounceinfo_create( f, arg); 90 | if( ! info) 91 | return( -1); 92 | 93 | return( mulle_thread_create( thread, thread_bounceinfo_bounce, info)); 94 | } 95 | ``` 96 | -------------------------------------------------------------------------------- /mulle-thread.sublime-project: -------------------------------------------------------------------------------- 1 | { 2 | "folders": 3 | [ 4 | { 5 | "path": "." 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /overview.dot.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | sourcetree 11 | 12 | 13 | 14 | mulle-thread 15 | 16 | mulle-thread 17 | 18 | 19 | 20 | mintomic 21 | 22 | 23 | mintomic 24 | 25 | 26 | 27 | 28 | 29 | mulle-thread->mintomic 30 | 31 | 32 | 33 | 34 | 35 | mulle-c11 36 | 37 | 38 | mulle-c11 39 | 40 | 41 | 42 | 43 | 44 | mulle-thread->mulle-c11 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /run-on-ipad/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // run-on-ipad 4 | // 5 | // Created by Nat! on 12.10.15. 6 | // Copyright © 2015 Mulle kybernetiK. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /run-on-ipad/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // run-on-ipad 4 | // 5 | // Created by Nat! on 12.10.15. 6 | // Copyright © 2015 Mulle kybernetiK. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | extern int _main(int argc, const char * argv[]); 40 | 41 | _main( 0, NULL); 42 | } 43 | 44 | - (void)applicationWillTerminate:(UIApplication *)application { 45 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /run-on-ipad/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /run-on-ipad/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /run-on-ipad/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /run-on-ipad/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /run-on-ipad/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // run-on-ipad 4 | // 5 | // Created by Nat! on 12.10.15. 6 | // Copyright © 2015 Mulle kybernetiK. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /run-on-ipad/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // run-on-ipad 4 | // 5 | // Created by Nat! on 12.10.15. 6 | // Copyright © 2015 Mulle kybernetiK. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view, typically from a nib. 20 | } 21 | 22 | - (void)didReceiveMemoryWarning { 23 | [super didReceiveMemoryWarning]; 24 | // Dispose of any resources that can be recreated. 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /run-on-ipad/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // run-on-ipad 4 | // 5 | // Created by Nat! on 12.10.15. 6 | // Copyright © 2015 Mulle kybernetiK. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/generic/include-private.h: -------------------------------------------------------------------------------- 1 | #ifndef mulle_thread_include_private_h__ 2 | #define mulle_thread_include_private_h__ 3 | 4 | /* This is a central include file to not expose includes to consumers of 5 | this library. It must not be imported by .h files, but by .c files 6 | only. 7 | */ 8 | 9 | #include "include.h" 10 | 11 | /* Include the header file automatically generated by c-sourcetree-update. 12 | Here the prefix is harmless and serves disambiguation. If you have no 13 | sourcetree, then you don't need it. 14 | */ 15 | 16 | #include "_mulle-thread-include-private.h" 17 | 18 | /* You can add some more include statements here */ 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/generic/include.h: -------------------------------------------------------------------------------- 1 | #ifndef mulle_thread_include_h__ 2 | #define mulle_thread_include_h__ 3 | 4 | /* This is a central include file to keep dependencies out of the library 5 | C files. It is usally included by .h files only. 6 | 7 | The advantage is that now .c and .h files become motile. They can 8 | be moved to other projects and don't need to be edited. Also less typing... 9 | 10 | Therefore it is important that this file is called "include.h" and 11 | not "mulle-thread-include.h" to keep the #include statements in the 12 | library code uniform. 13 | 14 | The C-compiler will pick up the nearest one. 15 | */ 16 | 17 | /* Include the header file automatically generated by c-sourcetree-update. 18 | Here the prefix is harmless and serves disambiguation. If you have no 19 | sourcetree, then you don't need it. 20 | */ 21 | 22 | #include "_mulle-thread-include.h" 23 | 24 | #ifdef MULLE__THREAD_BUILD 25 | # define MULLE__THREAD_GLOBAL MULLE_C_GLOBAL 26 | #else 27 | # if defined( MULLE_THREAD_INCLUDE_DYNAMIC) || (defined( MULLE_INCLUDE_DYNAMIC) && ! defined( MULLE_THREAD_INCLUDE_STATIC)) 28 | # define MULLE__THREAD_GLOBAL MULLE_C_EXTERN_GLOBAL 29 | # else 30 | # define MULLE__THREAD_GLOBAL extern 31 | # endif 32 | #endif 33 | 34 | 35 | /* You can add some more include statements here */ 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/mintomic-empty.c: -------------------------------------------------------------------------------- 1 | // 2 | // mintomic_empty.c 3 | // mulle-thread 4 | // 5 | // Created by Nat! on 10.10.15. 6 | // Copyright (c) 2015 Mulle kybernetiK. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without 9 | // modification, are permitted provided that the following conditions are met: 10 | // 11 | // Redistributions of source code must retain the above copyright notice, this 12 | // list of conditions and the following disclaimer. 13 | // 14 | // Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // Neither the name of Mulle kybernetiK nor the names of its contributors 19 | // may be used to endorse or promote products derived from this software 20 | // without specific prior written permission. 21 | // 22 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 26 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | // POSSIBILITY OF SUCH DAMAGE. 33 | // 34 | // xcode not happy if .a not exist 35 | unsigned long __mulle_mintomic_version__ = 0x0000; 36 | -------------------------------------------------------------------------------- /src/mulle-atomic.h: -------------------------------------------------------------------------------- 1 | // 2 | // mulle_thread_atomic.h 3 | // mulle-thread 4 | // 5 | // Created by Nat! on 16.03.15. 6 | // Copyright (c) 2015 Mulle kybernetiK. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without 9 | // modification, are permitted provided that the following conditions are met: 10 | // 11 | // Redistributions of source code must retain the above copyright notice, this 12 | // list of conditions and the following disclaimer. 13 | // 14 | // Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // Neither the name of Mulle kybernetiK nor the names of its contributors 19 | // may be used to endorse or promote products derived from this software 20 | // without specific prior written permission. 21 | // 22 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 26 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | // POSSIBILITY OF SUCH DAMAGE. 33 | // 34 | 35 | #ifndef mulle_atomic_h__ 36 | #define mulle_atomic_h__ 37 | 38 | #include "include.h" 39 | 40 | 41 | #ifndef HAVE_C11_STDATOMIC 42 | # ifdef __clang__ 43 | # if __has_include() 44 | # define HAVE_C11_STDATOMIC 1 45 | # endif 46 | # else 47 | # if __STDC_VERSION__ >= 201112L && ! defined( __STDC_NO_ATOMICS__) 48 | # define HAVE_C11_STDATOMIC 1 49 | # endif 50 | # endif 51 | #endif 52 | 53 | // 54 | // http://stackoverflow.com/questions/11805636/how-do-i-check-by-using-stdc-version-if-is-std-c1x-in-use 55 | // http://en.cppreference.com/w/c/atomic 56 | // 57 | #if HAVE_C11_STDATOMIC && ! defined( MULLE_THREAD_USE_MINTOMIC) 58 | # if TRACE_INCLUDE 59 | # pragma message( "Using C11 for atomics") 60 | # endif 61 | # include "mulle-atomic-c11.h" 62 | #else 63 | # if TRACE_INCLUDE 64 | # pragma message( "Using mintomic for atomics") 65 | # endif 66 | # include "mulle-atomic-mintomic.h" 67 | #endif 68 | 69 | 70 | #pragma mark - additional API 71 | 72 | MULLE_C_STATIC_ALWAYS_INLINE void * 73 | _mulle_atomic_pointer_set( mulle_atomic_pointer_t *address, 74 | void *value) 75 | { 76 | void *expect; // random contents don't matter 77 | void *previous; 78 | 79 | expect = value; // contents don't matter, let compiler not get a heart attack 80 | for(;;) 81 | { 82 | previous = __mulle_atomic_pointer_weakcas( address, value, expect); 83 | if( previous == expect) 84 | return( previous); 85 | expect = previous; 86 | } 87 | } 88 | 89 | 90 | MULLE_C_STATIC_ALWAYS_INLINE mulle_functionpointer_t 91 | _mulle_atomic_functionpointer_set( mulle_atomic_functionpointer_t *address, 92 | mulle_functionpointer_t value) 93 | { 94 | mulle_functionpointer_t expect; 95 | mulle_functionpointer_t previous; 96 | 97 | expect = value; // contents don't matter, let compiler not get a heart attack 98 | for(;;) 99 | { 100 | previous = __mulle_atomic_functionpointer_weakcas( address, value, expect); 101 | if( previous == expect) 102 | return( previous); 103 | expect = previous; 104 | } 105 | } 106 | 107 | 108 | #pragma mark - old API 109 | 110 | static inline int 111 | _mulle_atomic_pointer_compare_and_swap( mulle_atomic_pointer_t *address, 112 | void *value, 113 | void *expect) 114 | { 115 | return( _mulle_atomic_pointer_cas( address, value, expect)); 116 | } 117 | 118 | 119 | static inline void * 120 | __mulle_atomic_pointer_compare_and_swap( mulle_atomic_pointer_t *address, 121 | void *value, 122 | void *expect) 123 | { 124 | return( __mulle_atomic_pointer_cas( address, value, expect)); 125 | } 126 | 127 | 128 | static inline mulle_functionpointer_t 129 | __mulle_atomic_functionpointer_compare_and_swap( mulle_atomic_functionpointer_t *address, 130 | mulle_functionpointer_t value, 131 | mulle_functionpointer_t expect) 132 | { 133 | return( __mulle_atomic_functionpointer_cas( address, value, expect)); 134 | } 135 | 136 | 137 | static inline int 138 | _mulle_atomic_functionpointer_compare_and_swap( mulle_atomic_functionpointer_t *address, 139 | mulle_functionpointer_t value, 140 | mulle_functionpointer_t expect) 141 | { 142 | return( _mulle_atomic_functionpointer_cas( address, value, expect)); 143 | } 144 | 145 | 146 | #endif 147 | -------------------------------------------------------------------------------- /src/mulle-thread-linkage.c: -------------------------------------------------------------------------------- 1 | // 2 | // linkage.c 3 | // mulle-thread 4 | // 5 | // Created by Nat! on 16/09/15. 6 | // Copyright (c) 2015 Mulle kybernetiK. All rights reserved. 7 | // 8 | // Redistribution and use in source and binary forms, with or without 9 | // modification, are permitted provided that the following conditions are met: 10 | // 11 | // Redistributions of source code must retain the above copyright notice, this 12 | // list of conditions and the following disclaimer. 13 | // 14 | // Redistributions in binary form must reproduce the above copyright notice, 15 | // this list of conditions and the following disclaimer in the documentation 16 | // and/or other materials provided with the distribution. 17 | // 18 | // Neither the name of Mulle kybernetiK nor the names of its contributors 19 | // may be used to endorse or promote products derived from this software 20 | // without specific prior written permission. 21 | // 22 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 26 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | // POSSIBILITY OF SUCH DAMAGE. 33 | // 34 | // don't need it but finds compiler C11 problems early 35 | #include "mulle-thread.h" 36 | 37 | // provide linkage to glom thread lib unto (if dylib) 38 | // but you can live without it in .a 39 | unsigned long __mulle_thread_version__ = 0x0000; 40 | 41 | // we include mintomic, if we need it 42 | // 43 | // if we are building with mulle-core this file is in "src/mulle-thread" and 44 | // "mintomic_gcc.c" is in "mintomic/mintomic_gcc.c" -> "../../mintomic" 45 | // 46 | // if we are building alone, this file is in "src" and "mintomic_gcc.c" is 47 | // in "mintomic/src/mintomic/mintomic_gcc.c" "../mintomic/src/mintomic" 48 | // 49 | #if __STDC_VERSION__ < 201112L || defined( __STDC_NO_ATOMICS__) 50 | // variable defined by Executable.cmake 51 | # ifdef MULLE__CORE_BUILD 52 | # include "../../mintomic/mintomic_gcc.c" 53 | # else 54 | # include "../mintomic/src/mintomic/mintomic_gcc.c" 55 | # endif 56 | #endif 57 | -------------------------------------------------------------------------------- /src/mulle-thread-standalone.c: -------------------------------------------------------------------------------- 1 | /* the required "anything linkable symbol" to get a shared libary going */ 2 | int __mulle_thread_unused__ = 1848; 3 | -------------------------------------------------------------------------------- /src/reflect/_mulle-thread-include-private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file will be regenerated by `mulle-sourcetree-to-c` via 3 | * `mulle-sde reflect` and any edits will be lost. 4 | * Suppress generation of this file with: 5 | * 6 | * mulle-sde environment set MULLE_SOURCETREE_TO_C_PRIVATEINCLUDE_FILE DISABLE 7 | * 8 | * To not let mulle-sourcetree-to-c generate any header files: 9 | * 10 | * mulle-sde environment set MULLE_SOURCETREE_TO_C_RUN DISABLE 11 | * 12 | */ 13 | 14 | #ifndef _mulle_thread_include_private_h__ 15 | #define _mulle_thread_include_private_h__ 16 | 17 | /* no headers */ 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/reflect/_mulle-thread-include.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file will be regenerated by `mulle-sourcetree-to-c` via 3 | * `mulle-sde reflect` and any edits will be lost. 4 | * Suppress generation of this file with: 5 | * 6 | * mulle-sde environment set MULLE_SOURCETREE_TO_C_INCLUDE_FILE DISABLE 7 | * 8 | * To not let mulle-sourcetree-to-c generate any header files: 9 | * 10 | * mulle-sde environment set MULLE_SOURCETREE_TO_C_RUN DISABLE 11 | * 12 | */ 13 | 14 | #ifndef _mulle_thread_include_h__ 15 | #define _mulle_thread_include_h__ 16 | 17 | // To remove the following dependency (headers and library) completely: 18 | // `mulle-sde dependency remove mulle-c11` 19 | // (Use 97F390B6-FA26-4BAC-BB87-90A654AAB3B6 instead of mulle-c11, if there are duplicate entries) 20 | // 21 | // You can tweak the following #include with these commands: 22 | // remove #include: `mulle-sde dependency mark mulle-c11 no-header` 23 | // rename : `mulle-sde dependency|library set mulle-c11 include whatever.h` 24 | // reorder : `mulle-sde dependency move mulle-c11 ` 25 | // toggle #include: `mulle-sde dependency mark mulle-c11 [no-]import` 26 | // toggle public : `mulle-sde dependency mark mulle-c11 [no-]public` 27 | // toggle optional : `mulle-sde dependency mark mulle-c11 [no-]require` 28 | // remove for platform : `mulle-sde dependency mark mulle-c11 no-platform-` 29 | // (use `mulle-sourcetree-to-c --unames` to list known values) 30 | #include // mulle-c11 31 | 32 | // To remove the following dependency (headers and library) completely: 33 | // `mulle-sde dependency remove stdthreads` 34 | // (Use 91a3a06c-669f-4cd4-9060-562b3d0b6315 instead of stdthreads, if there are duplicate entries) 35 | // 36 | // You can tweak the following #include with these commands: 37 | // remove #include: `mulle-sde dependency mark stdthreads no-header` 38 | // rename : `mulle-sde dependency|library set stdthreads include whatever.h` 39 | // reorder : `mulle-sde dependency move stdthreads ` 40 | // toggle #include: `mulle-sde dependency mark stdthreads [no-]import` 41 | // toggle public : `mulle-sde dependency mark stdthreads [no-]public` 42 | // toggle optional : `mulle-sde dependency mark stdthreads [no-]require` 43 | // remove for platform : `mulle-sde dependency mark stdthreads no-platform-` 44 | // (use `mulle-sourcetree-to-c --unames` to list known values) 45 | # if defined( __FreeBSD__) 46 | # include // stdthreads 47 | #endif 48 | 49 | // To remove the following dependency (headers and library) completely: 50 | // `mulle-sde dependency remove pthread` 51 | // (Use 8fd8130b-1d75-4633-89b4-57e61467847e instead of pthread, if there are duplicate entries) 52 | // 53 | // You can tweak the following #include with these commands: 54 | // remove #include: `mulle-sde dependency mark pthread no-header` 55 | // rename : `mulle-sde dependency|library set pthread include whatever.h` 56 | // reorder : `mulle-sde dependency move pthread ` 57 | // toggle #include: `mulle-sde dependency mark pthread [no-]import` 58 | // toggle public : `mulle-sde dependency mark pthread [no-]public` 59 | // toggle optional : `mulle-sde dependency mark pthread [no-]require` 60 | // remove for platform : `mulle-sde dependency mark pthread no-platform-` 61 | // (use `mulle-sourcetree-to-c --unames` to list known values) 62 | # if ! defined( __ANDROID__) && ! defined( _WIN32) 63 | # ifdef __has_include 64 | # if __has_include() 65 | # include // pthread 66 | # define HAVE_LIB_PTHREAD 67 | # endif 68 | # endif 69 | #endif 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /src/reflect/_mulle-thread-provide.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file will be regenerated by `mulle-match-to-c` via 3 | * `mulle-sde reflect` and any edits will be lost. 4 | * Suppress generation of this file with: 5 | * 6 | * mulle-sde environment set MULLE_MATCH_TO_C_C_HEADERS_FILE DISABLE 7 | * 8 | * To not let mulle-match-to-c generate any header files: 9 | * 10 | * mulle-sde environment set MULLE_MATCH_TO_C_RUN DISABLE 11 | */ 12 | #ifndef _mulle__thread__provide_h__ 13 | #define _mulle__thread__provide_h__ 14 | 15 | 16 | #include "mulle-atomic-c11.h" 17 | #include "mulle-atomic.h" 18 | #include "mulle-atomic-mintomic.h" 19 | #include "mulle-thread-c11.h" 20 | #include "mulle-thread-pthreads.h" 21 | #include "mulle-thread-windows.h" 22 | 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/reflect/_mulle-thread-versioncheck.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file will be regenerated by `mulle-project-versioncheck`. 3 | * Any edits will be lost. 4 | */ 5 | #ifndef mulle_thread_versioncheck_h__ 6 | #define mulle_thread_versioncheck_h__ 7 | 8 | #if defined( MULLE__C11_VERSION) 9 | # ifndef MULLE__C11_VERSION_MIN 10 | # define MULLE__C11_VERSION_MIN ((4UL << 20) | (6 << 8) | 1) 11 | # endif 12 | # ifndef MULLE__C11_VERSION_MAX 13 | # define MULLE__C11_VERSION_MAX ((5UL << 20) | (0 << 8) | 0) 14 | # endif 15 | # if MULLE__C11_VERSION < MULLE__C11_VERSION_MIN || MULLE__C11_VERSION >= MULLE__C11_VERSION_MAX 16 | # pragma message("MULLE__C11_VERSION is " MULLE_C_STRINGIFY_MACRO( MULLE__C11_VERSION)) 17 | # pragma message("MULLE__C11_VERSION_MIN is " MULLE_C_STRINGIFY_MACRO( MULLE__C11_VERSION_MIN)) 18 | # pragma message("MULLE__C11_VERSION_MAX is " MULLE_C_STRINGIFY_MACRO( MULLE__C11_VERSION_MAX)) 19 | # if MULLE__C11_VERSION < MULLE__C11_VERSION_MIN 20 | # error "mulle-c11 is too old" 21 | # else 22 | # error "mulle-c11 is too new" 23 | # endif 24 | # endif 25 | #endif 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /test/.mulle-test/etc/environment.sh: -------------------------------------------------------------------------------- 1 | CFLAGS="-isystem `mulle-sde project-dir`/mintomic/include" 2 | -------------------------------------------------------------------------------- /test/.mulle/.gitignore: -------------------------------------------------------------------------------- 1 | var/ 2 | environment-host-*.sh 3 | !environment-host-ci-*.sh 4 | -------------------------------------------------------------------------------- /test/.mulle/README.md: -------------------------------------------------------------------------------- 1 | # .mulle 2 | 3 | This `.mulle` folder is used by [mulle-sde](//mulle-sde.github.io) to 4 | store project information. 5 | 6 | ## Structure 7 | 8 | * `etc` is user editable, changes will be preserved. 9 | * `share` is read only, changes will be lost on the next upgrade. 10 | * `var` is ephemeral. You can delete and it will get recreated. 11 | 12 | Every mulle-sde tool may have its own subfolder within those three folders. 13 | It's name will be the name of the tool without the "mulle-" prefix. 14 | 15 | You can edit the files in `etc` with any editor, but for consistency and 16 | ease of use, it's usually better to use the appropriate mulle-sde tool. 17 | 18 | ## Remove .mulle 19 | 20 | The share folder is often write protected, to prevent accidental user edits. 21 | 22 | ``` 23 | chmod -R ugo+rwX .mulle && rm -rf .mulle 24 | ``` 25 | 26 | -------------------------------------------------------------------------------- /test/.mulle/etc/env/auxscope: -------------------------------------------------------------------------------- 1 | project;20 2 | -------------------------------------------------------------------------------- /test/.mulle/etc/env/environment-global.sh: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # 4 | export MULLE_FETCH_SEARCH_PATH="${MULLE_FETCH_SEARCH_PATH}:${MULLE_VIRTUAL_ROOT}/../.." 5 | 6 | 7 | # 8 | # 9 | # 10 | export MULLE_TEST_FLAGS="--no-memory-checker" 11 | 12 | 13 | -------------------------------------------------------------------------------- /test/.mulle/etc/env/environment-host-ci-prerelease.sh: -------------------------------------------------------------------------------- 1 | # 2 | # mulle-thread nodetype: ${MULLE__THREAD_NODETYPE:-tar} 3 | # 4 | export MULLE__THREAD_NODETYPE="git" 5 | 6 | 7 | # 8 | # mulle-thread url: ${MULLE__THREAD_URL:-https://github.com/mulle-concurrent/mulle-thread/archive/${MULLE_TAG}.tar.gz} 9 | # 10 | export MULLE__THREAD_URL="https://github.com/mulle-concurrent/mulle-thread.git" 11 | 12 | 13 | # 14 | # mulle-thread branch: ${MULLE__THREAD_BRANCH} 15 | # 16 | export MULLE__THREAD_BRANCH="prerelease" 17 | 18 | 19 | # 20 | # mulle-c11 nodetype: ${MULLE__C11_NODETYPE:-tar} 21 | # 22 | export MULLE__C11_NODETYPE="git" 23 | 24 | 25 | # 26 | # mulle-c11 url: ${MULLE__C11_URL:-https://github.com/mulle-c/mulle-c11/archive/${MULLE_TAG}.tar.gz} 27 | # 28 | export MULLE__C11_URL="https://github.com/mulle-c/mulle-c11.git" 29 | 30 | 31 | # 32 | # mulle-c11 branch: ${MULLE__C11_BRANCH} 33 | # 34 | export MULLE__C11_BRANCH="prerelease" 35 | 36 | 37 | -------------------------------------------------------------------------------- /test/.mulle/etc/env/environment-project.sh: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # 4 | export PROJECT_NAME="mulle-thread" 5 | 6 | 7 | # 8 | # 9 | # 10 | export PROJECT_IDENTIFIER="mulle_thread" 11 | 12 | 13 | # 14 | # 15 | # 16 | export PROJECT_DOWNCASE_IDENTIFIER="mulle_thread" 17 | 18 | 19 | # 20 | # 21 | # 22 | export PROJECT_UPCASE_IDENTIFIER="MULLE_THREAD" 23 | 24 | 25 | # 26 | # 27 | # 28 | export PROJECT_TYPE="none" 29 | 30 | 31 | # 32 | # 33 | # 34 | export PROJECT_LANGUAGE="c" 35 | 36 | 37 | # 38 | # 39 | # 40 | export PROJECT_DIALECT="c" 41 | 42 | 43 | # 44 | # 45 | # 46 | export PROJECT_EXTENSIONS="c" 47 | 48 | 49 | -------------------------------------------------------------------------------- /test/.mulle/etc/sourcetree/config: -------------------------------------------------------------------------------- 1 | mulle-thread;${MULLE__THREAD_NODETYPE:-tar};no-all-load,no-import;85E1D35A-F5D7-45D4-AC2C-1F737CB49626;${MULLE__THREAD_URL:-https://github.com/mulle-concurrent/mulle-thread/archive/${MULLE_TAG}.tar.gz};${MULLE__THREAD_BRANCH};${MULLE__THREAD_TAG:-latest};; 2 | -------------------------------------------------------------------------------- /test/.mulle/share/env/auxscope: -------------------------------------------------------------------------------- 1 | extension;30 2 | post-extension;210 3 | -------------------------------------------------------------------------------- /test/.mulle/share/env/environment-plugin-os-darwin.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Git mirror and Zip/TGZ cache to conserve bandwidth 3 | # 4 | export MULLE_FETCH_MIRROR_DIR="${HOME:-/tmp}/Library/Caches/mulle-fetch/git-mirror" 5 | 6 | # 7 | # Git mirror and Zip/TGZ cache to conserve bandwidth 8 | # 9 | export MULLE_FETCH_ARCHIVE_DIR="${HOME:-/tmp}/Library/Caches/mulle-fetch/archive" 10 | -------------------------------------------------------------------------------- /test/.mulle/share/env/environment-plugin.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Git mirror and Zip/TGZ cache to conserve bandwidth 3 | # Memo: Will often be overridden in an os-specific environment file 4 | # Can be overridden with -DMULLE_FETCH_ARCHIVE_DIR on the commandline 5 | # 6 | export MULLE_FETCH_MIRROR_DIR="${HOME:-/tmp}/.cache/mulle-fetch/git-mirror" 7 | 8 | # 9 | # Git mirror and Zip/TGZ cache to conserve bandwidth 10 | # 11 | export MULLE_FETCH_ARCHIVE_DIR="${HOME:-/tmp}/.cache/mulle-fetch/archive" 12 | 13 | # 14 | # PATH to search for git repositories locally. 15 | # 16 | export MULLE_FETCH_SEARCH_PATH="${MULLE_VIRTUAL_ROOT}/.." 17 | 18 | # 19 | # Prefer symlinks to clones of git repos found in MULLE_FETCH_SEARCH_PATH 20 | # 21 | export MULLE_SOURCETREE_SYMLINK='YES' 22 | # 23 | # 24 | # 25 | export MULLE_SDE_INSTALLED_VERSION="3.4.2" 26 | 27 | 28 | -------------------------------------------------------------------------------- /test/.mulle/share/env/environment.sh: -------------------------------------------------------------------------------- 1 | ####### 2 | ### none startup 3 | ####### 4 | [ "${TRACE}" = 'YES' -o "${ENVIRONMENT_SH_TRACE}" = 'YES' ] && set -x && : "$0" "$@" 5 | 6 | # 7 | # If mulle-env is broken, sometimes its nice just to source this file. 8 | # If you're sourcing this manually on a regular basis, you're doing it wrong. 9 | # 10 | if [ -z "${MULLE_VIRTUAL_ROOT}" ] 11 | then 12 | MULLE_VIRTUAL_ROOT="`PATH=/bin:/usr/bin pwd -P`" 13 | echo "Using ${MULLE_VIRTUAL_ROOT} as MULLE_VIRTUAL_ROOT for \ 14 | your convenience" >&2 15 | fi 16 | 17 | if [ -z "${MULLE_UNAME}" ] 18 | then 19 | MULLE_UNAME="`PATH=/bin:/usr/bin uname -s 2> /dev/null | tr '[:upper:]' '[:lower:]'`" 20 | MULLE_UNAME="${MULLE_UNAME:-unknown}" 21 | echo "Using ${MULLE_UNAME} as MULLE_UNAME for your convenience" >&2 22 | fi 23 | 24 | # 25 | # now read in custom envionment (required) 26 | # 27 | . "${MULLE_VIRTUAL_ROOT}/.mulle/share/env/include-environment.sh" 28 | 29 | # 30 | # basic setup for interactive shells 31 | # 32 | case "${MULLE_SHELL_MODE}" in 33 | *INTERACTIVE*) 34 | # 35 | # Set PS1 so that we can see, that we are in a mulle-env 36 | # 37 | envname="`PATH=/bin:/usr/bin basename -- "${MULLE_VIRTUAL_ROOT}"`" 38 | 39 | case "${PS1}" in 40 | *\\h\[*) 41 | ;; 42 | 43 | *\\h*) 44 | PS1="$( PATH=/bin:/usr/bin sed 's/\\h/\\h\['${envname}'\]/' <<< "${PS1}" )" 45 | ;; 46 | 47 | *) 48 | PS1='\u@\h['${envname}'] \W$ ' 49 | ;; 50 | esac 51 | export PS1 52 | 53 | unset envname 54 | 55 | # install cd catcher 56 | if [ ! -z "${MULLE_ENV_LIBEXEC_DIR}" ] 57 | then 58 | . "${MULLE_ENV_LIBEXEC_DIR}/mulle-env-cd.sh" 59 | unset MULLE_ENV_LIBEXEC_DIR 60 | fi 61 | 62 | # install mulle-env-reload 63 | 64 | alias mulle-env-reload='. "${MULLE_VIRTUAL_ROOT}/.mulle/share/env/include-environment.sh"' 65 | 66 | # 67 | # source in any bash completion files 68 | # 69 | # memo: nullglob not easily done on both bash and zsh 70 | for filename in "${MULLE_VIRTUAL_ROOT}/.mulle/share/env/libexec"/*-bash-completion.sh 71 | do 72 | if [ -f "${filename}" ] 73 | then 74 | . "${filename}" 75 | fi 76 | done 77 | 78 | unset filename 79 | 80 | vardir="${MULLE_VIRTUAL_ROOT}/.mulle/var/${MULLE_HOSTNAME:-unknown-host}" 81 | [ -d "${vardir}" ] || PATH=/bin:/usr/bin mkdir -p "${vardir}" 82 | 83 | HISTFILE="${vardir}/bash_history" 84 | export HISTFILE 85 | 86 | unset vardir 87 | 88 | # 89 | # show motd, if any 90 | # 91 | if [ -z "${NO_MOTD}" ] 92 | then 93 | if [ -f "${MULLE_VIRTUAL_ROOT}/.mulle/etc/env/motd" ] 94 | then 95 | cat "${MULLE_VIRTUAL_ROOT}/.mulle/etc/env/motd" 96 | else 97 | if [ -f "${MULLE_VIRTUAL_ROOT}/.mulle/share/env/motd" ] 98 | then 99 | cat "${MULLE_VIRTUAL_ROOT}/.mulle/share/env/motd" 100 | fi 101 | fi 102 | fi 103 | ;; 104 | esac 105 | 106 | # remove some uglies 107 | unset NO_MOTD 108 | unset TRACE 109 | 110 | ####### 111 | ### mulle startup 112 | ####### 113 | 114 | case "${MULLE_SHELL_MODE}" in 115 | *INTERACTIVE*) 116 | if [ -z "${MULLE_SDE_NO_ALIAS}" ] 117 | then 118 | alias clean="mulle-sde clean" 119 | alias craft="mulle-sde craft" 120 | alias craftorder="mulle-sde craftorder" 121 | alias dependency="mulle-sde dependency" 122 | alias environment="mulle-sde environment" 123 | alias extension="mulle-sde extension" 124 | alias fetch="mulle-sde fetch" 125 | alias library="mulle-sde library" 126 | alias list="mulle-sde list" 127 | alias log="mulle-sde log" 128 | alias match="mulle-sde match" 129 | alias monitor="mulle-sde monitor" 130 | alias patternfile="mulle-sde patternfile" 131 | alias reflect="mulle-sde reflect" 132 | alias run="mulle-sde run" 133 | alias show="mulle-sde show" 134 | alias subproject="mulle-sde subproject" 135 | fi 136 | 137 | if [ -z "${MULLE_SDE_NO_QUICK_ALIAS}" ] 138 | then 139 | alias C="mulle-sde clean; mulle-sde craft" 140 | alias c="mulle-sde craft" 141 | alias CC="mulle-sde clean all; mulle-sde craft" 142 | alias l="mulle-sde list --files" 143 | alias r="mulle-sde reflect" 144 | alias T="mulle-sde test craft ; mulle-sde test" 145 | alias t="mulle-sde test rerun --serial" 146 | alias TT="mulle-sde test clean all; mulle-sde test" 147 | alias tt="mulle-sde test craft ; mulle-sde test rerun --serial" 148 | fi 149 | ;; 150 | esac 151 | -------------------------------------------------------------------------------- /test/.mulle/share/env/include-environment.sh: -------------------------------------------------------------------------------- 1 | [ -z "${MULLE_VIRTUAL_ROOT}" -o -z "${MULLE_UNAME}" ] && \ 2 | echo "Your script needs to setup MULLE_VIRTUAL_ROOT \ 3 | and MULLE_UNAME properly" >&2 && exit 1 4 | 5 | MULLE_ENV_SHARE_DIR="${MULLE_VIRTUAL_ROOT}/.mulle/share/env" 6 | MULLE_ENV_ETC_DIR="${MULLE_VIRTUAL_ROOT}/.mulle/etc/env" 7 | # Top/down order of inclusion. 8 | # Keep these files (except environment-custom.sh) clean off manual edits so 9 | # that mulle-env can read and set environment variables. 10 | # 11 | # .mulle/etc/env | .mulle/share/env 12 | # --------------------------------------|-------------------- 13 | # | environment-plugin.sh 14 | # | environment-plugin-os-${MULLE_UNAME}.sh 15 | # environment-project.sh | 16 | # environment-global.sh | 17 | # environment-os-${MULLE_UNAME}.sh | 18 | # environment-host-${MULLE_HOSTNAME}.sh | 19 | # environment-user-${MULLE_USERNAME}.sh | 20 | # environment-custom.sh | 21 | # environment-post-global.sh | 22 | # 23 | scopes="s:plugin;5 24 | s:plugin-os-${MULLE_UNAME};15 25 | e:global;40 26 | e:os-${MULLE_UNAME};60 27 | e:host-${MULLE_HOSTNAME};80 28 | e:user-${MULLE_USERNAME};100 29 | e:user-${MULLE_USERNAME}-os-${MULLE_UNAME};120 30 | e:user-${MULLE_USERNAME}-host-${MULLE_HOSTNAME};140 31 | e:custom;1000 32 | e:post-global;2000" 33 | 34 | if [ -f "${MULLE_ENV_ETC_DIR}/auxscope" ] 35 | then 36 | auxscopes="`PATH=/bin:/usr/bin sed -e 's/^/e:/' \ 37 | -e "s/\${MULLE_UNAME}/${MULLE_UNAME}/" \ 38 | -e "s/\${MULLE_HOSTNAME}/${MULLE_HOSTNAME}/" \ 39 | -e "s/\${MULLE_USERNAME}/${MULLE_USERNAME}/" \ 40 | "${MULLE_ENV_ETC_DIR}/auxscope"`" 41 | scopes="${scopes}"$'\n'"${auxscopes}" 42 | fi 43 | 44 | if [ -f "${MULLE_ENV_SHARE_DIR}/auxscope" ] 45 | then 46 | auxscopes="`PATH=/bin:/usr/bin sed -e 's/^/s:/' \ 47 | -e "s/\${MULLE_UNAME}/${MULLE_UNAME}/" \ 48 | -e "s/\${MULLE_HOSTNAME}/${MULLE_HOSTNAME}/" \ 49 | -e "s/\${MULLE_USERNAME}/${MULLE_USERNAME}/" \ 50 | "${MULLE_ENV_SHARE_DIR}/auxscope"`" 51 | scopes="${scopes}"$'\n'"${auxscopes}" 52 | fi 53 | 54 | # 55 | # Load scopes according to priority now 56 | # put in local var for crazy old bashes 57 | # 58 | prioscopes=`printf "%s\n" "${scopes}" \ 59 | | PATH=/bin:/usr/bin sort -t';' -k2n -k1 \ 60 | | PATH=/bin:/usr/bin sed -n -e 's/\(.*\);.*$/\1/p'` 61 | 62 | for scope in ${prioscopes} 63 | do 64 | case "${scope}" in 65 | e:*) 66 | includefile="${MULLE_ENV_ETC_DIR}/environment-${scope#?:}.sh" 67 | ;; 68 | 69 | s:*) 70 | includefile="${MULLE_ENV_SHARE_DIR}/environment-${scope#?:}.sh" 71 | ;; 72 | 73 | *) 74 | continue; 75 | ;; 76 | esac 77 | 78 | if [ -f "${includefile}" ] 79 | then 80 | . "${includefile}" 81 | fi 82 | done 83 | 84 | unset scope 85 | unset scopes 86 | unset auxscopes 87 | unset includefile 88 | 89 | unset MULLE_ENV_ETC_DIR 90 | unset MULLE_ENV_SHARE_DIR 91 | -------------------------------------------------------------------------------- /test/.mulle/share/env/style: -------------------------------------------------------------------------------- 1 | mulle/wild 2 | -------------------------------------------------------------------------------- /test/.mulle/share/env/tool-plugin: -------------------------------------------------------------------------------- 1 | autoconf 2 | autoreconf 3 | awk;required 4 | base64 5 | basename;required 6 | bash 7 | bash;optional 8 | cat;required 9 | chgrp;required 10 | chmod;required 11 | chown;required 12 | clear 13 | column 14 | cp;required 15 | curl 16 | cut;required 17 | date;required 18 | dd 19 | df 20 | dirname;required 21 | dmesg 22 | echo;required 23 | ed 24 | egrep 25 | emacs 26 | env;required 27 | expr;required 28 | false;required 29 | fgrep 30 | file 31 | find;required 32 | grep;required 33 | head;required 34 | hostname 35 | kill;required 36 | less 37 | ln;required 38 | login 39 | ls;required 40 | make 41 | meson 42 | mkdir;required 43 | mknod 44 | more 45 | mount 46 | mulle-column 47 | mv;required 48 | nano 49 | ninja 50 | ps 51 | pwd;required 52 | readlink;required 53 | rmdir;required 54 | rm;required 55 | sed;required 56 | shasum 57 | sh;required 58 | sleep;required 59 | sort;required 60 | stat;required 61 | stty 62 | su 63 | sw_vers 64 | sync 65 | sysctl 66 | tail;required 67 | tee;required 68 | test;required 69 | touch;required 70 | tree 71 | tr;required 72 | true;required 73 | tty 74 | umount 75 | uname;required 76 | uptime 77 | uuidgen 78 | vi 79 | wc;required 80 | wget 81 | which;required 82 | xargs 83 | xcodebuild 84 | xcrun 85 | zsh 86 | zsh;optional 87 | -------------------------------------------------------------------------------- /test/.mulle/share/env/version: -------------------------------------------------------------------------------- 1 | 5.4.2 2 | -------------------------------------------------------------------------------- /test/.mulle/share/sde/extension: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/.mulle/share/test/mulle-test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mulle-concurrent/mulle-thread/88b330b1290839b8133601416289f8563b6d855a/test/.mulle/share/test/mulle-test -------------------------------------------------------------------------------- /test/atomic/README.md: -------------------------------------------------------------------------------- 1 | I had bench.c fail on me occasionally, with: 2 | 3 | ``` 4 | better-cas is slower than read-cas, which is faster than double-cas | better-cas is faster than read-cas, which is faster than double-cas 5 | ``` 6 | 7 | because this is extremely rare, I still think that better-cas is better. 8 | If this changes on a platform we gotta ifdef around, so that read-cas 9 | becomes better-cas. 10 | -------------------------------------------------------------------------------- /test/atomic/bench.stdout: -------------------------------------------------------------------------------- 1 | better-cas is faster than read-cas, which is faster than double-cas 2 | -------------------------------------------------------------------------------- /test/atomic/default.stdout: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 6 | 6 7 | 7 8 | 8 9 | 9 10 | 10 11 | 11 12 | 12 13 | 13 14 | 14 15 | 15 16 | 16 17 | 17 18 | 18 19 | 19 20 | 20 21 | 21 22 | 22 23 | 23 24 | 24 25 | 25 26 | 26 27 | 27 28 | 28 29 | 29 30 | 30 31 | 31 32 | 32 33 | 33 34 | 34 35 | 35 36 | 36 37 | 37 38 | 38 39 | 39 40 | 40 41 | 41 42 | 42 43 | 43 44 | 44 45 | 45 46 | 46 47 | 47 48 | 48 49 | 49 50 | 50 51 | 51 52 | 52 53 | 53 54 | 54 55 | 55 56 | 56 57 | 57 58 | 58 59 | 59 60 | 60 61 | 61 62 | 62 63 | 63 64 | 64 65 | 65 66 | 66 67 | 67 68 | 68 69 | 69 70 | 70 71 | 71 72 | 72 73 | 73 74 | 74 75 | 75 76 | 76 77 | 77 78 | 78 79 | 79 80 | 80 81 | 81 82 | 82 83 | 83 84 | 84 85 | 85 86 | 86 87 | 87 88 | 88 89 | 89 90 | 90 91 | 91 92 | 92 93 | 93 94 | 94 95 | 95 96 | 96 97 | 97 98 | 98 99 | 99 100 | 100 101 | -------------------------------------------------------------------------------- /test/mutex/mutex-do.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | int main( void) 6 | { 7 | mulle_thread_mutex_t lock; 8 | int rval; 9 | 10 | printf( "init\n"); 11 | if( mulle_thread_mutex_init( &lock)) 12 | return( 1); 13 | 14 | printf( "do\n"); 15 | mulle_thread_mutex_do( lock) 16 | { 17 | printf( "trylock\n"); 18 | rval = mulle_thread_mutex_trylock( &lock); 19 | if( rval == 0) 20 | { 21 | printf( "mistake\n"); 22 | return( 2); 23 | } 24 | 25 | if( rval != EBUSY) 26 | { 27 | printf( "unexpected %d\n", rval); 28 | return( 3); 29 | } 30 | } 31 | 32 | printf( "trylock\n"); 33 | rval = mulle_thread_mutex_trylock( &lock); 34 | 35 | 36 | if( rval == EBUSY) 37 | return( 1); 38 | 39 | if( rval) 40 | { 41 | printf( "unexpected = %d\n", rval); 42 | return( 3); 43 | } 44 | 45 | printf( "unlock\n"); 46 | if( mulle_thread_mutex_unlock( &lock)) 47 | return( 1); 48 | 49 | printf( "done\n"); 50 | if( mulle_thread_mutex_done( &lock)) 51 | return( 1); 52 | 53 | return( 0); 54 | } 55 | -------------------------------------------------------------------------------- /test/mutex/mutex-do.stdout: -------------------------------------------------------------------------------- 1 | init 2 | do 3 | trylock 4 | trylock 5 | unlock 6 | done 7 | -------------------------------------------------------------------------------- /test/mutex/mutex-stress.c: -------------------------------------------------------------------------------- 1 | // 2 | // main.c 3 | // test-atomic 4 | // 5 | // Created by Nat! on 19.03.15. 6 | // Copyright (c) 2015 Mulle kybernetiK. All rights reserved. 7 | // 8 | // Redistributions of source code must retain the above copyright notice, this 9 | // list of conditions and the following disclaimer. 10 | // 11 | // Redistributions in binary form must reproduce the above copyright notice, 12 | // this list of conditions and the following disclaimer in the documentation 13 | // and/or other materials provided with the distribution. 14 | // 15 | // Neither the name of Mulle kybernetiK nor the names of its contributors 16 | // may be used to endorse or promote products derived from this software 17 | // without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | // POSSIBILITY OF SUCH DAMAGE. 30 | // 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | 39 | #define PROGRESS 0 40 | #define MAX_ITERATIONS 100 41 | #define LOOPS 1000 42 | #define MAX_THREADS 4 43 | 44 | 45 | 46 | struct 47 | { 48 | unsigned long values[ 2]; 49 | mulle_thread_mutex_t lock; 50 | } central = 51 | { 52 | 0, 53 | 1 54 | }; 55 | 56 | #pragma mark - run test 57 | 58 | static void multi_threaded_test_each_thread( void) 59 | { 60 | unsigned long i; 61 | void *value; 62 | void *expect; 63 | 64 | for( i = 0; i < LOOPS; i++) 65 | { 66 | mulle_thread_mutex_lock( ¢ral.lock); 67 | 68 | if( central.values[ 0] != central.values[ 1] - 1) 69 | abort(); 70 | 71 | central.values[ 0]++; 72 | MULLE_THREAD_UNPLEASANT_RACE_YIELD(); 73 | central.values[ 1] = central.values[ 0] + 1; 74 | 75 | mulle_thread_mutex_unlock( ¢ral.lock); 76 | } 77 | } 78 | 79 | 80 | static void _wait_around( mulle_atomic_pointer_t *n_threads) 81 | { 82 | // wait for all threads to materialize 83 | _mulle_atomic_pointer_decrement( n_threads); 84 | while( _mulle_atomic_pointer_read( n_threads) != 0) 85 | mulle_thread_yield(); 86 | } 87 | 88 | 89 | struct thread_info 90 | { 91 | mulle_atomic_pointer_t *n_threads; 92 | }; 93 | 94 | 95 | static mulle_thread_rval_t run_test( struct thread_info *info) 96 | { 97 | _wait_around( info->n_threads); 98 | multi_threaded_test_each_thread(); 99 | 100 | return( 0); 101 | } 102 | 103 | 104 | void multi_threaded_test( intptr_t n) 105 | { 106 | int i; 107 | mulle_atomic_pointer_t n_threads; 108 | mulle_thread_t *threads; 109 | struct thread_info *info; 110 | 111 | threads = alloca( n * sizeof( mulle_thread_t)); 112 | assert( threads); 113 | 114 | _mulle_atomic_pointer_nonatomic_write( &n_threads, (void *) n); 115 | 116 | info = alloca( sizeof( struct thread_info) * n); 117 | 118 | for( i = 1; i < n; i++) 119 | { 120 | info[ i].n_threads = &n_threads; 121 | if( mulle_thread_create( (void *) run_test, &info[ i], &threads[ i])) 122 | abort(); 123 | } 124 | 125 | info[ 0].n_threads = &n_threads; 126 | run_test( &info[ 0]); 127 | 128 | for( i = 1; i < n; i++) 129 | if( mulle_thread_join( threads[ i])) 130 | { 131 | perror( "mulle_thread_join"); 132 | abort(); 133 | } 134 | } 135 | 136 | 137 | 138 | #ifdef __APPLE__ 139 | #include 140 | 141 | MULLE_C_CONSTRUCTOR(__enable_core_dumps) 142 | static void __enable_core_dumps(void) 143 | { 144 | struct rlimit limit; 145 | 146 | limit.rlim_cur = RLIM_INFINITY; 147 | limit.rlim_max = RLIM_INFINITY; 148 | setrlimit(RLIMIT_CORE, &limit); 149 | } 150 | #endif 151 | 152 | 153 | int main(int argc, const char * argv[]) 154 | { 155 | unsigned long i; 156 | unsigned int j; 157 | int rval; 158 | 159 | // srand( (unsigned int) time( NULL)); 160 | 161 | mulle_thread_mutex_init( ¢ral.lock); 162 | for( i = 1; i <= MAX_ITERATIONS; i++) 163 | { 164 | for( j = 1; j <= MAX_THREADS; j += j) 165 | { 166 | multi_threaded_test( j); 167 | } 168 | printf( "%ld\n", i); 169 | } 170 | mulle_thread_mutex_done( ¢ral.lock); 171 | return( 0); 172 | } 173 | 174 | -------------------------------------------------------------------------------- /test/mutex/mutex-stress.stdout: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 6 | 6 7 | 7 8 | 8 9 | 9 10 | 10 11 | 11 12 | 12 13 | 13 14 | 14 15 | 15 16 | 16 17 | 17 18 | 18 19 | 19 20 | 20 21 | 21 22 | 22 23 | 23 24 | 24 25 | 25 26 | 26 27 | 27 28 | 28 29 | 29 30 | 30 31 | 31 32 | 32 33 | 33 34 | 34 35 | 35 36 | 36 37 | 37 38 | 38 39 | 39 40 | 40 41 | 41 42 | 42 43 | 43 44 | 44 45 | 45 46 | 46 47 | 47 48 | 48 49 | 49 50 | 50 51 | 51 52 | 52 53 | 53 54 | 54 55 | 55 56 | 56 57 | 57 58 | 58 59 | 59 60 | 60 61 | 61 62 | 62 63 | 63 64 | 64 65 | 65 66 | 66 67 | 67 68 | 68 69 | 69 70 | 70 71 | 71 72 | 72 73 | 73 74 | 74 75 | 75 76 | 76 77 | 77 78 | 78 79 | 79 80 | 80 81 | 81 82 | 82 83 | 83 84 | 84 85 | 85 86 | 86 87 | 87 88 | 88 89 | 89 90 | 90 91 | 91 92 | 92 93 | 93 94 | 94 95 | 95 96 | 96 97 | 97 98 | 98 99 | 99 100 | 100 101 | -------------------------------------------------------------------------------- /test/mutex/mutex.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | int main( void) 6 | { 7 | mulle_thread_mutex_t lock; 8 | int rval; 9 | 10 | printf( "init\n"); 11 | if( mulle_thread_mutex_init( &lock)) 12 | return( 1); 13 | 14 | printf( "lock\n"); 15 | if( mulle_thread_mutex_lock( &lock)) 16 | return( 1); 17 | 18 | printf( "trylock\n"); 19 | rval = mulle_thread_mutex_trylock( &lock); 20 | if( ! rval) 21 | { 22 | printf( "mistake\n"); 23 | return( 2); 24 | } 25 | 26 | if( rval != EBUSY) 27 | return( 1); 28 | 29 | printf( "unlock\n"); 30 | if( mulle_thread_mutex_unlock( &lock)) 31 | return( 1); 32 | 33 | printf( "trylock\n"); 34 | rval = mulle_thread_mutex_trylock( &lock); 35 | if( rval == EBUSY) 36 | { 37 | printf( "mistake\n"); 38 | return( 2); 39 | } 40 | 41 | if( rval) 42 | return( 1); 43 | 44 | printf( "unlock\n"); 45 | if( mulle_thread_mutex_unlock( &lock)) 46 | return( 1); 47 | 48 | printf( "done\n"); 49 | if( mulle_thread_mutex_done( &lock)) 50 | return( 1); 51 | 52 | return( 0); 53 | } 54 | -------------------------------------------------------------------------------- /test/mutex/mutex.stdout: -------------------------------------------------------------------------------- 1 | init 2 | lock 3 | trylock 4 | unlock 5 | trylock 6 | unlock 7 | done 8 | -------------------------------------------------------------------------------- /test/threads/threads.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | static mulle_thread_rval_t thread_main( void *arg) 6 | { 7 | if( arg != (void *) 0x1847) 8 | printf( "mistaken arg\n"); 9 | 10 | printf( "thread done\n"); 11 | return( (mulle_thread_rval_t) 1848); 12 | } 13 | 14 | 15 | // 16 | // destruktor doesn't run in current thread, which is not neccessarily a 17 | // pthread (?) 18 | // 19 | // parameters different to pthreads! 20 | 21 | static void call_me_once( void) 22 | { 23 | printf( "thread once\n"); 24 | } 25 | 26 | 27 | int main( void) 28 | { 29 | mulle_thread_t thread; 30 | mulle_thread_rval_t rval; 31 | 32 | // stupid fix for stupid compilers 33 | #if MULLE_THREAD_ONCE_DATA 34 | static mulle_thread_once_t once = MULLE_THREAD_ONCE_DATA; 35 | #else 36 | static mulle_thread_once_t once; 37 | #endif 38 | mulle_thread_once( &once, call_me_once); 39 | mulle_thread_once( &once, call_me_once); 40 | 41 | printf( "thread start\n"); 42 | if( mulle_thread_create( thread_main, (void *) 0x1847, &thread)) 43 | return( 1); 44 | rval = mulle_thread_join( thread); 45 | if( rval == (mulle_thread_rval_t) -1) 46 | return( 1); 47 | if( rval != (mulle_thread_rval_t) 1848) 48 | { 49 | printf( "wrong return value\n"); 50 | return( 1); 51 | } 52 | 53 | printf( "thread joined\n"); 54 | 55 | return( 0); 56 | } 57 | -------------------------------------------------------------------------------- /test/threads/threads.stdout: -------------------------------------------------------------------------------- 1 | thread once 2 | thread start 3 | thread done 4 | thread joined 5 | -------------------------------------------------------------------------------- /test/tss/tss.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | static char *shared_value = "VfL Bochum 1848"; 6 | static char *shared_value2 = "VfL Bochum"; 7 | static mulle_thread_tss_t key; 8 | 9 | 10 | static void destruktor( void *p) 11 | { 12 | if( p != shared_value2) 13 | printf( "destruktor fail\n"); 14 | else 15 | printf( "destruktor\n"); 16 | } 17 | 18 | 19 | static mulle_thread_rval_t thread_main( void *arg) 20 | { 21 | // destruktor may only run if tss has been set in current thread 22 | printf( "thread set\n"); 23 | if( mulle_thread_tss_set( key, shared_value2)) 24 | mulle_thread_exit( 1); 25 | 26 | mulle_thread_exit( 0); 27 | mulle_thread_return(); 28 | } 29 | 30 | 31 | // 32 | // destruktor doesn't run in current thread, which is not neccessarily a 33 | // pthread (?) 34 | // 35 | int main( int argc, char *argv[]) 36 | { 37 | mulle_thread_t thread; 38 | 39 | printf( "create\n"); 40 | if( mulle_thread_tss_create( destruktor, &key)) 41 | return( 1); 42 | 43 | printf( "get empty\n"); 44 | if( mulle_thread_tss_get( key)) 45 | return( 1); 46 | 47 | printf( "set\n"); 48 | if( mulle_thread_tss_set( key, shared_value)) 49 | return( 1); 50 | 51 | printf( "get\n"); 52 | if( mulle_thread_tss_get( key) != shared_value) 53 | return( 1); 54 | 55 | printf( "thread start\n"); 56 | if( mulle_thread_create( thread_main, NULL, &thread)) 57 | return( 1); 58 | if( mulle_thread_join( thread)) 59 | return( 1); 60 | 61 | return( 0); 62 | } 63 | -------------------------------------------------------------------------------- /test/tss/tss.stdout: -------------------------------------------------------------------------------- 1 | create 2 | get empty 3 | set 4 | get 5 | thread start 6 | thread set 7 | destruktor 8 | --------------------------------------------------------------------------------