├── .cproject ├── .gitignore ├── .project ├── .pydevproject ├── .settings └── language.settings.xml ├── ChangeLog.md ├── LICENSE ├── README.md ├── edapack ├── __init__.py ├── __main__.py ├── avail_m.py ├── install_m.py ├── link_m.py ├── plugins_m.py ├── read_packages.py ├── tempdir_m.py ├── update_m.py └── update_scripts_m.py ├── etc ├── edapack.index ├── package.info └── sources ├── modulefiles ├── python3 └── tcl ├── plugins └── edapack_link_quartus.py ├── scripts ├── Makefile ├── edapack ├── edapack.csh ├── edapack.sh ├── mkfiles │ ├── fusesoc.mk │ └── python.mk └── modules.patch ├── setup.py └── templates └── edapack_link_template.py /.cproject: -------------------------------------------------------------------------------- 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 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | packages/ 3 | __pycache__/ 4 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | edapack 4 | 5 | 6 | 7 | 8 | 9 | org.python.pydev.PyDevBuilder 10 | 11 | 12 | 13 | 14 | 15 | org.python.pydev.pythonNature 16 | 17 | 18 | -------------------------------------------------------------------------------- /.pydevproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /${PROJECT_DIR_NAME}/edapack 5 | 6 | python interpreter 7 | Default 8 | 9 | -------------------------------------------------------------------------------- /.settings/language.settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /ChangeLog.md: -------------------------------------------------------------------------------- 1 | # ChangeLog 2 | 3 | ## 0.0.6 4 | - Add support for linking Quartus installations into an EDAPack tree 5 | - Add plug-in support for creating custom link plug-ins 6 | 7 | ## 0.0.5 8 | - Correct an erroneous import in a core script 9 | 10 | ## 0.0.4 11 | - Add GTKWave support 12 | 13 | ## 0.0.3 14 | - Add support for updating packages 15 | 16 | ## 0.0.2 17 | - Correct an issue with path location in the edapack script 18 | 19 | - Correct an issue with the index URL in etc/sources 20 | 21 | - Enhance the install process to update source indexes first 22 | 23 | ## 0.0.1 24 | 25 | - Initial trial release of EDAPack. Linux-only, and just a couple of tools. 26 | 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, and 10 | distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright 13 | owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all other entities 16 | that control, are controlled by, or are under common control with that entity. 17 | For the purposes of this definition, "control" means (i) the power, direct or 18 | indirect, to cause the direction or management of such entity, whether by 19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the 20 | outstanding shares, or (iii) beneficial ownership of such entity. 21 | 22 | "You" (or "Your") shall mean an individual or Legal Entity exercising 23 | permissions granted by this License. 24 | 25 | "Source" form shall mean the preferred form for making modifications, including 26 | but not limited to software source code, documentation source, and configuration 27 | files. 28 | 29 | "Object" form shall mean any form resulting from mechanical transformation or 30 | translation of a Source form, including but not limited to compiled object code, 31 | generated documentation, and conversions to other media types. 32 | 33 | "Work" shall mean the work of authorship, whether in Source or Object form, made 34 | available under the License, as indicated by a copyright notice that is included 35 | in or attached to the work (an example is provided in the Appendix below). 36 | 37 | "Derivative Works" shall mean any work, whether in Source or Object form, that 38 | is based on (or derived from) the Work and for which the editorial revisions, 39 | annotations, elaborations, or other modifications represent, as a whole, an 40 | original work of authorship. For the purposes of this License, Derivative Works 41 | shall not include works that remain separable from, or merely link (or bind by 42 | name) to the interfaces of, the Work and Derivative Works thereof. 43 | 44 | "Contribution" shall mean any work of authorship, including the original version 45 | of the Work and any modifications or additions to that Work or Derivative Works 46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work 47 | by the copyright owner or by an individual or Legal Entity authorized to submit 48 | on behalf of the copyright owner. For the purposes of this definition, 49 | "submitted" means any form of electronic, verbal, or written communication sent 50 | to the Licensor or its representatives, including but not limited to 51 | communication on electronic mailing lists, source code control systems, and 52 | issue tracking systems that are managed by, or on behalf of, the Licensor for 53 | the purpose of discussing and improving the Work, but excluding communication 54 | that is conspicuously marked or otherwise designated in writing by the copyright 55 | owner as "Not a Contribution." 56 | 57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf 58 | of whom a Contribution has been received by Licensor and subsequently 59 | incorporated within the Work. 60 | 61 | 2. Grant of Copyright License. 62 | 63 | Subject to the terms and conditions of this License, each Contributor hereby 64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 65 | irrevocable copyright license to reproduce, prepare Derivative Works of, 66 | publicly display, publicly perform, sublicense, and distribute the Work and such 67 | Derivative Works in Source or Object form. 68 | 69 | 3. Grant of Patent License. 70 | 71 | Subject to the terms and conditions of this License, each Contributor hereby 72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 73 | irrevocable (except as stated in this section) patent license to make, have 74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where 75 | such license applies only to those patent claims licensable by such Contributor 76 | that are necessarily infringed by their Contribution(s) alone or by combination 77 | of their Contribution(s) with the Work to which such Contribution(s) was 78 | submitted. If You institute patent litigation against any entity (including a 79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a 80 | Contribution incorporated within the Work constitutes direct or contributory 81 | patent infringement, then any patent licenses granted to You under this License 82 | for that Work shall terminate as of the date such litigation is filed. 83 | 84 | 4. Redistribution. 85 | 86 | You may reproduce and distribute copies of the Work or Derivative Works thereof 87 | in any medium, with or without modifications, and in Source or Object form, 88 | provided that You meet the following conditions: 89 | 90 | You must give any other recipients of the Work or Derivative Works a copy of 91 | this License; and 92 | You must cause any modified files to carry prominent notices stating that You 93 | changed the files; and 94 | You must retain, in the Source form of any Derivative Works that You distribute, 95 | all copyright, patent, trademark, and attribution notices from the Source form 96 | of the Work, excluding those notices that do not pertain to any part of the 97 | Derivative Works; and 98 | If the Work includes a "NOTICE" text file as part of its distribution, then any 99 | Derivative Works that You distribute must include a readable copy of the 100 | attribution notices contained within such NOTICE file, excluding those notices 101 | that do not pertain to any part of the Derivative Works, in at least one of the 102 | following places: within a NOTICE text file distributed as part of the 103 | Derivative Works; within the Source form or documentation, if provided along 104 | with the Derivative Works; or, within a display generated by the Derivative 105 | Works, if and wherever such third-party notices normally appear. The contents of 106 | the NOTICE file are for informational purposes only and do not modify the 107 | License. You may add Your own attribution notices within Derivative Works that 108 | You distribute, alongside or as an addendum to the NOTICE text from the Work, 109 | provided that such additional attribution notices cannot be construed as 110 | modifying the License. 111 | You may add Your own copyright statement to Your modifications and may provide 112 | additional or different license terms and conditions for use, reproduction, or 113 | distribution of Your modifications, or for any such Derivative Works as a whole, 114 | provided Your use, reproduction, and distribution of the Work otherwise complies 115 | with the conditions stated in this License. 116 | 117 | 5. Submission of Contributions. 118 | 119 | Unless You explicitly state otherwise, any Contribution intentionally submitted 120 | for inclusion in the Work by You to the Licensor shall be under the terms and 121 | conditions of this License, without any additional terms or conditions. 122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of 123 | any separate license agreement you may have executed with Licensor regarding 124 | such Contributions. 125 | 126 | 6. Trademarks. 127 | 128 | This License does not grant permission to use the trade names, trademarks, 129 | service marks, or product names of the Licensor, except as required for 130 | reasonable and customary use in describing the origin of the Work and 131 | reproducing the content of the NOTICE file. 132 | 133 | 7. Disclaimer of Warranty. 134 | 135 | Unless required by applicable law or agreed to in writing, Licensor provides the 136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, 137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, 138 | including, without limitation, any warranties or conditions of TITLE, 139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are 140 | solely responsible for determining the appropriateness of using or 141 | redistributing the Work and assume any risks associated with Your exercise of 142 | permissions under this License. 143 | 144 | 8. Limitation of Liability. 145 | 146 | In no event and under no legal theory, whether in tort (including negligence), 147 | contract, or otherwise, unless required by applicable law (such as deliberate 148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be 149 | liable to You for damages, including any direct, indirect, special, incidental, 150 | or consequential damages of any character arising as a result of this License or 151 | out of the use or inability to use the Work (including but not limited to 152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or 153 | any and all other commercial damages or losses), even if such Contributor has 154 | been advised of the possibility of such damages. 155 | 156 | 9. Accepting Warranty or Additional Liability. 157 | 158 | While redistributing the Work or Derivative Works thereof, You may choose to 159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or 160 | other liability obligations and/or rights consistent with this License. However, 161 | in accepting such obligations, You may act only on Your own behalf and on Your 162 | sole responsibility, not on behalf of any other Contributor, and only if You 163 | agree to indemnify, defend, and hold each Contributor harmless for any liability 164 | incurred by, or claims asserted against, such Contributor by reason of your 165 | accepting any such warranty or additional liability. 166 | 167 | END OF TERMS AND CONDITIONS 168 | 169 | APPENDIX: How to apply the Apache License to your work 170 | 171 | To apply the Apache License to your work, attach the following boilerplate 172 | notice, with the fields enclosed by brackets "[]" replaced with your own 173 | identifying information. (Don't include the brackets!) The text should be 174 | enclosed in the appropriate comment syntax for the file format. We also 175 | recommend that a file or class name and description of purpose be included on 176 | the same "printed page" as the copyright notice for easier identification within 177 | third-party archives. 178 | 179 | Copyright [yyyy] [name of copyright owner] 180 | 181 | Licensed under the Apache License, Version 2.0 (the "License"); 182 | you may not use this file except in compliance with the License. 183 | You may obtain a copy of the License at 184 | 185 | http://www.apache.org/licenses/LICENSE-2.0 186 | 187 | Unless required by applicable law or agreed to in writing, software 188 | distributed under the License is distributed on an "AS IS" BASIS, 189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 190 | See the License for the specific language governing permissions and 191 | limitations under the License. 192 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | edapack 2 | ======= 3 | 4 | EDAPack provides a simple way to install and manage EDA tools, along with a packaged collection of open source EDA tools. This project (edapack) provides the base software needed to install and manage other tool installations. Other projects under the EDAPack GitHub organization provide the specific tool builds. 5 | 6 | 7 | # Installing 8 | Install the EDAPack base tools by downloading the latest release from GitHub. Extract the .tar.gz file. 9 | 10 | # Environment Setup 11 | Source /etc/edapack.sh to configure the environment. This adds the 'edapack' command to your path, and configures Environment Modules. 12 | 13 | # Installing Tools 14 | Run 'edapack avail' to list the packages that are available to install. 15 | Run 'edapack install ' will download and install one of the packages shown by 'edapack avail' 16 | 17 | # Enable Tools 18 | Configuring tools in the environment is done via the 'module' command. 'module avail' lists tools and tool versions that can be added to the environment. 'module load ' enables a specific tool. The most-recent installed tool version can always be enabled by loading /latest. To load the latest version of Verilator, for example, 'module load verilator/latest'. 19 | 20 | 21 | -------------------------------------------------------------------------------- /edapack/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | try: 3 | from edapack.version import version as __version__ 4 | except ImportError: 5 | __version__ = "unknown" 6 | 7 | 8 | -------------------------------------------------------------------------------- /edapack/__main__.py: -------------------------------------------------------------------------------- 1 | #**************************************************************************** 2 | #* edapack __main__.py 3 | #* 4 | #* Main entry point for the 'edapack' command 5 | #* 6 | #**************************************************************************** 7 | import argparse 8 | import configparser 9 | import os 10 | 11 | # Bring in local modules 12 | from . import install_m 13 | from . import avail_m 14 | from . import update_m 15 | from . import tempdir_m 16 | from . import update_scripts_m 17 | from . import link_m 18 | from . import plugins_m 19 | 20 | #******************************************************************** 21 | #* Bring in the script version 22 | #******************************************************************** 23 | try: 24 | from . import version 25 | version = version.version 26 | except Exception as e: 27 | version = "unknown" 28 | 29 | # Installation steps 30 | # - Fetch package to a temporary location 31 | # - Determine the package version 32 | # - Determine whether the version is already installed 33 | # - Abort unless --force 34 | # - Remove old package if --force 35 | # - Unpack into install_m location 36 | # - 37 | 38 | def main(): 39 | main_arguments = argparse.ArgumentParser() 40 | 41 | main_arguments.add_argument("-p", action="append", 42 | help="Append to plug-in path") 43 | 44 | subparsers = main_arguments.add_subparsers( 45 | help="EDAPack sub-commands", 46 | dest="subparser_name") 47 | avail_cmd = subparsers.add_parser("avail", help="checks for available packages") 48 | avail_cmd.add_argument("--no-update-indexes", 49 | action="store_true", 50 | default=False, 51 | help="Disable updating of package-index files") 52 | 53 | install_cmd = subparsers.add_parser("install", help="installs one or more packages") 54 | install_cmd.add_argument("--no-update-indexes", 55 | action="store_true", 56 | default=False, 57 | help="Disable updating of package-index files") 58 | 59 | install_cmd.add_argument("packages", nargs="+", 60 | help="package identifiers of packages to install") 61 | # help="Package identifier, archive path, or URL") 62 | 63 | link_cmd = subparsers.add_parser("link", help="links external tools into an EDAPack installation") 64 | # link_cmd.add_argument("-create-link", action="store_true", 65 | # help="Creates a link to the tool installation inside the EDAPack tree") 66 | link_cmd.add_argument("-version", help="specifies the tool version if it cannot be determined") 67 | link_cmd.add_argument("tool", help="specifies the name of the tool to link") 68 | link_cmd.add_argument("tool_path", help="specifies the installation location for the tool") 69 | 70 | list_plugins_cmd = subparsers.add_parser("list-plugins", 71 | help="Lists available plug-ins") 72 | list_plugins_cmd.add_argument("-p", action="append", 73 | help="Specifies entries to the plug-in path") 74 | 75 | update_cmd = subparsers.add_parser("update", help="updates all packages, or a select set") 76 | update_cmd.add_argument("packages", nargs="*", help="specifies the packages to update") 77 | update_cmd.add_argument("-y", 78 | action="store_true", 79 | help="Forces installation without confirmation") 80 | # update_cmd.add_argument("--check-only", help="Only checks for newer packages") 81 | # update_cmd.add_argument("--no-update-indexes", 82 | # action="store_true", 83 | # help="Disable updating of package-index files") 84 | 85 | update_scripts_cmd = subparsers.add_parser("update-scripts", 86 | help="updates the EDAPack core scripts") 87 | update_scripts_cmd.add_argument("--force", 88 | action="store_true", 89 | help="force updating scripts") 90 | 91 | # check_update_cmd = subparsers.add_parser("check-update", help="Checks for available package updates") 92 | 93 | args = main_arguments.parse_args() 94 | 95 | if args.subparser_name == "avail": 96 | avail_m.avail(args) 97 | elif args.subparser_name == "install": 98 | install_m.install(args) 99 | elif args.subparser_name == "link": 100 | link_m.link(args) 101 | elif args.subparser_name == "list-plugins": 102 | plugins_m.list_plugins(args) 103 | elif args.subparser_name == "update": 104 | update_m.update(args) 105 | elif args.subparser_name == "update-scripts": 106 | update_scripts_m.update_scripts(args) 107 | else: 108 | main_arguments.print_help() 109 | exit(1) 110 | 111 | 112 | if __name__ == "__main__": 113 | main() 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /edapack/avail_m.py: -------------------------------------------------------------------------------- 1 | #**************************************************************************** 2 | #* avail_m.py 3 | #* 4 | #* Implements the EDAPack 'avail' command to list available packages 5 | #**************************************************************************** 6 | from . import read_packages 7 | from . import update_m 8 | 9 | #******************************************************************** 10 | #* avail 11 | #******************************************************************** 12 | def avail(args): 13 | print("Available EDAPack packages") 14 | 15 | # Get the latest indexes before listing available packages 16 | if args.no_update_indexes == False: 17 | update_m.update_indexes() 18 | 19 | packages = read_packages.read_packages() 20 | 21 | max_len = 0 22 | for pkg in packages.keys(): 23 | if len(pkg) > max_len: 24 | max_len = len(pkg) 25 | 26 | fmt_string = "%-" + str(max_len) + "s - %s" 27 | for pkg in sorted(packages.keys()): 28 | print(fmt_string % (pkg, packages[pkg].description)) 29 | -------------------------------------------------------------------------------- /edapack/install_m.py: -------------------------------------------------------------------------------- 1 | #**************************************************************************** 2 | #* install_m.py 3 | #* 4 | #* Implements the install command for EDAPack 5 | #**************************************************************************** 6 | 7 | from github import Github 8 | from subprocess import call 9 | import os 10 | import sys 11 | import platform 12 | import urllib 13 | import tarfile 14 | from . import read_packages 15 | from . import tempdir_m 16 | from . import update_m 17 | 18 | 19 | #******************************************************************** 20 | #* install 21 | #******************************************************************** 22 | def install(args): 23 | # First update indexes 24 | if args.no_update_indexes == False: 25 | update_m.update_indexes() 26 | 27 | packages = read_packages.read_packages() 28 | 29 | # First, validate that all packages exist 30 | for pkg in args.packages: 31 | if (pkg in packages.keys()) == False and os.path.exists(pkg) == False and pkg.startswith("http://") == False and pkg.startswith("https://") == False: 32 | print("Error: package \"" + pkg + "\" does not exist"); 33 | exit(1) 34 | 35 | # Okay, now we believe that we know how to deal with all packages 36 | for pkg in args.packages: 37 | if pkg in packages.keys(): 38 | print("Note: installing package \"" + pkg + "\"") 39 | install_index_pkg(packages[pkg]) 40 | 41 | edapack_script_dir = os.path.dirname(os.path.abspath(__file__)) 42 | # print("edapack_script_dir=" + edapack_script_dir) 43 | 44 | # First, validate that all packages make sense 45 | # for pkg in args.packages: 46 | # print("package=" + pkg); 47 | 48 | #******************************************************************** 49 | #* install_index_pkg 50 | #******************************************************************** 51 | def install_index_pkg(pkg_src): 52 | tempdir = tempdir_m.mktempdir() 53 | 54 | without_protocol = pkg_src.url[pkg_src.url.find("://")+3:] 55 | path = without_protocol.split('/') 56 | archive = None 57 | if path[0] == "github.com": 58 | # Okay, we know how to work with this 59 | archive = fetch_github(path[1], path[2], pkg_src.id, tempdir) 60 | else: 61 | print("Error: unsupported host (" + path[0] + ") in URL " + pkg_src.url) 62 | exit(1) 63 | 64 | install_tar_gz(archive, True) 65 | 66 | 67 | def fetch_github(org_user, repo, id, tempdir): 68 | # TODO: need to probe platform 69 | pkg_platform_prefix = id + "-" + "linux" + "_" + "x86_64"; 70 | pkg_any_prefix = id + "-" + "any"; 71 | 72 | if os.getenv("GITHUB_API_TOKEN") is not None: 73 | g = Github(os.environ['GITHUB_API_TOKEN']) 74 | else: 75 | g = Github() 76 | 77 | org = g.get_organization(org_user); 78 | if org != None: 79 | r = org.get_repo(repo) 80 | else: 81 | user = g.get_user(org_user) 82 | if user == None: 83 | print("Error: specified organization or user (" + org_user + ") is invalid"); 84 | exit(1) 85 | else: 86 | r = user.get_repo(repo) 87 | 88 | if r == None: 89 | print("Error: Failed to obtain repository " + repo + " for org/user " + org_user) 90 | exit(1) 91 | 92 | latest = r.get_latest_release() 93 | 94 | if latest == None: 95 | print("Error: there doesn't appear to be a release on GitHub for " + org_user + "/" + repo) 96 | exit(1) 97 | 98 | assets = latest.get_assets() 99 | pkg_asset = None 100 | for asset in assets: 101 | # print("asset.name=" + asset.name + " pkg_prefix=" + pkg_platform_prefix) 102 | if (asset.name.startswith(pkg_platform_prefix) or asset.name.startswith(pkg_any_prefix)) and asset.name.endswith(".tar.gz"): 103 | pkg_asset = asset 104 | break 105 | 106 | if pkg_asset == None: 107 | print("Error: failed to find a package to download for " + org_user + "/" + repo) 108 | exit(1) 109 | 110 | print("Note: downloading package from " + pkg_asset.browser_download_url) 111 | 112 | package_path = os.path.join(tempdir, os.path.basename(pkg_asset.name)) 113 | response = urllib.request.urlretrieve( 114 | pkg_asset.browser_download_url, 115 | package_path) 116 | 117 | print("Done... ") 118 | return package_path 119 | 120 | 121 | def install_tar_gz(archive, in_tempdir): 122 | if in_tempdir == True: 123 | tempdir = os.path.dirname(archive) 124 | else: 125 | tempdir = tempdir_m.mktempdir() 126 | 127 | # Extract etc/install.py and etc/package.info 128 | tf = tarfile.open(archive, "r:gz") 129 | tf.extract("etc/package.info", tempdir) 130 | tf.extract("etc/install.py", tempdir) 131 | 132 | # Run the installer 133 | print("Note: running package installer") 134 | call([sys.executable, 135 | os.path.join(tempdir, "etc/install.py"), 136 | "install", 137 | read_packages.edapack_dir(), 138 | "--archive", archive]) 139 | print("Done!") 140 | 141 | 142 | -------------------------------------------------------------------------------- /edapack/link_m.py: -------------------------------------------------------------------------------- 1 | #**************************************************************************** 2 | #* link_m.py 3 | #**************************************************************************** 4 | import os 5 | import importlib.util 6 | from . import read_packages 7 | from . import plugins_m 8 | 9 | #******************************************************************** 10 | #* link() 11 | #* Entry-point for the link command 12 | #******************************************************************** 13 | def link(args): 14 | 15 | edapack = read_packages.edapack_dir(); 16 | plugin_path = plugins_m.get_plugin_path(args.p) 17 | 18 | # Validate that the tool location exists 19 | if os.path.isdir(args.tool_path) == False: 20 | print("Error: tool-installation path \"" + args.tool_path + "\" does not exist") 21 | exit(1) 22 | 23 | # Try to find the link plug-in on the plug-in path 24 | link_plugin = "" 25 | for pd in plugin_path: 26 | for file in os.listdir(pd): 27 | if file.startswith("edapack_link_") and file.endswith(".py"): 28 | if file == "edapack_link_" + args.tool + ".py": 29 | link_plugin = os.path.join(pd, file) 30 | break 31 | if link_plugin != "": 32 | break 33 | 34 | if link_plugin == "": 35 | print("Error: no link plug-in found for tool \"" + args.tool + "\"") 36 | print(" Try running edapack list-plugins to see available plug-ins") 37 | raise("Failed to find link plug-in") 38 | 39 | 40 | # Okay, load the plug-in and see what we can do 41 | spec = importlib.util.spec_from_file_location(os.path.basename(link_plugin), link_plugin) 42 | plugin_module = importlib.util.module_from_spec(spec) 43 | spec.loader.exec_module(plugin_module) 44 | 45 | print("Note: validating installation directory..."); 46 | try: 47 | plugin_module.validate_tool_install(args.tool_path) 48 | except Exception as e: 49 | print("Error: installation path is invalid (" + str(e) + ")") 50 | exit(1) 51 | 52 | # Now, see if we can get a version 53 | if args.version != None: 54 | version = args.version 55 | else: 56 | try: 57 | version = plugin_module.get_tool_version(args.tool_path) 58 | except: 59 | print("Error: no -version specified, and \"" + args.tool + "\" version cannot be queried from install") 60 | exit(1) 61 | 62 | # Okay, now we have 63 | # - link plug-in 64 | # - tool install path 65 | # - tool version 66 | # 67 | # Next, we need to create the modulefile and add it to the EDAPack tree 68 | modulefile = plugin_module.get_modulefile(args.tool_path, version) 69 | 70 | # Create the modulefiles dir if it doesn't exist 71 | if os.path.isdir(os.path.join(edapack, "modulefiles", args.tool)) == False: 72 | os.makedirs(os.path.join(edapack, "modulefiles", args.tool)) 73 | 74 | # First, determine whether we should update the 'latest' modulefile version 75 | is_latest = True 76 | for exist_ver in os.listdir(os.path.join(edapack, "modulefiles", args.tool)): 77 | if exist_ver != "latest": 78 | if read_packages.compare_versions(version, exist_ver) == False: 79 | is_latest = False 80 | break 81 | 82 | # Now, create a version-specific modulefile 83 | print("Note: creating modulefile...") 84 | fp = open(os.path.join(edapack, "modulefiles", args.tool, version), "w") 85 | fp.write(modulefile) 86 | fp.close() 87 | 88 | # See if we also need to update the 'latest' 89 | if is_latest == True: 90 | print("Note: updating 'latest' link...") 91 | fp = open(os.path.join(edapack, "modulefiles", args.tool, "latest"), "w") 92 | fp.write(modulefile) 93 | fp.close() 94 | 95 | print("Note: done!") 96 | 97 | -------------------------------------------------------------------------------- /edapack/plugins_m.py: -------------------------------------------------------------------------------- 1 | #**************************************************************************** 2 | #* plugins_m.py 3 | #**************************************************************************** 4 | import os 5 | import importlib.util 6 | from . import read_packages 7 | 8 | def get_plugin_path(extra_plugins=None): 9 | edapack = read_packages.edapack_dir(); 10 | plugin_path = [os.path.join(edapack, "lib", "plugins")] 11 | 12 | # Build up the plug-in path first 13 | if extra_plugins != None: 14 | for path in extra_plugins: 15 | plugin_path.append(path) 16 | 17 | if "EDAPACK_PLUGIN_PATH" in os.environ.keys(): 18 | path = os.environ["EDAPACK_PLUGIN_PATH"] 19 | for elem in path.split(":"): 20 | elem = elem.strip() 21 | 22 | if elem != "": 23 | if os.path.isdir(elem): 24 | plugin_path.append(elem) 25 | else: 26 | print("Warning: ignoring non-existent plug-in path dir \"" + elem + "\"") 27 | 28 | return plugin_path 29 | 30 | #******************************************************************** 31 | #* load_plugin() 32 | #******************************************************************** 33 | def load_plugin(plugin): 34 | spec = importlib.util.spec_from_file_location( 35 | os.path.basename(plugin), 36 | plugin) 37 | plugin_module = importlib.util.module_from_spec(spec) 38 | spec.loader.exec_module(plugin_module) 39 | 40 | return plugin_module 41 | 42 | #******************************************************************** 43 | #* list_plugins() 44 | #* Entry-point for the list-plugins command 45 | #******************************************************************** 46 | def list_plugins(args): 47 | 48 | plugin_path = get_plugin_path(args.p) 49 | 50 | link_plugins = {} 51 | 52 | for pd in plugin_path: 53 | for file in os.listdir(pd): 54 | if file.startswith("edapack_") and file.endswith(".py"): 55 | if file.startswith("edapack_link_"): 56 | id = file[len("edapack_link_"):len(file)-3] 57 | link_plugins[id] = os.path.join(pd, file) 58 | else: 59 | # Ignore plug-ins that we don't recognize 60 | print("Warning: unknown plug-in type for file \"" + file + "\"") 61 | 62 | 63 | # Link plug-ins first 64 | print("Link Plug-ins:") 65 | for id in sorted(link_plugins.keys()): 66 | plugin = load_plugin(link_plugins[id]) 67 | try: 68 | desc = plugin.get_short_description() 69 | except Exception as e: 70 | desc = "(Error: exception thrown)" 71 | 72 | print(" " + id + ": " + desc) 73 | -------------------------------------------------------------------------------- /edapack/read_packages.py: -------------------------------------------------------------------------------- 1 | #**************************************************************************** 2 | #* read_packages.py 3 | #**************************************************************************** 4 | 5 | import os; 6 | import configparser 7 | 8 | class package_src: 9 | def __init__(self, source, id, description, url): 10 | self.source = source 11 | self.id = id 12 | self.description = description 13 | self.url = url 14 | 15 | class source: 16 | def __init__(self, source, url): 17 | self.source = source 18 | self.url = url 19 | 20 | 21 | #******************************************************************** 22 | #* edapack_dir 23 | #******************************************************************** 24 | def edapack_dir(): 25 | edapack_pkg_dir = os.path.dirname(os.path.abspath(__file__)) 26 | edapack_lib_dir = os.path.dirname(edapack_pkg_dir) 27 | 28 | edapack = os.path.dirname(edapack_lib_dir) 29 | 30 | return edapack 31 | 32 | def read_index(path, source, packages): 33 | index = configparser.ConfigParser() 34 | index.read(path) 35 | 36 | for pkg in index.sections(): 37 | packages[pkg] = package_src( 38 | source, pkg, 39 | index[pkg]["description"], 40 | index[pkg]["url"]) 41 | 42 | def read_sources(): 43 | srcs = [] 44 | edapack = edapack_dir() 45 | sources = configparser.ConfigParser() 46 | if os.path.exists(os.path.join(edapack, "etc", "sources")) == False: 47 | print("Error: etc/sources doesn't exist") 48 | exit(1) 49 | 50 | sources.read(os.path.join(edapack, "etc", "sources")) 51 | 52 | for src in sources.sections(): 53 | srcs.append(source(src, sources[src]['url'])) 54 | 55 | 56 | return srcs 57 | 58 | def read_packages(): 59 | packages = {} 60 | edapack = edapack_dir() 61 | sources = configparser.ConfigParser() 62 | if os.path.exists(os.path.join(edapack, "etc", "sources")) == False: 63 | print("Error: etc/sources doesn't exist") 64 | exit(1) 65 | 66 | sources.read(os.path.join(edapack, "etc", "sources")) 67 | 68 | for source in sources.sections(): 69 | 70 | index_path = os.path.join(edapack, "etc", source + ".index") 71 | 72 | if os.path.exists(index_path) == True: 73 | read_index(index_path, source, packages) 74 | else: 75 | print("Error: index file \"" + index_path + "\" does not exist") 76 | exit(1) 77 | 78 | return packages 79 | 80 | def compare_versions(v1, v2): 81 | v1_list = v1.split(".") 82 | v2_list = v2.split(".") 83 | 84 | # Ensure the versions are the same length 85 | while len(v1_list) < len(v2_list): 86 | v1_list.append("0") 87 | while len(v2_list) < len(v1_list): 88 | v2_list.append("0") 89 | 90 | # Convert each version to an integer that can be compared 91 | v1_val = 0 92 | v2_val = 0 93 | for i in range(len(v1_list)): 94 | v1_val *= 10 95 | v1_val += int(v1_list[i]) 96 | for i in range(len(v2_list)): 97 | v2_val *= 10 98 | v2_val += int(v2_list[i]) 99 | 100 | is_ge = v1_val >= v2_val 101 | # print("Compare: " + v1 + " " + v2 + ": " + str(is_ge)) 102 | if v1_val > v2_val: 103 | return 1 104 | elif v1_val < v2_val: 105 | return -1 106 | else: 107 | return 0 108 | -------------------------------------------------------------------------------- /edapack/tempdir_m.py: -------------------------------------------------------------------------------- 1 | #**************************************************************************** 2 | #* tempdir_m.py 3 | #* 4 | #* Manage temp directories for EDAPack 5 | #**************************************************************************** 6 | import atexit 7 | import shutil 8 | import tempfile 9 | 10 | tempdirs = [] 11 | 12 | def cleanup(): 13 | if len(tempdirs) > 0: 14 | print("Note: cleaning up temp directories") 15 | 16 | for dir in tempdirs: 17 | shutil.rmtree(dir) 18 | 19 | def mktempdir(): 20 | dir = tempfile.mkdtemp(prefix="edapack_") 21 | tempdirs.append(dir) 22 | return dir 23 | 24 | 25 | atexit.register(cleanup) -------------------------------------------------------------------------------- /edapack/update_m.py: -------------------------------------------------------------------------------- 1 | #**************************************************************************** 2 | #* update.py 3 | #**************************************************************************** 4 | 5 | 6 | import urllib 7 | import os 8 | import shutil 9 | from . import read_packages 10 | from. import tempdir_m 11 | from . import install_m 12 | from github import Github 13 | 14 | def update(args): 15 | print("Update EDAPack Packages") 16 | 17 | # Update the index files as long as the user didn't 18 | # force skipping of this 19 | # if args.no_update_indexes == False: 20 | update_indexes() 21 | 22 | edapack = read_packages.edapack_dir() 23 | 24 | packages = read_packages.read_packages() 25 | 26 | update_packages_l = [] 27 | if len(args.packages) == 0: 28 | for pkg in packages.keys(): 29 | if os.path.isdir(os.path.join(edapack, pkg)): 30 | update_packages_l.append(pkg) 31 | else: 32 | for pkg in args.packages: 33 | update_packages_l.append(pkg) 34 | 35 | update_packages(edapack, packages, update_packages_l, args.y) 36 | 37 | 38 | #******************************************************************** 39 | #* Ensure we are working with up-to-date index information 40 | #******************************************************************** 41 | def update_indexes(): 42 | tmp = tempdir_m.mktempdir() 43 | print("Updating EDAPack Indexes") 44 | edapack = read_packages.edapack_dir() 45 | 46 | srcs = read_packages.read_sources() 47 | 48 | for src in srcs: 49 | print(" Fetching " + src.source + ".index from " + src.url) 50 | urllib.request.urlretrieve( 51 | src.url, 52 | os.path.join(tmp, src.source + ".index")) 53 | 54 | for src in srcs: 55 | shutil.copy( 56 | os.path.join(tmp, src.source + ".index"), 57 | os.path.join(edapack, "etc", src.source + ".index") 58 | ) 59 | 60 | print("Done updating indexes") 61 | 62 | #******************************************************************** 63 | #* is_version_gt 64 | #* 65 | #* Compares two versions and returns (v1>v2) 66 | #******************************************************************** 67 | def is_version_gt(v1, v2): 68 | v1_list = v1.split(".") 69 | v2_list = v2.split(".") 70 | 71 | if v1_list[0] == "": 72 | v1_list.clear() 73 | if v2_list[0] == "": 74 | v2_list.clear() 75 | 76 | # Ensure the versions are the same length 77 | while len(v1_list) < len(v2_list): 78 | v1_list.append("0") 79 | while len(v2_list) < len(v1_list): 80 | v2_list.append("0") 81 | 82 | # Convert each version to an integer that can be compared 83 | v1_val = 0 84 | v2_val = 0 85 | for i in range(len(v1_list)): 86 | v1_val *= 10 87 | v1_val += int(v1_list[i]) 88 | for i in range(len(v2_list)): 89 | v2_val *= 10 90 | v2_val += int(v2_list[i]) 91 | 92 | is_ge = v1_val > v2_val 93 | 94 | return is_ge 95 | 96 | #******************************************************************** 97 | #* update_packages() 98 | #******************************************************************** 99 | def update_packages(edapack, packages, update_packages_l, force): 100 | if os.getenv("GITHUB_API_TOKEN") is not None: 101 | g = Github(os.environ['GITHUB_API_TOKEN']) 102 | else: 103 | g = Github() 104 | packages_with_update = [] 105 | 106 | for pkg in update_packages_l: 107 | if packages.get(pkg) == None: 108 | print("Error: package \"" + pkg + "\" is not a recognized package") 109 | exit(1) 110 | 111 | pkg_src = packages[pkg] 112 | without_protocol = pkg_src.url[pkg_src.url.find("://")+3:] 113 | path = without_protocol.split('/') 114 | 115 | latest_remote_version = "0.0.0" 116 | latest_local_version = local_get_latest_version(edapack, pkg) 117 | if path[0] == "github.com": 118 | # 119 | latest_remote_version = github_get_latest_version(g, path[1], path[2], pkg_src.id) 120 | else: 121 | print("Error: unsupported host (" + path[0] + ") in URL " + pkg_src.url) 122 | exit(1) 123 | 124 | print("Checking package " + pkg + ": local version=" + latest_local_version + 125 | " remote version=" + latest_remote_version) 126 | 127 | if is_version_gt(latest_remote_version, latest_local_version): 128 | packages_with_update.append(pkg) 129 | 130 | if len(packages_with_update) == 0: 131 | print("Note: packages are up-to-date"); 132 | return 133 | 134 | if force == True: 135 | print("Installing " + str(len(packages_with_update)) + " packages with updates.") 136 | else: 137 | yn = input("" + str(len(packages_with_update)) + " packages have updates. Install (Y/n)?") 138 | 139 | if yn != "" and yn != "y" and yn != "Y" and yn != "yes": 140 | print("Cancelling...") 141 | return 142 | 143 | print("Installing updates...") 144 | for pkg in packages_with_update: 145 | install_m.install_index_pkg(packages[pkg]) 146 | 147 | print("Note: finished updating " + str(len(packages_with_update)) + " packages") 148 | 149 | def local_get_latest_version(edapack, pkg_id): 150 | if os.path.isdir(os.path.join(edapack, pkg_id)) == False: 151 | print("Error: package " + pkg_id + " is not installed"); 152 | exit(1) 153 | 154 | version = "" 155 | 156 | for v in os.listdir(os.path.join(edapack, pkg_id)): 157 | if is_version_gt(v, version): 158 | version = v 159 | 160 | return version 161 | 162 | def github_get_latest_version(g, org_user, repo, pkg_id): 163 | 164 | org = g.get_organization(org_user); 165 | 166 | if org != None: 167 | r = org.get_repo(repo) 168 | else: 169 | user = g.get_user(org_user) 170 | if user == None: 171 | print("Error: specified organization or user (" + org_user + ") is invalid"); 172 | exit(1) 173 | else: 174 | r = user.get_repo(repo) 175 | 176 | if r == None: 177 | print("Error: Failed to obtain repository " + repo + " for org/user " + org_user) 178 | exit(1) 179 | 180 | latest = r.get_latest_release() 181 | 182 | if latest == None: 183 | print("Error: there doesn't appear to be a release on GitHub for " + org_user + "/" + repo) 184 | exit(1) 185 | 186 | return latest.title 187 | -------------------------------------------------------------------------------- /edapack/update_scripts_m.py: -------------------------------------------------------------------------------- 1 | #**************************************************************************** 2 | #* update_scripts_m.py 3 | #* 4 | #* Update the 5 | #**************************************************************************** 6 | from . import read_packages 7 | from . import tempdir_m 8 | from github import Github 9 | import os 10 | import urllib 11 | import tarfile 12 | import shutil 13 | 14 | 15 | #******************************************************************** 16 | #* Bring in the script version 17 | #******************************************************************** 18 | try: 19 | from . import version 20 | version = version.version 21 | except Exception as e: 22 | version = "unknown" 23 | 24 | def update_scripts(args): 25 | print("Checking for scripts update...") 26 | print(" Current script version is: " + version) 27 | 28 | g = Github() 29 | 30 | org = g.get_organization("EDAPack") 31 | repo = org.get_repo("edapack") 32 | 33 | latest_release = repo.get_latest_release() 34 | 35 | print(" Latest script version is: " + latest_release.title) 36 | 37 | if read_packages.compare_versions(latest_release.title, version) > 0: 38 | print(" Installing new script version") 39 | download_install(latest_release) 40 | print(" Done installing latest scripts") 41 | else: 42 | print(" Scripts are up-to-date") 43 | if args.force: 44 | print(" --force specified. Re-installing anyway") 45 | download_install(latest_release) 46 | 47 | def download_install(latest_release): 48 | edapack_dir = read_packages.edapack_dir() 49 | tempdir = tempdir_m.mktempdir() 50 | 51 | pkg_asset = None 52 | for asset in latest_release.get_assets(): 53 | if asset.name.startswith("edapack-scripts-update") and asset.name.endswith(".tar.gz"): 54 | pkg_asset = asset 55 | break 56 | 57 | if pkg_asset == None: 58 | print("Error: failed to find edapack-scripts-update package"); 59 | exit(1) 60 | 61 | package_path = os.path.join(tempdir, os.path.basename(pkg_asset.name)) 62 | 63 | response = urllib.request.urlretrieve( 64 | pkg_asset.browser_download_url, 65 | package_path) 66 | 67 | # Now, delete the existing ${EDAPACK}/lib/edapack directory and 68 | # unpack the new one 69 | shutil.rmtree( 70 | os.path.join(edapack_dir, 'lib', 'edapack') 71 | ) 72 | 73 | tf = tarfile.open(package_path, "r:gz") 74 | tf.extractall(os.path.join(edapack_dir, "lib")) 75 | os.makedirs(os.path.join(edapack_dir, "lib2")) 76 | tf.extractall(os.path.join(edapack_dir, "lib2")) 77 | 78 | -------------------------------------------------------------------------------- /etc/edapack.index: -------------------------------------------------------------------------------- 1 | #**************************************************************************** 2 | #* edapack.index 3 | #* 4 | #* Provides a master list of available packages 5 | #**************************************************************************** 6 | 7 | #[gcc4] 8 | # url = https://github.com/EDAPack/gcc4 9 | # description = Provides a build of the GCC 4.x.x compiler for the host platform 10 | 11 | [gcc7] 12 | url = https://github.com/EDAPack/gcc7 13 | description = Provides a build of the GCC 7.x.x compiler for the host platform 14 | 15 | [ghdl] 16 | url = https://github.com/EDAPack/ghdl 17 | description = Provides the GHDL VHDL simulator 18 | 19 | [gtkwave] 20 | url = https://github.com/EDAPack/gtkwave 21 | description = Provides the GTKWave waveform viewer 22 | 23 | [icestorm] 24 | url = https://github.com/EDAPack/icestorm 25 | description = Projects the Project Icestorm tools targeting Lattice devices 26 | 27 | [iverilog] 28 | url = https://github.com/EDAPack/iverilog 29 | description = Provides the Icarus Verilog simulator 30 | 31 | [symbiyosys] 32 | url = https://github.com/EDAPack/symbiyosys 33 | description = Provides the SymbiYosys formal verification tool for Verilog 34 | 35 | [verilator] 36 | url = https://github.com/EDAPack/verilator 37 | description = Provides the Verilator Verilog simulator 38 | 39 | [vte] 40 | url = https://github.com/EDAPack/vte 41 | description = Provides the Verification Template Engine 42 | 43 | [vunit] 44 | url = https://github.com/EDAPack/vunit 45 | description = Provides the VUnit VHDL/SystemVerilog unit testing framework 46 | -------------------------------------------------------------------------------- /etc/package.info: -------------------------------------------------------------------------------- 1 | 2 | version=0.0.6 3 | name=edapack 4 | 5 | 6 | -------------------------------------------------------------------------------- /etc/sources: -------------------------------------------------------------------------------- 1 | #**************************************************************************** 2 | #* sources file for EDAPack 3 | #**************************************************************************** 4 | 5 | [edapack] 6 | url = https://github.com/EDAPack/edapack/raw/master/etc/edapack.index 7 | description = Primary EDAPack Index 8 | 9 | 10 | -------------------------------------------------------------------------------- /modulefiles/python3: -------------------------------------------------------------------------------- 1 | #**************************************************************************** 2 | #* python3 3 | #* 4 | #* Configures python3 from the EDAPack installation 5 | #**************************************************************************** 6 | 7 | proc ModulesHelp { } { 8 | puts stderr "\tPython3 Module\n" 9 | puts stderr "\tThis module adds Python3 from the EDAPack installation" 10 | } 11 | 12 | module-whatis "adds Python3 to the path" 13 | 14 | -------------------------------------------------------------------------------- /modulefiles/tcl: -------------------------------------------------------------------------------- 1 | #**************************************************************************** 2 | #* tcl 3 | #* 4 | #* Configures TCL from the EDAPack installation 5 | #**************************************************************************** 6 | 7 | proc ModulesHelp { } { 8 | puts stderr "\tTCL Module\n" 9 | puts stderr "\tThis module adds TCL from the EDAPack installation" 10 | } 11 | 12 | module-whatis "adds TCL to the path" 13 | 14 | 15 | -------------------------------------------------------------------------------- /plugins/edapack_link_quartus.py: -------------------------------------------------------------------------------- 1 | #**************************************************************************** 2 | #* edapack_link_template.py 3 | #* 4 | #* Template for an extension script to link a tool into EDAPack 5 | #**************************************************************************** 6 | from string import Template 7 | import os 8 | 9 | #******************************************************************** 10 | #* get_short_description 11 | #* 12 | #* Returns a sort description of this plug-in's functionality 13 | #******************************************************************** 14 | def get_short_description(): 15 | return "Links a Quartus installation into an EDAPack tree" 16 | 17 | #******************************************************************** 18 | #* validate_tool_install 19 | #* 20 | #* Validates that the user-specified path is valid. 21 | #* Throw an exception with an error message if the installation 22 | #* is not valid 23 | #******************************************************************** 24 | def validate_tool_install(tool_path): 25 | if os.path.isdir(os.path.join(tool_path, "quartus")) == False: 26 | raise Exception("missing 'quartus' subdirectory") 27 | 28 | #******************************************************************** 29 | #* get_tool_version 30 | #* 31 | #* Queries the tool version based on the installation. 32 | #* Throw an exception if this operation is not supported 33 | #******************************************************************** 34 | def get_tool_version(tool_path): 35 | raise("Querying the version is not supported") 36 | 37 | #******************************************************************** 38 | #* get_modulefile 39 | #* 40 | #* Returns the modulefile for this tool install and version. The 41 | #* modulefile will be added to the EDAPack tree 42 | #******************************************************************** 43 | def get_modulefile(tool_path, tool_version): 44 | modulefile = """ 45 | prepend-path PATH [file join ${tool_path} quartus bin] 46 | setenv QUARTUS [file join ${tool_path} quartus] 47 | 48 | # Configure Modelsim if it is installed 49 | if [file isdirectory [file join ${tool_path} modelsim_ase]] { 50 | prepend-path PATH [file join ${tool_path} modelsim_ase bin] 51 | } 52 | """ 53 | 54 | template_vars = { 55 | "tool_path": tool_path, 56 | "tool_version": tool_version 57 | } 58 | 59 | template = Template(modulefile) 60 | 61 | return template.safe_substitute(template_vars) 62 | 63 | -------------------------------------------------------------------------------- /scripts/Makefile: -------------------------------------------------------------------------------- 1 | 2 | SCRIPTS_DIR:=$(abspath $(dir $(lastword $(MAKEFILE_LIST)))) 3 | EDAPACK_DIR:=$(abspath $(SCRIPTS_DIR)/..) 4 | MKFILES_DIR:=$(SCRIPTS_DIR)/mkfiles 5 | PACKAGES_DIR:=$(EDAPACK_DIR)/packages 6 | BUILD_DIR:=$(EDAPACK_DIR)/build 7 | 8 | include $(EDAPACK_DIR)/etc/package.info 9 | 10 | MK_INCLUDES += $(wildcard $(MKFILES_DIR)/*.mk) 11 | EDAPACK_TARGETS += $(BUILD_DIR)/edapack_init.d 12 | 13 | PYTHON_PACKAGES += argparse textwrap fusesoc 14 | EDAPACK_PACKAGES += iverilog verilator gtkwave 15 | 16 | MODULES_VERSION=4.2.1 17 | MODULES_DIR=modules-$(MODULES_VERSION) 18 | MODULES_TGZ=$(MODULES_DIR).tar.gz 19 | MODULES_URL=https://sourceforge.net/projects/modules/files/Modules/$(MODULES_DIR)/$(MODULES_TGZ)/download 20 | 21 | TCL_VERSION=8.6.9 22 | TCL_DIR=tcl$(TCL_VERSION) 23 | TCL_TGZ=$(TCL_DIR).tar.gz 24 | TCL_URL=https://sourceforge.net/projects/tcl/files/Tcl/$(TCL_VERSION)/$(TCL_DIR)-src.tar.gz/download 25 | 26 | PYTHON_VERSION_MAJOR=3.6 27 | PYTHON_VERSION=$(PYTHON_VERSION_MAJOR).8 28 | PYTHON_DIR=Python-$(PYTHON_VERSION) 29 | PYTHON_TXZ=$(PYTHON_DIR).tar.xz 30 | PYTHON_URL=https://www.python.org/ftp/python/$(PYTHON_VERSION)/$(PYTHON_TXZ) 31 | 32 | ifeq (true,$(VERBOSE)) 33 | Q= 34 | WGET=wget 35 | UNTARXZ=tar xvJf 36 | UNTARGZ=tar xvzf 37 | else 38 | Q=@ 39 | WGET=wget -q 40 | UNTARXZ=tar xJf 41 | UNTARGZ=tar xzf 42 | endif 43 | 44 | uname_o:=$(shell uname -o) 45 | 46 | ifeq (Linux,$(uname_o)) 47 | platform=linux_x86_64 48 | else 49 | ifeq (GNU/Linux,$(uname_o)) 50 | platform=linux_x86_64 51 | else 52 | platform=unknown 53 | endif 54 | endif 55 | 56 | EDAPACK_PREFIX=$(BUILD_DIR)/edapack-$(platform)-$(version) 57 | TCL_ENV=export PATH=$(EDAPACK_PREFIX)/tcl/bin:$$PATH; 58 | 59 | include $(MK_INCLUDES) 60 | 61 | RULES := 1 62 | 63 | all : $(BUILD_DIR)/edapack-$(platform)-$(version).tar.gz 64 | 65 | $(BUILD_DIR)/modules.d : \ 66 | $(BUILD_DIR)/tcl.d \ 67 | $(PACKAGES_DIR)/$(MODULES_TGZ) 68 | $(Q)rm -rf $(BUILD_DIR)/modules 69 | $(Q)mkdir -p $(BUILD_DIR)/modules 70 | $(Q)cd $(BUILD_DIR)/modules ; \ 71 | $(UNTARGZ) $(PACKAGES_DIR)/$(MODULES_TGZ) 72 | $(Q)cd $(BUILD_DIR)/modules/$(MODULES_DIR) ; \ 73 | patch -p1 < $(SCRIPTS_DIR)/modules.patch 74 | $(Q)cd $(BUILD_DIR)/modules/$(MODULES_DIR) ; \ 75 | ./configure --prefix=$(EDAPACK_PREFIX)/modules \ 76 | --with-tclsh=$(EDAPACK_PREFIX)/tcl/bin/tclsh8.6 \ 77 | --with-tcl=$(EDAPACK_PREFIX)/tcl/lib \ 78 | --with-tcl-ver=8.6 \ 79 | --disable-compat-version 80 | $(Q)cd $(BUILD_DIR)/modules/$(MODULES_DIR) ; \ 81 | $(MAKE) 82 | $(Q)cd $(BUILD_DIR)/modules/$(MODULES_DIR) ; \ 83 | $(MAKE) install 84 | # Remove the built-in modulefiles, since they're not really useful 85 | $(Q)rm -f $(EDAPACK_PREFIX)/modules/modulefiles/* 86 | $(Q)touch $@ 87 | 88 | $(PACKAGES_DIR)/$(MODULES_TGZ) : 89 | $(Q)mkdir -p $(PACKAGES_DIR) 90 | $(Q)$(WGET) -O $@ $(MODULES_URL) 91 | 92 | $(BUILD_DIR)/edapack-$(platform)-$(version).tar.gz : \ 93 | $(BUILD_DIR)/modules.d \ 94 | $(BUILD_DIR)/tcl.d \ 95 | $(BUILD_DIR)/python3.d \ 96 | $(BUILD_DIR)/scripts.d 97 | $(Q)cd $(BUILD_DIR) ; \ 98 | tar czf $(BUILD_DIR)/edapack-$(platform)-$(version).tar.gz \ 99 | edapack-$(platform)-$(version) 100 | 101 | release : \ 102 | $(BUILD_DIR)/edapack-$(platform)-$(version).tar.gz \ 103 | $(BUILD_DIR)/edapack-scripts-update-$(version).tar.gz \ 104 | $(PACKAGES_DIR)/upload.py 105 | $(Q)python3 $(PACKAGES_DIR)/upload.py \ 106 | --org EDAPack --repo edapack \ 107 | --key $(GITHUB_API_TOKEN) --version $(version) \ 108 | $(BUILD_DIR)/edapack-$(platform)-$(version).tar.gz \ 109 | $(BUILD_DIR)/edapack-scripts-update-$(version).tar.gz 110 | 111 | clean : 112 | $(Q)rm -rf $(BUILD_DIR) 113 | 114 | clean-all : 115 | $(Q)rm -rf $(BUILD_DIR) $(PACKAGES_DIR) 116 | 117 | 118 | $(BUILD_DIR)/tcl.d : $(PACKAGES_DIR)/$(TCL_TGZ) 119 | $(Q)rm -rf $(BUILD_DIR)/tcl 120 | $(Q)mkdir -p $(BUILD_DIR)/tcl 121 | $(Q)cd $(BUILD_DIR)/tcl; $(UNTARGZ) $(PACKAGES_DIR)/$(TCL_TGZ) 122 | $(Q)cd $(BUILD_DIR)/tcl/$(TCL_DIR)/unix; \ 123 | ./configure --prefix=$(EDAPACK_PREFIX)/tcl \ 124 | --disable-shared 125 | $(Q)cd $(BUILD_DIR)/tcl/$(TCL_DIR)/unix; $(MAKE) 126 | $(Q)cd $(BUILD_DIR)/tcl/$(TCL_DIR)/unix; $(MAKE) install 127 | $(Q)touch $@ 128 | 129 | $(PACKAGES_DIR)/$(TCL_TGZ) : 130 | $(Q)mkdir -p $(PACKAGES_DIR) 131 | $(Q)$(WGET) -O $@ $(TCL_URL) 132 | 133 | $(BUILD_DIR)/python3.d : $(PACKAGES_DIR)/$(PYTHON_TXZ) 134 | $(Q)rm -rf $(BUILD_DIR)/python 135 | $(Q)mkdir -p $(BUILD_DIR)/python 136 | $(Q)cd $(BUILD_DIR)/python ; $(UNTARXZ) $^ 137 | $(Q)cd $(BUILD_DIR)/python/$(PYTHON_DIR) ; \ 138 | ./configure --prefix=$(EDAPACK_PREFIX)/python3 139 | $(Q)cd $(BUILD_DIR)/python/$(PYTHON_DIR); $(MAKE) 140 | $(Q)cd $(BUILD_DIR)/python/$(PYTHON_DIR); $(MAKE) install 141 | $(Q)$(EDAPACK_PREFIX)/python3/bin/pip3 install Jinja2 142 | $(Q)$(EDAPACK_PREFIX)/python3/bin/pip3 install pyyaml 143 | $(Q)$(EDAPACK_PREFIX)/python3/bin/pip3 install PyGitHub 144 | $(Q)cd $(EDAPACK_PREFIX)/python3/bin ; strip python3.6 145 | $(Q)rm -rf $(EDAPACK_PREFIX)/python3/lib/python3.6/test 146 | $(Q)touch $@ 147 | 148 | $(PACKAGES_DIR)/$(PYTHON_TXZ) : 149 | $(Q)if test ! -d $(PACKAGES_DIR); then mkdir -p $(PACKAGES_DIR); fi 150 | $(Q)$(WGET) -O $@ $(PYTHON_URL) 151 | 152 | EDAPACK_FILES:=$(shell find $(EDAPACK_DIR)/edapack -type f) 153 | PLUGIN_FILES:=$(shell find $(EDAPACK_DIR)/plugins -type f) 154 | TEMPLATE_FILES:=$(shell find $(EDAPACK_DIR)/templates -type f) 155 | $(BUILD_DIR)/scripts.d : \ 156 | $(SCRIPTS_DIR)/edapack \ 157 | $(SCRIPTS_DIR)/edapack.sh \ 158 | $(SCRIPTS_DIR)/edapack.csh \ 159 | $(EDAPACK_DIR)/etc/sources \ 160 | $(EDAPACK_DIR)/etc/edapack.index \ 161 | $(EDAPACK_FILES) \ 162 | $(PLUGIN_FILES) \ 163 | $(TEMPLATE_FILES) 164 | $(Q)mkdir -p $(EDAPACK_PREFIX)/bin 165 | $(Q)cp $(SCRIPTS_DIR)/edapack $(EDAPACK_PREFIX)/bin/edapack 166 | $(Q)chmod +x $(EDAPACK_PREFIX)/bin/edapack 167 | $(Q)mkdir -p $(EDAPACK_PREFIX)/etc 168 | $(Q)cp $(EDAPACK_DIR)/etc/sources $(EDAPACK_PREFIX)/etc/sources 169 | $(Q)cp $(EDAPACK_DIR)/etc/edapack.index $(EDAPACK_PREFIX)/etc/edapack.index 170 | $(Q)cp $(SCRIPTS_DIR)/edapack.sh $(EDAPACK_PREFIX)/etc/edapack.sh 171 | # $(Q)cp $(SCRIPTS_DIR)/edapack.csh $(EDAPACK_PREFIX)/etc/edapack.csh 172 | $(Q)rm -rf $(EDAPACK_PREFIX)/lib/edapack 173 | $(Q)rm -rf $(EDAPACK_PREFIX)/templates 174 | $(Q)mkdir -p $(EDAPACK_PREFIX)/lib 175 | $(Q)cp -r $(EDAPACK_DIR)/edapack $(EDAPACK_PREFIX)/lib 176 | $(Q)cp -r $(EDAPACK_DIR)/plugins $(EDAPACK_PREFIX)/lib 177 | $(Q)cp -r $(EDAPACK_DIR)/templates $(EDAPACK_PREFIX)/templates 178 | $(Q)echo "version = '$(version)'" > $(EDAPACK_PREFIX)/lib/edapack/version.py 179 | $(Q)touch $@ 180 | 181 | 182 | $(BUILD_DIR)/edapack-scripts-update-$(version).tar.gz : $(BUILD_DIR)/scripts.d 183 | $(Q)cd $(EDAPACK_PREFIX)/lib ; tar czf $@ edapack plugins 184 | 185 | $(PACKAGES_DIR)/upload.py : 186 | $(Q)mkdir -p $(PACKAGES_DIR) 187 | $(Q)$(WGET) -O $@ \ 188 | https://github.com/EDAPack/edapack-build/raw/master/scripts/upload.py 189 | 190 | include $(MK_INCLUDES) 191 | 192 | 193 | -------------------------------------------------------------------------------- /scripts/edapack: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #**************************************************************************** 3 | #* edapack 4 | #* 5 | #* Command wrapper for EDAPack 6 | #**************************************************************************** 7 | 8 | if test -f $0; then 9 | script_dir=$(dirname $0) 10 | script_dir=$(cd $script_dir ; pwd) 11 | else 12 | # Find ourselves in the PATH 13 | for elem in $(echo PATH | sed -e 's%:% %g'); do 14 | script=${elem}/$0 15 | if test -f $script; then 16 | script_dir=$elem 17 | break 18 | fi 19 | done 20 | fi 21 | 22 | edapack_dir=$(dirname $script_dir) 23 | 24 | export PYTHONPATH=${edapack_dir}/lib 25 | 26 | exec ${edapack_dir}/python3/bin/python3 -m edapack ${@:1} 27 | 28 | 29 | -------------------------------------------------------------------------------- /scripts/edapack.csh: -------------------------------------------------------------------------------- 1 | #**************************************************************************** 2 | #* edpack.csh 3 | #* 4 | #* Setup script for C-shell 5 | #**************************************************************************** -------------------------------------------------------------------------------- /scripts/edapack.sh: -------------------------------------------------------------------------------- 1 | #**************************************************************************** 2 | #* edapack.sh 3 | #* 4 | #* Setup script for bourne shell 5 | #**************************************************************************** 6 | 7 | etc_dir="$(cd "$(dirname "${BASH_SOURCE[0]}" )" > /dev/null && pwd)" 8 | edapack_dir=$(dirname $etc_dir) 9 | 10 | # Add the bin directory to the PATH 11 | if [[ ! ":$PATH:" =~ ":${edapack_dir}/bin:" ]]; then 12 | export PATH=${edapack_dir}/bin:$PATH 13 | fi 14 | 15 | # Add our modules directory to the MODULESPATH 16 | modulepath=${MODULEPATH:-} 17 | if [[ ! ":$modulepath:" =~ ":${edapack_dir}/modulefiles:" ]]; then 18 | MODULEPATH=${edapack_dir}/modulefiles${modulepath:+:}$modulepath 19 | export MODULEPATH 20 | fi 21 | 22 | # Bring in modules commands 23 | source ${edapack_dir}/modules/init/bash 24 | 25 | 26 | -------------------------------------------------------------------------------- /scripts/mkfiles/fusesoc.mk: -------------------------------------------------------------------------------- 1 | 2 | ifneq (1,$(RULES)) 3 | 4 | EDAPACK_TARGETS += $(BUILD_DIR)/fusesoc.d 5 | 6 | else # Rules 7 | 8 | $(BUILD_DIR)/fusesoc.d : $(BUILD_DIR)/edapack_init.d 9 | $(Q)$(BUILD_DIR)/edapack/bin/pip3 install fusesoc 10 | $(Q)touch $@ 11 | 12 | endif 13 | 14 | -------------------------------------------------------------------------------- /scripts/mkfiles/python.mk: -------------------------------------------------------------------------------- 1 | 2 | ifneq (1,$(RULES)) 3 | 4 | EDAPACK_TARGETS += $(BUILD_DIR)/python.d 5 | 6 | else # Rules 7 | 8 | endif 9 | 10 | -------------------------------------------------------------------------------- /scripts/modules.patch: -------------------------------------------------------------------------------- 1 | diff -rcNB modules-4.2.1.orig/init/bash.in modules-4.2.1/init/bash.in 2 | *** modules-4.2.1.orig/init/bash.in 2018-11-11 06:51:17.000000000 -0800 3 | --- modules-4.2.1/init/bash.in 2019-01-06 20:07:01.927095126 -0800 4 | *************** 5 | *** 1,3 **** 6 | --- 1,9 ---- 7 | + 8 | + @silentshdbgsupport@init_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" > /dev/null && pwd)" 9 | + @silentshdbgsupport@modules_dir=$(dirname ${init_dir}) 10 | + @silentshdbgsupport@edapack_dir=$(dirname ${modules_dir}) 11 | + @silentshdbgsupport@tclsh=${edapack_dir}/tcl/bin/tclsh8.6 12 | + @silentshdbgsupport@ 13 | @silentshdbgsupport@unset _mlshdbg; 14 | @silentshdbgsupport@# disable shell debugging for the run of this init file 15 | @silentshdbgsupport@if [ "${MODULES_SILENT_SHELL_DEBUG:-0}" = '1' ]; then 16 | *************** 17 | *** 36,43 **** 18 | @quarantinesupport@ 19 | # define module command and surrounding initial environment (default value 20 | # for MODULESHOME, MODULEPATH, LOADEDMODULES and parse of init/.modulespath) 21 | ! @quarantinesupport@_mlcode=`${_mlre:-}@TCLSH@ @libexecdir@/modulecmd.tcl bash autoinit` 22 | ! @notquarantinesupport@_mlcode=`@TCLSH@ @libexecdir@/modulecmd.tcl bash autoinit` 23 | _mlret=$? 24 | 25 | @quarantinesupport@# clean temp variables used to setup quarantine 26 | --- 42,49 ---- 27 | @quarantinesupport@ 28 | # define module command and surrounding initial environment (default value 29 | # for MODULESHOME, MODULEPATH, LOADEDMODULES and parse of init/.modulespath) 30 | ! @quarantinesupport@_mlcode=`${_mlre:-}${tclsh} ${modules_dir}/libexec/modulecmd.tcl bash autoinit` 31 | ! @notquarantinesupport@_mlcode=`${tclsh} ${modules_dir}/libexec/modulecmd.tcl bash autoinit` 32 | _mlret=$? 33 | 34 | @quarantinesupport@# clean temp variables used to setup quarantine 35 | *************** 36 | *** 54,64 **** 37 | 38 | @compatversion@ # redefine module command if compat version has been activated 39 | @compatversion@ if [ "${MODULES_USE_COMPAT_VERSION:-0}" = '1' ]; then 40 | ! @compatversion@ MODULES_CMD=@libexecdir@/modulecmd-compat; export MODULES_CMD 41 | @compatversion@ if [ -t 2 ]; then 42 | ! @compatversion@ _module_raw() { eval `@libexecdir@/modulecmd-compat bash $*`; } 43 | @compatversion@ else 44 | ! @compatversion@ module() { eval `@libexecdir@/modulecmd-compat bash $*`; } 45 | @compatversion@ fi 46 | @compatversion@ fi 47 | @compatversion@ 48 | --- 60,70 ---- 49 | 50 | @compatversion@ # redefine module command if compat version has been activated 51 | @compatversion@ if [ "${MODULES_USE_COMPAT_VERSION:-0}" = '1' ]; then 52 | ! @compatversion@ MODULES_CMD=${modules_dir}libexec/modulecmd-compat; export MODULES_CMD 53 | @compatversion@ if [ -t 2 ]; then 54 | ! @compatversion@ _module_raw() { eval `${modules_dir}/libexec/modulecmd-compat bash $*`; } 55 | @compatversion@ else 56 | ! @compatversion@ module() { eval `${modules_dir}/libexec/modulecmd-compat bash $*`; } 57 | @compatversion@ fi 58 | @compatversion@ fi 59 | @compatversion@ 60 | *************** 61 | *** 73,85 **** 62 | @compatversion@ typeset swfound=1 63 | @compatversion@ if [ "${MODULES_USE_COMPAT_VERSION:-0}" = '1' ]; then 64 | @compatversion@ typeset swname='main' 65 | ! @compatversion@ if [ -e @libexecdir@/modulecmd.tcl ]; then 66 | @compatversion@ typeset swfound=0 67 | @compatversion@ unset MODULES_USE_COMPAT_VERSION 68 | @compatversion@ fi 69 | @compatversion@ else 70 | @compatversion@ typeset swname='compatibility' 71 | ! @compatversion@ if [ -e @libexecdir@/modulecmd-compat ]; then 72 | @compatversion@ typeset swfound=0 73 | @compatversion@ MODULES_USE_COMPAT_VERSION=1; export MODULES_USE_COMPAT_VERSION 74 | @compatversion@ fi 75 | --- 79,91 ---- 76 | @compatversion@ typeset swfound=1 77 | @compatversion@ if [ "${MODULES_USE_COMPAT_VERSION:-0}" = '1' ]; then 78 | @compatversion@ typeset swname='main' 79 | ! @compatversion@ if [ -e ${modules_dir}/libexec/modulecmd.tcl ]; then 80 | @compatversion@ typeset swfound=0 81 | @compatversion@ unset MODULES_USE_COMPAT_VERSION 82 | @compatversion@ fi 83 | @compatversion@ else 84 | @compatversion@ typeset swname='compatibility' 85 | ! @compatversion@ if [ -e ${modules_dir}/libexec/modulecmd-compat ]; then 86 | @compatversion@ typeset swfound=0 87 | @compatversion@ MODULES_USE_COMPAT_VERSION=1; export MODULES_USE_COMPAT_VERSION 88 | @compatversion@ fi 89 | *************** 90 | *** 88,94 **** 91 | @compatversion@ # switch version only if command found 92 | @compatversion@ if [ $swfound -eq 0 ]; then 93 | @compatversion@ echo "Switching to Modules $swname version" 94 | ! @compatversion@ source @initdir@/bash 95 | @compatversion@ else 96 | @compatversion@ echo "Cannot switch to Modules $swname version, command not found" 97 | @compatversion@ return 1 98 | --- 94,100 ---- 99 | @compatversion@ # switch version only if command found 100 | @compatversion@ if [ $swfound -eq 0 ]; then 101 | @compatversion@ echo "Switching to Modules $swname version" 102 | ! @compatversion@ source ${init_dir}/bash 103 | @compatversion@ else 104 | @compatversion@ echo "Cannot switch to Modules $swname version, command not found" 105 | @compatversion@ return 1 106 | *************** 107 | *** 99,127 **** 108 | # setup ENV variables to get module defined in sub-shells (works for 'sh' 109 | # and 'ksh' in interactive mode and 'sh' (zsh-compat), 'bash' and 'ksh' 110 | # (zsh-compat) in non-interactive mode. 111 | ! ENV=@initdir@/profile.sh; export ENV 112 | ! BASH_ENV=@initdir@/bash; export BASH_ENV 113 | 114 | # enable completion only in interactive mode 115 | if [ ${BASH_VERSINFO:-0} -ge 3 ] && [[ $- =~ i ]] && 116 | ! [ -r @initdir@/bash_completion ]; then 117 | ! source @initdir@/bash_completion 118 | fi 119 | @setbinpath@ 120 | ! @setbinpath@ if [[ ! ":$PATH:" =~ ':@bindir@:' ]]; then 121 | ! @setbinpath@@prependbinpath@ PATH=@bindir@${PATH:+:}$PATH; export PATH 122 | ! @setbinpath@@appendbinpath@ PATH=$PATH${PATH:+:}@bindir@; export PATH 123 | @setbinpath@ fi 124 | @setmanpath@ 125 | @setmanpath@@usemanpath@ manpath=`manpath 2>/dev/null` 126 | @setmanpath@@notusemanpath@ manpath=${MANPATH:-} 127 | ! @setmanpath@ if [[ ! ":$manpath:" =~ ':@mandir@:' ]]; then 128 | ! @setmanpath@@prependmanpath@ MANPATH=@mandir@${manpath:+:}$manpath; export MANPATH 129 | ! @setmanpath@@appendmanpath@ MANPATH=$manpath${manpath:+:}@mandir@; export MANPATH 130 | @setmanpath@ fi 131 | fi 132 | 133 | unset _mlcode _mlret 134 | @silentshdbgsupport@ 135 | @silentshdbgsupport@# restore shell debugging options if disabled 136 | @silentshdbgsupport@if [ -n "${_mlshdbg:-}" ]; then 137 | --- 105,135 ---- 138 | # setup ENV variables to get module defined in sub-shells (works for 'sh' 139 | # and 'ksh' in interactive mode and 'sh' (zsh-compat), 'bash' and 'ksh' 140 | # (zsh-compat) in non-interactive mode. 141 | ! ENV=${init_dir}/profile.sh; export ENV 142 | ! BASH_ENV=${init_dir}/bash; export BASH_ENV 143 | 144 | # enable completion only in interactive mode 145 | if [ ${BASH_VERSINFO:-0} -ge 3 ] && [[ $- =~ i ]] && 146 | ! [ -r ${init_dir}/bash_completion ]; then 147 | ! source ${init_dir}/bash_completion 148 | fi 149 | @setbinpath@ 150 | ! @setbinpath@ if [[ ! ":$PATH:" =~ ':${modules_dir}/bin:' ]]; then 151 | ! @setbinpath@@prependbinpath@ PATH=${modules_dir}/bin${PATH:+:}$PATH; export PATH 152 | ! @setbinpath@@appendbinpath@ PATH=$PATH${PATH:+:}${modules_dir}/bin; export PATH 153 | @setbinpath@ fi 154 | @setmanpath@ 155 | @setmanpath@@usemanpath@ manpath=`manpath 2>/dev/null` 156 | @setmanpath@@notusemanpath@ manpath=${MANPATH:-} 157 | ! @setmanpath@ if [[ ! ":$manpath:" =~ ':${modules_dir}/share/man:' ]]; then 158 | ! @setmanpath@@prependmanpath@ MANPATH=${modules_dir}/share/man${manpath:+:}$manpath; export MANPATH 159 | ! @setmanpath@@appendmanpath@ MANPATH=$manpath${manpath:+:}${modules_dir}/share/man; export MANPATH 160 | @setmanpath@ fi 161 | fi 162 | 163 | unset _mlcode _mlret 164 | + unset init_dir modules_dir edapack_dir 165 | + 166 | @silentshdbgsupport@ 167 | @silentshdbgsupport@# restore shell debugging options if disabled 168 | @silentshdbgsupport@if [ -n "${_mlshdbg:-}" ]; then 169 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | from setuptools import setup 4 | 5 | setup( 6 | name = "edapack", 7 | packages=['edapack'], 8 | author = "Matthew Ballance", 9 | author_email = "matt.ballance@gmail.com", 10 | description = ("EDAPack is a pre-compiled collection of open source EDA tools"), 11 | license = "Apache 2.0", 12 | keywords = ["Electronic Design Automation"], 13 | url = "https://github.com/EDAPack/edapack", 14 | # TODO 15 | entry_points={ 16 | 'console_scripts': [ 17 | 'edapack = edapack.__main__:main' 18 | ] 19 | } 20 | ) 21 | 22 | -------------------------------------------------------------------------------- /templates/edapack_link_template.py: -------------------------------------------------------------------------------- 1 | #**************************************************************************** 2 | #* edapack_link_template.py 3 | #* 4 | #* Template for an extension script to link a tool into EDAPack 5 | #**************************************************************************** 6 | from string import Template 7 | 8 | #******************************************************************** 9 | #* get_short_description 10 | #* 11 | #* Returns a sort description of this plug-in's functionality 12 | #******************************************************************** 13 | def get_short_description(): 14 | return "TODO: description of the template file" 15 | 16 | #******************************************************************** 17 | #* validate_tool_install 18 | #* 19 | #* Validates that the user-specified path is valid. 20 | #* Throw an exception with an error message if the installation 21 | #* is not valid 22 | #******************************************************************** 23 | def validate_tool_install(tool_path): 24 | raise("Tool installation is invalid") 25 | 26 | #******************************************************************** 27 | #* get_tool_version 28 | #* 29 | #* Queries the tool version based on the installation. 30 | #* Throw an exception if this operation is not supported 31 | #******************************************************************** 32 | def get_tool_version(tool_path): 33 | raise("Querying the version is not supported") 34 | 35 | #******************************************************************** 36 | #* get_modulefile 37 | #* 38 | #* Returns the modulefile for this tool install and version. The 39 | #* modulefile will be added to the EDAPack tree 40 | #******************************************************************** 41 | def get_modulefile(tool_path, tool_version): 42 | modulefile = """ 43 | prepend-path PATH [file join ${tool_path} bin] 44 | setenv TOOL_ENV_VAR ${tool_path} 45 | """ 46 | 47 | template_vars = { 48 | "tool_path": tool_path, 49 | "tool_version": tool_version 50 | } 51 | 52 | template = Template(modulefile) 53 | 54 | return template.save_substitute(template_vars) 55 | 56 | --------------------------------------------------------------------------------