├── .github └── FUNDING.yml ├── LICENSE ├── README.md ├── doc └── concept.png └── makePipRecipes.py /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: robseb 4 | 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Robin Sebastian 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PiP2Bitbake 2 | ![GitHub](https://img.shields.io/static/v1?label=Ubuntu&message=18.04+LTS,+20.04+LTS&color=yellowgreen) 3 | ![GitHub](https://img.shields.io/static/v1?label=CentOS&message=7.0,+8.0&color=blue) 4 | ![GitHub](https://img.shields.io/static/v1?label=Python&message=3.7&color=green) 5 | ![GitHub](https://img.shields.io/github/license/robseb/PiP2Bitbake) 6 | 7 | ![Alt text](doc/concept.png?raw=true "Concept") 8 | ___ 9 | **This Python script allows to pre-install any Python** *pip* (*PyPI*) (*Python Package Index*)- **Packages within a final *Yocto Project* Linux Image.** 10 | 11 | In order to make this possible a Bitbake-file with all necessary information's (Version Number, Checksums,..) will be generated 12 | to allow Bitbake to include the chosen pip-package to the *rootfs* of the generated Yocto-Project Linux Distribution. 13 | 14 | I developed this Python script to create [*rsYocto*](https://github.com/robseb/rsyocto) an embedded Linux for *Intel SoC-FPGAs*. 15 | 16 | ## Features 17 | 18 | * **Python script to automatically create Bitbake recipe files for the Yocto Project to pre-install any Python *pip* package** 19 | * **Almost every Python pip package can implemented into a custom Linux Distribution** 20 | * Of cause, it is only necessary that the package is as a cross Platform version available 21 | * **Outputs a *".bb"*-Bitbake recipe file that can easily included to any Yocto Project *meta-layer*** 22 | * **Supported *Python Package Index Version***: 1-3 23 | * **Supported Python pip package archive file types:** "*.tar.gz*" and "*.zip*" 24 | * **It is enabled to use URL/Link to a specific Python package version or to a custom Server** 25 | 26 | 27 | # Guide to use this script 28 | 1. Pull this repository to your Yocto Project building machine 29 | 2. Be sure that **Python pip 3** is installed on your development machine 30 | * To install that use on **Ubuntu**: 31 | ```bash 32 | sudo apt-get -y install python-pip 33 | ```` 34 | * To install that use on **CentOS**: 35 | ```bash 36 | sudo yum install python-pip 37 | ```` 38 | 3. Start the python script 39 | ```bash 40 | python3 makePipRecipes.py 41 | ```` 42 | 4. **Find a Python [PyPI](https://pypi.org/)-package to include to the Yocto Project** 43 | 5. **Follow the instruction of the Python script** 44 | * The script will ask for: 45 | 1. The **pip-package** name (e.g. by `pip install pyserial` use "`pyserial`") 46 | * Be sure that the uppercase/lowercase of the string is exact (**Case sensitive!**) 47 | * **Alternatively here it is enabled to insert a URL/Link to the package** 48 | * Use the entire Link with the "*http*"- or "*https*"- pre-fix and with the file suffix 49 | * You can find the URLs to the package inside the *"Download files"* selection of the [PyPI](https://pypi.org/) package website 50 | * For instance "*pyserial*" it would be: "*https://files.pythonhosted.org/packages/1e/7d/ae3f0a63f41e4d2f6cb66a5b57197850f919f59e558159a4dd3a818f5082/pyserial-3.5.tar.gz*" 51 | * **Note:** "*.whl*" archive packages are not supported! 52 | 53 | 2. For the required **Python-Version** 54 | 3. For the **Type of Licence** (e.g. MIT) for recipe 55 | 7. **The Python script will generate a *".bb"*-Bitbake-file** 56 | * **Copy** this file to your recipe folder 57 | * If you don't have a *meta-layer* create a new one 58 | * Execute following command inside your Yocto Project build Folder (`poky/build`) 59 | ```bash 60 | bitbake-layers create-layer meta-example 61 | ```` 62 | * Include the new layer to your Yocto Project by **adding following line** to the `poky/build/conf/bblayers.conf`-file: 63 | ````txt 64 | /home//poky/meta-example \ 65 | ```` 66 | * **Copy** the generated recipe file to your recipes: 67 | ```txt 68 | meta-example 69 | |- conf 70 | | - README 71 | |- recipes-test 72 | |- test 73 | |-GENERATED_BITBAKAE_FILE.bb 74 | ``` 75 | 8. **Include the Python pip package to your Yocto Build by adding following line to the `poky/build/conf/local.conf`-file** 76 | ```txt 77 | IMAGE_INSTALL_append = "pip-PIPNAME" 78 | ```` 79 | 9. **To execute the implementation start the building process of the Yocto Project normally** 80 | * For example with (*inside `poky/build`*): 81 | ```bash 82 | bitbake core-image-minimal 83 | ```` 84 | 85 | ## Example: Embedding the Python pip-package `pyserial` to the Yocto Project 86 | 87 |
88 | Example output after an execution 89 | 90 | 91 | ````txt 92 | vm@ubuntu:$ python3 makePipRecipes.py 93 | ############################################################################# 94 | # # 95 | # ######## ###### ## ## ####### ###### ######## ####### # 96 | # ## ## ## ## ## ## ## ## ## ## ## ## ## # 97 | # ## ## ## #### ## ## ## ## ## ## # 98 | # ######## ###### ## ## ## ## ## ## ## # 99 | # ## ## ## ## ## ## ## ## ## ## # 100 | # ## ## ## ## ## ## ## ## ## ## ## ## # 101 | # ## ## ###### ## ####### ###### ## ####### # 102 | # # 103 | # AUTOMATIC SCRIPT FOR GENERATING RECIPES TO INCLUDE # 104 | # PYTHON PIP-PACKAGES TO YOUR YOCTO-PROJECT LINUX DISTO # 105 | # # 106 | # by Robin Sebastian (https://github.com/robseb) # 107 | # Contact: git@robseb.de # 108 | # Vers.: 1.2 # 109 | # # 110 | ############################################################################## 111 | 112 | 113 | Type in the Name of the Python pip (PyPI) Package to include to your Yocto Project Linux Distro 114 | Note: Consider the exact writing! Case sensitive! 115 | You can find Python pip packages here: https://pypi.org/ 116 | PiP-Package Name: pyserial 117 | Choose the requiered Python Version: 118 | Python 1-2: 1,2 119 | Python 3 : 3 120 | Python Version:3 121 | Type in the used License name for the recipe (e.g.: MIT) 122 | License name: 123 | Chosen License name: "MIT" 124 | Starting the generation... 125 | 126 | --> Download for testing the Python PiP package 127 | Collecting pyserial 128 | Downloading https://files.pythonhosted.org/packages/1e/7d/ae3f0a63f41e4d2f6cb66a5b57197850f919f59e558159a4dd3a818f5082/pyserial-3.5.tar.gz (159kB) 129 | 100% |████████████████████████████████| 163kB 1.1MB/s 130 | Saved ./makePipRec_workingFolder/pyserial-3.5.tar.gz 131 | Successfully downloaded pyserial 132 | 133 | The Name of the downloaded file: "pyserial-3.5.tar.gz" 134 | --> Calculate md5 checksum of this file 135 | md5sum = 1cf25a76da59b530dbfc2cf99392dc83 136 | --> Calculate sha256sum checksum of this file 137 | sha256sum = 3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb 138 | --> Decode the current Version Code of this PiP Package 139 | Version: 3.5 140 | --> Unpackage the downloaded file to decode the included licence file 141 | Unpackage the downloaded package 142 | [sudo] password for vm: 143 | Unpackaging was successful 144 | Try to find a Licence file 145 | The License File was found 146 | --> Calculate the md5-checksum for the License file 147 | md5sum = 520e45e59fc2cf94aa53850f46b86436 148 | --> Create the Bitbake .bb-File with the name 149 | pip-pyserial_3.5.bb 150 | --> Generate the content of this file 151 | Bitbake file generation was successfull 152 | --> Deleting the working Folder 153 | 154 | ################################################################################ 155 | # # 156 | # GENERATION WAS SUCCESSFUL # 157 | # # 158 | #---------------------------- Implementation Guide ----------------------------# 159 | # 1. Step: Copy the recipe file: "pip-pyserial_3.5.bb" 160 | # to your recipe folder inside a meta layer 161 | # For example here: 162 | # meta-example 163 | # |- conf 164 | # |- recipes-test 165 | # |- test 166 | # |- pip-pyserial_3.5.bb <-- 167 | 168 | # (this file is located here:/home/vm/Desktop/PiP2Bitbake ) 169 | # 2. Step: Include the PiP-Package to your Yocto Project by 170 | # by adding following line to the conf/local.conf file: 171 | # conf/local.conf: 172 | # IMAGE_INSTALL_append = "pip-pyserial" 173 | 174 | # 3. Step: Build your Yocto Project normally with bitbake 175 | 176 | #------------------------------------------------------------------------------# 177 | # # 178 | # SUPPORT THE AUTHOR # 179 | # # 180 | # ROBIN SEBASTIAN # 181 | # (https://github.com/robseb/) # 182 | # git@robseb.de # 183 | # # 184 | # makePipRecipes and rsYocto are projects, that I have fully # 185 | # developed on my own. No companies are involved in this projects. # 186 | # I am recently graduated as Master of Since of electronic engineering # 187 | # Please support me for further development # 188 | # # 189 | ################################################################################ 190 | ```` 191 | 192 | ### Content of the generated file: `pip-pyserial_3.4.bb` 193 | ````bitbake 194 | # The is a automatic generated Code by "makePipRecipes.py" 195 | # (by Robin Sebastian (https://github.com/robseb) Vers.: 1.0) 196 | 197 | SUMMARY = "Recipe to embedded the Python PiP Package pyserial" 198 | HOMEPAGE ="https://pypi.org/project/pyserial" 199 | LICENSE = "MIT" 200 | LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=d476d94926db6e0008a5b3860d1f5c0d" 201 | 202 | inherit pypi setuptools 203 | PYPI_PACKAGE = "pyserial" 204 | SRC_URI[md5sum] = "ed6183b15519a0ae96675e9c3330c69b" 205 | SRC_URI[sha256sum] = "6e2d401fdee0eab996cf734e67773a0143b932772ca8b42451440cfed942c627" 206 | ```` 207 |
208 | 209 | ### Finally on the running Yocto-Project Linux Distribution .... 210 | ````bash 211 | root@cyclone5:~# pip list 212 | Package Version 213 | ---------- ------- 214 | pyserial 3.4.0 215 | ```` 216 | ### is `pyserial`pre-installed 217 |
218 | 219 | 220 | * *rsyocto*; **Robin Sebastian,M.Sc. [(LinkedIn)](https://www.linkedin.com/in/robin-sebastian-a5080220a)** 221 | 222 | *Pip2BitBake* and *rsyocto* are self-developed projects in which no other companies are involved. 223 | It is specifically designed to serve students and the Linux/FPGA open-source community with its publication on GitHub and its open-source MIT license. 224 | In the future, *rsyocto* will retain its open-source status and it will be further developed. 225 | 226 | Due to the enthusiasm of commercial users, special features for industrial, scientific and automotive applications 227 | were developed and ready for the implementation in a highly optimazed closed commercial version. 228 | Partnerships as an embedded SoC-FPGA design service to fulfil these specific commercial requirements are offered. 229 | It should help, besides students with the *rsyocto* open-source version, commercial users, as well. 230 | 231 | **For commercial users, please visit the *rsyocto* embedded service provider website:** 232 | [**rsyocto.com**](https://rsyocto.com/) 233 | 234 | [![GitHub stars](https://img.shields.io/github/stars/robseb/PiP2Bitbake?style=social)](https://GitHub.com/robseb/PiP2Bitbake/stargazers/) 235 | [![GitHub watchers](https://img.shields.io/github/watchers/robseb/PiP2Bitbake?style=social)](https://github.com/robseb/NIOSII_EclipseCompProject/watchers) 236 | [![GitHub followers](https://img.shields.io/github/followers/robseb?style=social)](https://github.com/robseb) 237 | 238 | -------------------------------------------------------------------------------- /doc/concept.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robseb/PiP2Bitbake/273cffff8dcf4d634cc3f756c3b0946c4bb61a66/doc/concept.png -------------------------------------------------------------------------------- /makePipRecipes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3.7 2 | # 3 | # ######## ###### ## ## ####### ###### ######## ####### 4 | # ## ## ## ## ## ## ## ## ## ## ## ## ## 5 | # ## ## ## #### ## ## ## ## ## ## 6 | # ######## ###### ## ## ## ## ## ## ## 7 | # ## ## ## ## ## ## ## ## ## ## 8 | # ## ## ## ## ## ## ## ## ## ## ## ## 9 | # ## ## ###### ## ####### ###### ## ####### 10 | # ___ _ _ _ ___ _ 11 | # | _ ) _ _ (_) | | __| | / __| _ _ ___ | |_ ___ _ __ 12 | # | _ \ | || | | | | | / _` | \__ \ | || | (_-< | _| / -_) | ' \ 13 | # |___/ \_,_| |_| |_| \__,_| |___/ \_, | /__/ \__| \___| |_|_|_| 14 | # |__/ 15 | # 16 | # 17 | # Robin Sebastian (https://github.com/robseb) 18 | # 19 | # Contact: git@robseb.de 20 | # 21 | # Python Script to automatically create a Bitbake recipe for Python PiP Packages 22 | # This recipe can then be used inside a meta layer for embedded Linux building with 23 | # the Yocto Project 24 | # 25 | # (2019-12-28) Vers.1.0 26 | # first Version 27 | # 28 | # (2020-05-23) Vers.1.1 29 | # better interface 30 | # 31 | # (2021-02-15) Vers.1.2 32 | # Allow to use packages with "-" in the name 33 | # Allow to use URLs as pip name to create recipes for on the 34 | # build machine not supported packages 35 | # Information of the not supported ".whl" packages 36 | # 37 | version = "1.2" 38 | 39 | import os 40 | import sys 41 | import shutil 42 | import hashlib, pathlib 43 | import re 44 | 45 | WORKING_FOLDER_NAME = "makePipRec_workingFolder" 46 | 47 | # 48 | # @brief Function to remove the working folder 49 | # @return success 50 | # 51 | def removeWorkingFolder(): 52 | # Create a temp working directory 53 | if(os.path.isdir(WORKING_FOLDER_NAME)): 54 | try: 55 | os.system('sudo rm -r '+os.getcwd()+'/'+WORKING_FOLDER_NAME) 56 | except PermissionError: 57 | print('\nERROR: Failed to delete the working Folder') 58 | print('Super user (root) privileges required to delate this folder!') 59 | print(' Please delete following folder by hand') 60 | print('"'+os.getcwd()+'/'+WORKING_FOLDER_NAME+'"') 61 | print('and try it again') 62 | return False 63 | except Exception as ex: 64 | print('\nERROR: Failed to delete the working Folder') 65 | print(' Error Msg.: "'+str(ex)+'"') 66 | print(' Please delete following folder by hand') 67 | print('"'+os.getcwd()+'/'+WORKING_FOLDER_NAME+'"') 68 | print('and try it again') 69 | return False 70 | return True 71 | 72 | if __name__ == '__main__': 73 | 74 | print('\n##############################################################################') 75 | print('# #') 76 | print('# ######## ###### ## ## ####### ###### ######## ####### #') 77 | print('# ## ## ## ## ## ## ## ## ## ## ## ## ## #') 78 | print('# ## ## ## #### ## ## ## ## ## ## #') 79 | print('# ######## ###### ## ## ## ## ## ## ## #') 80 | print('# ## ## ## ## ## ## ## ## ## ## #') 81 | print('# ## ## ## ## ## ## ## ## ## ## ## ## #') 82 | print('# ## ## ###### ## ####### ###### ## ####### #') 83 | print('# #') 84 | print("# AUTOMATIC SCRIPT FOR GENERATING RECIPES TO INCLUDE #") 85 | print("# PYTHON PIP-PACKAGES TO YOUR YOCTO-PROJECT LINUX DISTO #") 86 | print('# #') 87 | print("# by Robin Sebastian (https://github.com/robseb) #") 88 | print("# Contact: git@robseb.de #") 89 | print("# Vers.: "+version+" #") 90 | print('# #') 91 | print('##############################################################################\n\n') 92 | 93 | # Runtime environment check 94 | if sys.version_info[0] < 3: 95 | print("Use Python 3 for this script!") 96 | sys.exit() 97 | 98 | if not sys.platform =='linux': 99 | print("This Script can only run on Linux!") 100 | sys.exit() 101 | ############################################ READ USER INPUT (PiP Name and Version) ########################################### 102 | 103 | print('Type in the Name of the Python pip (PyPI) Package to include to your Yocto Project Linux Distro') 104 | print('Note: Consider the exact writing! Case sensitive!') 105 | print('You can find Python pip packages here: https://pypi.org/') 106 | PipName =input('PiP-Package Name: ') 107 | Pipurl = PipName 108 | 109 | if PipName=='q' or PipName=='Q': sys.exit() 110 | if PipName.endswith('.whl'): 111 | print('ERROR: Download URLs with ".whl" archive files are not supported!') 112 | print(' It is only enabled to download ".tar.gz"- and ".zip" source code files!') 113 | sys.exit() 114 | elif (PipName.endswith('.tar.gz') or PipName.endswith('.zip')) and PipName.find('http')!=-1: 115 | # A HTTP/HTTPS URL was used 116 | print('\nYou inserted a URL to a Python pip (PyPi) package ') 117 | print('Insert the regular pip(PyPI) Package name:') 118 | print('Note: Consider the exact writing! Case sensitive!') 119 | PipName =input('PiP-Package Name: ') 120 | if PipName=='q' or PipName=='Q': sys.exit() 121 | if (PipName.endswith('.whl') or PipName.endswith('.zip')) and PipName.find('http'): 122 | print('ERROR: Insert the regular Python pip name not a URL (e.g. "django")') 123 | sys.exit() 124 | 125 | selectedPythonVersion = 0 126 | print("Choose the requiered Python Version:") 127 | print(" Python 1-2: 1,2 ") 128 | print(" Python 3 : 3 ") 129 | 130 | while(True): 131 | temp = input("Python Version:") 132 | if temp=='q' or temp=='Q': sys.exit() 133 | 134 | try: 135 | selectedPythonVersion = int(temp) 136 | except ValueError: 137 | print('Your Input is not valid! Please choose a Number between 1 and 3!') 138 | continue 139 | 140 | if(selectedPythonVersion>=1 and selectedPythonVersion<=3): 141 | break 142 | else: 143 | print('Your Input is not valid! Please choose a Number between 1 and 3!') 144 | 145 | print("Type in the used License name for the recipe (e.g.: MIT)") 146 | licensenName = input('License name: ') 147 | 148 | if licensenName=='\r' or licensenName=='\n\r'or licensenName=='': licensenName='MIT' 149 | if PipName=='q' or PipName=='Q': sys.exit() 150 | print('Chosen License name: "'+licensenName+'"') 151 | print('Starting the generation...\n') 152 | 153 | ################################################ Download the PiP File ########################################### 154 | 155 | # Remove the old temp working directory and create a new one 156 | if not removeWorkingFolder(): 157 | sys.exit() 158 | os.mkdir(WORKING_FOLDER_NAME) 159 | 160 | # Download for testing the pip package 161 | print('--> Download for testing the Python PiP package') 162 | 163 | os.system('pip3 download --no-deps --no-binary :all: --only-binary none -d '+WORKING_FOLDER_NAME+'/ '+Pipurl) 164 | 165 | 166 | 167 | # Reading the downloaded files and detect the file type 168 | targzFiles = [f for f in os.listdir(os.getcwd()+'/'+WORKING_FOLDER_NAME) if f.endswith('.tar.gz')] 169 | zipFiles = [f for f in os.listdir(os.getcwd()+'/'+WORKING_FOLDER_NAME) if f.endswith('.zip')] 170 | 171 | detectedFiletype = 0 # 1= .tar.gz-File | 2= .zip-File 172 | filename = '' 173 | 174 | # Check if the download was successfully 175 | if(len(targzFiles) ==1): 176 | detectedFiletype = 1 177 | filename = targzFiles[0] 178 | elif(len(zipFiles) ==1): 179 | detectedFiletype = 2 180 | filename = zipFiles[0] 181 | else: 182 | print('\n##############################################################################') 183 | print('# ERROR: Failed to download the chosen Python pip (PyPi) package! #') 184 | print('# #') 185 | print('# Please read the error report of the executed "pip" command above! #') 186 | print('# #') 187 | print('# You can use the direct download URL (with ".tar.gz"- or ".zip"- suffix) #') 188 | print('# as pip package name #') 189 | print('# #') 190 | print('# Note: It is only enabled incase the universal source code is available #') 191 | print('# as ".tar.gz" or ".zip" archive file (".whl"-files are not supported) #') 192 | print('# #') 193 | print('##############################################################################\n') 194 | sys.exit() 195 | 196 | print('\n The Name of the downloaded file: \"'+filename+'\"') 197 | 198 | ############################################# Calculate checksums for the file ######################################## 199 | 200 | print('--> Calculate md5 checksum of this file') 201 | md5sum=hashlib.md5(pathlib.Path(os.getcwd()+'/'+WORKING_FOLDER_NAME+'/'+filename).read_bytes()).hexdigest() 202 | print(' md5sum = '+str(md5sum)) 203 | 204 | print('--> Calculate sha256sum checksum of this file') 205 | sha256sum=hashlib.sha256(pathlib.Path(os.getcwd()+'/'+WORKING_FOLDER_NAME+'/'+filename).read_bytes()).hexdigest() 206 | print(' sha256sum = '+str(sha256sum)) 207 | 208 | ######################################### Read the Version Code for this package ###################################### 209 | print('--> Decode the current Version Code of this PiP Package') 210 | 211 | # PIP File name syntax: -. 212 | 213 | decodingversionFailed = False 214 | 215 | pipNamepos = filename.find(PipName) 216 | if pipNamepos ==-1: 217 | # try to replace "-" with "_" 218 | PipName = PipName.replace('-','_') 219 | pipNamepos = filename.find(PipName) 220 | 221 | if (pipNamepos >-1): 222 | # Find the position of the File Suffix 223 | if(detectedFiletype == 1 ): 224 | PipSufixPos = filename.find('.tar.gz') 225 | else: 226 | PipSufixPos = filename.find('.zip') 227 | 228 | if(PipSufixPos >-1 ): 229 | PiPversionStr = filename[pipNamepos+len(PipName+'-'):PipSufixPos] 230 | fileFolderName = filename[:PipSufixPos] 231 | print(' Version: '+PiPversionStr) 232 | else: 233 | decodingversionFailed = True 234 | else: 235 | decodingversionFailed = True 236 | 237 | # In case of Version string encoding trigger an error message 238 | if decodingversionFailed: 239 | print('--> ERROR: Decoding downloaded file failed!') 240 | print(' The file name must be in following syntax:') 241 | print(' -.') 242 | sys.exit() 243 | 244 | 245 | ############################## Read in the Licence File inside the downloaded file ################################### 246 | print('--> Unpackage the downloaded file to decode the included licence file') 247 | 248 | ####### Insert the compressed rootfs to the rootfs folder 249 | print(' Unpackage the downloaded package') 250 | 251 | if(detectedFiletype == 1 ): 252 | os.system('sudo tar -xzpf '+WORKING_FOLDER_NAME+'/'+filename+' -C '+WORKING_FOLDER_NAME) 253 | else: 254 | os.system('unzip '+'WORKING_FOLDER_NAME/'+filename+' -d '+WORKING_FOLDER_NAME) 255 | 256 | # Check if the unpacking was successful 257 | if(os.path.isdir(WORKING_FOLDER_NAME+'/'+fileFolderName)): 258 | print(' Unpackaging was successful') 259 | else: 260 | print('ERROR: The unpacking of the downloaded file failed!') 261 | sys.exit() 262 | 263 | ####### Try to find the Licence file 264 | print(' Try to find a Licence file') 265 | noSufFiles = [f for f in os.listdir(os.getcwd()+'/'+WORKING_FOLDER_NAME+'/'+fileFolderName) if f.endswith('')] 266 | LicenseFileFoundingError = False 267 | 268 | LicenseFileType =0 # 1: LICENSE.txt | 2: LICENSE | 3: any other file (see LicenseFileName) 269 | LicenseFileName='' 270 | 271 | if(len(noSufFiles) >-1): 272 | while(True): 273 | LicenseFileType = LicenseFileType +1 274 | LicenseFileFoundingError =False 275 | # Search for the LICENCE File 276 | try: 277 | if(LicenseFileType==1): 278 | LicenseFilePos =noSufFiles.index('LICENSE.txt') 279 | LicenseFileName = 'LICENSE.txt' 280 | elif (LicenseFileType==2): 281 | LicenseFilePos =noSufFiles.index('LICENSE') 282 | LicenseFileName = 'LICENSE' 283 | except ValueError: 284 | LicenseFileFoundingError =True 285 | 286 | if(not LicenseFileFoundingError): 287 | if(LicenseFilePos >-1): 288 | print(' The License File was found') 289 | break 290 | else: 291 | LicenseFileFoundingError = True 292 | 293 | if LicenseFileType == 2: 294 | # Use any other file as LICENSE-File 295 | print('NOTE: The LICENSE-File was not found inside the PiP-Package!') 296 | for it in noSufFiles: 297 | if(os.path.isfile(os.getcwd()+'/'+WORKING_FOLDER_NAME+'/'+fileFolderName+'/'+it)): 298 | LicenseFileName = it 299 | 300 | if(LicenseFileName ==""): 301 | LicenseFileFoundingError = True 302 | else: 303 | print(' To avoid this problem the File:\"'+LicenseFileName +'\" will be used instead') 304 | LicenseFileType =3 305 | LicenseFileFoundingError = False 306 | break 307 | # Try to find the LICENSE without a suffix (type =2) 308 | else: 309 | LicenseFileFoundingError = True 310 | 311 | if LicenseFileFoundingError: 312 | print('ERROR: No LICENSE.txt or LICENSE file inside this PiP-Package found!') 313 | sys.exit() 314 | 315 | ####### Calculate the md5sum for LICENSE.txt 316 | print('--> Calculate the md5-checksum for the License file') 317 | 318 | LicenseMd5sum=hashlib.md5(pathlib.Path(os.getcwd()+'/'+WORKING_FOLDER_NAME+'/'+fileFolderName+'/'+LicenseFileName).read_bytes()).hexdigest() 319 | print(' md5sum = '+str(LicenseMd5sum)) 320 | 321 | ########## 322 | # At this point the user input is valide and checked 323 | 324 | ############################## Giving the .bb ################################### 325 | 326 | # Yocto allows only lower case numbers without numbers and others caractors 327 | 328 | # Check if there are only lower cases in the chosen PiP-name 329 | tempName='' 330 | for c in PipName: 331 | if not c.islower(): 332 | # if not set character low 333 | c = c.lower() 334 | tempName=tempName+c 335 | RecipeFileName = tempName 336 | 337 | # Check if any not allowed characters are in this string and remove them 338 | pos =0 339 | tempName='' 340 | for c in RecipeFileName: 341 | if not re.match('^[0-9]*$', c): 342 | tempName=tempName+c 343 | 344 | RecipeFileName = tempName 345 | 346 | ############################################################################################################ 347 | # # 348 | # Collected Variables for Building a recipes for embedding Python PiP-packages to the Yocto Project # 349 | # # 350 | # PipName -> PiP Package name # 351 | # selectedPythonVersion -> required Python Version (1,2,3) # 352 | # licensenName -> License Type Name (e.g. MIT) # 353 | # md5sum -> PiP Package md5 checksum # 354 | # sha256sum -> PiP Package sha256 checksum # 355 | # PiPversionStr -> piP Package Version String # 356 | # LicenseFileName -> the file name of License File # 357 | # LicenseMd5sum -> md5 checksum of the License file # 358 | # RecipeFileName -> name of the two recipe files (without suffix) # 359 | # # 360 | # # 361 | # # 362 | ############################################################################################################ 363 | 364 | 365 | ############################## Create the .bb-Bitbake file ################################### 366 | 367 | #### Create a new blank .bb-file 368 | # File syntax: pip-_. 369 | bbfilename = 'pip-'+RecipeFileName+'_'+PiPversionStr+'.bb' 370 | inheritPiPstr = '','inherit pypi setuptools','inherit pypi setuptools','inherit pypi setuptools3' 371 | print('--> Create the Bitbake .bb-File with the name') 372 | print(' '+bbfilename) 373 | 374 | if(os.path.isfile(bbfilename)): 375 | os.remove(bbfilename) 376 | 377 | try: 378 | fp = open(bbfilename) 379 | except IOError: 380 | # If not exists, create the file 381 | fp = open(bbfilename, 'w+') 382 | 383 | ########### Generate the conntet of the .bb-file 384 | bbFileContent = '# The is automatic generated Code by "makePipRecipes.py"\n' \ 385 | '# (build by Robin Sebastian (https://github.com/robseb) (git@robseb.de) Vers.: '+version+') \n' \ 386 | '\n' \ 387 | 'SUMMARY = "Recipe to embedded the Python PiP Package '+PipName+'"\n' \ 388 | 'HOMEPAGE ="https://pypi.org/project/'+PipName+'"\n' \ 389 | 'LICENSE = "'+licensenName+'"\n' \ 390 | 'LIC_FILES_CHKSUM = "file://'+LicenseFileName+';md5='+LicenseMd5sum+'"\n' \ 391 | '\n' \ 392 | +inheritPiPstr[selectedPythonVersion]+'\n' \ 393 | 'PYPI_PACKAGE = "'+PipName+'"\n' \ 394 | 'SRC_URI[md5sum] = "'+md5sum+'"\n' \ 395 | 'SRC_URI[sha256sum] = "'+sha256sum+'"\n' 396 | 397 | print('--> Generate the content of this file') 398 | with open(bbfilename, "a") as f: 399 | f.write(bbFileContent) 400 | 401 | # Download for test the pip package 402 | print(' Bitbake file generation was successfull') 403 | 404 | 405 | ############################ Remove the Working Folder ################################ 406 | print('--> Deleting the working Folder') 407 | removeWorkingFolder() 408 | 409 | ############################## Implementation Guide ################################### 410 | print('\n################################################################################') 411 | print('# #') 412 | print('# GENERATION WAS SUCCESSFUL #') 413 | print('# #') 414 | print('#---------------------------- Implementation Guide ----------------------------#') 415 | print('# 1. Step: Copy the recipe file: \"'+bbfilename+'\" ') 416 | print('# to your recipe folder inside a meta layer ') 417 | print('# For example here: ') 418 | print('# meta-example ') 419 | print('# |- conf ') 420 | print('# |- recipes-test ') 421 | print('# |- test ') 422 | print('# |- '+bbfilename+' <--\n ') 423 | print('# (this file is located here:'+os.getcwd()+' ) ') 424 | print('# 2. Step: Include the PiP-Package to your Yocto Project by ') 425 | print('# by adding following line to the conf/local.conf file: ') 426 | print('# conf/local.conf: ') 427 | print('# IMAGE_INSTALL_append = "pip-'+RecipeFileName+'"\n ') 428 | print('# 3. Step: Build your Yocto Project normanly with bitbake\n ') 429 | print('#------------------------------------------------------------------------------#') 430 | print('# #') 431 | print('# SUPPORT THE AUTHOR #') 432 | print('# #') 433 | print('# ROBIN SEBASTIAN #') 434 | print('# (https://github.com/robseb/) #') 435 | print('# git@robseb.de #') 436 | print('# #') 437 | print('# makePipRecipes and rsYocto are projects, that I have fully #') 438 | print('# developed on my own. No companies are involved in this projects. #') 439 | print('# I am recently graduated as Master of Since of electronic engineering #') 440 | print('# Please support me for further development #') 441 | print('# #') 442 | print('################################################################################') 443 | # EOF --------------------------------------------------------------------------------