├── .github └── workflows │ ├── flic-button.yml │ └── package.yml ├── .travis.yml.bak ├── .travis ├── install.sh └── run.sh ├── Jenkinsfile ├── README.md ├── appveyor.yml ├── azure-pipelines.yml ├── build.py ├── conanfile.py ├── test_package ├── CMakeLists.txt ├── conanfile.py └── example.c └── zengithub ├── CMakeLists.txt ├── zengithub.c └── zengithub.h /.github/workflows/flic-button.yml: -------------------------------------------------------------------------------- 1 | name: React on flic button 2 | on: [repository_dispatch] 3 | 4 | jobs: 5 | react-on-flic-button: 6 | runs-on: ubuntu-latest 7 | if: startsWith(github.event.action, 'flic') 8 | steps: 9 | - name: Hold - Merge pull request 10 | if: github.event.action == 'flic-hold' 11 | uses: actions/github-script@0.5.0 12 | with: 13 | github-token: ${{secrets.GITHUB_TOKEN}} 14 | script: | 15 | github.pulls.merge({ 16 | pull_number: 31, 17 | owner: context.repo.owner, 18 | repo: context.repo.repo, 19 | }) 20 | -------------------------------------------------------------------------------- /.github/workflows/package.yml: -------------------------------------------------------------------------------- 1 | name: Test libzengithub package on main platforms 2 | on: [push] 3 | jobs: 4 | test: 5 | strategy: 6 | fail-fast: false 7 | matrix: 8 | os: [macOS-10.15, windows-2019, ubuntu-16.04, ubuntu-20.04, ARM, ARM64] 9 | include: 10 | - os: ubuntu-16.04 11 | python-arch: "x64" 12 | python-version: "3.6.x" 13 | install-headerfiles: true 14 | prepare-python: true 15 | gcc-version: "5" 16 | - os: ubuntu-20.04 17 | python-arch: "x64" 18 | python-version: "3.6.x" 19 | install-headerfiles: true 20 | prepare-python: true 21 | gcc-version: "9" 22 | - os: macOS-10.15 23 | python-arch: "x64" 24 | python-version: "3.6.x" 25 | install-headerfiles: false 26 | prepare-python: true 27 | - os: windows-2019 28 | vs-version: 16 29 | python-arch: "x86" 30 | python-version: "3.6.x" 31 | install-headerfiles: false 32 | prepare-python: true 33 | - os: ARM 34 | python-arch: "armv7" 35 | python-version: "3.6.x" 36 | install-headerfiles: false 37 | prepare-python: false 38 | gcc-version: "8" 39 | - os: ARM64 40 | python-arch: "armv8" 41 | python-version: "3.6.x" 42 | install-headerfiles: false 43 | prepare-python: false 44 | gcc-version: "8" 45 | 46 | runs-on: ${{ matrix.os }} 47 | steps: 48 | - uses: actions/checkout@master 49 | - name: Set up Python ${{ matrix.python-version }} 50 | uses: actions/setup-python@v1 51 | with: 52 | python-version: ${{ matrix.python-version }} 53 | architecture: ${{ matrix.python-arch }} 54 | if: matrix.prepare-python 55 | - name: Install C and C++ header files 56 | run: | 57 | sudo apt-get update && sudo apt-get install -y gcc-multilib g++-multilib 58 | if: matrix.install-headerfiles 59 | - name: Install conan && conan package tools 60 | run: | 61 | python3 -m pip install --upgrade pip 62 | pip3 install conan 63 | pip3 install conan_package_tools 64 | - name: ARM hotfix 65 | run: | 66 | conan remove "ZenGitHub*" --builds --force 67 | conan remove "ZenGitHub*" --packages --force 68 | conan remove "ZenGitHub*" --src --force 69 | conan remove "ZenGitHub*" --force 70 | echo "CONAN_ARCHS=${{ matrix.python-arch }}" >> $GITHUB_ENV 71 | if: startsWith(matrix.python-arch, 'arm') 72 | - name: Generating conan user directory and building the solution 73 | run: | 74 | conan user 75 | python3 build.py 76 | env: 77 | CONAN_REFERENCE: "ZenGitHub/1.0" 78 | CONAN_USERNAME: "jonico" 79 | CONAN_PASSWORD: ${{ secrets.CONAN_PASSWORD }} 80 | CONAN_LOGIN_USERNAME: "jonico@github.com" 81 | CONAN_CHANNEL: "stable" 82 | CONAN_UPLOAD: "https://jonico.jfrog.io/artifactory/api/conan/libzengithub-conan-local" 83 | CONAN_STABLE_BRANCH_PATTERN: "release/*" 84 | CONAN_VISUAL_VERSIONS: ${{ matrix.vs-version }} 85 | CONAN_APPLE_CLANG_VERSIONS: "12.0" 86 | CONAN_GCC_VERSIONS: ${{ matrix.gcc-version }} 87 | CONAN_PIP_COMMAND: pip3 88 | -------------------------------------------------------------------------------- /.travis.yml.bak: -------------------------------------------------------------------------------- 1 | 2 | env: 3 | global: 4 | - CONAN_REFERENCE: "ZenGitHub/1.0" 5 | - CONAN_USERNAME: "jonico" 6 | - CONAN_LOGIN_USERNAME: "jonico" 7 | - CONAN_CHANNEL: "testing" 8 | - CONAN_UPLOAD: "https://api.bintray.com/conan/conan-jonico/libzengithub" 9 | - CONAN_STABLE_BRANCH_PATTERN: "release/*" 10 | 11 | linux: &linux 12 | os: linux 13 | sudo: required 14 | language: python 15 | python: "3.6" 16 | services: 17 | - docker 18 | osx: &osx 19 | os: osx 20 | language: generic 21 | matrix: 22 | include: 23 | 24 | - <<: *linux 25 | env: CONAN_GCC_VERSIONS=4.9 CONAN_DOCKER_IMAGE=lasote/conangcc49 26 | - <<: *linux 27 | env: CONAN_GCC_VERSIONS=5 CONAN_DOCKER_IMAGE=lasote/conangcc5 28 | - <<: *linux 29 | env: CONAN_GCC_VERSIONS=6 CONAN_DOCKER_IMAGE=lasote/conangcc6 30 | - <<: *linux 31 | env: CONAN_GCC_VERSIONS=7 CONAN_DOCKER_IMAGE=lasote/conangcc7 32 | - <<: *osx 33 | osx_image: xcode7.3 34 | env: CONAN_APPLE_CLANG_VERSIONS=7.3 35 | - <<: *osx 36 | osx_image: xcode8.3 37 | env: CONAN_APPLE_CLANG_VERSIONS=8.1 38 | - <<: *osx 39 | osx_image: xcode9.2 40 | env: CONAN_APPLE_CLANG_VERSIONS=9.0 41 | 42 | install: 43 | - chmod +x .travis/install.sh 44 | - ./.travis/install.sh 45 | 46 | script: 47 | - chmod +x .travis/run.sh 48 | - ./.travis/run.sh 49 | -------------------------------------------------------------------------------- /.travis/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -x 5 | 6 | if [[ "$(uname -s)" == 'Darwin' ]]; then 7 | brew update || brew update 8 | brew outdated pyenv || brew upgrade pyenv 9 | brew install pyenv-virtualenv 10 | brew install cmake || true 11 | 12 | if which pyenv > /dev/null; then 13 | eval "$(pyenv init -)" 14 | fi 15 | 16 | pyenv install 2.7.10 17 | pyenv virtualenv 2.7.10 conan 18 | pyenv rehash 19 | pyenv activate conan 20 | fi 21 | 22 | pip install conan --upgrade 23 | pip install conan_package_tools 24 | 25 | conan user 26 | -------------------------------------------------------------------------------- /.travis/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -x 5 | 6 | if [[ "$(uname -s)" == 'Darwin' ]]; then 7 | if which pyenv > /dev/null; then 8 | eval "$(pyenv init -)" 9 | fi 10 | pyenv activate conan 11 | fi 12 | 13 | python build.py 14 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | def artifactory_name = "artifactory" 2 | def artifactory_repo = "conan" 3 | def repo_url = 'https://github.com/jonico/libzengithub.git' 4 | def repo_branch = "master" 5 | 6 | node { 7 | stage("Get recipe"){ 8 | git branch: repo_branch, url: repo_url 9 | } 10 | 11 | stage("Configure Artifactory/Conan") 12 | def server = Artifactory.server artifactory_name 13 | def client = Artifactory.newConanClient() 14 | def serverName = client.remote.add server: server, repo: artifactory_repo 15 | client.run(command: "remote remove conan.io") 16 | 17 | stage("Test recipe"){ 18 | client.run(command: "test_package") 19 | } 20 | 21 | stage("Upload packages"){ 22 | String command = "upload * --all -r ${serverName} --confirm" 23 | def b = client.run(command: command) 24 | server.publishBuildInfo b 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Build Status](https://github.com/jonico/libzengithub/workflows/Test%20libzengithub%20package%20on%20main%20platforms/badge.svg) 2 | 3 | 4 | # libzengithub - how to build portable [conan.io](https://www.conan.io/) C/C++ packages with multiple CI platforms 5 | 6 | This project has been featured at the SwampUp conference ([talk recording](https://www.youtube.com/watch?v=G598xN6kyH8)) and the Volkswagen Azure Days. 7 | 8 | ```libzengithub``` prints out a random [Zen of Github](http://ben.balter.com/2015/08/12/the-zen-of-github/) whenever you call its only function. 9 | 10 | ```c 11 | #include 12 | 13 | int main() { 14 | zen_of_github(); 15 | } 16 | ``` 17 | 18 | will provide you something like 19 | 20 | ``` 21 | MMM. .MMM 22 | MMMMMMMMMMMMMMMMMMM 23 | MMMMMMMMMMMMMMMMMMM _________________________________________ 24 | MMMMMMMMMMMMMMMMMMMMM | | 25 | MMMMMMMMMMMMMMMMMMMMMMM | Anything added dilutes everything else. | 26 | MMMMMMMMMMMMMMMMMMMMMMMM |_ _____________________________________| 27 | MMMM::- -:::::::- -::MMMM |/ 28 | MM~:~ 00~:::::~ 00~:~MM 29 | .. MMMMM::.00:::+:::.00::MMMMM .. 30 | .MM::::: ._. :::::MM. 31 | MMMM;:::::;MMMM 32 | -MM MMMMMMM 33 | ^ M+ MMMMMMMMM 34 | MMMMMMM MM MM MM 35 | MM MM MM MM 36 | MM MM MM MM 37 | .~~MM~MM~MM~MM~~. 38 | ~~~~MM:~MM~~~MM~:MM~~~~ 39 | ~~~~~~==~==~~~==~==~~~~~~ 40 | ~~~~~~==~==~==~==~~~~~~ 41 | :~==~==~==~==~~ 42 | ``` 43 | 44 | See the [zenofgithub](https://github.com/jonico/zenofgithub) for a conan.io based application that makes use of this package. 45 | 46 | # conan.io package dependencies 47 | 48 | libzengithub is relying on [libcurl](https://github.com/lasote/conan-libcurl) to call the ```https://api.github.com/octocat``` endpoint and retrieve a random Zen of GitHub. 49 | Its main purpose is to demonstrate how to build portable [conan.io](https://www.conan.io/) packages that rely on conan.io packages (libcurl) themselves. 50 | conan.io is a great package manager for C and C++ libraries which works for various platforms including Linux, Mac OS and Windows. 51 | 52 | The only thing needed for ```libzengithub``` to declare a dependency to ```libcurl``` is to declare that dependency in its [conanfile.py](https://github.com/jonico/libzengithub/blob/master/conanfile.py): 53 | 54 | ```python 55 | ... 56 | class ZenGithubConan(ConanFile): 57 | name = "ZenGitHub" 58 | version = "1.0" 59 | license = "Apache 2.0" 60 | url = "https://github.com/jonico/libzengithub" 61 | settings = "os", "compiler", "build_type", "arch" 62 | options = {"shared": [True, False], "fPIC": [True, False]} 63 | default_options = {"shared": False, "fPIC": True} 64 | generators = "cmake" 65 | exports_sources = "zengithub/*" 66 | requires = "libcurl/7.75.0" 67 | ... 68 | ``` 69 | 70 | conan will then automatically build the following dependency tree: 71 | 72 | ``` 73 | conan info . --graph deps.html 74 | open deps.html 75 | ``` 76 | 77 | ![image](https://user-images.githubusercontent.com/1872314/117568339-fe805f00-b0bf-11eb-9a86-13dc9f972b3d.png) 78 | 79 | and automatically downloads the packages it depends upon from the conan repository. If it should find pre-built packages for the dependencies, it will build them locally. 80 | 81 | # Consuming the package 82 | 83 | See [zenofgithub](https://github.com/jonico/zenofgithub) for an example application that consumes this library. 84 | 85 | ## Basic setup 86 | 87 | First, [install](http://docs.conan.io/en/latest/installation.html) the conan.io package manager locally. 88 | Then, add the remote to [my conan.io repo](https://jonico.jfrog.io/artifactory/api/conan/libzengithub-conan): 89 | 90 | ``` 91 | conan remote add conan-jonico https://jonico.jfrog.io/artifactory/api/conan/libzengithub-conan 92 | ``` 93 | 94 | Now, you can install the library: 95 | 96 | ` 97 | conan install ZenGitHub/1.0@jonico/stable 98 | ` 99 | 100 | If conan complains about missing dependencies (like libCurl or libz or OpenSSL), this is an indication that your current conan.io do not have a pre-built version of those dependent packages and you can build them locally instead: 101 | 102 | ` 103 | conan install ZenGitHub/1.0@jonico/stable --build missing 104 | ` 105 | 106 | If you rather want to install the shared library instead of a static library, use 107 | 108 | ` 109 | conan install ZenGitHub/1.0@jonico/stable -o ZenGitHub:shared=True --build missing 110 | ` 111 | 112 | ## Project setup 113 | 114 | If you handle multiple dependencies in your project is better to add a [conanfile.txt](https://github.com/jonico/zenofgithub/blob/master/conanfile.txt) 115 | 116 | ``` 117 | [requires] 118 | ZenGitHub/1.0@jonico/stable 119 | 120 | [options] 121 | ZenGitHub:shared=False # True 122 | 123 | [generators] 124 | cmake 125 | 126 | [imports] 127 | bin, *.dll -> ./bin # Copies all dll files from packages bin folder to my "bin" folder 128 | lib, *.dylib* -> ./bin # Copies all dylib files from packages lib folder to my "bin" folder 129 | ``` 130 | 131 | Complete the installation of requirements for your project running: 132 | 133 | ` 134 | conan install . 135 | ` 136 | 137 | Project setup installs the library (and all his dependencies) and generates the files *conanbuildinfo.txt* and *conanbuildinfo.cmake* with all the paths and variables that you need to link with your dependencies. 138 | 139 | # Automatic builds of libzengithub 140 | 141 | I was following https://github.com/conan-io/conan-package-tools to provide a range of different operating system, compiler version, debug and release builds for this library. 142 | 143 | I am using [Travis CI](https://github.com/jonico/libzengithub/blob/master/.travis.yml) for Linux and Mac builds and [AppVeyor](https://github.com/jonico/libzengithub/blob/master/appveyor.yml) for Windows builds and [Azure Pipelines](https://dev.azure.com/nicolaijohannes/nicolaijohannes/_build?definitionId=3&_a=summary) for Windows, Linux and Mac. 144 | 145 | I am now using GitHub Actions for all builds as it supports all hardware configurations :point_up: with [one config file](https://github.com/jonico/libzengithub/blob/master/.github/workflows/package.yml). 146 | 147 | ![image](https://user-images.githubusercontent.com/1872314/117568074-08ee2900-b0bf-11eb-8d24-f04186103b68.png) 148 | 149 | 150 | I had to exclude certain platforms as ```libcurl``` and OpenSSL packages were not built for all possible mutations. Packages are uploaded to https://jonico.jfrog.io/artifactory/api/conan/libzengithub-conan 151 | 152 | Here are the results: 153 | 154 | ``` 155 | conan search ZenGitHub/1.0@jonico/stable -r=conan --table build_matrix.html 156 | open build_matrix.html 157 | ``` 158 | 159 | ![image](https://user-images.githubusercontent.com/1872314/117568251-95005080-b0bf-11eb-832f-0563cd280bd4.png) 160 | 161 | 162 | # Building, testing and installing locally 163 | 164 | If you are a consumer of ```libzengithub```, you would not need to build this package by yourself but get it as part of your consumer build or pre-built from [my conan.io repo](https://api.bintray.com/conan/conan-jonico/libzengithub) 165 | Checkout [zenofgithub](https://github.com/jonico/zenofgithub) for an example application that consumes this library. 166 | 167 | If you still like to build, test and install ```libzengithub``` directly, clone this repository, [get the conan CLI](http://docs.conan.io/en/latest/installation.html) and run 168 | 169 | ``` 170 | conan create . jonico/testing 171 | conan export . ZenGitHub/1.0@jonico/stable 172 | ``` 173 | 174 | If tests run through successfully, a picture like this should appear 175 | 176 | ``` 177 | 178 | MMM. .MMM 179 | MMMMMMMMMMMMMMMMMMM 180 | MMMMMMMMMMMMMMMMMMM _____________________ 181 | MMMMMMMMMMMMMMMMMMMMM | | 182 | MMMMMMMMMMMMMMMMMMMMMMM | Design for failure. | 183 | MMMMMMMMMMMMMMMMMMMMMMMM |_ _________________| 184 | MMMM::- -:::::::- -::MMMM |/ 185 | MM~:~ 00~:::::~ 00~:~MM 186 | .. MMMMM::.00:::+:::.00::MMMMM .. 187 | .MM::::: ._. :::::MM. 188 | MMMM;:::::;MMMM 189 | -MM MMMMMMM 190 | ^ M+ MMMMMMMMM 191 | MMMMMMM MM MM MM 192 | MM MM MM MM 193 | MM MM MM MM 194 | .~~MM~MM~MM~MM~~. 195 | ~~~~MM:~MM~~~MM~:MM~~~~ 196 | ~~~~~~==~==~~~==~==~~~~~~ 197 | ~~~~~~==~==~==~==~~~~~~ 198 | :~==~==~==~==~~ 199 | ``` 200 | 201 | ## Upload packages to your own conan.io server 202 | 203 | First of all, [configure the remote](http://conanio.readthedocs.io/en/latest/reference/commands/remote.html) to your local conan.io server. 204 | 205 | ``` 206 | conan remote add 207 | ``` 208 | 209 | ``` 210 | conan upload ZenGitHub/1.0@jonico/stable --all -r= 211 | ``` 212 | 213 | ## :tada: GitHub SlowMerge / Octoplush Incentive :tada: 214 | 215 | ### We have a [winner](https://github.com/jonico/libzengithub/pull/34) :tada: 216 | 217 | The first one who creates a PR with a working example on how to build and publish ARM/ARM64 packages for `libzengithub` using [self-hosted runners](https://help.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners) is in for a special treat. 218 | 219 | ![](https://user-images.githubusercontent.com/1872314/75146322-240f8b80-56fb-11ea-970d-e6f9d3fba95e.JPG) 220 | 221 | Enjoy :octocat::heart: 222 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | build: false 2 | 3 | environment: 4 | PYTHON: "C:\\Python27" 5 | PYTHON_VERSION: "2.7.8" 6 | PYTHON_ARCH: "32" 7 | 8 | CONAN_REFERENCE: "ZenGitHub/1.0" 9 | CONAN_USERNAME: "jonico" 10 | CONAN_LOGIN_USERNAME: "jonico" 11 | CONAN_CHANNEL: "stable" 12 | VS150COMNTOOLS: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\Common7\\Tools\\" 13 | CONAN_UPLOAD: "https://api.bintray.com/conan/conan-jonico/libzengithub" 14 | CONAN_STABLE_BRANCH_PATTERN: "release/*" 15 | 16 | matrix: 17 | #- MINGW_CONFIGURATIONS: "4.9@x86_64@seh@posix, 4.9@x86_64@sjlj@posix, 4.9@x86@sjlj@posix, 4.9@x86@dwarf2@posix" 18 | # commented out because OpenSSH package for libcurl is missing 19 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 20 | CONAN_VISUAL_VERSIONS: 12 21 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 22 | CONAN_VISUAL_VERSIONS: 14 23 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 24 | CONAN_VISUAL_VERSIONS: 15 25 | 26 | install: 27 | - set PATH=%PATH%;%PYTHON%/Scripts/ 28 | - pip.exe install conan --upgrade 29 | - pip.exe install conan_package_tools 30 | - conan user # It creates the conan data directory 31 | 32 | test_script: 33 | - python build.py 34 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | # C/C++ with GCC 2 | # Build your C/C++ project with GCC using make. 3 | # Add steps that publish test results, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/apps/c-cpp/gcc 5 | 6 | trigger: 7 | - master 8 | 9 | strategy: 10 | matrix: 11 | linux: 12 | imageName: 'ubuntu-16.04' 13 | python-arch: "x64" 14 | python-version: "3.6.x" 15 | install-headerfiles : true 16 | mac: 17 | imageName: 'macos-10.13' 18 | python-arch: "x64" 19 | python-version: "3.6.x" 20 | install-headerfiles : false 21 | windows: 22 | imageName: 'vs2017-win2016' 23 | vs-version: 15 24 | python-arch: "x86" 25 | python-version: "2.7.x" 26 | install-headerfiles : false 27 | 28 | pool: 29 | vmImage: $(imageName) 30 | 31 | variables: 32 | CONAN_REFERENCE: "ZenGitHub/1.0" 33 | CONAN_USERNAME: "jonico" 34 | CONAN_LOGIN_USERNAME: "jonico" 35 | CONAN_CHANNEL: "stable" 36 | CONAN_UPLOAD: "https://api.bintray.com/conan/conan-jonico/libzengithub" 37 | CONAN_STABLE_BRANCH_PATTERN: "release/*" 38 | CONAN_VISUAL_VERSIONS: $(vs-version) 39 | CONAN_APPLE_CLANG_VERSIONS: "10.0" 40 | CONAN_GCC_VERSIONS: "5" 41 | INSTALL_HEADERFILES: $(install-headerfiles) 42 | 43 | steps: 44 | - task: UsePythonVersion@0 45 | inputs: 46 | versionSpec: $(python-version) 47 | addToPath: true 48 | architecture: $(python-arch) 49 | - script: sudo apt-get update && sudo apt-get install -y gcc-multilib 50 | displayName: Installing C/C++ header files 51 | condition: eq(variables.INSTALL_HEADERFILES, true) 52 | - script: pip install conan 53 | displayName: Installing Conan 54 | - script: pip install conan_package_tools 55 | displayName: Installing Conan package tools 56 | - script: conan user 57 | displayName: Generating conan data directory 58 | - script: python build.py 59 | displayName: Building the solution 60 | -------------------------------------------------------------------------------- /build.py: -------------------------------------------------------------------------------- 1 | from cpt.packager import ConanMultiPackager 2 | 3 | if __name__ == "__main__": 4 | builder = ConanMultiPackager(build_policy="missing") 5 | builder.add_common_builds(pure_c=True, shared_option_name="ZenGitHub:shared") 6 | # for some reason arm fails to link shared against openssl static build 7 | builder.remove_build_if(lambda build: build.settings['arch'].startswith("arm") and build.options['ZenGitHub:shared'] == True) 8 | builder.run() 9 | -------------------------------------------------------------------------------- /conanfile.py: -------------------------------------------------------------------------------- 1 | from conans import ConanFile, CMake 2 | 3 | 4 | class ZenGithubConan(ConanFile): 5 | name = "ZenGitHub" 6 | version = "1.0" 7 | license = "Apache 2.0" 8 | url = "https://github.com/jonico/libzengithub" 9 | settings = "os", "compiler", "build_type", "arch" 10 | options = {"shared": [True, False], "fPIC": [True, False]} 11 | default_options = {"shared": False, "fPIC": True} 12 | generators = "cmake" 13 | exports_sources = "zengithub/*" 14 | requires = "libcurl/7.75.0" 15 | 16 | def configure(self): 17 | del self.settings.compiler.libcxx 18 | 19 | def build(self): 20 | cmake = CMake(self) 21 | cmake.configure(source_folder="zengithub") 22 | cmake.build() 23 | 24 | def package(self): 25 | self.copy("*.h", dst="include", src="zengithub") 26 | self.copy("*zengithub.lib", dst="lib", keep_path=False) 27 | self.copy("*.dll", dst="bin", keep_path=False) 28 | self.copy("*.dylib*", dst="lib", keep_path=False) 29 | self.copy("*.so", dst="lib", keep_path=False) 30 | self.copy("*.a", dst="lib", keep_path=False) 31 | 32 | def package_info(self): 33 | self.cpp_info.libs = ["zengithub"] 34 | -------------------------------------------------------------------------------- /test_package/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(PackageTest C) 2 | cmake_minimum_required(VERSION 2.8.12) 3 | 4 | include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) 5 | conan_basic_setup() 6 | 7 | add_executable(example example.c) 8 | target_link_libraries(example ${CONAN_LIBS}) 9 | 10 | # CTest is a testing tool that can be used to test your project. 11 | # enable_testing() 12 | # add_test(NAME example 13 | # WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin 14 | # COMMAND example) 15 | -------------------------------------------------------------------------------- /test_package/conanfile.py: -------------------------------------------------------------------------------- 1 | from conans import ConanFile, CMake, tools 2 | import os 3 | 4 | 5 | class ZenGithubTestConan(ConanFile): 6 | settings = "os", "compiler", "build_type", "arch" 7 | generators = "cmake" 8 | 9 | def build(self): 10 | cmake = CMake(self) 11 | cmake.configure() 12 | cmake.build() 13 | 14 | def imports(self): 15 | self.copy("*.dll", dst="bin", src="bin") 16 | self.copy("*.dylib*", dst="bin", src="lib") 17 | 18 | def test(self): 19 | with tools.chdir("bin"): 20 | self.run(".%sexample" % os.sep) 21 | -------------------------------------------------------------------------------- /test_package/example.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | zen_of_github(); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /zengithub/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | PROJECT(ZenGitHub C) 2 | cmake_minimum_required(VERSION 2.8) 3 | 4 | include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) 5 | conan_basic_setup() 6 | 7 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin) 8 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/bin) 9 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/bin) 10 | 11 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib) 12 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}) 13 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}) 14 | 15 | add_library(zengithub zengithub.c) 16 | target_link_libraries(zengithub ${CONAN_LIBS}) 17 | -------------------------------------------------------------------------------- /zengithub/zengithub.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include "zengithub.h" 7 | 8 | struct MemoryStruct { 9 | char *memory; 10 | size_t size; 11 | }; 12 | 13 | static size_t 14 | WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) 15 | { 16 | size_t realsize = size * nmemb; 17 | struct MemoryStruct *mem = (struct MemoryStruct *)userp; 18 | 19 | mem->memory = realloc(mem->memory, mem->size + realsize + 1); 20 | if(mem->memory == NULL) { 21 | /* out of memory! */ 22 | printf("not enough memory (realloc returned NULL)\n"); 23 | return 0; 24 | } 25 | 26 | memcpy(&(mem->memory[mem->size]), contents, realsize); 27 | mem->size += realsize; 28 | mem->memory[mem->size] = 0; 29 | 30 | return realsize; 31 | } 32 | 33 | void zen_of_github (void) 34 | { 35 | CURL *curl_handle; 36 | CURLcode res; 37 | 38 | struct MemoryStruct chunk; 39 | 40 | chunk.memory = malloc(1); /* will be grown as needed by the realloc above */ 41 | chunk.size = 0; /* no data at this point */ 42 | 43 | curl_global_init(CURL_GLOBAL_ALL); 44 | 45 | /* init the curl session */ 46 | curl_handle = curl_easy_init(); 47 | 48 | /* specify URL to get */ 49 | curl_easy_setopt(curl_handle, CURLOPT_URL, "https://api.github.com/octocat"); 50 | 51 | /* send all data to this function */ 52 | curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); 53 | 54 | /* we pass our 'chunk' struct to the callback function */ 55 | curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); 56 | 57 | /* some servers don't like requests that are made without a user-agent 58 | field, so we provide one */ 59 | curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0"); 60 | 61 | /* get it! */ 62 | res = curl_easy_perform(curl_handle); 63 | 64 | /* check for errors */ 65 | if(res != CURLE_OK) { 66 | fprintf(stderr, "curl_easy_perform() failed: %s\n", 67 | curl_easy_strerror(res)); 68 | } 69 | else { 70 | /* 71 | * Now, our chunk.memory points to a memory block that is chunk.size 72 | * bytes big and contains the remote file. 73 | * 74 | * Do something nice with it! 75 | */ 76 | 77 | printf("%s\n", chunk.memory); 78 | } 79 | 80 | /* cleanup curl stuff */ 81 | curl_easy_cleanup(curl_handle); 82 | 83 | free(chunk.memory); 84 | 85 | /* we're done with libcurl, so clean it up */ 86 | curl_global_cleanup(); 87 | } 88 | -------------------------------------------------------------------------------- /zengithub/zengithub.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef WIN32 4 | #define ZENGITHUB_EXPORT __declspec(dllexport) 5 | #else 6 | #define ZENGITHUB_EXPORT 7 | #endif 8 | 9 | /* 10 | * Prints a random zen of GitHub 11 | * using lib curl to https://api.github.com/octocat 12 | */ 13 | ZENGITHUB_EXPORT void zen_of_github(void); 14 | --------------------------------------------------------------------------------