Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Documentation License.”
2 Autotools 简介
如果以前没有接触过Automake,你可能大概也许知道它是 Autotools 工具集的一部分。
如果你已经开始研究诸如 configure,configure.ac,Makefile.in,Makefile.am,aclocal.m等,那么你可能已经看到他们被声明为 generated by Autoconf or Automake。
[HOST1] ~ % mkdir /tmp/amh && cd /tmp/amh [HOST1] /tmp/amh % /nfs/src/amhello-1.0/configure --prefix /usr ... [HOST1] /tmp/amh % make && sudo make install ...
On the second host, however, we need only install the architecture-specific files.
1 2 3 4 5
[HOST2] ~ % mkdir /tmp/amh && cd /tmp/amh [HOST2] /tmp/amh % /nfs/src/amhello-1.0/configure --prefix /usr ... [HOST2] /tmp/amh % make && sudo make install-exec ...
In packages that have installation checks, it would make sense to run make installcheck to verify that the package works correctly despite the apparent partial installation.
~/amhello-1.0 % ./configure --build i686-pc-linux-gnu --host i586-mingw32msvc checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for gawk... gawk checking whether make sets $(MAKE)... yes checking for i586-mingw32msvc-strip... i586-mingw32msvc-strip checking for i586-mingw32msvc-gcc... i586-mingw32msvc-gcc checking for C compiler default output file name... a.exe checking whether the C compiler works... yes checking whether we are cross compiling... yes checking for suffix of executables... .exe checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether i586-mingw32msvc-gcc accepts -g... yes checking for i586-mingw32msvc-gcc option to accept ANSI C... ... ~/amhello-1.0 % make ... ~/amhello-1.0 % cd src; file hello.exe hello.exe: MS Windows PE 32-bit Intel 80386 console executable not relocatable
2.2.9 安装时重命名程序
可以使用 configure的编译选项,在安装之前加上特定的前缀或后缀来避免与系统程序冲突。
--program-prefix=PREFIX:增加前缀
--program-suffix=SUFFIX:增加后缀
--program-transform-name=PROGRAM:安装时运行sed PROGRAM
比如下面的例子将安装 hello到/usr/local/bin/test-hello。
1 2 3 4 5 6
~/amhello-1.0 % ./configure --program-prefix test- ... ~/amhello-1.0 % make ... ~/amhello-1.0 % sudo make install ...
2.2.10 使用DESTDIR编译二进制包
单纯的GNU Build System的 make install和 make uninstall接口并不能完全满足系统管理员的部署,比如我们希望在编译的时候安装指定路径,而在make的时候因为可能没有root权限暂时放在一个临时目录,然后再部署到其他机器。
比如像下面这个例子就很好的诠释了这个方法。
1 2 3 4 5 6 7 8 9 10 11
~/amhello-1.0 % ./configure --prefix /usr ... ~/amhello-1.0 % make ... ~/amhello-1.0 % make DESTDIR=$HOME/inst install ... ~/amhello-1.0 % cd ~/inst ~/inst % find . -type f -print > ../files.lst ~/inst % tar zcvf ~/amhello-1.0-i686.tar.gz `cat ../files.lst` ./usr/bin/hello ./usr/share/doc/amhello/README
make dist收集源码及必须的文件创建一个压缩包,名为 PACKAGE-VERSION.tar.gz。
虽然也能满足大部分的功能,但是还有一个更有用的命令 make distcheck,这个命令也会像 make dist一样创建压缩包 PACKAGE-VERSION.tar.gz,并会做各种各样的检查以确保压缩包没有问题:
• 将运行所有的软件包命令,比如 make, make check, make install和 make installcheck, 甚至是 make dist,来确保软件发布没有问题 • 测试只读源码树的VPATH编译 • 确保 make clean, make distclean, and make uninstall不忽略任何文件 • 检查 DESTDIR安装是否工作
所有的这些操作都在一个临时目录进行,所以并不需要root权限。
如果 make distcheck失败了,意味着其中的一个场景没有满足,可能不会影响程序的使用,不过最好根据失败的提示进一步改进得到一个完美的发布包。
~/amhello % ./configure checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for gawk... no checking for mawk... mawk checking whether make sets $(MAKE)... yes checking for gcc... gcc checking for C compiler default output file name... a.out checking whether the C compiler works... yes checking whether we are cross compiling... no checking for suffix of executables... checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether gcc accepts -g... yes checking for gcc option to accept ISO C89... none needed checking for style of include used by make... GNU checking dependency style of gcc... gcc3 configure: creating ./config.status config.status: creating Makefile config.status: creating src/Makefile config.status: creating config.h config.status: executing depfiles commands
此时我们就可以看到已经创建了 Makefile, src/Makefile和 config.h。
1 2 3 4 5 6 7 8 9 10 11
~/amhello % make ... ~/amhello % src/hello Hello World! This is amhello 1.0. ~/amhello % make distcheck ... ============================================= amhello-1.0 archives ready for distribution: amhello-1.0.tar.gz =============================================
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Documentation License.”
withopen("README.md", "r") as fh: long_description = fh.read()
setuptools.setup( name="example-pkg-YOUR-USERNAME-HERE", # Replace with your own username version="0.0.1", author="Example Author", author_email="author@example.com", description="A small example package", long_description=long_description, long_description_content_type="text/markdown", url="https://github.com/pypa/sampleproject", packages=setuptools.find_packages(), classifiers=[ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ], python_requires='>=3.6', )
setup() 的几个最必须的参数如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
nameis the distribution nameof your package. This can be anynameas long asonly contains letters, numbers, _ , and -. It also must not already be taken on pypi.org. Be sure toupdate this with your username, as this ensures you won’t try to upload a package with the same nameas one which already existswhen you upload the package.
versionis the package version see PEP 440for more details on versions.
author and author_email are used to identify the author of the package.
description is a short, one-sentence summaryof the package.
long_description is a detailed description of the package. This is shown on the package detail package on the Python Package Index. In this case, the long description is loaded from README.md which is a common pattern.
long_description_content_type tells the index what typeof markup is used for the long description. In this case, it’s Markdown.
url is the URL for the homepage of the project. For many projects, this will just be a link to GitHub, GitLab, Bitbucket, orsimilar code hosting service.
packages is a list ofall Python import packages that should be included in the distribution package. Insteadof listing each package manually, we can use find_packages() to automatically discover all packages and subpackages. In this case, the list of packages will be example_pkg as that’s the only package present.
classifiers gives the indexand pip some additional metadata about your package. In this case, the package isonly compatible with Python 3, is licensed under the MIT license, andis OS-independent. You should alwaysinclude at least which version(s) of Python your package works on, which license your package is available under, and which operating systems your package will workon. For a complete list of classifiers, see https://pypi.org/classifiers/.
创建README.md
创建 README.md ,写上你准备写入的内容:
1 2 3 4 5
# Example Package
Thisis a simple example package. You can use [Github-flavored Markdown](https://guides.github.com/features/mastering-markdown/) to write your content.
创建LICENSE
比如使用MIT
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Copyright (c) 2018 The Python Packaging Authority
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
for student in students: print('%(name)s is %(age)d years old' % student)
输出结果如下所示:
1 2 3 4 5 6 7 8 9 10 11 12
1234 => hex => 4d2 1234 => hex => 4D2 1234 => hex => 0x4d2 1234 => hex => 0X4D2 value f is 3.141593 value f is 3.1416 name: Han Meimei, age: 17 name: Li Lei , age: 18 name: Li Lei, age: 0000000018 Han Meimei is 17 years old Li Lei is 18 years old Wei Hua is 17 years old
字符串模板
示例如下:
1 2 3 4 5 6 7
from string import Template
s = Template('Hi, $name! $name is $age years old.') print(s.substitute(name='Han Meimei', age='17'))
print('{0} is {1} years old.'.format('lily', 18)) print('{} is {} years old.'.format('lily', 18)) print('Hi {0}. {0} is {1} years old.'.format('lily', 18))
# 关键字参数 print('{name} is {age} years old'.format(name='lily', age=18))
# 下标参数 lily = ['lily', 18] print('{0[0]} is {0[1]} years old'.format(lily))
lily is 18 years old. lily is 18 years old. Hi lily. lily is 18 years old. lily is 18 years old lily is 18 years old 3.14 3.14 3.14 00003.14 aaaa3.14 3.1416 00003.1416 1100 12 14 c 0xc 0XC 1,230,000,000