Compare commits

...

79 Commits

Author SHA1 Message Date
Matthew Johnson 48d17550a7 Release v1.2.0
This release adds several new features:
* Bitbake infile parsing using the --infile flag (see README)
* Support override file for %description section
* Default python pattern now distutils3 instead of distutils23
* Improved Rust/Cargo support
* Improved 32bit make/make_install args support
* Print fingerprint of imported pubkey
* Change default keyring to package repository with fallback the
  autospec repository.
* Improved output

...makes some configuration updates:
* Adds several new public keys
* Adds lines to configure_whitelist
* Adds patterns for failed_patterns

...and makes several fixes as well:
* Print guessed commitmessage as string instead of list
* Fix several issues with catkin support
* Follow redirects by the license server
* Add a couple new URL patterns
* Remove unneeded V and VERBOSE flags for make lines
* Remove no-longer-used functional test suite
* Turn off string interpolation for URLs containing '%'
* Respect [autospec][urlban] for archive URLs

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2018-01-18 15:20:26 -08:00
Matthew Johnson 02c63d802c Record imported public key in commit message
When the user chooses to import a public key during the autospec run
display information on that key in the commit message.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2018-01-18 15:20:30 -08:00
Matthew Johnson 6593bfb3b5 Change default keyring to package directory
Instead of relying on a centralized keyring that resides in the autospec
repository, make the default keyring the package directory itself. Any
key imports will be to the package repository and will be committed as
part of the automatic autospec commit.

Retain the autospec repo keyring as a fallback keyring when the public
key does not exist in the package repo.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2018-01-18 15:20:30 -08:00
Matthew Johnson a7e0d4b53e Add --fingerprint output when importing pubkeys
Fixes #79

Print the key's fingerprint so the user can cross-reference a PGP key
server and make a more informed decision to import the public key.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2018-01-18 08:51:18 -08:00
Matthew Johnson 7e28a3a7de Print instructions when not automatically committing
When skipping automatic git commit due to --skip-git flag print a
message informing the user they must commit their changes themselves.

Fixes #89

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2018-01-17 17:02:23 -08:00
Matthew Johnson 4b2ca0518b Respect [autospec][urlban] for archive URLs
Fixes #104

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2018-01-17 17:02:02 -08:00
Matthew Johnson 4d4ae84553 Add new mappings to failed_commands
Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2018-01-17 13:43:25 -08:00
Matthew Johnson 56eaaea26c Construct gnome git urls with github
Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2018-01-17 13:43:08 -08:00
William Douglas 165752000c Add 32bit versions of make/make_install args
Add make32_args and make32_install_args config file handling to allow
specific options to be passed that are specific to the 32bit builds.
2018-01-17 13:42:50 -08:00
William Douglas 4befc85602 Fixups for rust/cargo building
Improve rust/cargo support by:
1) Better handling only toplevel Cargo configuration files for dependency
lookup.
2) Adding runtime requirements for buildreq packages in order to get
dependencies from non directly dependent packages resolved.
3) Add cargo as a buildreq for rust packages to handle the rustc/cargo
split.
4) Add cargo detection from failed_commands.
5) Fix rust source directory destination to not append version in case
the package name already had version information in it.
6) Get name and version information from crates.io package files.
2018-01-16 14:17:09 -08:00
Matthew Johnson 3dd33f1daf Add several new strings to the configure_whitelist
Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2018-01-12 10:32:56 -08:00
Matthew Johnson 7c3dd04b17 Fix mismatched quotes in specfile write
The intention here is to use the self.cmake_srcdir variable, not print
the literal string to the file...

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2018-01-12 10:32:42 -08:00
Matthew Johnson e7b1302768 Check for ConfigParser regressions in all source files
Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2018-01-11 17:31:49 -08:00
Matthew Johnson 9739ab703a Turn off ConfigParser string interpolation
configparser.ConfigParser attempts to interpolate "%" characters in the
values of the key-value pairs when parsing. This is absolutely unwanted
behavior, especially when parsing URLs such as

<sourceforge url>/joe-editor/files/JOE%20sources/<joe tar>

which cause an uncaught exception.

Turn off interpolation by passing the interpolation=None argument to
ConfigParser.

Add a unit tests to report when ConfigParser(...) is called in the
codebase without setting interpolation to None.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2018-01-11 17:24:39 -08:00
Matthew Johnson eb4ba41d37 Remove no-longer-used functional test suite
This test suite is extremely hard to keep up-to-date and is no longer as
valuable now that unit tests have been written for much of the code
base. Actual functional testing can be done against package repos
without requiring them to be included in the autospec repository.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2018-01-11 14:47:39 -08:00
Matthew Johnson 6cfd31086a Remove remaining VERBOSE make flags
Finish the work of 9bb89743d4 and remove
remaining VERBOSE flags for make. As mentioned in the previous commit
autospec does not parse the verbose output from make, so the flag is not
necessary and causes a considerable slowdown when parsing large build
logs.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2018-01-10 16:27:54 -08:00
Matthew Johnson e7fc47f019 Import new public key (Matthew Johnson)
Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2018-01-10 10:58:59 -08:00
Patrick McCarty 00ae2e0cfb Import new public key (William Douglas)
Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2018-01-10 10:53:33 -08:00
William Douglas 6e5e7f6107 Import new public key FPComplete
This key is needed to verify the signature for 'stack' release
tarballs.
2018-01-03 09:02:26 -08:00
Arzhan Kinzhalin a950d006a4 Add Arzhan Kinzhalin to known signers.
Needed to verify clrtrust release signatures.

pub   rsa2048 2017-10-02 [SC] [expires: 2022-10-01]
      42EE4AEEE3AA6BA74215C289C9D50845DE5519CB
uid           Arzhan Kinzhalin (kai) <arzhan@kinzhalin.com>
uid           Arzhan Kinzhalin (kai) <arzhan.i.kinzhalin@intel.com>
sub   rsa2048 2017-10-02 [E] [expires: 2022-10-01]

Yours faithfully.
2017-12-26 09:53:43 -08:00
Arzhan Kinzhalin a148072bf7 Do not follow location when using HEAD request.
Suffice to get 302 or 200 on HEAD. Subsequent locations may point to
arbitrary servers which may return 403 on HEAD (while allow GET). This
issue happens with releases hosted on github.com, for example.
2017-12-22 16:58:12 -08:00
Leandro Dorileo f718e18275 more catkin patterns
Depending on the dependencies name catkin will break the line or not,
this new patterns will catch more errors.

Signed-off-by: Leandro Dorileo <leandro.maciel.dorileo@intel.com>
2017-12-19 13:48:29 -08:00
Matthew Johnson 4bf66cbc4e Change default python buildpattern to distutils3
Change default python buildpattern from distutils23 (both python2 and
python3) to distutils3 (python3 only). This is a step toward deprecating
python2 usage in distro packages. Any packages that rely on python2
should have "distutils23" added to the build_pattern configuration file
to maintain their python2 subpackage (or, preferrably, built with
python3 only as is default).

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-12-19 12:10:56 -08:00
Matthew Johnson 9bb89743d4 Remove verbose flag for make line
Autospec does not parse the verbose output from make, so V=1 is not
necessary and slows down autospec build log parsing considerably. If
users want to debug a build at that level they should add the V=1 back
manually.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-12-14 15:11:50 -08:00
Leandro Dorileo af19c7e567 add new url pattern
Consider package names with an underscore separator.

Signed-off-by: Leandro Dorileo <leandro.maciel.dorileo@intel.com>
2017-12-14 14:50:03 -08:00
Matthew Johnson 4897e3974e Follow redirects from license server
Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-12-13 14:24:01 -08:00
Leandro Dorileo 28d7fb63c4 catkin: add the detected module (not only the pkgconfig)
We want to add a buildreq of the package providing the detected module'
pkgconfig (-lib/-dev), but, the package providing it will not install
the expected cmake files then make sure we also add it.

Signed-off-by: Leandro Dorileo <leandro.maciel.dorileo@intel.com>
2017-12-07 16:45:29 -08:00
Leandro Dorileo 04161a1c24 catkin: add one more catkin failure pattern
Signed-off-by: Leandro Dorileo <leandro.maciel.dorileo@intel.com>
2017-12-07 16:45:29 -08:00
Leandro Dorileo b0f8925c97 catkin: fix issue with CMakeLists.txt parsing
Only try to parse CMakeLists.txt (looking for catkin' deps) only if
the CMakeLists.txt being processed is in the root tarball dir or in
the cmake_srcdir directory. With this we prevent to detect
dependencies on undesired sub components.

Signed-off-by: Leandro Dorileo <leandro.maciel.dorileo@intel.com>
2017-12-07 16:45:29 -08:00
Gabi Beyer 77584ce991 Add README information for infile argument
Provide information ahout the infile parser to the README for a
better user experience.

Signed-off-by: Gabi Beyer <Gabib@live.com>
2017-12-06 15:02:32 -08:00
Patrick McCarty 834314211c Import new public key (Thomas Orgis)
This key is needed to verify the signature for 'mpg123' release
tarballs.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2017-12-05 09:01:10 -08:00
Patrick McCarty 9c5f24d17a Support spec %description section override
Resolves #34

In case the user wants to override the base package %description content
autodetected by autospec, add support for a config file named
"description" to provide the content instead.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2017-12-04 14:45:40 -08:00
Matthew Johnson 76a62e0c10 Print commitmessage as a string
commitmessage is a list and is being printed as a string representation
of a list. Join it to a string to the print looks sane.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-12-01 14:22:33 -08:00
Patrick McCarty 52f5d0e2ea Add new public key from Andy Wingo
I verified that the fingerprint on this key matches the one listed on
PGP key servers.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2017-12-01 12:27:00 -08:00
Gabi Beyer 7da1d6c9e8 Add infile print statements
Add print statements with the INFILE header to show when a value
from the infile has been incorporated into the autospec build
of a package.

Signed-off-by: Gabi Beyer <gabib@live.com>
2017-11-30 09:07:19 -08:00
Gabi Beyer a904b9869a Logic to write bb tasks to files as comments
Bitbake files contain executable tasks like configure and install.
Additionally, some have operations like append and prepend with
the task names. Scrape these commands, perform the operations and
store them in the dictionary as appropriate.

Then, after updating the specfile, write these patterns, as
comments to their mapped file name.

Signed-off-by: Gabi Beyer <gabib@live.com>
2017-11-30 09:07:19 -08:00
Gabi Beyer 5d4644720c Add request requirement and pass infile dict
To use the infile_dict after the creation of the specfile, it
must be passed into the package function.

Also the requirement request for python is needed.

Signed-off-by: Gabi Beyer <gabib@live.com>
2017-11-30 09:07:19 -08:00
Gabi Beyer 5474ed39d1 fix make check for infile
Signed-off-by: Gabi Beyer <gabib@live.com>
2017-11-30 09:07:19 -08:00
Gabi Beyer 953dffd893 Move license to update sooner
Add the license from the recipe file to the spec licenses
prior to the specfile creation, so that tarball analysis
that does not find a license file will get one from the
bitbake file.

Signed-off-by: Gabi Beyer <gabib@live.com>
2017-11-30 09:07:19 -08:00
Gabi Beyer 0ef4314c4d scrape src url from bb and inc file
Get the source url to set the url if one is not passed into
autospec. This allows a user to use an infile file as the
source for the tarball, and prevents them having to manually
find the url. It also requires that the variable PV and ROS_SPN
are replaced with their correct strings (version and name,
respectively).

Changed the name of the infile_parsers.py file to infile_bb_parser
since it is specific to recipe files.

Have string read into lists and joined to fix spacing issues.

Signed-off-by: Gabi Beyer <gabib@live.com>
2017-11-30 09:07:19 -08:00
Gabi Beyer aef3399d10 Refactor to use multiple files and change inputs
Create 3 separate infile files, the infile_handler reads in the
inputs and determnes how to parse them. The --infile argument now
allows a url, file, or directory of files to be passed as the
input. The infile_handler determines that type of input, calls the
correct parser depending on the filetype, and calls the update to
the specfile.

The infile parsers contains the scraping and parsing for all file
types. Currently it scrapes both .bb and .inc files and stores the
data into one dictionary. Because these files are both for recipes
their data corresponds and the .inc file takes presedence.

The infile update spec file udpates aspects of the specfile that
have been scraped and stored into a dict from the infile parsers
file. If there exists a value for ROS_SPN in the .bb file, use that
when replace the ROS_SNP value in the replace PV function.

Signed-off-by: Gabi Beyer <gabib@live.com>
2017-11-30 09:07:19 -08:00
Gabi Beyer 07d0d53470 Add update license function and fix comments
Add comments to the update functions (summary, license, build
deps) within the funcion.

Add an update_license function that appends any licenses scraped
from the bb file to the autospec licenses list if they don't
already exist.

Also added unittests for functionality

Signed-off-by: Gabi Beyer <gabib@live.com>
2017-11-30 09:07:19 -08:00
Gabi Beyer bc7f5a8b51 Update dependencies in specfile from infile
The specfile dependencies are a set, so create a set from the
deps scraped from the bb file, union the two sets, and write
it to the specfile.

Signed-off-by: Gabi Beyer <gabib@live.com>
2017-11-30 09:07:19 -08:00
Gabi Beyer 0a1def5f0b Update specfile summary from infile file
If the specfile doesn't have a summary in the specfile, it
is overwritten by the summary provided by the bitbake recipe.

Signed-off-by: Gabi Beyer <gabib@live.com>
2017-11-30 09:07:19 -08:00
Gabi Beyer 8b0c5439e5 Initial commit for infile parser
Add --infile argument that takes a url, path, or directory
to a bitbake/recipe file. It scrapes the .bb/.inc file for
configuration data and stores it in a dictionary. This
architecture can be used for multiple file formats.

Also adds some initial unit tests for scraping functionality.

Signed-off-by: Gabi Beyer <gabib@live.com>
2017-11-30 09:07:19 -08:00
Caio Marcelo de Oliveira Filho 25724b09a1 Extra case for name/version extraction with GitHub
In this case, the project uses one GitHub repo to distribute different
packages. The existing extraction rules are not enough

Signed-off-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
2017-11-29 17:55:47 -08:00
Matthew Johnson c98571de01 Release v1.1.8
* Add catkin build pattern recognition
* Add configuration file for cmake_srcdir
* Add failed_commands pattern for ldap-dev
* Update README.rst

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-28 15:23:42 -08:00
Matthew Johnson be834de817 Clean up README format
Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-28 15:22:13 -08:00
Matthew Johnson 934269f006 Update README
Update README to latest options and configurations available in
autospec.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-28 15:22:13 -08:00
Leandro Dorileo 5b152f172e catkin: introduce catkin pattern recognition
Catkin is based on cmake and is a way to package/build modules as a
cmake components. This patch recognizes the patterns and handle the
dependencies, every catkin package provides a package-config descriptor
so it's pretty safe to rely on that.
2017-11-28 15:21:51 -08:00
Leandro Dorileo 42c6c8fa64 cmake: add cmake_srcdir configuration
There are some packages that will ship multiple packages in the same
tarball. This configuration works around that and run cmake on the
correct source sub directory.
2017-11-28 10:04:05 -08:00
Simental Magana, Marcos 50f9806daa failed_commands: add pattern to detect ldap.h
with this change autospec detects when ldap.h is missing
to add the openldap-dev build requirement.

Signed-off-by: Simental Magana, Marcos <marcos.simental.magana@intel.com>
2017-11-27 09:38:28 -08:00
Matthew Johnson 574198586b Release 1.1.7
* Improves test coverage for several modules
* Adds "autoupdate" flag for usage by third-party tools

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-20 09:55:44 -08:00
Matthew Johnson 3dd679b459 Add autoupdate flag to options.conf
This flag is a no-op for autospec itself, but allows humans to indicate
that a package is trusted enough to automatically release new updates of
the package. In practice this should be used by a tool that runs
autospec in an automated manner to push the package to a build server.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-17 15:06:42 -08:00
Matthew Johnson bbaade01c7 Add test for build.log missing file parsing
Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-16 13:19:11 -08:00
Matthew Johnson ad2fa386a4 license: Add tests for complete coverage of license module
The additional test uncovered a syntax error in the print_fatal call in
license_from_copying_hash, which was fixed as well. An unnecessary mock
was removed from another test.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-16 13:11:53 -08:00
Matthew Johnson 07622d5770 Increase count.py test coverage
Also remove some never-hit regular expressions from count.py

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-16 13:11:07 -08:00
Matthew Johnson 0c74c918c1 Release v1.1.6
This release deprecates Makefile writing by autospec since per-package
Makefiles are not used by autospec.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-14 10:16:51 -08:00
Matthew Johnson 79246f925a Deprecate Makefile writing
The package metadata is now written to options.conf so the Makefile
writing is no longer needed.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-14 10:17:07 -08:00
Matthew Johnson a0bae50f72 Release v1.1.5
This release adds efivar and gnu-efi simple patterns.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-09 15:02:46 -08:00
William Douglas 8281fb1b97 Add efivar and gnu-efi simple patterns
Enable detecting missing efivar and gnu-efi build requirements (with
meson).
2017-11-09 15:02:45 -08:00
Matthew Johnson a5b085e2cc Release v1.1.4
This release introduces safeguards to remove directories from the
package file list to protect against top-level directories being
included in packages (such as /usr). The build.log files are now saved
to the target directory for each failed build attempt. The urlban is now
respected when writing metadata to options.conf.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-07 16:44:11 -08:00
Matthew Johnson e34b4e9315 Respect urlban when writing metadata to options.conf
This also requires moving the read_config_opts() call to after
autospec.conf is read so the urlban is populated.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-07 14:27:12 -08:00
Matthew Johnson 7c4e0e9fd6 Do not clean any files with a directive
Use a regular expression in order to exclude all directives at the
beginning of the filename, including %doc.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-07 13:54:50 -08:00
Matthew Johnson a2b467e6b0 Do not attempt to clean "%dir" files
When cleaning directories from the package file lists do not attempt to
clean "%dir" prefixed files. Although autospec does not currently
support empty directories, it could in the future.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-07 13:54:50 -08:00
Matthew Johnson 7d7263d684 Remove directories from file list
Clean directories from package file lists. If directories are
encountered, print a warning, add the directory to the blacklist, and
re-run.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-07 13:54:50 -08:00
Matthew Johnson 7591bb9d25 Save build.log files from failed rounds
This is useful for debugging purposes. The file must be saved to the
target directory since the results directory is wiped on each round.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-07 11:32:21 -08:00
Matthew Johnson 9b8ef511d2 Add coverage statistics to unittest runs
Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-07 11:04:46 -08:00
Matthew Johnson 52a48c0c69 Release v1.1.3
This release makes some small updates to our README documentation,
improves tarball.py and pkg_integrity.py testing, fixes a bug that
allowed an empty file to remain on failed downloads, and adds a regular
expression for build.log test scanning.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-02 11:20:40 -07:00
Matthew Johnson 5d722054e9 Add regular expression for vim tests
Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-11-02 11:05:11 -07:00
Gabi Beyer e13d3edb03 Remove network dependencies for pkg_integrity test
Create a mock function that copies files from the testfiles
directory to a tmp directory, when attempting to download
files from the network.

Create a mock function for head_request that returns 404 for
a few specified urls, and 200 for the rest.

The mock calls will allow the functionality of the pkg_integrity
program to be tested and not dependent on networking. Tests will
no longer need to be skipped in travis with the removal of
network dependency.

Removed a few tests that were not specific to pkg_integrity, but
instead were testing the importing and exporting abilities
of the gpg key server.

Added mock as a requirement to the requirements.txt file.

Signed-off-by: Gabi Beyer <gabib@live.com>
2017-11-01 16:58:58 -07:00
Matthew Johnson 55feeec051 Remove empty download file on pycurl failure
Fixes #26

Remove empty file created when a download fails. The empty file caused
autospec to fail on consecutive runs due to autospec attempting to reuse
the file when it exists.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-10-27 15:20:16 -07:00
Brett T. Warden 7fa9e21b83 Add/enhance test cases for giturl
Add test cases for empty/null giturl. Add message to case when regex
fails to match.

Signed-off-by: Brett T. Warden <brett.t.warden@intel.com>
2017-10-26 14:34:08 -07:00
Brett T. Warden 3db36c3093 tarball: Use repo name only if more descriptive
For github URLs, only use the repo name as the package name if it's more
descriptive than what was extracted from the tarball name. Otherwise,
filter off prefix "release-" or a numeric suffix.

Signed-off-by: Brett T. Warden <brett.t.warden@intel.com>
2017-10-26 14:34:08 -07:00
Brett T. Warden 0eb744f788 tarball: de-conflate github repo and package name
For github URLs, capture and identify repo name separately from package
name. This is a building block for resolving cases where the package
name is actually different than the github repo name.

Signed-off-by: Brett T. Warden <brett.t.warden@intel.com>
2017-10-26 14:34:08 -07:00
Brett T. Warden 17fa67533f tarball: extend github URL match patterns
Extend the regular expressions used to match github URLs. Covers
additional cases found in the wild.

Signed-off-by: Brett T. Warden <brett.t.warden@intel.com>
2017-10-26 14:34:08 -07:00
Brett T. Warden 5132520108 Add test for giturl generation
For github URLs in tests/packageurls, check that we produce a giturl
that looks reasonably correct.

Signed-off-by: Brett T. Warden <brett.t.warden@intel.com>
2017-10-26 14:34:08 -07:00
William Douglas ff87f71be3 Add additional build_pattern options to README
Adds R, perl, ruby, and Java build pattern targets.
2017-10-24 10:38:14 -07:00
Brett T. Warden e9e9b5de2a Fix formatting --target option
Add missing comma to --target help text, fixing formatting to match previous command-line options.
2017-10-23 16:59:54 -07:00
581 changed files with 2592 additions and 194602 deletions
+2
View File
@@ -3,3 +3,5 @@ __pycache__
*~
*.swp
tags
.coverage
htmlcov
+4
View File
@@ -2,6 +2,10 @@ language: python
sudo: enabled
python:
- "3.6"
install:
- pip install -r requirements.txt
# command to run tests
script:
- make check
+9 -3
View File
@@ -43,8 +43,14 @@ test_test:
test_util:
PYTHONPATH=${CURDIR}/autospec python3 tests/test_util.py
test_autospec:
python3 tests/test_autospec.py -c ${CASES}
test_infile_parser:
PYTHONPATH=${CURDIR}/autospec python3 -m unittest discover -b -s tests -p 'test_infile_*'
test_general:
PYTHONPATH=${CURDIR}/autospec python3 tests/test_general.py
unittests:
PYTHONPATH=${CURDIR}/autospec python3 -m unittest discover -b -s tests -p 'test_*.py'
PYTHONPATH=${CURDIR}/autospec coverage run -m unittest discover -b -s tests -p 'test_*.py' && coverage report
coverage:
coverage report -m
+314 -284
View File
@@ -5,16 +5,18 @@
Autospec
========
autospec is a tool to assist in the automated creation and maintainence
of RPM packaging. It will continuously run updated builds based on new
information discovered from build failures, until it has a complete and
valid .spec file. The tool makes use of mock to achieve this.
autospec is a tool to assist in the automated creation and maintenance of RPM
packaging. It will continuously run updated builds based on new information
discovered from build failures until it has a complete and valid .spec file. The
tool makes use of mock to achieve this.
.. contents:: Table of Contents
License
=======
autospec is available under the terms of the GPL, version 3.0
Copyright (C) 2015 Intel Corporation
Copyright (C) 2017 Intel Corporation
Configuration of autospec
@@ -30,45 +32,65 @@ Example ``autospec.conf`` file::
license_fetch = http://yourhost/hash.php
license_show = http://yourhost/showone.php?hash=%(HASH)s
packages_file = file:///path/to/package_list_file
yum_conf = file:///path/to/yum.conf
upstream = http://yourhost/tarballs/%(HASH)s/%(NAME)s
git
The upstream git repository URL base
**git**
The upstream git repository URL base
license_fetch
Optional URL to use for scanning license files
**license_fetch**
Optional URL to use for scanning license files
license_show
Optional URL to interact with online license checker
**license_show**
Optional URL to interact with online license checker
packages_file
Optional path to add autodetected runtime requirement checking
**packages_file**
Optional path to add autodetected runtime requirement checking against
yum_conf
Optional path to yum configuration
**yum_conf**
Optional path to yum configuration
**upstream**
Base URL for stored upstream tarballs
upstream
Base URL for stored upstream tarballs
Synopsis
========
Usage: ``python3 autospec.py [options] URL``
.. code-block:: bash
usage: autospec.py [-h] [-g] [-n NAME] [-v VERSION]
[-a [ARCHIVES [ARCHIVES ...]]] [-l] [-b] [-c CONFIG]
[-t TARGET] [-i] [-p] [--non_interactive] [-C]
[--infile INFILE]
[url]
-h, --help show help message and exit
-g, --skip-git Don't commit result to git
-n NAME, --name NAME Override the package name
-a ARCHIVES, --archives ARCHIVES
tarball URLs for additional source archives and a
location for the sources to be extacted to (e.g.
http://example.com/downloads/dependency.tar.gz
/directory/relative/to/extract/root )
-l, --license-only Only scan for license files
-b, --skip-bump Don't bump release number
-c CONFIG, --config CONFIG Set configuration file to use
-t DIRECTORY --target DIRECTORY Set location to create or use
url (required - unless infile is passed) tarball URL
(e.g. http://example.com/downloads/mytar.tar.gz)
optional arguments:
-h, --help show this help message and exit
-g, --skip-git Don't commit result to git
-n NAME, --name NAME Override the package name
-v VERSION, --version VERSION
Override the package version
-a ARCHIVES, --archives ARCHIVES
tarball URLs for additional source archives and a
location for the sources to be extacted to (e.g.
http://example.com/downloads/dependency.tar.gz
/directory/relative/to/extract/root )
-l, --license-only Only scan for license files
-b, --skip-bump Don't bump release number
-c CONFIG, --config CONFIG
Set configuration file to use
-t TARGET, --target TARGET
Target location to create or reuse
-i, --integrity Search for package signature from source URL and
attempt to verify package
-p, --prep-only Only perform preparatory work on package
--non_interactive Disable interactive mode for package verification
--infile INFILE Additional input to contribute to specfile creation.
Can be a url, directory of files, or a file.
-C, --cleanup Clean up mock chroot after building the package
@@ -77,27 +99,58 @@ Requirements
In order to run correctly, ``autospec`` requires the following components:
* python3
* correctly configured mock
* python3
* correctly configured mock
If ``autospec`` is not configured to use a license server, then you will
need a ``common/licenses`` file - which should be an up to date list of
licenses to facilitate automatic license detection during the scan of a
tarball. For correctness, license names should be in the SPDX identifier
format. Each line in the file constitutes a license definition, for example::
If ``autospec`` is not configured to use a license server, then it will use the
``autospec/license_hashes`` file - which is a list of licenses to facilitate
automatic license detection during the scan of a tarball. For correctness,
license names should be in the SPDX identifier format. Each line in the file
constitutes a license definition, for example::
750b9d9cc986bfc80b47c9672c48ca615cac0c87 | BSD-3-Clause
175e59be229a5bedc6be93e958a970385bb04a62 | Apache-2.0
794a893e510ca5c15c9c97a609ce47b0df74fc1a | BSD-2-Clause
750b9d9cc986bfc80b47c9672c48ca615cac0c87, BSD-3-Clause
175e59be229a5bedc6be93e958a970385bb04a62, Apache-2.0
794a893e510ca5c15c9c97a609ce47b0df74fc1a, BSD-2-Clause
Infile option
=============
To provide additional build information for a package, a supplementary format
file may be used with the --infile command. The file is scraped and the data is
mapped to the appropriate location for the specfile build. A source URL is not
required when using the ``--infile`` argument, for it can be scraped from the
additional format file.
Supported format types:
Currently autospec supports recipe / bitbake (``.bb``) filetypes, and their
include directives (``.inc``)
Input type:
The --infile argument can parse a url to a file, a path to a directory of
files (that are the same format and support the same packages), or a path
to a file.
Variables included:
All variables, and commands are scraped from the format file, however not all
are added to the specfile build process. The following are incorporated into
the specfile build flow, unless they already exist:
* Source url - If a source url is not passed in, or already found, the tarball
used for building the package can be scraped from the infile.
* Summary
* Licenses
* Build dependencies
* Commands - These are appended to the associated files as comments
* ``configure``
* ``make_install_append``
Control files
==============
It is possible to influence precisely how autospec will behave in order to
gain fine control over the build itself. These files may be used to alter
the default behaviour of the configure routine, to blacklist build dependencies
from being automatically added, and such.
It is possible to influence precisely how autospec will behave in order to gain
fine control over the build itself. These files may be used to alter the default
behaviour of the configure routine, to blacklist build dependencies from being
automatically added, and such.
These files are expected to live in same directory that the resulting ``.spec``
will live.
@@ -105,315 +158,292 @@ will live.
Common files
------------
**release**
release
This file contains the current release number that will be used in the
``.spec``. This is also bumped and generated on existing and new packages,
respectively. This results in less manual work via automatic management.
This file contains the current release number that will be used in the
``.spec``. This is also bumped and generated on existing and new packages,
respectively. This results in less manual work via automatic management.
**$package.license**
In certain cases, the package license may not be automatically discovered.
In this instance, ``autospec`` will exit with an error. Update this file
to contain the valid SPDX identifier for any license(s) for the package,
replacing ``$package`` in the filename with the actual package name.
$package.license
In certain cases, the package license may not be automatically discovered. In
this instance, ``autospec`` will exit with an error. Update this file to
contain the valid SPDX identifier for any license(s) for the package,
replacing ``$package`` in the filename with the actual package name.
Controlling dependencies
-------------------------
**buildreq_add**
buildreq_add
Each line in the file provides the name of a package to add as a build
dependency to the ``.spec``.
Each line in the file provides the name of a package to add
as a build dependency to the ``.spec``.
pkgconfig_add
Each line in the file is assumed to be a pkgconfig() build dependency. Add
the pkg-config names here, as ``autospec`` will automatically transform the
names into their ``pkgconfig($name)`` style when generating the ``.spec``.
**pkgconfig_add**
requires_add
Each line in the file provides the name of a package to add as a runtime
dependency to the ``.spec``.
Each line in the file is assumed to be a pkgconfig() build dependency.
Add the pkg-config names here, as ``autospec`` will automatically transform
the names into their ``pkgconfig($name)`` style when generating the ``.spec``.
buildreq_ban
Each line in the file is a build dependency that under no circumstance should
be automatically added to the build dependencies. This is useful to block
automatic configuration routines adding undesired functionality, or to omit
any automatically discovered dependencies during tarball scanning.
**requires_add**
pkgconfig_ban
Each line in this file is a pkgconfig() build dependency that should not be
added automatically to the build, much the same as ``buildreq_ban``. As with
``pkgconfig_add``, these names are automatically transformed by ``autospec``
into their correct ``pkgconfig($name))`` style.
Each line in the file provides the name of a package to add
as a runtime dependency to the ``.spec``.
requires_ban
Each line in the file is a runtime dependency that under no circumstance
should be automatically added to the runtime dependencies. This is useful to
block automatic configuration routines adding undesired functionality, or to
omit any automatically discovered dependencies during tarball scanning.
**buildreq_ban**
.. note::
Each line in the file is a build dependency that under no circumstance
should be automatically added to the build dependencies. This is useful
to block automatic configuration routines adding undesired functionality,
or to omit any automatically discovered dependencies during tarball scanning.
**pkgconfig_ban**
Each line in this file is a pkgconfig() build dependency that should not
be added automatically to the build, much the same as ``buildreq_ban``.
As with ``pkgconfig_add``, these names are automatically transformed by
``autospec`` into their correct ``pkgconfig($name))`` style.
**requires_ban**
Each line in the file is a runtime dependency that under no circumstance
should be automatically added to the runtime dependencies. This is useful
to block automatic configuration routines adding undesired functionality,
or to omit any automatically discovered dependencies during tarball scanning.
Run time requirements are not assumed to be build time requirements.
If a package has the same build and run time requirement it must be added
to both buildreq_add and requires_add.
Run time requirements are not assumed to be build time requirement
If a package has the same build and run time requirement it must be added
to both buildreq_add and requires_add.
Controlling the build process
------------------------------
**configure**
configure
This file contains configuration flags to pass to the ``%configure`` macro for
autotools based tarballs. As an example, adding ``--disable-static`` to
``./configure`` for an autootools based tarball would result in ``%configure
--disable-static`` being emitted in the ``.spec``.
This file contains configuration flags to pass to the ``%configure``
macro for autotools based tarballs. As an example, adding ``--disable-static``
to ``./configure`` for an autootools based tarball would result in
``%configure --disable-static`` being emitted in the ``.spec``.
cmake_args
This file contains arguments that should be passed to the ``%cmake`` macro for
CMake based tarballs. As an example, adding ``-DUSE_LIB64=ON`` to
``./cmake_args`` would result in ``%cmake -DUSE_LIB64=ON`` being emitted in
the ``.spec``.
**cmake_args**
make_args
The contents of this file are appended to the ``make`` invocation. This may be
useful for passing arguments to ``make``, i.e. ``make TOOLDIR=/usr``
This file contains arguments that should be passed to the ``%cmake``
macro for CMake based tarballs. As an example, adding ``-DUSE_LIB64=ON`` to
``./cmake_args`` would result in ``%cmake -DUSE_LIB64=ON`` being emitted
in the ``.spec``.
make32_args
The contents of this file are appended to the ``make`` invocation of the 32bit
build. It is appended after the make_args content so 32bit specific overrides
can be added.
**broken_parallel_build**
make_install_args
Much like ``make_args``, this will pass arguments to the ``make install``
macro in the ``.spec``
This option is set in the ``options.conf`` file described below. If this
option is set, then parallelisation will be disabled in the build.
This usually means that ``%{?_smp_mflags}`` will not be passed to ``make``
make32_install_args
Much like ``make32_args``, this will pass arguments to the ``make install``
macro in the ``.spec`` for the 32bit build. Again it is appended after
make_install_args so 32bit specific overrides can be added.
**make_args**
make_install_append
Additional actions that should take place after the ``make install`` step has
completed. This will be placed in the resulting ``.spec``, and is used for
situations where fine-grained control is required.
The contents of this file are appended to the ``make`` invocation. This
may be useful for passing arguments to ``make``, i.e. ``make TOOLDIR=/usr``
install_macro
The contents of this file be used instead of the automatically detected
``install`` routine, i.e. use this if ``%make_install`` is insufficient.
**make_install_args**
subdir
Not all packages have their ``Makefile``'s available in the root of the
tarball. An example of this may be cross-platform projects that split
Makefile's into the ``unix`` subdirectory. Set the name in this file and the
``.spec`` will emit the correct ``pushd`` and ``popd`` lines to utilise these
directories for each step in the build.
Much like ``make_args``, this will pass arguments to the ``make install``
macro in the ``.spec``
cmake_srcdir
The contents of this file are a path the source directory in which to run cmake
for non-standard packages.
**make_install_append**
build_pattern
In certain situations, the automatically detected build pattern may not work
for the given package. This one line file allows you to override the build
pattern that ``autospec`` will use. The supported build_pattern types are:
Additional actions that should take place after the ``make install`` step
has completed. This will be placed in the resulting ``.spec``, and is used
for situations where fine-grained control is required.
* R: R language package
* cpan: perl language package
* ruby: ruby language package
* maven: Java language package
* configure: Traditional ``%configure`` autotools route
* configure_ac: Like ``configure, but performs ``%reconfigure`` to regenerate
``./configure``
* autogen: Similar to ``configure_ac`` but uses the existing ``./autogen.sh``
instead of ``%reconfigure``
* distutils: Only build the Pythonic package with Python 2
* distutils3: Only build the Pythonic package with Python 3
* distutils23: Build the Pythonic package using both Python 2 and Python 3
**install_macro**
series
This file contains a list of patches to apply during the build, using the
``%patch`` macro. As such it is affected by ``-p1`` style modifiers.
The contents of this file be used instead of the automatically detected
``install`` routine, i.e. use this if ``%make_install`` is insufficient.
**subdir**
Not all packages have their ``Makefile``'s available in the root of the tarball.
An example of this may be cross-platform projects that split Makefile's into
the ``unix`` subdirectory. Set the name in this file and the ``.spec`` will
emit the correct ``pushd`` and ``popd`` lines to utilise these directories
for each step in the build.
**build_pattern**
In certain situations, the automatically detected build pattern may not
work for the given package. This one line file allows you to override the
build pattern that ``autospec`` will use. The supported build_pattern types are:
- configure: Traditional ``%configure`` autotools route
- configure_ac: Like ``configure, but performs ``%reconfigure`` to regenerate ``./configure``
- autogen: Similar to ``configure_ac`` but uses the existing ``./autogen.sh`` instead of ``%reconfigure``
- distutils: Only build the Pythonic package with Python 2
- distutils3: Only build the Pythonic package with Python 3
- distutils23: Build the Pythonic package using both Python 2 and Python 3
**series**
This file contains a list of patches to apply during the build, using the ``%patch``
macro. As such it is affected by ``-p1`` style modifiers.
**golang_libpath**
When building go packages, the go import path will be guessed automatically
(e.g. building ``https://github.com/go-yaml/yaml/`` would get
``github.com/go-yaml/yaml``). While this is handy, it's not always correct
(in the previous example, the correct import path should be
``gopkg.in/yaml.v2``). This could be easily fixed by placing
``gopkg.in/yaml.v`` in this file, changing where the go bits will be placed.
golang_libpath
When building go packages, the go import path will be guessed automatically
(e.g. building ``https://github.com/go-yaml/yaml/`` would get
``github.com/go-yaml/yaml``). While this is handy, it's not always correct (in
the previous example, the correct import path should be ``gopkg.in/yaml.v2``).
This could be easily fixed by placing ``gopkg.in/yaml.v`` in this file,
changing where the go bits will be placed.
Controlling files and subpackages
---------------------------------
**excludes**
excludes
This file is used to generate ``%exclude`` lines in the ``.spec``. This is
useful for omitting files from being included in the resulting package. Each
line in the file should be a full path name.
This file is used to generate ``%exclude`` lines in the ``.spec``. This
is useful for omitting files from being included in the resulting package.
Each line in the file should be a full path name.
extras
Each line in the file should be a full path within the resulting package, that
you wish to be placed into an automatic ``-extras`` subpackage. This allows
one to keep the main package slim and split out optional functionality or
files.
**keepstatic**
setuid
Each line in this file should contain the full path to a binary in the
resulting build that should have the ``setuid`` attribute set with the
``%attr`` macro.
This option is set in the ``options.conf`` file described below. If this
option is set, then ``%define keepstatic 1`` is emitted in the ``.spec``.
As a result, any static archive (``.a``) files will not be removed by rpmbuild.
**extras**
Each line in the file should be a full path within the resulting package,
that you wish to be placed into an automatic ``-extras`` subpackage. This
allows one to keep the main package slim and split out optional functionality
or files.
**no_autostart**
This option is set in the ``options.conf`` file described below. If this
option is set the autostart subpackage (which contains all files matching
/usr/lib/systemd/system/*.target.wants/) will not be required by the base package.
**setuid**
Each line in this file should contain the full path to a binary in the resulting
build that should have the ``setuid`` attribute set with the ``%attr`` macro.
**attrs**
Each line in this file should be a full ``%attr`` macro line that will be included
in the ``.spec`` to have fine-grained control over the permissions and ownership
of files in the package.
attrs
Each line in this file should be a full ``%attr`` macro line that will be
included in the ``.spec`` to have fine-grained control over the permissions
and ownership of files in the package.
Controlling test suites
-----------------------
By default, ``autospec`` will attempt to detect potential test suites that
can be run in the ``%check`` portion of the ``.spec``.
**skip_test_suite**
make_check_command
Override or set the command to use in the ``%check`` portion of the ``.spec``.
This may be useful when a package uses a custom test suite, or requires
additional work/parameters, to work correctly.
If this file exists, ``autospec`` will not emit any ``%check`` functionality.
This file has been deprecated and will be removed during an autospec run and
replaced with a ``skip_tests`` option in ``options.conf``.
Controlling miscellaneous spec metadata
---------------------------------------
**unit_tests_must_pass**
description
Provides content for the %description section, overriding the content
autospec autodetects. This is useful if autospec cannot find proper content
for the description, if one wants to customize the content for better
presentation, etc.
This file is automatically created upon successful completion of a package build.
This allows one to identify regressions in test failures when updating or
altering a package.
``autospec`` will fail a package that does not pass it's test suite if this file
exists.
**make_check_command**
Override or set the command to use in the ``%check`` portion of the ``.spec``.
This may be useful when a package uses a custom test suite, or requires
additional work/parameters, to work correctly.
**allow_test_failures**
This option is set in the ``options.conf`` file described below. If this
option is set it will allow test failures, and will still emit the
``%check`` code in a way that allows the build to continue.
Controlling flags and optimisation
Controlling flags and optimization
----------------------------------
Further control of the build can be achieved through the use of the
``options.conf`` file. If this file does not exist it is created by autospec.
Autospec generates this file based on the presence of deprecated 'file-exists'
files, then removes the deprecated files.
``options.conf`` file. If this file does not exist it is created by autospec
with default values. If certain deprecated configuration files exists autospec
will use the value indicated by those files and remove them.
The options that can be set in ``options.conf`` are as follows:
**asneeded**
asneeded
If this is option set, the ``.spec`` will disable the LD_AS_NEEDED variable.
Supporting binutils (such as found in Clear Linux Project for Intel
Architecture) will then revert to their normal behaviour, instead of enforcing
``-Wl,-as-needed`` in the most correct sense.
If this is option set, the ``.spec`` will disable the LD_AS_NEEDED variable.
Supporting binutils (such as found in Clear Linux Project for Intel Architecture)
will then revert to their normal behaviour, instead of enforcing ``-Wl,-as-needed``
in the most correct sense.
optimize_size
If this option is set, the ``CFLAGS/LDFLAGS`` will be extended to build the
package optimized for *size*, and not for *speed*. Use this when size is more
critical than performance.
**optimize_size**
funroll-loops
If this option is set, the ``CFLAGS/LDFLAGS`` will be extended to build the
package optimized for *speed*. In short this where speed is of paramount
importance, and will use ``-03`` by default.
If this option is set, the ``CFLAGS/LDFLAGS`` will be extended to build
the package optimised for *size*, and not for *speed*. Use this when
size is more critical than performance.
insecure_build
If this option is set, the ``CFLAGS/LDFLAGS`` will be **replaced**, using the
smallest ``-02`` based generic flags possible. This is useful for operating
systems employing heavy optimizations or full RELRO by default.
**funroll-loops**
pgo
If this option is set, the ``CFLAGS/CXXFLAGS`` will be extended to build the
package with profile-guided optimization data. It will add ``-O3``,
``-fprofile-use``, ``-fprofile-correction`` and ``-fprofile-dir=pgo``.
If this option is set, the ``CFLAGS/LDFLAGS`` will be extended to build
the package optimised for *speed*. In short this where speed is of
paramount importance, and will use ``-03`` by default.
use_lto
If this option is set, link time optimization is enabled for the build.
**insecure_build**
use_avx2
If this option is set, a second set of libraries, for AVX2, is built.
If this option is set, the ``CFLAGS/LDFLAGS`` will be **replaced**, using
the smallest ``-02`` based generic flags possible. This is useful for
operating systems employing heavy optimisations or full RELRO by default.
fast-math
If this option is set, -ffast-math is passed to the compiler.
**pgo**
broken_c++
If this option is set, flags are extended with -std=gnu++98.
If this option is set, the ``CFLAGS/CXXFLAGS`` will be extended to build
the package with profile-guided optimization data. It will add ``-O3``,
``-fprofile-use``, ``-fprofile-correction`` and ``-fprofile-dir=pgo``.
allow_test_failures
If this option is set it will allow test failures, and will still emit the
``%check`` code in a way that allows the build to continue.
**use_lto**
skip_tests
If this option is set the test suite will not be run.
If this option is set, link time optimization is enabled for the build.
no_autostart
If this option is set the autostart subpackage (which contains all files
matching /usr/lib/systemd/system/\*.target.wants/) will not be required by the
base package.
**use_avx2**
conservative_flags
If this option is set autospec will set conservative build flags
If this option is set, a second set of libraries, for AVX2, is built.
use_clang
If this option is set autospec will utilize clang. This unsets the
funroll-loops optimization if it is set.
**fast-math**
keepstatic
If this option is set, then ``%define keepstatic 1`` is emitted in the
``.spec``. As a result, any static archive (``.a``) files will not be removed
by rpmbuild.
If this option is set, -ffast-math is passed to the compiler.
32bit
This option will trigger the creation of 32-bit libraries for a 32-bit build.
**broken_c++**
nostrip
This option will suppress the stripping of the created binaries.
If this option is set, flags are extended with -std=gnu++98.
verify_required
This option will make package verification required for the build. This option
is automatically set if package verification is ever successful, but can be
turned off manually.
**allow_test_failures**
security_sensitive
This options sets flags for security-sensitive builds.
If this option is set it will allow test failures, and will still emit the
``%check`` code in a way that allows the build to continue.
**no_autostart**
If this option is set the autostart subpackage (which contains all files matching
/usr/lib/systemd/system/*.target.wants/) will not be required by the base package.
**conservative_flags**
If this option is set autospec will set conservative build flags
**use_clang**
If this option is set autospec will utilize clang. This unsets the
funroll-loops optimization if it is set.
**keepstatic**
If this option is set, then ``%define keepstatic 1`` is emitted in the ``.spec``.
As a result, any static archive (``.a``) files will not be removed by rpmbuild.
**32bit**
This option will trigger the creation of 32-bit libraries for a 32-bit
build.
so_to_lib
This option causes package ``.so`` files to be added to the ``lib`` subpackage
instead of the ``dev`` subpackage.
autoupdate
This option indicates that the package is trusted enough to be automatically
update to its newest available version when set to ``true``. This flag is
intended to be used by tools running autospec automatically.
Name and version resolution
===========================
``autospec`` will attempt to use a number of patterns to determine the name
and version of the package by examining the URL. For most tarballs this is
simple, if they are of the format ``$name-$version.tar.$compression``.
``autospec`` will attempt to use a number of patterns to determine the name and
version of the package by examining the URL. For most tarballs this is simple,
if they are of the format ``$name-$version.tar.$compression``.
For websites such as ``bitbucket`` or ``GitHub``, using ``get$`` and ``v$.tar.*``
style links, the project name itself is used from the URL and the version is
determined by stripping down the tag.
For websites such as ``bitbucket`` or ``GitHub``, using ``get$`` and
``v$.tar.*`` style links, the project name itself is used from the URL and the
version is determined by stripping down the tag.
CPAN Perl packages, R packages, and rubygems.org rubygems are automatically
prefixed with their language name: ``perl-``, ``R-`` and ``rubygem-`` respectively.
prefixed with their language name: ``perl-``, ``R-`` and ``rubygem-``
respectively.
When these automated detections are not desirable, it is possible to override
these with the ``--name`` flag when invoking ``autospec``
@@ -428,14 +458,14 @@ talks HTTP.
This URL should accept ``POST`` requests with the following keys:
**hash**
Contains the SHA-1 hash of the potential license file being checked.
hash
Contains the SHA-1 hash of the potential license file being checked.
**package**
The name of the package being examined
package
The name of the package being examined
**text**
The contents of the potential license file
text
The contents of the potential license file
Implementations return a *plain text* response with the SPDX identifier
of the license, if known. An empty response is assumed to mean that this
@@ -443,4 +473,4 @@ license is unknown, in which case ``autospec`` will emit the ``license_show``
URL. The implementation should show the now-stored license file via a
web page, and enable a human to make a decision on the license. This is
then stored internally, allowing future requests to automatically know
the license type when this hash is encounted again.
the license type when this hash is encountered again.
+57 -6
View File
@@ -19,6 +19,7 @@
import argparse
import sys
import os
import shutil
import re
import tempfile
import configparser
@@ -37,8 +38,10 @@ import commitmessage
import pkg_integrity
import specfiles
import pkg_scan
import infile_handler
import infile_update_spec
from util import print_fatal, binary_in_path, write_out
from util import print_fatal, binary_in_path, write_out, print_infile
from abireport import examine_abi
from logcheck import logcheck
@@ -102,7 +105,7 @@ def read_old_metadata():
if not os.path.exists(os.path.join(os.getcwd(), 'options.conf')):
return None, None, []
config_f = configparser.ConfigParser()
config_f = configparser.ConfigParser(interpolation=None)
config_f.read('options.conf')
if "package" not in config_f.sections():
return None, None, []
@@ -116,6 +119,17 @@ def read_old_metadata():
archives)
def save_build_log(path, iteration):
"""
Save build log to <path>/build.log.round<iteration>
Must be saved outside of the results/ directory since it gets wiped away on
each round.
"""
buildlog = os.path.join(path, "results", "build.log")
shutil.copyfile(buildlog, "{}/build.log.round{}".format(path, iteration))
def write_prep(workingdir):
"""
Write metadata to the local workingdir when --prep-only is used
@@ -184,12 +198,30 @@ def main():
parser.add_argument("-C", "--cleanup", dest="cleanup", action="store_true",
default=False,
help="Clean up mock chroot after building the package")
parser.add_argument("--infile", action="store", dest="infile", default="",
help="type of input file for .specfile creation")
args = parser.parse_args()
name, url, archives = read_old_metadata()
name = args.name or name
url = args.url or url
archives = args.archives or archives
infile_dict = {}
if args.infile:
infile_dict = infile_handler.infile_reader(args.infile, name)
if not url:
try:
url = infile_dict.get('URL')
except:
pass
else:
print_infile("Source url found: {}".format(url))
if infile_dict.get("LICENSE"):
license.add_license(infile_dict.get("LICENSE"))
print_infile("License added: {}".format(infile_dict.get("LICENSE")))
if not url:
parser.error(argparse.ArgumentTypeError(
@@ -201,13 +233,13 @@ def main():
"even number of arguments"))
if args.prep_only:
package(args, url, name, archives, "./workingdir")
package(args, url, name, archives, "./workingdir", infile_dict)
else:
with tempfile.TemporaryDirectory() as workingdir:
package(args, url, name, archives, workingdir)
package(args, url, name, archives, workingdir, infile_dict)
def package(args, url, name, archives, workingdir):
def package(args, url, name, archives, workingdir, infile_dict):
check_requirements(args.git)
build.setup_workingdir(workingdir)
@@ -257,6 +289,12 @@ def package(args, url, name, archives, workingdir):
filemanager.load_specfile(specfile)
load_specfile(specfile)
#
# If infile is passed, parse it and overwrite the specfile configurations
# with the newly found values.
#
if args.infile:
specfile = infile_update_spec.update_specfile(specfile, infile_dict, args.target)
print("\n")
if args.integrity:
@@ -270,9 +308,20 @@ def package(args, url, name, archives, workingdir):
filemanager.load_specfile(specfile)
specfile.write_spec(build.download_path)
filemanager.newfiles_printed = 0
mock_chroot = "/var/lib/mock/clear-{}/root/builddir/build/BUILDROOT/" \
"{}-{}-{}.x86_64".format(build.uniqueext,
tarball.name,
tarball.version,
tarball.release)
if filemanager.clean_directories(mock_chroot):
# directories added to the blacklist, need to re-run
build.must_restart += 1
if build.round > 20 or build.must_restart == 0:
break
save_build_log(build.download_path, build.round)
test.check_regression(build.download_path)
if build.success == 0:
@@ -298,10 +347,12 @@ def package(args, url, name, archives, workingdir):
# record logcheck output
logcheck(build.download_path)
commitmessage.guess_commit_message()
commitmessage.guess_commit_message(pkg_integrity.IMPORTED)
if args.git:
git.commit_to_git(build.download_path)
else:
print("To commit your changes, run 'git commit -F commitmsg'")
if __name__ == '__main__':
+4
View File
@@ -101,6 +101,10 @@ def failed_pattern(line, pattern, verbose, buildtool=None):
must_restart += buildreq.add_buildreq(config.maven_jars[s])
else:
must_restart += buildreq.add_buildreq('jdk-%s' % s)
elif buildtool == 'catkin':
must_restart += buildreq.add_pkgconfig_buildreq(s)
must_restart += buildreq.add_buildreq(s)
except:
if verbose > 0:
print("Unknown pattern match: ", s)
+43 -3
View File
@@ -33,6 +33,7 @@ import subprocess
banned_requires = set()
buildreqs = set()
requires = set()
extra_cmake = set()
verbose = False
cargo_bin = False
banned_buildreqs = set(["llvm-devel",
@@ -223,6 +224,7 @@ def parse_cargo_toml(filename):
"""
global cargo_bin
buildpattern.set_build_pattern("cargo", 1)
add_buildreq("cargo")
add_buildreq("rustc")
with open(filename, "r", encoding="latin-1") as ctoml:
cargo = toml.loads(ctoml.read())
@@ -230,8 +232,9 @@ def parse_cargo_toml(filename):
cargo_bin = True
if not cargo.get("dependencies"):
return
for bdep in cargo["dependencies"]:
add_buildreq(bdep)
for cdep in cargo["dependencies"]:
if add_buildreq(cdep):
add_requires(cdep)
def set_build_req():
@@ -470,6 +473,38 @@ def add_setup_py_requires(filename):
pass
def parse_catkin_deps(cmakelists_file):
f = open(cmakelists_file, "r", encoding="latin-1")
lines = f.readlines()
pat = re.compile(r"^find_package.*\(.*(catkin)(?: REQUIRED *)?(?:COMPONENTS (?P<comp>.*))?\)$")
catkin = False
for line in lines:
match = pat.search(line)
if not match:
continue
# include catkin's required components
comp = match.group("comp")
if comp:
for curr in comp.split(" "):
add_pkgconfig_buildreq(curr)
catkin = True
# catkin find_package() function will always rely on CMAKE_PREFIX_PATH
# make sure we keep it consistent with CMAKE_INSTALL_PREFIX otherwise
# it'll never be able to find its modules
if catkin:
for curr in ["catkin", "catkin_pkg", "empy", "googletest"]:
add_buildreq(curr)
extra_cmake.add("-DCMAKE_PREFIX_PATH=/usr")
extra_cmake.add("-DCATKIN_BUILD_BINARY_PACKAGE=ON")
extra_cmake.add("-DSETUPTOOLS_DEB_LAYOUT=OFF")
def scan_for_configure(dirn):
"""
Scan the package directory for build files to determine build pattern
@@ -486,6 +521,10 @@ def scan_for_configure(dirn):
add_buildreq("cmake")
buildpattern.set_build_pattern("cmake", default_score)
srcdir = os.path.abspath(os.path.join(dirn, "clr-build", config.cmake_srcdir or ".."))
if os.path.samefile(dirpath, srcdir):
parse_catkin_deps(os.path.join(srcdir, "CMakeLists.txt"))
if "configure" in files and os.access(dirpath + '/configure', os.X_OK):
buildpattern.set_build_pattern("configure", default_score)
@@ -519,7 +558,7 @@ def scan_for_configure(dirn):
buildpattern.set_build_pattern("meson", default_score)
for name in files:
if name.lower() == "cargo.toml":
if name.lower() == "cargo.toml" and dirpath == dirn:
parse_cargo_toml(os.path.join(dirpath, name))
if name.lower().startswith("configure."):
parse_configure_ac(os.path.join(dirpath, name))
@@ -560,3 +599,4 @@ def load_specfile(specfile):
specfile.buildreqs = buildreqs
specfile.requires = requires
specfile.cargo_bin = cargo_bin
specfile.extra_cmake += " " + " ".join(extra_cmake)
+5 -2
View File
@@ -218,7 +218,7 @@ def process_git(giturl, oldversion, newversion):
return shortlog
def guess_commit_message():
def guess_commit_message(keyinfo):
"""
guess_commit_message() parses newsfiles and determines a sane commit
message. The commit message defaults to the following for an updated
@@ -277,11 +277,14 @@ def guess_commit_message():
commitmessage.extend(sorted(list(cves)))
commitmessage.append("")
if keyinfo:
commitmessage.append("Key imported:\n{}".format(keyinfo))
util.write_out(os.path.join(build.download_path, "commitmsg"),
"\n".join(commitmessage) + "\n")
print("Guessed commit message:")
try:
print(commitmessage)
print("\n".join(commitmessage))
except:
print("Can't print")
+48 -10
View File
@@ -40,8 +40,11 @@ config_files = set()
parallel_build = " %{?_smp_mflags} "
urlban = ""
extra_make = ""
extra32_make = ""
extra_make_install = ""
extra_make32_install = ""
extra_cmake = ""
cmake_srcdir = ""
prep_append = []
subdir = ""
install_macro = "%make_install"
@@ -49,6 +52,7 @@ disable_static = "--disable-static"
make_install_append = []
patches = []
autoreconf = False
custom_desc = ""
license_fetch = None
license_show = None
@@ -107,7 +111,9 @@ config_options = {
"nostrip": "disable stripping binaries",
"verify_required": "require package verification for build",
"security_sensitive": "set flags for security-sensitive builds",
"so_to_lib": "add .so files to the lib package instead of dev"}
"so_to_lib": "add .so files to the lib package instead of dev",
"autoupdate": "this package is trusted enough to automatically update "
"(used by other tools)"}
# simple_pattern_pkgconfig patterns
# contains patterns for parsing build.log for missing dependencies
@@ -158,7 +164,9 @@ simple_pats = [
(r"Package systemd was not found in the pkg-config search path.", "systemd-dev"),
(r"Unable to find the requested Boost libraries.", "boost-dev"),
(r"libproc not found. Please configure without procps", "procps-ng-dev"),
(r"configure: error: glib2", "glib-dev")]
(r"configure: error: glib2", "glib-dev"),
(r"C library 'efivar' not found", "efivar-dev"),
(r"Has header \"efi.h\": NO", "gnu-efi-dev")]
# failed_pattern patterns
# contains patterns for parsing build.log for missing dependencies
@@ -265,7 +273,10 @@ failed_pats = [
(r"\[ERROR\] .* Cannot access central \(.*\) in offline mode and the artifact "
r".*:(.*):[jar|pom]+:.* has not been downloaded from it before.*", 0, 'maven'),
(r"\[WARNING\] The POM for .*:(.*):[jar|pom]+:.* is missing, no dependency information "
r"available", 0, 'maven')]
r"available", 0, 'maven'),
(r"^.*Could not find a package configuration file provided by \"(.*)\".*$", 0, 'catkin'),
(r"^.*By not providing \"Find(.*).cmake\" in CMAKE_MODULE_PATH this.*$", 0, 'catkin'),
(r"^.*\"(.*)\" with any of the following names.*$", 0, 'catkin')]
def get_metadata_conf():
@@ -274,8 +285,13 @@ def get_metadata_conf():
"""
metadata = {}
metadata['name'] = tarball.name
metadata['url'] = tarball.url
metadata['archives'] = ' '.join(tarball.archives)
if urlban:
metadata['url'] = re.sub(urlban, "localhost", tarball.url)
metadata['archives'] = re.sub(urlban, "localhost", " ".join(tarball.archives))
else:
metadata['url'] = tarball.url
metadata['archives'] = " ".join(tarball.archives)
metadata['giturl'] = tarball.giturl
return metadata
@@ -284,7 +300,7 @@ def create_conf(path):
"""
Create options.conf file. Use deprecated configuration files or defaults to populate
"""
config_f = configparser.ConfigParser(allow_no_value=True)
config_f = configparser.ConfigParser(interpolation=None, allow_no_value=True)
# first the metadata
config_f['package'] = get_metadata_conf()
@@ -323,7 +339,7 @@ def read_config_opts(path):
if not os.path.exists(opts_path):
create_conf(path)
config_f = configparser.ConfigParser()
config_f = configparser.ConfigParser(interpolation=None)
config_f.read(opts_path)
if "autospec" not in config_f.sections():
print("Missing autospec section in options.conf")
@@ -342,7 +358,7 @@ def rewrite_config_opts(path):
"""
Rewrite options.conf file when an option has changed (verify_required for example)
"""
config_f = configparser.ConfigParser(allow_no_value=True)
config_f = configparser.ConfigParser(interpolation=None, allow_no_value=True)
config_f['package'] = get_metadata_conf()
config_f['autospec'] = {}
@@ -471,8 +487,11 @@ def parse_config_files(path, bump, filemanager):
global profile_payload
global config_opts
global extra_make
global extra32_make
global extra_make_install
global extra_make32_install
global extra_cmake
global cmake_srcdir
global prep_append
global subdir
global install_macro
@@ -481,11 +500,10 @@ def parse_config_files(path, bump, filemanager):
global patches
global autoreconf
global yum_conf
global custom_desc
packages_file = None
read_config_opts(path)
# Require autospec.conf for additional features
if os.path.exists(config_file):
config = configparser.ConfigParser(interpolation=None)
@@ -507,6 +525,9 @@ def parse_config_files(path, bump, filemanager):
urlban = config['autospec'].get('urlban', None)
# Read values from options.conf (and deprecated files) and rewrite as necessary
read_config_opts(path)
if not git_uri:
print("Warning: Set [autospec][git] upstream template for git support")
if not license_fetch:
@@ -652,10 +673,18 @@ def parse_config_files(path, bump, filemanager):
if content and content[0]:
extra_make = content[0]
content = read_conf_file(os.path.join(path, "make32_args"))
if content and content[0]:
extra32_make = content[0]
content = read_conf_file(os.path.join(path, "make_install_args"))
if content and content[0]:
extra_make_install = content[0]
content = read_conf_file(os.path.join(path, "make32_install_args"))
if content and content[0]:
extra_make32_install = content[0]
content = read_conf_file(os.path.join(path, "install_macro"))
if content and content[0]:
install_macro = content[0]
@@ -664,6 +693,10 @@ def parse_config_files(path, bump, filemanager):
if content and content[0]:
extra_cmake = content[0]
content = read_conf_file(os.path.join(path, "cmake_srcdir"))
if content and content[0]:
cmake_srcdir = content[0]
content = read_conf_file(os.path.join(path, "subdir"))
if content and content[0]:
subdir = content[0]
@@ -705,6 +738,8 @@ def parse_config_files(path, bump, filemanager):
profile_payload = read_conf_file(os.path.join(path, "profile_payload"))
custom_desc = read_conf_file(os.path.join(path, "description"))
def load_specfile(specfile):
"""
@@ -714,8 +749,11 @@ def load_specfile(specfile):
specfile.keepstatic = config_opts['keepstatic']
specfile.no_autostart = config_opts['no_autostart']
specfile.extra_make = extra_make
specfile.extra32_make = extra32_make
specfile.extra_make_install = extra_make_install
specfile.extra_make32_install = extra_make32_install
specfile.extra_cmake = extra_cmake
specfile.cmake_srcdir = cmake_srcdir or specfile.cmake_srcdir
specfile.prep_append = prep_append
specfile.subdir = subdir
specfile.install_macro = install_macro
+50
View File
@@ -628,3 +628,53 @@ sem_init
whether we can link with -static
if building for some Win32 platform
more warnings
x86_64-generic-linux-gnu-makeindex
x86_64-generic-linux-gnu-pdflatex
x86_64-generic-linux-gnu-egrep
x86_64-generic-linux-gnu-dvips
x86_64-generic-linux-gnu-latex
x86_64-generic-linux-gnu-dot
x86_64-generic-linux-gnu-perl
x86_64-generic-linux-gnu-doxygen
latex
dvips
whether more special flags are required for pthreads
Configure miss: whether to build with gcov testing
if compiler needs -Werror to reject unknown flags
pow
struct stat.st_mtimensec
struct statvfs.f_basetype
struct statvfs.f_fstypename
sys/audioio.h presence
valgrind/valgrind.h presence
valgrind/valgrind.h usability
whether C compiler handles -Werror -Wunknown-warning-option
whether self tests are run under valgrind
arc4random_buf
sys/ucred.h
sys/utime.h
valgrind/valgrind.h
struct statfs.f_fstypename
whether __argv is declared
whether <limits.h> defines MIN and MAX
whether C compiler accepts -Werror=unknown-warning-option
whether gcc is Clang
whether more special flags are required for pthreads
whether the C locale is free of encoding errors
winsock2.h
getpeereid
getpeerucred
whether wint_t is too small
xlocale.h usability
whether the linker accepts -Wl,-fatal_warnings
whether to build with code coverage support
xlocale.h presence
getexecname
getprogname
whether stdint.h predates C++11
xlocale.h
i686-generic-linux-gnu-pkg-config
i686-generic-linux-gnu-objdump
i686-generic-linux-gnu-dlltool
i686-generic-linux-gnu-mt
i686-generic-linux-gnu-strip
+9 -31
View File
@@ -211,7 +211,7 @@ def parse_log(log, pkgname=''):
# apr
# testatomic : SUCCESS
if re.search(r"\: SUCCESS$", line) and incheck:
if re.search(r": SUCCESS$", line) and incheck:
counted_pass += 1
continue
@@ -283,7 +283,7 @@ def parse_log(log, pkgname=''):
total_fail += convert_int(match.group(1))
continue
match = re.search(r"/== ([0-9]+) failed, ([0-9]+) passed, ([0-9]+) xfailed in ", line)
match = re.search(r"== ([0-9]+) failed, ([0-9]+) passed, ([0-9]+) xfailed in ", line)
if match and incheck:
total_pass += convert_int(match.group(2))
total_fail += convert_int(match.group(1))
@@ -967,13 +967,6 @@ def parse_log(log, pkgname=''):
counted_pass += 1
continue
# apr-util
# : SUCCESS
match = re.search(r": SUCCESS$", line)
if match and incheck:
counted_pass += 1
continue
# bash
# < Failed 126 of 1378 Unicode tests
match = re.search(r"^[<,>] Failed ([0-9]+) of ([0-9]+)", line)
@@ -1015,18 +1008,6 @@ def parse_log(log, pkgname=''):
counted_pass += 1
continue
# *** zlib test OK ***
# *** zlib 64-bit test OK ***
match = re.search(r"\*\*\* zlib .*test OK \*\*\*", line)
if match and incheck:
counted_pass += 1
continue
match = re.search(r"\*\*\* zlib .*test [A-Z!O][A-Z!K] \*\*\*", line)
if match and incheck:
counted_fail += 1
continue
# LVM2
# valgrind pool awareness ... fail
# dfa matching ... fail
@@ -1104,6 +1085,13 @@ def parse_log(log, pkgname=''):
total_fail += convert_int(match.group(3))
continue
# vim
# Executed 9 tests
match = re.search(r"Executed ([0-9]+) tests$", line)
if match and incheck:
total_tests += convert_int(match.group(1))
continue
# rubygem-formatador
# 9 succeeded in 0.00375661 seconds
match = re.search(r"([0-9]+) succeeded in [0-9]+\.[0-9]+ seconds", line)
@@ -1288,16 +1276,6 @@ def parse_log(log, pkgname=''):
total_skip += 1
continue
match = re.search(r"^Testing .+\ +\*FAILED\*$", line)
if match and incheck:
total_fail += 1
continue
match = re.search(r"^Verifying .+\ +\*FAILED\*$", line)
if match and incheck:
total_fail += 1
continue
# libconfig
# 3 tests; 3 passed, 0 failed
match = re.search(r"^([0-9]+) tests; ([0-9]+) passed\, ([0-9]+) failed", line)
+7
View File
@@ -505,3 +505,10 @@ libxml/xmlversion.h, libxml2-dev
g-ir-scanner, gobject-introspection
get_mempolicy, numactl-dev
pcap_dump, libpcap-dev
ldap.h, openldap-dev
cargo, cargo
libaio.h, libaio-dev
boost/bind.hpp, boost-dev
sox.h, sox-dev
asciidoc, asciidoc
gpgconf, gnupg
+42
View File
@@ -23,6 +23,8 @@ import build
import tarball
import config
import re
import os
import util
from collections import OrderedDict
# todo package splits
@@ -101,6 +103,46 @@ class FileManager(object):
else:
return False
def _clean_dirs(self, root, files):
"""
Do the work to remove the directories from the files list
"""
res = set()
removed = False
directive_re = re.compile("(%\w+(\([^\)]*\))?\s+)(.*)")
for f in files:
# skip the files with directives at the beginning, including %doc
# and %dir directives.
# autospec does not currently support adding empty directories to
# the file list by prefixing "%dir". Regardless, skip these entries
# because if they exist at this point it is intentional (i.e.
# support was added).
if directive_re.match(f):
res.add(f)
continue
if os.path.isdir(os.path.join(root, f.lstrip("/"))):
util.print_warning("Removing directory {} from file list".format(f))
self.files_blacklist.add(f)
removed = True
else:
res.add(f)
return (res, removed)
def clean_directories(self, root):
"""
Remove directories from file list
"""
removed = False
for pkg in self.packages:
self.packages[pkg], _rem = self._clean_dirs(root, self.packages[pkg])
if _rem:
removed = True
return removed
def push_file(self, filename):
"""
Perform a number of checks against the filename and push the filename
+2
View File
@@ -56,6 +56,7 @@ def commit_to_git(path):
call("bash -c 'shopt -s failglob; git add -f *.sig'", check=False, stderr=subprocess.DEVNULL, cwd=path)
call("bash -c 'shopt -s failglob; git add -f *.sha256'", check=False, stderr=subprocess.DEVNULL, cwd=path)
call("bash -c 'shopt -s failglob; git add -f *.sign'", check=False, stderr=subprocess.DEVNULL, cwd=path)
call("bash -c 'shopt -s failglob; git add -f *.pkey'", check=False, stderr=subprocess.DEVNULL, cwd=path)
call("git add configure", check=False, stderr=subprocess.DEVNULL, cwd=path)
call("git add configure32", check=False, stderr=subprocess.DEVNULL, cwd=path)
call("git add configure64", check=False, stderr=subprocess.DEVNULL, cwd=path)
@@ -74,6 +75,7 @@ def commit_to_git(path):
call("git add options.conf", check=False, stderr=subprocess.DEVNULL, cwd=path)
call("git add configure_misses", check=False, stderr=subprocess.DEVNULL, cwd=path)
call("git add whatrequires", check=False, stderr=subprocess.DEVNULL, cwd=path)
call("git add description", check=False, stderr=subprocess.DEVNULL, cwd=path)
# remove deprecated config files
call("git rm use_clang", check=False, stderr=subprocess.DEVNULL, cwd=path)
+266
View File
@@ -0,0 +1,266 @@
#!/usr/bin/true
#
# infile_parser.py - part of autospec
# Copyright (C) 2017 Intel Corporation
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import re
# TODO: VAR_append = "" _append same functionality as +=
operators_dict = {
"=": "{1}",
"=.": "{1}{0}",
".=": "{0}{1}",
":=": "{1}",
"=+": "{1} {0}",
"+=": "{0} {1}",
"??=": "{1}",
"?=": "{1}"
}
def scrape_version(bb_dict):
"""
Get the package version from the bb filename.
Return None if filename doesn't exist, or there is no version
within the filename. Otherwise, return the version.
"""
try:
return bb_dict.get('filename')[-1].split('_', 1,)[1].rsplit('.', 1)[0]
except:
return None
def replace_bb_variable_names(bb_dict):
"""
Replace bitbake variable name with values.
Bitbake files use various variable names defined by a string
surrounded by ${}.
Variables able for replacement:
- ${PV} with version
- ${ROS_SPN} with name, or actual value if defined in .bb
"""
def replace_var(bb_dict, val):
if bb_dict.get("VERSION"):
val = val.replace("${PV}", bb_dict.get('VERSION'))
if "ROS_SPN" in bb_dict:
val = val.replace("${ROS_SPN}", bb_dict.get("ROS_SPN"))
elif "NAME" in bb_dict:
val = val.replace("${ROS_SPN}", bb_dict.get('NAME'))
return val
for k, v in bb_dict.items():
if isinstance(v, list):
for i, j in enumerate(v):
v[i] = replace_var(bb_dict, j)
elif isinstance(v, str):
v = replace_var(bb_dict, v)
bb_dict[k] = v
def get_src_url(bb_dict):
"""
return the tarball url of the package source from the bb file
"""
if bb_dict.get('SRC_URI'):
bb_dict["URL"] = bb_dict.get("SRC_URI").split('\\')[0].split(';')[0]
def clean_values(value):
"""
Remove quotations and line continuations from values
"""
# remove beginning and end quote
value = value.strip('"')
# remove line continuations
value = value.replace("\\", "")
return value
def read_in_command(line, depth):
"""
Determines if a line is a part of a command.
If it returns a depth of 0, then the command has been read completely
from the file.
"""
for c in line:
if c == '{':
depth += 1
if c == '}' and depth > 0:
depth -= 1
if c != "\n":
continue
return depth
def pattern_match_regex():
"""
Compile the regular expression to determine the operation being used by
the line to perform the correct task on the variable.
Returns the match object from searching a string
for the correct pattern as: [key, operator, value].
"""
# escape operators for regex handling
operators = ["\\??\\=", "\\?\\=", "\\:\\=",
"\\+\\=", "\\=\\+", "\\.\\=",
"\\=\\.", "\\="]
# Split line to be [Key, operator, value] if in operators list
oper_pattern = r"(^[A-Z]+[_\-${}\[\]A-Za-z0-9]*)\s(" + '|'.join(
operators) + r")\s(\".*\")"
return re.compile(oper_pattern)
def evaluate_expr(op, cur_val, assignment):
"""
Using the operators_dict. get the correct value from the expression. This
function returns the syntactically correct value for the bb_dict key. For
example, if the op is "=", and the assignment is "value", the return will
be "value". However, if the op is "+=" and the cur_value is "first", and
the assignment is "second" this function will return the appending of
second to first: "first second".
:param op: The operation (The key from the operators_dict)
:param cur_val: The current value of the key within in the bb_dict
:param assignment: The new value from the line that will be assigned to the
bb_dict key.
"""
if not cur_val:
return assignment
return operators_dict.get(op).format(cur_val, assignment)
def write_to_dict(bb_dict, m):
"""
Store the correct information to the bb_dict that is correctly parsed from
the bitbake file. This function uses the "evaluate_expr" function heavily
to ensure that the values are correctly parsed.
"""
if len(m.groups()) == 3:
key = m.group(1)
value = clean_values(m.group(3))
op = m.group(2)
#
# ??= is the weakest variable assignment, so if that variable already
# has an assignment, do not overwrite it. = has the highest precedence
# and ?= is between the two.
#
if key in bb_dict and op == "??=":
return bb_dict
elif key in bb_dict and op == "?=":
if not isinstance(bb_dict[key], list):
return bb_dict
if key in bb_dict and isinstance(bb_dict[key], list):
v = bb_dict[key]
del [v[1]]
bb_dict[key] = "".join(v)
try:
bb_dict[key] = evaluate_expr(op, bb_dict.get(key), value)
if op == "??=":
bb_dict[key] = [bb_dict[key], 1]
except AttributeError as error:
print("Missing operation functionality: {}".format(error))
return bb_dict
def bb_scraper(bb_fp, bb_dict):
"""
Scrapes data from a filepointer (to a bitbake or .inc file) and stores
the values in a dictionary.
"""
bb_dict["VERSION"] = scrape_version(bb_dict)
bb_dict["inherits"] = []
# compile the regex once, prior to the line parsing for faster searching
line_regex = pattern_match_regex()
for line in bb_fp:
line = line.strip()
if not line or line.startswith('#'):
continue
# If line is a command, create array of command lines
# TODO: command could be python code
if line.startswith('do_'):
cmd_name = line.split('()')[0].strip()
cmd = []
depth = 0
while 1:
depth = read_in_command(line, depth)
if line:
cmd.append("# " + line)
if depth == 0:
break
else:
line = next(bb_fp).strip()
# Remove the 'do_command {' and '}' from the list, so that
# the dict value is a list of the commands.
if cmd[0].startswith("# " + cmd_name) and cmd[-1] == '# }':
cmd = cmd[1:-1]
# Some bitbake files have tasks with prepend or append operations.
# Perform the logic to store all tasks with the same 'core' command
# name in the dictionary.
if not bb_dict.get(cmd_name):
bb_dict[cmd_name] = cmd
elif cmd_name.rsplit('_') == 'prepend':
cmd.extend(bb_dict.get(cmd_name))
bb_dict[cmd_name] = cmd
else:
bb_dict.get(cmd_name).extend(cmd)
continue
# If a line continuation, create a string that can easily be split
# by '\' for src_uri and other variables.
elif line[-1] == '\\':
lines = []
while 1:
lines.append(line)
line = next(bb_fp).strip()
if line[-1] != '\\':
lines.append(line)
break
line = " ".join(lines)
if line.startswith('inherit'):
bb_dict['inherits'].append(line.split(maxsplit=1)[1])
continue
match = line_regex.search(line)
if match:
bb_dict = write_to_dict(bb_dict, match)
get_src_url(bb_dict)
replace_bb_variable_names(bb_dict)
return bb_dict
+149
View File
@@ -0,0 +1,149 @@
#!/usr/bin/true
#
# infile_parser.py - part of autospec
# Copyright (C) 2017 Intel Corporation
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import os
import re
import requests
import tempfile
from urllib.request import urlretrieve
import util
import infile_bb_parser
# filetypes and their parse order (lower parsed first)
parsable_filetypes = {'.inc': 1, '.bb': 2}
def parse_ext(path):
"""
Gets the extension of a file and determines if the filetype can be handled
by the infile_parser. If so, it returns the extension. If not, it returns
nothing, which will cause the file_handler to return and infile parsing
will NOT be used on that file.
"""
ext = os.path.splitext(path)[1]
if ext not in parsable_filetypes:
util.print_warning("Cannot parse infile \"{}\" type. From input: {}."
" \nContinuing with the execution of "
"autospec".format(ext, path))
return None
return ext.lstrip('.')
def check_url_content(url):
"""
Check that the url to the infile file is raw or in plaintext.
This function checks the header content-type for a request to the infile
url. If it is html it converts eith a github url to point to the raw file,
a git url to point to the plaintext file, or returns None with a statement
that the file must be in plaintext or raw.
"""
if "text/html" in requests.head(url).headers['content-type']:
if re.match(r'^(http)s?://github.com(.*)', url):
url = url.replace("github", "raw.githubusercontent").replace("blob/", "")
elif 'git' in url and "/tree/" in url:
url = url.replace("/tree/", "/plain/", 1)
else:
util.print_fatal("infile url has an html content-type, "
"please use plaintext.")
return None
return url
def sort_files(x):
"""
Sorts files depending on their priority in the parsable_filetypes dict.
"""
return parsable_filetypes.get(os.path.splitext(x)[1])
def parse_infile(bb_fp, output_dict, parse_type):
"""
Depending on the type of file, scrape and parse the infile file returning
the dictionary of collected data.
"""
if parse_type == "bb":
return infile_bb_parser.bb_scraper(bb_fp, output_dict)
elif parse_type == "inc":
return infile_bb_parser.bb_scraper(bb_fp, output_dict)
def file_handler(indata, output_dict):
"""
This function determines whether the input is a file or a url. If it is a
url it checks that it is in the correct format (plaintext), downloads the
url to a temporary file and passes the file handler to be scraped.
If the input is a file, then it opens the file and passes the handler to
be scraped.
The type of parsing bitbake, inc, deb, etc is based on the file extension.
"""
# If ext is not parsable, return from using infile parser on that file.
parse_type = parse_ext(indata)
if not parse_type:
return
if output_dict.get('filename'):
output_dict['filename'].append(indata)
else:
output_dict['filename'] = [indata]
if not os.path.isfile(indata):
# check that input is plain or raw text and not html
indata = check_url_content(indata)
with tempfile.NamedTemporaryFile() as tmpfile:
try:
tmp, _ = urlretrieve(indata, tmpfile.name)
with open(tmp, 'r') as bb_fp:
output_dict = parse_infile(bb_fp, output_dict, parse_type)
except Exception as e:
util.print_warning("Infile was unable to be parsed with the "
"error: \"{}\". \nContinuing with the "
"execution of autospec.".format(e))
else:
with open(indata, 'r') as bb_fp:
output_dict = parse_infile(bb_fp, output_dict, parse_type)
return output_dict
def infile_reader(indata, name):
"""
The infile parser can take 3 different inputs:
A url to a file
A directory with multiple files or urls
A path or filename
Each file in the directory should scraped to the same dictionary instance.
"""
output_dict = {"NAME": name}
if os.path.isdir(indata):
files = [f for f in os.listdir(indata) if os.path.isfile(
os.path.join(indata, f)) and not f.startswith('.')]
for f in sorted(files, key=sort_files):
output_dict = file_handler(os.path.join(indata, f), output_dict)
else:
output_dict = file_handler(indata, output_dict)
return output_dict
+101
View File
@@ -0,0 +1,101 @@
#!/usr/bin/true
#
# infile_parser.py - part of autospec
# Copyright (C) 2017 Intel Corporation
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import re
import os
from util import print_infile
cmd_mappings = {
"do_configure": "configure",
"do_configure_prepend": "configure",
"do_configure_append": "configure",
"EXTRA_OECONF": "configure",
"do_install": "make_install_append",
"do_install_append": "make_install_append",
"do_install_prepend": "make_install_append"
}
def update_summary(bb_dict, specfile):
"""
Updates the default summary to the summary or description scraped from
the bitbake file. The bitbake "SUMMARY" variable is first priority,
then the "DESCRIPTION" variable. If neither exist, set set it back to the
specfile value.
"""
specfile.default_sum = bb_dict.get("SUMMARY") or \
bb_dict.get("DESCRIPTION") or specfile.default_sum
if specfile.default_sum == bb_dict.get("SUMMARY") or \
specfile.default_sum == bb_dict.get("DESCRIPTION"):
print_infile("Summary updated: {}".format(specfile.default_sum))
def update_licenses(bb_dict, specfile):
"""
The specfile contains a list of licenses for a package, if the bitbake
license is not included in that list, add it.
"""
if "LICENSE" in bb_dict:
if bb_dict.get("LICENSE").lower() not in [l.lower() for l in specfile.licenses]:
specfile.licenses.append(bb_dict.get("LICENSE"))
print_infile("License added: {}".format(bb_dict.get("LICENSE")))
def update_build_deps(bb_dict, specfile):
"""
Add build dependencies to the buildreq set, if the bb_dict scraped build
time dependencies.
"""
if bb_dict.get('DEPENDS'):
for dep in bb_dict.get('DEPENDS').split():
dep = re.match(r"(\$\{PYTHON_PN\}\-)?([a-zA-Z0-9\-]+)", dep).group(2)
if dep.endswith('-native'):
dep = dep[:-7]
specfile.buildreqs.add(dep)
print_infile("Build dependency added: {}".format(dep))
def write_cmd_files(bb_dict, dirname):
"""
Append "do_" task commands that are scraped from the bitbake file(s). Some
of these commands have append/prepend. These operations are performed
prior to being added to the dict. This function appends all commands to
as comments to their mapped file within the target directory.
"""
for cmd_name, cmd in bb_dict.items():
if cmd_name.startswith("do_"):
filename = os.path.join(dirname, cmd_mappings.get(cmd_name))
with open(filename, 'a') as cmdfp:
cmdfp.write("# Infile parser added the following lines:\n")
cmdfp.write("\n".join(cmd) + "\n")
print_infile("Suggestions added to the {} file".format(
cmd_mappings.get(cmd_name)))
def update_specfile(specfile, bb_dict, dirname):
update_summary(bb_dict, specfile)
update_licenses(bb_dict, specfile)
update_build_deps(bb_dict, specfile)
write_cmd_files(bb_dict, dirname)
return specfile
+122
View File
@@ -0,0 +1,122 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
=si8t
-----END PGP PUBLIC KEY BLOCK-----
+58
View File
@@ -0,0 +1,58 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
NjgXDBwVxd03KA==
=mpsA
-----END PGP PUBLIC KEY BLOCK-----
+30
View File
@@ -0,0 +1,30 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFoEpHwBCACtBZaIiL+t7OdYJPMBjgOpfEA275KujTwJwriC3HI7h+mdgR+i
zDf95SeJjvMDj0E14yj+wEDEwdsCxwf37l7Giu4ni5ZMrubj9zJ+/vMBo7aD7oZz
dfbFGn1dj6opOFi4HbyraXtDN+5pfLgYP+yXu4opcV73lIeIG8KiGmEspei6XF6Q
NByH53SKD72EqQCA4OgZjOu26TE2qS10owyqsWxY02z/onIM8g+ejJ8feCqbQlVy
k8X1lk8bzg8IaWKlhn0PTlLUakcQo6YGMloYatq3abTDMhSwtQgy6iX7kvZtcH6e
wD1HpwsTNNsmn3U+mHNpXkIJ/dz41vvDId2zABEBAAG0LVdpbGxpYW0gRG91Z2xh
cyA8d2lsbGlhbS5yLmRvdWdsYXNAZ21haWwuY29tPokBPwQTAQgAKRYhBIk6+9Bc
CBSgLFcnSWRrTDdJ0gjyBQJaBKR8AhsDBQkDwmcAAheAAAoJEGRrTDdJ0gjyV4kI
AJ2qInQXQYcJ+nWkRWDwHf0RYaIGOWqrHC2WK948M3Whldgzpa4e+ubsjKmsBPQ7
2PduJ+BjUjlBwrdgLsTJO3I1w9cMKUZcgKkm6FY/goKdqpjG9i/LeBpCLNnwlNgb
Eql1m6urpMRwcHP2ndWEWdUz5CTRB3Cnvj6yVXJPxxa8GDzES6UDzufzFPkFmEbV
fs9PzYLELBkXqFJLdXJaYI8f46tkuFdQ0+Z4/a2VljVSSWgNzMU2I/N6cThxR9Qs
KfNAnasGqi2o3CJzBRFKEa7tNsOMlP+ffuZJ5+IuhMEsF1CVl6Owa8LkR2B+dg5m
dwVUdvZxchj5Sb8x1KtJ6cy5AQ0EWgSkfAEIAPB8ZilP3/DgoQL0EA+bfgUXqdkv
LHnAPv4TILVw6BmBBgfyV/BTEXygRQL1DurTQv32O3hs2cdXZ+6VYBoW+fFm61ZC
dRT7mMpVdMki00hDJfVVIfYOKqmGW+BVH+S5200dI+WVqt1D0tDHPO+9iz662F1v
8UVK0i2nn/N066nKxA6fOhOF8d4FTel7ksllDKM418ZZUuxuIk9H9Pi6Y4NhfTLP
KQdcqG75zyfqPNmOmFlSk7U7NQaR/eQHpCVHORKBQN3brrG/EPp5yp8B04weRbmE
wKX53N50b823oD1EYdxt9b3YGaJzEdcf6c2j0Vm385eN/sTbaRbfNK75kJEAEQEA
AYkBPAQYAQgAJhYhBIk6+9BcCBSgLFcnSWRrTDdJ0gjyBQJaBKR8AhsMBQkDwmcA
AAoJEGRrTDdJ0gjywIQH/2kdIO3ncszs6Pn3RJJ69xuP8ApUJEhHZL7KDRnnNP9I
rXfMS99o77cRfpEWLt3Bv18UFED4wRKfz2wfaSZq8idyBfgg7BnHjSmsdBxT5YsR
FYVMGYQN+Y19h6xu30Da4n5OCyouatnuuY1MDa4VfYQQy4WXVal/EMeWhIcjTl8Z
7H/bl3FSEMpUAF0aHvHjLNm58aay3C92YutPTWL21OB9ugwacphfl3BJ03Z2yF6x
thlMwZCr1Cub8bfomTNsoqLHS2Ou6NLplqeCnT7wt07mGTNR847J4caATwmLfAVq
8fQ93zpI0a66aR1Kx3zNF5gftkM+TcnWzQ4yg2QYTuI=
=aQ8U
-----END PGP PUBLIC KEY BLOCK-----
+84
View File
@@ -0,0 +1,84 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
S17sbZHmc5T5UpnEcKg=
=o7cj
-----END PGP PUBLIC KEY BLOCK-----
+38
View File
@@ -0,0 +1,38 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
xi8zPaYysXKMXAg4WyKoAKeZgQPQV9TNYg==
=Os1/
-----END PGP PUBLIC KEY BLOCK-----
+30
View File
@@ -0,0 +1,30 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFnWnPwBCADaOcYK2oersBkoe0MxahLagZk7tZzMUHeFjHDz42uaiUINJAsq
dFdt1KlRPvGLyuUY7s6oY7YQ1Sxyijihfqett4dkQKkWcToHM9BJuq2Gte0ewzj9
imhyZm96dItytsh7tp1jk3FbMPNqlbKOHe9Sk9S+iQPdStfYIApdYwBUBNq+tQj1
+n3yWtAAKtvv+/AjlzKSWVr4ei5RxJwgFXVYtMyM18VblEbvB4ZEZZ0pjQhGgZXJ
msVtk+B9YpXkU5GJrVb0s9T1dx0f0OD3/HtWjjKHvrhOIKTmLVsjWsiraKrUWmcC
7ojclDLnqxetfETd0XEs+HUQ2wuSRI7y+iyRABEBAAG0K01hdHRoZXcgSm9obnNv
biA8bWF0dGhldy5qb2huc29uQGludGVsLmNvbT6JAT8EEwEIACkWIQQSLdi6pNRS
OcgqXITU0PX06UgvvgUCWdac/AIbAwUJA8JnAAIXgAAKCRDU0PX06UgvvrK+B/9h
4/1X1yku5Rhboj6xiJaWjqwlTBdp2gN09QygY9BNYSINUzUl0qKSxPJizhs5HNmT
B6Fn5pkcre9tG/uRQ5hsgYfAZJw/ckrtC/lfZc8PbrPFjd5d6fFp3RceyB97sgR0
CIhKWkhNgwpCkM72DPJxSe2RmED1sK3tVGDaZuuL9cz8JpEr5QpXDivq9ZSQn0hf
arDciM/83xuZzLLrXF0SPQgVx0W9ofo+piR8t0a5IvX0NC4eH0LqqNSsmSgypHMY
xqGjK+4pa3AuiDkhZ8/CX9dNX0lXAJinnOZNPLq92dMo1wzktiJ5C3UZN30E7hV2
ny8SQG2C6tlWwkf0bon3uQENBFnWnPwBCADbee/g7x7hxkYE0CWVHI77bkHkIotp
Snxe/O7Wszc5hU5LjI72FD4wLAodmKGl1tvY/G7YiLQPzE71/u7x8RbemIpMbKsv
ZpNYGp/SE3gpG0rbVI4RnTE25a5nXzV4NxxBwqX5J0bMrwjAgvRLpencUupWTVFB
G1N9fbU8WGbdpNMJqG529v3Y8lE7fbMD68C9ILVG0C32M2Eo3ZJ1W3oiyQe7ROAD
ZJ6A4yj4WFtVpoYdDVguotz+3LQk17hmpcJe6QH4nELsQq9Yqsc3/WIhTf+gmgJ/
PiwD9UiQk5AngJX9UvLWwTFrbXJL3wwcOUKOoBVu2W677otacfy/fXbxABEBAAGJ
ATwEGAEIACYWIQQSLdi6pNRSOcgqXITU0PX06UgvvgUCWdac/AIbDAUJA8JnAAAK
CRDU0PX06UgvvmvHB/wLgqkm1EOGsYRWg1hHDFmKMP4Q59NPhnZWI7oxgWxXmkxK
xYjwHL6JHiSbYRzBobselKOatnOdcCYdqv7ezgmo7f5zVnU66r8DcOZgAzBu3SPm
Mhc2cx3GQThMToJT2fB2P8Dy2LO1LUHLtMCO2tv32433L3pp7N/h3HUcWlSMSjCe
kYPCDo/ImyJJ9eu4kw8Cv3QptBlLRo9yKOnwzXqlpV3cnm4R0+3tviRsuKE8R/sv
925xkdvX4UAtN0ijdTfeOn46Wn9eFfoT/LJ5V+zf9DGn0fxRxCkGaj26dnkbW5Cy
nI+IjoGoK+JTOE2LwxqP97UFPekDC9+Y+f7DVuqM
=VB1i
-----END PGP PUBLIC KEY BLOCK-----
+3 -2
View File
@@ -72,11 +72,12 @@ def license_from_copying_hash(copying):
c.setopt(c.URL, config.license_fetch)
c.setopt(c.WRITEDATA, buffer)
c.setopt(c.POSTFIELDS, data)
c.setopt(c.FOLLOWLOCATION, 1)
try:
c.perform()
except Exception as excep:
print_fatal("Failed to fetch license from " + config.license_fetch,
excep)
print_fatal("Failed to fetch license from {}: {}"
.format(config.license_fetch, excep))
c.close()
sys.exit(1)
+46 -25
View File
@@ -45,9 +45,9 @@ RUBYORG_API = "https://rubygems.org/api/v1/versions/{}.json"
PYPIORG_API = "https://pypi.python.org/pypi/{}/json"
KEYID_TRY = ""
KEYID = ""
IMPORTED = ""
EMAIL = ""
GNUPGCONF = """keyserver keys.gnupg.net"""
PUBKEY_PATH = '/'.join([os.path.dirname(os.path.abspath(__file__)), "keyring", "{}.pkey"])
CMD_TIMEOUT = 20
ENV = os.environ
INPUT_GETTER_TIMEOUT = 60
@@ -130,10 +130,20 @@ class GPGCli(object):
def display_keyinfo(self, keyfile):
args = self.args + ['--list-packet', keyfile]
output, err, code = self.exec_cmd(args)
if code == 0:
return None, output.decode('utf-8')
return GPGCliStatus(err.decode('utf-8')), None
lp, err, code = self.exec_cmd(args)
if code != 0:
return GPGCliStatus(err.decode('utf-8')), None
# trim list-packet output to 10 lines
lp = "--list-packet:\n" + "\n".join(lp.decode("utf-8").split("\n")[:10])
args = self.args + ['--fingerprint', os.path.basename(keyfile.replace(".pkey", ""))]
fp, err, code = self.exec_cmd(args)
if code != 0:
return GPGCliStatus(err.decode('utf-8')), None
fp = "--fingerprint:\n" + fp.decode("utf-8")
return None, "{}\n\n{}".format(lp, fp)
@contextmanager
@@ -205,7 +215,6 @@ def head_request(url):
curl.setopt(curl.URL, url)
curl.setopt(curl.CUSTOMREQUEST, "HEAD")
curl.setopt(curl.NOBODY, True)
curl.setopt(curl.FOLLOWLOCATION, True)
curl.setopt(curl.TIMEOUT, 5)
curl.perform()
http_code = curl.getinfo(pycurl.HTTP_CODE)
@@ -431,11 +440,12 @@ class GPGVerifier(Verifier):
# <package directory>/<key url basename>
self.package_sign_path = os.path.join(os.path.dirname(self.package_path),
os.path.basename(self.key_url))
def get_pubkey_path(self):
keyid = get_keyid(self.package_sign_path)
if keyid:
return PUBKEY_PATH.format(keyid)
# default pubkey path is the package directory - this is where imports
# will go
self.pubkey_path = os.path.join(os.path.dirname(self.package_path), "{}.pkey")
# fallback to autospec repo for global keyring
self.fallback_pubkey_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
"keyring", "{}.pkey")
def get_sign(self):
code = self.download_file(self.key_url, self.package_sign_path)
@@ -459,17 +469,27 @@ class GPGVerifier(Verifier):
self.print_result(False, err_msg='{} is not a GPG signature'.format(self.package_sign_path))
os.unlink(self.package_sign_path)
return None
pub_key = self.get_pubkey_path()
EMAIL = parse_key(pub_key, r':user ID packet: ".* <(.+?)>"\n')
if not pub_key or os.path.exists(pub_key) is False:
key_id = get_keyid(self.package_sign_path)
self.print_result(False, 'Public key {} not found in keyring'.format(key_id))
if self.interactive is True and recursion is False and attempt_key_import(key_id):
print(SEPT)
return self.verify(recursion=True)
return None
sign_status = verify_cli(pub_key, self.package_path, self.package_sign_path)
if sign_status is None:
# valid signature exists at package_sign_path, operate on it now
keyid = get_keyid(self.package_sign_path)
# default location first
pubkey_loc = self.pubkey_path.format(keyid)
if not os.path.exists(pubkey_loc):
print_info("public key not in default keyring, checking fallback keyring")
# no pubkey at default location, fallback to global
pubkey_loc = self.fallback_pubkey_path.format(keyid)
if not os.path.exists(pubkey_loc):
# still nothing, attempt interactive if set to do so
self.print_result(False, 'Public key {} not found in keyring'.format(keyid))
if not self.interactive or recursion:
return None
if attempt_key_import(keyid, self.pubkey_path.format(keyid)):
print(SEPT)
return self.verify(recursion=True)
return None
# public key exists or is imported, verify
EMAIL = parse_key(pubkey_loc, r':user ID packet: ".* <(.+?)>"\n')
sign_status = verify_cli(pubkey_loc, self.package_path, self.package_sign_path)
if not sign_status:
if config.old_keyid:
compare_keys(KEYID_TRY, config.old_keyid)
self.print_result(self.package_path)
@@ -586,7 +606,8 @@ class InputGetter(object):
return inpt
def attempt_key_import(keyid):
def attempt_key_import(keyid, key_fullpath):
global IMPORTED
print(SEPT)
ig = InputGetter('\nDo you want to attempt to import keyid {}: (y/N) '.format(keyid))
import_key_answer = ig.get_answer()
@@ -600,7 +621,6 @@ def attempt_key_import(keyid):
err, key_content = ctx.export_key(keyid)
if err is not None:
print_error(err.strerror)
key_fullpath = PUBKEY_PATH.format(keyid)
util.write_out(key_fullpath, key_content)
print('\n')
print_success('Public key id: {} was imported'.format(keyid))
@@ -609,9 +629,10 @@ def attempt_key_import(keyid):
print_error('Unable to parse {}, will be removed'.format(key_fullpath))
os.unlink(key_fullpath)
return False
print('\n', '\n'.join(content.split('\n')[:10]))
print("\n", content)
ig = InputGetter(message='\nDo you want to keep this key: (Y/n) ', default='y')
if ig.get_answer() is True:
IMPORTED = content
return True
else:
os.unlink(key_fullpath)
+4 -1
View File
@@ -295,4 +295,7 @@ def load_specfile(specfile):
Load specfile with parse results
"""
specfile.default_sum = default_summary
specfile.default_desc = default_description
if config.custom_desc:
specfile.default_desc = "\n".join(config.custom_desc)
else:
specfile.default_desc = default_description
+25 -15
View File
@@ -57,7 +57,9 @@ class Specfile(object):
self.default_pattern = ""
self.autoreconf = False
self.extra_make = ""
self.extra32_make = ""
self.extra_make_install = ""
self.extra_make32_install = ""
self.tarball_prefix = ""
self.gcov_file = ""
self.rawname = ""
@@ -70,6 +72,7 @@ class Specfile(object):
self.install_macro = "%make_install"
self.disable_static = "--disable-static"
self.extra_cmake = ""
self.cmake_srcdir = ".."
self.make_install_append = []
self.excludes = []
self.keyid = ""
@@ -157,6 +160,8 @@ class Specfile(object):
self.sources["tmpfile"] +
self.sources["gcov"])):
self.source_index[source] = count + 1
if self.urlban:
source = re.sub(self.urlban, "localhost", source)
self._write("Source{0} : {1}\n".format(count + 1, source))
# if package is verified, include the signature in the source tarball
@@ -356,13 +361,16 @@ class Specfile(object):
self._write_strip("export https_proxy=http://127.0.0.1:9/")
self._write_strip("export no_proxy=localhost,127.0.0.1,0.0.0.0")
def write_make_line(self):
def write_make_line(self, build32=False):
"""
Write make line to spec file
make V=1 <config.parallel_build> <extra_make>
make <config.parallel_build> <extra_make>
"""
self._write_strip("make V=1 {}{}".format(config.parallel_build, self.extra_make))
if build32:
self._write_strip("make {}{}{}".format(config.parallel_build, self.extra_make, self.extra32_make))
else:
self._write_strip("make {}{}".format(config.parallel_build, self.extra_make))
def write_prep(self, ruby_pattern=False):
"""Write prep section to spec file"""
@@ -502,7 +510,8 @@ class Specfile(object):
if config.config_opts['32bit']:
self._write_strip("pushd ../build32/" + self.subdir)
self._write_strip("%make_install32 " + self.extra_make_install)
self._write_strip("%make_install32 {} {}".format(self.extra_make_install,
self.extra_make32_install))
self._write_strip("if [ -d %{buildroot}/usr/lib32/pkgconfig ]")
self._write_strip("then")
self._write_strip(" pushd %{buildroot}/usr/lib32/pkgconfig")
@@ -554,7 +563,8 @@ class Specfile(object):
if config.config_opts['32bit']:
self._write_strip("pushd clr-build32")
self._write_strip("%make_install32 " + self.extra_make_install)
self._write_strip("%make_install32 {} {}".format(self.extra_make_install,
self.extra_make32_install))
self._write_strip("if [ -d %{buildroot}/usr/lib32/pkgconfig ]")
self._write_strip("then")
self._write_strip(" pushd %{buildroot}/usr/lib32/pkgconfig")
@@ -689,7 +699,7 @@ class Specfile(object):
.format(self.disable_static,
config.extra_configure,
config.extra_configure32))
self.write_make_line()
self.write_make_line(True)
self._write_strip("popd")
if config.config_opts['use_avx2']:
@@ -754,7 +764,7 @@ class Specfile(object):
.format(self.disable_static,
config.extra_configure,
config.extra_configure32))
self.write_make_line()
self.write_make_line(True)
self._write_strip("popd")
if config.config_opts['use_avx2']:
@@ -826,7 +836,7 @@ class Specfile(object):
.format(self.disable_static,
config.extra_configure,
config.extra_configure32))
self.write_make_line()
self.write_make_line(True)
self._write_strip("popd")
self.write_check()
self.write_make_install()
@@ -983,7 +993,7 @@ class Specfile(object):
self._write_strip("mkdir clr-build")
self._write_strip("pushd clr-build")
self.write_variables()
self._write_strip("cmake .. -G \"Unix Makefiles\" "
self._write_strip("cmake " + self.cmake_srcdir + " -G \"Unix Makefiles\" "
"-DCMAKE_INSTALL_PREFIX=/usr -DBUILD_SHARED_LIBS:BOOL=ON "
"-DLIB_INSTALL_DIR:PATH=/usr/lib64 "
"-DCMAKE_AR=/usr/bin/gcc-ar "
@@ -999,7 +1009,7 @@ class Specfile(object):
self._write_strip("\nmake clean\n")
self._write_strip("{0}".format(self.get_profile_use_flags()))
self._write_strip("make VERBOSE=1 {}{}".format(config.parallel_build, self.extra_make))
self._write_strip("make {}{}".format(config.parallel_build, self.extra_make))
self._write_strip("popd")
if config.config_opts['32bit']:
@@ -1009,13 +1019,13 @@ class Specfile(object):
self._write_strip('export PKG_CONFIG_PATH="/usr/lib32/pkgconfig"')
self._write_strip('export CFLAGS="$CFLAGS -m32"')
self._write_strip('export CXXFLAGS="$CXXFLAGS -m32"')
self._write_strip('cmake .. -G "Unix Makefiles" '
self._write_strip('cmake ' + self.cmake_srcdir + ' -G "Unix Makefiles" '
"-DCMAKE_INSTALL_PREFIX=/usr -DBUILD_SHARED_LIBS:BOOL=ON "
"-DLIB_INSTALL_DIR:PATH=/usr/lib32 "
"-DCMAKE_AR=/usr/bin/gcc-ar "
"-DLIB_SUFFIX=32 "
"-DCMAKE_RANLIB=/usr/bin/gcc-ranlib " + self.extra_cmake)
self._write_strip("make VERBOSE=1 {}{}".format(config.parallel_build, self.extra_make))
self._write_strip("make {}{}".format(config.parallel_build, self.extra_make))
self._write_strip("popd")
if config.config_opts['use_avx2']:
@@ -1027,12 +1037,12 @@ class Specfile(object):
self.need_avx2_flags = saved_avx2flags
self._write_strip('export CFLAGS="$CFLAGS -march=haswell"')
self._write_strip('export CXXFLAGS="$CXXFLAGS -march=haswell"')
self._write_strip('cmake .. -G "Unix Makefiles" '
self._write_strip('cmake ' + self.cmake_srcdir + ' -G "Unix Makefiles" '
"-DCMAKE_INSTALL_PREFIX=/usr -DBUILD_SHARED_LIBS:BOOL=ON "
"-DLIB_INSTALL_DIR:PATH=/usr/lib/haswell "
"-DCMAKE_AR=/usr/bin/gcc-ar "
"-DCMAKE_RANLIB=/usr/bin/gcc-ranlib " + self.extra_cmake)
self._write_strip("make VERBOSE=1 {}{} || :".format(config.parallel_build, self.extra_make))
self._write_strip("make {}{} || :".format(config.parallel_build, self.extra_make))
self._write_strip("popd")
self._write_strip("\n")
@@ -1042,7 +1052,7 @@ class Specfile(object):
def write_cargo_pattern(self):
"""Write cargo build pattern to spec file"""
self.write_prep()
src_dir = "/usr/share/rust/src/{0}-{1}".format(self.name, self.version)
src_dir = "/usr/share/rust/src/{0}".format(self.name)
self._write_strip("%build")
self.write_proxy_exports()
self._write_strip("mkdir .cargo")
+31 -25
View File
@@ -66,6 +66,7 @@ def really_download(upstream_url, destination):
c.perform()
except pycurl.error:
print_fatal("unable to download {}".format(upstream_url))
os.remove(destination)
exit(1)
finally:
c.close()
@@ -189,7 +190,7 @@ def download_tarball(target_dir):
tarfile = os.path.basename(url)
target = os.path.join(os.getcwd(), name)
if os.path.exists(os.path.join(os.getcwd(), 'options.conf')):
config_f = configparser.ConfigParser()
config_f = configparser.ConfigParser(interpolation=None)
config_f.read('options.conf')
if "package" in config_f.sections():
if (config_f["package"].get("name") == name or
@@ -258,9 +259,8 @@ def detect_build_from_url(url):
# python
if "pypi.python.org" in url or "pypi.debian.net" in url:
buildpattern.set_build_pattern("distutils23", 10)
buildpattern.set_build_pattern("distutils3", 10)
buildreq.add_buildreq("python3-dev")
buildreq.add_buildreq("python-dev")
# cpan
if ".cpan.org/" in url or ".metacpan.org/" in url:
@@ -274,6 +274,10 @@ def detect_build_from_url(url):
if ".maven." in url:
buildpattern.set_build_pattern("maven", 10)
# rust crate
if "crates.io" in url:
buildpattern.set_build_pattern("cargo", 10)
def name_and_version(name_arg, version_arg, filemanager):
"""
@@ -284,6 +288,7 @@ def name_and_version(name_arg, version_arg, filemanager):
global version
global url
global giturl
global repo
tarfile = os.path.basename(url)
@@ -330,19 +335,31 @@ def name_and_version(name_arg, version_arg, filemanager):
# define regex accepted for valid packages, important for specific
# patterns to come before general ones
github_patterns = [r"https?://github.com/(.*)/(.*?)/archive/[v|r]?.*/(.*).tar",
r"https?://github.com/(.*)/(.*?)/archive/[-a-zA-Z]*-(.*).tar",
r"https?://github.com/(.*)/(.*?)/archive/[-a-zA-Z-_]*-(.*).tar",
r"https?://github.com/(.*)/(.*?)/archive/[vVrR]?(.*).tar",
r"https?://github.com/(.*)/(.*?)/releases/download/v.*/(.*).tar"]
r"https?://github.com/(.*)/.*-downloads/releases/download/.*?/(.*)-(.*).tar",
r"https?://github.com/(.*)/(.*?)/releases/download/.*?/(.*).tar",
r"https?://github.com/(.*)/(.*?)/files/.*?/(.*).tar"]
for pattern in github_patterns:
m = re.search(pattern, url)
if m:
name = m.group(2).strip()
repo = m.group(2).strip()
if repo not in name:
# Only take the repo name as the package name if it's more descriptive
name = repo
elif name != repo:
name = re.sub("release-", '', name)
name = re.sub("\d*$", '', name)
rawname = name
version = convert_version(m.group(3))
giturl = "https://github.com/" + m.group(1).strip() + "/" + name + ".git"
giturl = "https://github.com/" + m.group(1).strip() + "/" + repo + ".git"
break
# construct github giturl from gnome projects
if not giturl and "download.gnome.org" in url:
giturl = "https://github.com/GNOME/{}.git".format(name)
if "mirrors.kernel.org" in url:
m = re.search(r".*/sourceware/(.*?)/releases/(.*?).tgz", url)
if m:
@@ -390,6 +407,13 @@ def name_and_version(name_arg, version_arg, filemanager):
name = m.group(1).strip()
version = convert_version(m.group(2))
# rust crate
if "crates.io" in url:
m = re.search(r"/crates.io/api/v[0-9]+/crates/(.*)/(.*)/download.*\.crate", url)
if m:
name = m.group(1).strip()
version = convert_version(m.group(2))
# override name and version from commandline
name = name_arg if name_arg else name
version = version_arg if version_arg else version
@@ -432,22 +456,6 @@ def find_extract(tar_path, tarfile):
return extract_cmd, tar_prefix
def write_makefile(archives):
"""
Write the new makefile with url, name, and archives
"""
with open(build.download_path + "/Makefile", "w") as f:
f.write("PKG_NAME := " + name + "\n")
f.write("URL := " + url + "\n")
sep = "ARCHIVES := "
for archive in archives:
f.write("{}{}".format(sep, archive))
sep = " " if sep != " " else " \\\n\t"
f.write("\n")
f.write("\n")
f.write("include ../common/Makefile.common\n")
def prepare_and_extract(extract_cmd):
"""
Prepare the directory and extract the tarball
@@ -523,8 +531,6 @@ def process(url_arg, name_arg, ver_arg, target, archives_arg, filemanager):
# Now that the metadata has been collected print the header
print_header()
# write out the Makefile with the name, url, and archives we found
# DEPRECATED, this will be removed in a future version
write_makefile(archives_arg)
# prepare directory and extract tarball
prepare_and_extract(extract_cmd)
# locate or download archives and move them into the right spot
+4
View File
@@ -71,6 +71,10 @@ def print_warning(message):
print("[\033[31;1mWARNING\033[0m] {}".format(message))
def print_infile(message):
print("[\033[1;34mINFILE\033[0m] {}".format(message))
def binary_in_path(binary):
""" Determine if the given binary exists in the provided filesystem paths """
global os_paths
+3
View File
@@ -1,3 +1,6 @@
flake8>=3.4.0
pycurl>=7.43.0
toml>=0.9.0
mock>=2.0.0
coverage>=4.4.1
requests>=2.18.4
+4
View File
@@ -2,3 +2,7 @@
tag_build =
[pycodestyle]
ignore = E501
[coverage:run]
# omit tests and travis site-packages
omit = tests/*,*site-packages*,*site.py
+1 -1
View File
@@ -1,7 +1,7 @@
from setuptools import setup, find_packages
import sys, os
version = "1.1.2"
version = "1.2.0"
def readme():
with open("README.rst") as f:
+2
View File
@@ -320,6 +320,7 @@ https://download.gnome.org/sources/geocode-glib/3.24/geocode-glib-3.24.0.tar.xz,
http://mirrors.kernel.org/gnu/gettext/gettext-0.19.8.1.tar.xz,gettext,0.19.8.1
https://pypi.debian.net/gevent/gevent-1.2.2.tar.gz,gevent,1.2.2
https://github.com/gflags/gflags/archive/v2.2.1.tar.gz,gflags,2.2.1
https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs922/ghostscript-9.22.tar.gz,ghostscript,9.22
https://download.gimp.org/mirror/pub/gimp/v2.8/gimp-2.8.22.tar.bz2,gimp,2.8.22
https://www.kernel.org/pub/software/scm/git/git-2.14.2.tar.gz,git,2.14.2
https://github.com/sitaramc/gitolite/archive/v3.6.7.tar.gz,gitolite,3.6.7
@@ -1765,6 +1766,7 @@ http://ftp.gnome.org/pub/gnome/sources/vinagre/3.22/vinagre-3.22.0.tar.xz,vinagr
http://pypi.debian.net/vine/vine-1.1.4.tar.gz,vine,1.1.4
http://pypi.debian.net/virtualenv/virtualenv-15.1.0.tar.gz,virtualenv,15.1.0
https://virt-manager.org/download/sources/virt-viewer/virt-viewer-6.0.tar.gz,virt-viewer,6.0
https://github.com/felixonmars/volume_key/archive/volume_key-0.3.9.tar.gz,volume_key,0.3.9
https://pypi.debian.net/voluptuous/voluptuous-0.10.5.tar.gz,voluptuous,0.10.5
https://github.com/GNOME/vte/archive/0.50.1.tar.gz,vte,0.50.1
https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/archive/sdk-1.0.39.0.tar.gz,Vulkan-LoaderAndValidationLayers,1.0.39.0
-308
View File
@@ -1,308 +0,0 @@
"""
autospec test suite
"""
import tarfile
import os
import re
import shutil
import subprocess
import importlib
import multiprocessing
import getpass
import errno
import argparse
from difflib import unified_diff
IGNORES = set(['expectations.py',
'spec-expectations',
'__pychache__',
'autospecdir'])
NOT_PACKAGE = ['.tar', 'test', 'autospec.conf', 'results']
BASEDIR = os.getcwd()
TESTDIR = BASEDIR + '/tests/testfiles'
PCOLOR = '\033[92m'
FCOLOR = '\033[91m'
ENDCOLOR = '\033[0m'
def fmt_fail(msg):
"""returns colored and formatted failure message"""
return '{}FAIL:{} {}'.format(FCOLOR, ENDCOLOR, msg)
def fmt_pass(msg):
"""returns colored and formatted pass message"""
return '{}PASS:{} {}'.format(PCOLOR, ENDCOLOR, msg)
def tar_source(srcfiles):
"""tar the files in the testfiles directory"""
os.chdir(TESTDIR)
tar = tarfile.open('{}.tar.gz'.format(srcfiles), 'w:gz')
files = set(os.listdir(srcfiles)).difference(IGNORES)
for file in files:
tar.add('{}/{}'.format(srcfiles, file))
tar.close()
os.chdir(BASEDIR)
def build_and_run(srctar, expectations, entry, test_results):
"""run make autospec against the tarball, then run the tests"""
dest = '{}/test-{}'.format(TESTDIR, entry)
add_files(entry, dest)
os.chdir(dest)
output = "".encode('utf-8')
if os.path.exists('test.conf'):
config = ['-c', 'test.conf']
else:
config = []
# pylint: disable=broad-except
# pass on any exception because the build failure will be reported later
try:
output = subprocess.check_output(
['python3', '{}/autospec/autospec.py'.format(BASEDIR),
'-n', entry, '-t', '.',
'file://{}/{}'.format(TESTDIR, srctar)] + config)
except Exception:
pass
finally:
output = output.decode('utf-8')
print('Testing output for {}'.format(entry))
failures = check_output(output, expectations, entry, test_results)
if not failures:
with open('{}.spec'.format(entry), 'r') as spec_file:
spc = spec_file.read()
failures += check_spec(spc, expectations, entry, test_results)
with open('options.conf', 'r') as conf_file:
conf = conf_file.read()
failures += check_conf(conf, expectations, entry, test_results)
if failures:
# only copy logs and output over if a failure or error occurred
print('{} test failures detected'.format(entry))
copy_logs(entry, output)
os.chdir(BASEDIR)
def add_files(entry, dest):
"""add necessary files to the autospec test directory"""
os.makedirs(dest, exist_ok=True)
for file in os.listdir('{}/{}/autospecdir'.format(TESTDIR, entry)):
shutil.copy2('{}/{}/autospecdir/{}'.format(TESTDIR, entry, file), dest)
def check_output(output, expectations, entry, test_results):
"""
test the output of the autospec run against the expectations defined in
expectations.py
Returns number of failures (1 for a failure, 0 for success)
"""
if 'build successful' in output:
test_results[entry].append(fmt_pass('Build status - successful'))
print('{} build successful'.format(entry))
else:
test_results[entry].append(fmt_fail('Build status - failed, '
'skipping remaining tests'))
print('{} build failed'.format(entry))
return 1
for item in expectations.output_strings:
if item not in output:
test_results[entry].append(fmt_fail('"{}" expected in output, but '
'not present'.format(item)))
else:
test_results[entry].append(fmt_pass('"{}" found in output'
.format(item)))
return 0
def check_spec(spec_contents, expectations, entry, test_results):
"""
test the specfile against the expected specfile in spec-expectations
Returns the number of failures identified
"""
failures = 0
# replace the epoch time with a 1 so it can be tested for
spec_contents = re.sub(r'SOURCE_DATE_EPOCH=[0-9]+\n',
'SOURCE_DATE_EPOCH=1\n',
spec_contents)
diff = list(unified_diff(expectations.specfile,
spec_contents.split('\n'),
fromfile='expected_specfile',
tofile='generated_specfile'))
if len(diff):
test_results[entry].append(fmt_fail('generated specfile different from '
'expected\n'))
failures += 1
for line in diff:
test_results[entry][-1] += '\n{}'.format(line)
test_results[entry][-1] += '\n'
else:
test_results[entry].append(fmt_pass('generated specfile matches expected'))
# the following checks are superflous, but can give more granular
# indications of what has gone wrong
if expectations.license not in spec_contents:
test_results[entry].append(fmt_fail('license not detected as "{}"'
.format(expectations.license)))
failures += 1
else:
test_results[entry].append(fmt_pass('license correctly detected as "{}"'
.format(expectations.license)))
for item in expectations.buildreqs:
if item not in spec_contents:
test_results[entry].append(fmt_fail('expected "{}" to be a build '
'requirement, but was not found'
.format(item)))
failures += 1
else:
test_results[entry].append(fmt_pass('build requirement "{}" '
'successfully detected'
.format(item)))
return failures
def check_conf(conf_contents, expectations, entry, test_results):
"""
test the specfile against the expected specfile in spec-expectations
Returns the number of failures identified.
"""
failures = 0
diff = list(unified_diff(expectations.conffile,
conf_contents.split('\n'),
fromfile='expected_conffile',
tofile='generated_conffile'))
if len(diff):
test_results[entry].append(fmt_fail('generated conf file different '
'from expected\n'))
failures += 1
for line in diff:
test_results[entry][-1] += '\n{}'.format(line)
test_results[entry][-1] += '\n'
else:
test_results[entry].append(fmt_pass('generated configuration file '
'matches expected'))
return failures
def copy_logs(entry, output):
"""
Copies output and build and mock logs from the autospec build into
TESTDIR/results/
"""
os.makedirs('{}/results'.format(TESTDIR), exist_ok=True)
try:
shutil.copy2('{}/test-{}/results/build.log'.format(TESTDIR, entry),
'{}/results/{}-build.log'.format(TESTDIR, entry))
shutil.copy2('{}/test-{}/mock_srpm.log'.format(TESTDIR, entry),
'{}/results/{}-mock_srpm.log'.format(TESTDIR, entry))
shutil.copy2('{}/test-{}/mock_build.log'.format(TESTDIR, entry),
'{}/results/{}-mock_build.log'.format(TESTDIR, entry))
print('check {}/results/ for more logfiles and output'
.format(TESTDIR, entry))
except Exception:
print('no build log found')
with open('{}/results/{}.out'.format(TESTDIR, entry), 'w') as outf:
outf.write(output)
def clean_up(entry):
"""clean up generated files and directories"""
# try to remove each directory/file in turn
shutil.rmtree('/tmp/{}'.format(getpass.getuser()), ignore_errors=True)
shutil.rmtree('{}/{}/__pycache__'.format(TESTDIR, entry), ignore_errors=True)
shutil.rmtree('{}/test-{}'.format(TESTDIR, entry), ignore_errors=True)
try:
os.remove('{}/{}.tar.gz'.format(TESTDIR, entry))
except OSError as excep:
if excep.errno != errno.ENOENT:
raise
def print_results(entry, test_results):
"""pretty-print the results of the tests"""
title = 'Test results for {}'.format(entry)
line = ''
for _ in range(len(title)):
line += '-'
print(line)
print(title)
print(line)
print('\n')
failures = 0
passes = 0
fcolor = ''
pcolor = ''
for result in test_results[entry]:
print(result)
if 'PASS' in result:
passes += 1
pcolor = PCOLOR
else:
failures += 1
fcolor = FCOLOR
print('\nFailed tests: {}{}{}'.format(fcolor, failures, ENDCOLOR))
print('Passed tests: {}{}{}'.format(pcolor, passes, ENDCOLOR))
print(line)
print('\n')
def process_source(entry, test_results):
"""run autospec against entry and store the test results in test_results"""
# Remove previous run failure logs
shutil.rmtree('{}/results'.format(TESTDIR), ignore_errors=True)
expectations = importlib.import_module('testfiles.{}.expectations'
.format(entry))
tar_source(entry)
print('Building {}'.format(entry))
build_and_run('{}.tar.gz'.format(entry), expectations, entry, test_results)
print_results(entry, test_results)
clean_up(entry)
def main():
"""split off threads to run autospec and test the specfile and output"""
test_results = {}
results_list = []
parser = argparse.ArgumentParser()
parser.add_argument("-c", "--test-cases", dest="cases", nargs='*',
help="List of test cases to run (by package name) "
"separated by whitespace")
args = parser.parse_args()
pool = multiprocessing.Pool()
for entry in os.listdir(TESTDIR):
if any(x in entry for x in NOT_PACKAGE):
continue
clean_up(entry)
if args.cases and entry not in args.cases:
continue
test_results[entry] = []
res = pool.apply_async(process_source, (entry, test_results))
results_list.append(res)
pool.close()
pool.join()
for result in results_list:
result.get()
if __name__ == '__main__':
main()
+35 -1
View File
@@ -236,7 +236,7 @@ class TestBuildpattern(unittest.TestCase):
self.assertIn('jdk-apache-parent', build.buildreq.buildreqs)
self.assertEqual(build.must_restart, 1)
def test_parse_build_resultsi_pkgconfig(self):
def test_parse_build_results_pkgconfig(self):
"""
Test parse_build_results with a test log indicating failure due to a
missing qmake package (pkgconfig error)
@@ -314,6 +314,40 @@ class TestBuildpattern(unittest.TestCase):
self.assertIn('testpkg-python', build.buildreq.buildreqs)
self.assertEqual(build.must_restart, 1)
def test_parse_build_results_files(self):
"""
Test parse_build_results with a test log indicating files are missing
"""
def mock_util_call(cmd):
del cmd
build.config.setup_patterns()
call_backup = build.util.call
build.util.call = mock_util_call
fm = files.FileManager()
open_name = 'build.open'
content = 'line 1\n' \
'Installed (but unpackaged) file(s) found:\n' \
'/usr/testdir/file\n' \
'/usr/testdir/file1\n' \
'/usr/testdir/file2\n' \
'RPM build errors\n' \
'errors here\n'
m_open = mock_open(read_data=content)
with patch(open_name, m_open, create=True):
build.parse_build_results('testname', 0, fm)
build.util.call = call_backup
self.assertEqual(fm.files,
['/usr/testdir/file',
'/usr/testdir/file1',
'/usr/testdir/file2'])
# one for each file added
self.assertEqual(build.must_restart, 3)
def test_get_mock_cmd_without_consolehelper(self):
"""
Test get_mock_cmd when /usr/bin/mock doesn't point to consolehelper
+1 -1
View File
@@ -177,7 +177,7 @@ class TestBuildreq(unittest.TestCase):
buildreq.toml.loads = loads_backup
self.assertEqual(buildreq.buildreqs,
set(['rustc', 'dep1', 'dep2', 'dep3']))
set(['cargo', 'rustc', 'dep1', 'dep2', 'dep3']))
self.assertTrue(buildreq.cargo_bin)
self.assertEqual(buildreq.buildpattern.default_pattern, 'cargo')
+34 -2
View File
@@ -129,7 +129,7 @@ class TestCommitmessage(unittest.TestCase):
open_name = 'util.open'
with mock.patch(open_name, create=True) as mock_open:
mock_open.return_value = mock.MagicMock()
commitmessage.guess_commit_message()
commitmessage.guess_commit_message("")
# reset mocks before asserting so a failure doesn't cascade to
# other tests
commitmessage.process_NEWS = process_NEWS_backup
@@ -159,7 +159,7 @@ class TestCommitmessage(unittest.TestCase):
open_name = 'util.open'
with mock.patch(open_name, create=True) as mock_open:
mock_open.return_value = mock.MagicMock()
commitmessage.guess_commit_message()
commitmessage.guess_commit_message("")
# reset mocks before asserting so a failure doesn't cascade to
# other tests
commitmessage.process_NEWS = process_NEWS_backup
@@ -170,6 +170,38 @@ class TestCommitmessage(unittest.TestCase):
'cves\n\n\ncommit\nmessage\nwith\ncves\n\nCVEs fixed in this '
'build:\nCVE-1234-5678\ncve1\ncve2\n\n')
def test_guess_commit_message_imported_key(self):
"""
Test guess_commit_message() with mocked internal functions and both
commitmessage information and cves available from newsfile. A cve is
also available from config, which changes the first line of the commmit
message. Additionally there is imported key info that will be displayed
at the end of the message.
"""
process_NEWS_backup = commitmessage.process_NEWS
def mock_process_NEWS(newsfile):
return (['', 'commit', 'message', 'with', 'cves', ''],
set(['cve1', 'cve2']))
commitmessage.process_NEWS = mock_process_NEWS
commitmessage.config.cves = set(['CVE-1234-5678'])
commitmessage.config.old_version = None # Allow cve title to be set
open_name = 'util.open'
with mock.patch(open_name, create=True) as mock_open:
mock_open.return_value = mock.MagicMock()
commitmessage.guess_commit_message("keyinfo content")
# reset mocks before asserting so a failure doesn't cascade to
# other tests
commitmessage.process_NEWS = process_NEWS_backup
commitmessage.config.cves = set()
fh = mock_open.return_value.__enter__.return_value
fh.write.assert_called_with(
'testball: Fix for CVE-1234-5678\n\n\ncommit\nmessage\nwith\n'
'cves\n\n\ncommit\nmessage\nwith\ncves\n\nCVEs fixed in this '
'build:\nCVE-1234-5678\ncve1\ncve2\n\nKey imported:\nkeyinfo '
'content\n')
def test_scan_for_changes(self):
"""
Tests scan_for_changes using temporary directories
+25 -2
View File
@@ -36,6 +36,8 @@ pats = [
[332, 281, 38, 0, 13, 0, 0, 0, 0, 0]),
('===================== 5 failed, 318 passed in 1.06 seconds =====================',
[323, 318, 5, 0, 0, 0, 0, 0, 0, 0]),
('===================== 5 failed, 9 passed, 7 xfailed in 1.06 seconds ============',
[21, 9, 5, 7, 0, 0, 0, 0, 0, 0]),
('============= 1628 passed, 72 skipped, 4 xfailed in 146.26 seconds =============',
[1704, 1628, 0, 4, 72, 0, 0, 0, 0, 0]),
('=============== 119 passed, 2 skipped, 54 error in 2.19 seconds ================',
@@ -87,8 +89,9 @@ pats = [
('# of expected passes\t1144\n'
'# of expected failures\t57\n'
'# of untested testcases\t1\n'
'# of unsupported tests\t12',
[1213, 1144, 0, 57, 12, 0, 0, 0, 0, 0]),
'# of unsupported tests\t12\n'
'# of unexpected failures\t1\n',
[1214, 1144, 1, 57, 12, 0, 0, 0, 0, 0]),
# ccache
('PASSED: 448 assertions, 88 tests, 10 suites',
[88, 88, 0, 0, 0, 0, 0, 0, 0, 0]),
@@ -179,6 +182,13 @@ pats = [
'Failed with core: 0\n'
'Unknown status: 0',
[13042, 13036, 6, 0, 0, 1, 1, 0, 0, 0]),
# nss
('cert.sh: #101: Import chain-2-serverCA-ec CA -t u,u,u for localhost.localdomain (ext.) - FAILED\n'
'Passed: 13036\n'
'Failed: 6\n'
'Failed with core: 0\n'
'Unknown status: 0',
[13042, 13036, 6, 0, 0, 0, 0, 1, 0, 0]),
# rsync
(' 34 passed\n'
' 5 skipped',
@@ -191,6 +201,12 @@ pats = [
[30, 0, 6, 6, 18, 0, 0, 0, 0, 0]),
('FAILED (failures=1, errors=499, skipped=48)',
[548, 0, 1, 499, 48, 0, 0, 0, 0, 0]),
('FAILED (failures=1, errors=499)',
[500, 0, 1, 499, 0, 0, 0, 0, 0, 0]),
('FAILED (failures=1)',
[1, 0, 1, 0, 0, 0, 0, 0, 0, 0]),
('FAILED (errors=1)',
[1, 0, 0, 1, 0, 0, 0, 0, 0, 0]),
('OK (KNOWNFAIL=5, SKIP=15)',
[20, 0, 0, 5, 15, 0, 0, 0, 0, 0]),
# qpid-python
@@ -304,6 +320,9 @@ pats = [
# rubygem-ansi
('Executed 12 tests with 7 passing, 5 errors.',
[12, 7, 5, 0, 0, 0, 0, 0, 0, 0]),
# vim
('Executed 12 tests',
[12, 12, 0, 0, 0, 0, 0, 0, 0, 0]),
# rubygem-formatador
(' 9 succeeded in 0.00375661 seconds',
[9, 9, 0, 0, 0, 0, 0, 0, 0, 0]),
@@ -372,8 +391,12 @@ pats = [
# hdf5
('Testing h5repack h5repack_szip.h5 -f dset_szip:GZIP=1 -SKIP-',
[1, 0, 0, 0, 1, 0, 0, 0, 0, 0]),
('Verifying h5repack h5repack_szip.h5 -f dset_szip:GZIP=1 -SKIP-',
[1, 0, 0, 0, 1, 0, 0, 0, 0, 0]),
('Verifying h5dump output -f GZIP=1 -m 1024 *FAILED*',
[1, 0, 1, 0, 0, 0, 0, 0, 0, 0]),
('Testing h5dump output -f GZIP=1 -m 1024 *FAILED*',
[1, 0, 1, 0, 0, 0, 0, 0, 0, 0]),
('Testing h5repack --metadata_block_size=8192 PASSED',
[1, 1, 0, 0, 0, 0, 0, 0, 0, 0]),
('Verifying h5diff output h5repack_layout.h5 out-meta_long.h5repack_layo PASSED',
+66
View File
@@ -1,5 +1,7 @@
import unittest
import files
import tempfile
import os
from unittest.mock import call, MagicMock
from files import FileManager
@@ -184,5 +186,69 @@ class TestFiles(unittest.TestCase):
self.assertNotIn('test', self.fm.files)
self.assertNotIn('test', self.fm.files_blacklist)
def test_clean_directories(self):
"""
Test clean_directories with a directory in the list
"""
with tempfile.TemporaryDirectory() as tmpd:
os.mkdir(os.path.join(tmpd, "directory"))
with open(os.path.join(tmpd, "file1"), "w") as f:
f.write(" ")
with open(os.path.join(tmpd, "file2"), "w") as f:
f.write(" ")
self.fm.packages["main"] = set()
self.fm.packages["main"].add("/directory")
self.fm.packages["main"].add("/file1")
self.fm.packages["main"].add("/file2")
self.fm.clean_directories(tmpd)
self.assertEqual(self.fm.packages["main"], set(["/file1", "/file2"]))
def test_clean_directories_with_dir(self):
"""
Test clean_directories with a %dir directory in the list. This should
remain.
"""
with tempfile.TemporaryDirectory() as tmpd:
os.mkdir(os.path.join(tmpd, "directory"))
with open(os.path.join(tmpd, "file1"), "w") as f:
f.write(" ")
with open(os.path.join(tmpd, "file2"), "w") as f:
f.write(" ")
self.fm.packages["main"] = set()
self.fm.packages["main"].add("%dir /directory")
self.fm.packages["main"].add("/file1")
self.fm.packages["main"].add("/file2")
self.fm.clean_directories(tmpd)
self.assertEqual(self.fm.packages["main"],
set(["%dir /directory", "/file1", "/file2"]))
def test_clean_directories_with_doc(self):
"""
Test clean_directories with a %doc directive in the list. This should
remain.
"""
with tempfile.TemporaryDirectory() as tmpd:
os.mkdir(os.path.join(tmpd, "directory"))
with open(os.path.join(tmpd, "file1"), "w") as f:
f.write(" ")
with open(os.path.join(tmpd, "file2"), "w") as f:
f.write(" ")
self.fm.packages["main"] = set()
self.fm.packages["main"].add("%doc /directory")
self.fm.packages["main"].add("/file1")
self.fm.packages["main"].add("/file2")
self.fm.clean_directories(tmpd)
self.assertEqual(self.fm.packages["main"],
set(["%doc /directory", "/file1", "/file2"]))
if __name__ == '__main__':
unittest.main(buffer=True)
+24
View File
@@ -0,0 +1,24 @@
import subprocess
import unittest
class TestGeneral(unittest.TestCase):
def test_ConfigParser_regressions(self):
"""
Make sure ConfigParser is always called with the required
interpolation=None argument
"""
grep_cmd = ["grep", "-re",
"ConfigParser(.*\(^interpolation=None\).*)",
"autospec"]
try:
output = subprocess.check_output(grep_cmd).decode('utf-8')
except subprocess.CalledProcessError as e:
output = e.output.decode('utf-8')
self.assertEqual(output.strip(), "")
if __name__ == "__main__":
unittest.main(buffer=True)
+288
View File
@@ -0,0 +1,288 @@
import unittest
import os
import infile_handler
class TestParseBitBakeFile(unittest.TestCase):
def test_scrape_version_htop(self):
""""
Test that the version is correctly scraped from the file name
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'htop_1.0.3.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "1.0.3"
self.assertEqual(expect, bb_dict.get('VERSION'))
def test_scrape_version_vim(self):
""""
Test that the version is correctly scraped from the file name
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'vim_8.0.0983.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "8.0.0983"
self.assertEqual(expect, bb_dict.get('VERSION'))
def test_scrape_version_catkin_runtime(self):
""""
Test that the version is correctly scraped from the file name
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'catkin-runtime_0.6.19.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "0.6.19"
self.assertEqual(expect, bb_dict.get('VERSION'))
def test_scrape_url_catkin(self):
bb_file = os.path.join('tests', 'testfiles', 'bb', 'catkin.inc')
bb_dict = infile_handler.file_handler(bb_file, {"NAME": "catkin"})
expect = "https://github.com/ros/catkin/archive/${PV}.tar.gz"
self.assertEqual(expect, bb_dict.get('URL'))
def test_scrape_src_uri_htop(self):
"""
Test that the occurance of ${PV} is replaced by the scraped version.
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'htop_1.0.3.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "http://hisham.hm/htop/releases/1.0.3/htop-1.0.3.tar.gz"
self.assertEqual(expect, bb_dict.get('SRC_URI'))
def test_scrape_inherits_htop(self):
"""
Test that the package inherits are correctly scraped as a list with
only one line/inherit
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'htop_1.0.3.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = ["autotools"]
self.assertEqual(expect, bb_dict.get('inherits'))
def test_scrape_inherits_vim(self):
"""
Test that the package inherits are correctly scraped as a list with
multiple lines/inherits
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'vim_8.0.0983.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = ["autotools update-alternatives", "autotools-brokensep"]
self.assertEqual(expect, bb_dict.get('inherits'))
def test_scrape_summary_htop(self):
"""
Test that the package summary is correctly scraped
from the bitbake file.
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'htop_1.0.3.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "htop process monitor"
self.assertEqual(expect, bb_dict.get('SUMMARY'))
def test_scrape_section_htop(self):
"""
Test that the package section is correctly scraped
from the bitbake file.
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'htop_1.0.3.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "console/utils"
self.assertEqual(expect, bb_dict.get('SECTION'))
def test_scrape_license_htop(self):
"""
Test that the package license is correctly scraped
from the bitbake file.
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'htop_1.0.3.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "GPLv2"
self.assertEqual(expect, bb_dict.get('LICENSE'))
def test_scrape_depends_htop(self):
"""
Test that the package depends is correctly scraped
from the bitbake file.
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'htop_1.0.3.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "ncurses"
self.assertEqual(expect, bb_dict.get('DEPENDS'))
def test_scrape_rdepends_htop(self):
"""
Test that the package rsuggests_${PN} is correctly scraped
from the bitbake file.
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'htop_1.0.3.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "ncurses-terminfo"
self.assertEqual(expect, bb_dict.get('RDEPENDS_${PN}'))
def test_scrape_lic_files_chksum_htop_double_eq(self):
"""
Test that the package license file checksum is correctly scraped
from the bitbake file. This line contains two equal signs - which
will test pattern matching identifies the correct one.
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'htop_1.0.3.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "file://COPYING;md5=c312653532e8e669f30e5ec8bdc23be3"
self.assertEqual(expect, bb_dict.get('LIC_FILES_CHKSUM'))
def test_scrape_s_variable_vim(self):
"""
Test that the s variable is correctly scraped from the bitbake file.
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'vim_8.0.0983.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "${WORKDIR}/git/src"
self.assertEqual(expect, bb_dict.get('S'))
def test_scrape_vimdir_vim(self):
"""
Test that the vimdir variable is correctly scraped from the bitbake
file. This value contains multile 'PV' variables.
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'vim_8.0.0983.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "vim${@d.getVar('PV').split('.')[0]}${@d.getVar('PV').split('.')[1]}"
self.assertEqual(expect, bb_dict.get('VIMDIR'))
def test_scrape_packageconfig_gtkgui_vim(self):
"""
Test that packageconfig[gtkgui] returns the correct value scraped with
the parser.
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'vim_8.0.0983.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "--enable-gtk2-test --enable-gui=gtk2,--enable-gui=no,gtk+,"
self.assertEqual(expect, bb_dict.get('PACKAGECONFIG[gtkgui]'))
def test_scrape_packageconfig_tiny_vim(self):
"""
Test that packageconfig[tiny] returns the correct value scraped with
the parser.
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'vim_8.0.0983.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "--with-features=tiny,--with-features=big,,"
self.assertEqual(expect, bb_dict.get('PACKAGECONFIG[tiny]'))
def test_scrape_alternative_link_name_vim(self):
"""
Test that ALTERNATIVE_LINK_NAME[vim] is correctly scraped from the
bitbake file.
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'vim_8.0.0983.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "${bindir}/vim"
self.assertEqual(expect, bb_dict.get('ALTERNATIVE_LINK_NAME[vim]'))
def test_scrape_files_tutor_has_hyphen_vim(self):
"""
Test that FILES_${PN}-tutor is correctly scraped. It contains a hyphen
in the variable name.
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'vim_8.0.0983.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "${datadir}/${BPN}/${VIMDIR}/tutor ${bindir}/${BPN}tutor"
self.assertEqual(expect, bb_dict.get('FILES_${PN}-tutor'))
def test_scrape_packageconfig_x11_has_digits_vim(self):
"""
Test that PACKAGECONFIG[x11] is correctly scraped. It contains digits
in the variable name.
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'vim_8.0.0983.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "--with-x,--without-x,xt,"
self.assertEqual(expect, bb_dict.get('PACKAGECONFIG[x11]'))
def test_concatenation_op_packageconfig_vim(self):
"""
Test that the resulting value for the PACKAGECONFIG variable, is
the += of the initialization with ??= "".
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'vim_8.0.0983.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "${@bb.utils.filter('DISTRO_FEATURES', 'acl selinux', d)}"
self.assertEqual(expect, bb_dict.get('PACKAGECONFIG'))
def test_operations_one(self):
"""
Test that the operations result in the correct assignments in the
bb_dict
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'op_tests.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "second value"
self.assertEqual(expect, bb_dict.get('ONE'))
def test_operations_two(self):
"""
Test that the operations result in the correct assignments in the
bb_dict
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'op_tests.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "first value"
self.assertEqual(expect, bb_dict.get('TWO'))
def test_operations_three(self):
"""
Test that the operations result in the correct assignments in the
bb_dict
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'op_tests.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "third value"
self.assertEqual(expect, bb_dict.get('THREE'))
def test_operations_four(self):
"""
Test that the operations result in the correct assignments in the
bb_dict
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'op_tests.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "third value first value second value"
self.assertEqual(expect, bb_dict.get('FOUR'))
def test_operations_five(self):
"""
Test that the operations result in the correct assignments in the
bb_dict
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'op_tests.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = "third valuefirst valuesecond value"
self.assertEqual(expect, bb_dict.get('FIVE'))
def test_line_continuation_src_uri_vim(self):
"""
Test that when there is a line continuation, the entire line is
appended to a single string value.
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'vim_8.0.0983.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = 'git://github.com/vim/vim.git ' \
' file://disable_acl_header_check.patch;patchdir=.. ' \
' file://vim-add-knob-whether-elf.h-are-checked.patch;patchdir=.. '
self.assertEqual(expect, bb_dict.get('SRC_URI'))
def test_command_scraping_do_configure_vim(self):
"""
Test that when a line starts with do_ it is scraped as a command and
stored as a string.
"""
bb_file = os.path.join('tests', 'testfiles', 'bb', 'vim_8.0.0983.bb')
bb_dict = infile_handler.file_handler(bb_file, {})
expect = ["# rm -f auto/*", "# touch auto/config.mk", "# aclocal",
"# autoconf", "# oe_runconf", "# touch auto/configure",
"# touch auto/config.mk auto/config.h" ]
self.assertEqual(expect, bb_dict.get('do_configure'))
if __name__ == '__main__':
unittest.main(buffer=True)
+46
View File
@@ -0,0 +1,46 @@
import unittest
import infile_handler
class TestInputReader(unittest.TestCase):
def test_sort_files_with_inc_and_bb(self):
"""
Test that the sort_files key to the sorted function, returns the
correct order when multiple bb files and an inc file are passed.
The correct output should be the .inc file first, and then the .bb
files.
"""
files = ['catkin-runtime_0.6.19.bb', 'catkin.inc', 'catkin_0.6.19.bb']
sorted_files = sorted(files, key=infile_handler.sort_files)
expect = ['catkin.inc', 'catkin-runtime_0.6.19.bb', 'catkin_0.6.19.bb']
self.assertEqual(expect, sorted_files)
def test_parse_ext_bb(self):
path = "cython_7.8.1.bb"
ext = infile_handler.parse_ext(path)
expect = "bb"
self.assertEqual(expect, ext)
def test_parse_ext_inc(self):
path = "cython.inc"
ext = infile_handler.parse_ext(path)
expect = "inc"
self.assertEqual(expect, ext)
def test_parse_ext_none(self):
path = "cython.deb"
ext = infile_handler.parse_ext(path)
expect = None
self.assertEqual(expect, ext)
if __name__ == '__main__':
unittest.main(buffer=True)
+94
View File
@@ -0,0 +1,94 @@
import unittest
import infile_update_spec
import specfiles
class TestUpdateSpecfile(unittest.TestCase):
def setUp(self):
# url, version, name, release
url = "http://www.testpkg.com/testpkg/pkg-1.0.tar.gz"
self.specfile = specfiles.Specfile(url, '1.1.1', 'test_pkg', '1')
self.bb_dict = {
"DEPENDS": "ncurses gettext-native",
"LICENSE": "new"
}
def test_update_summary_if_bb_summary(self):
"""
Test that if a bitbake file has a summary variable it overwrites
the specfile - even if there is a description too.
"""
self.specfile.default_sum = "No detailed summary available"
self.bb_dict["SUMMARY"] = "Vi IMproved - enhanced vi editor"
self.bb_dict["DESCRIPTION"] = "Super awesome VIM description"
infile_update_spec.update_summary(self.bb_dict, self.specfile)
self.assertEqual(self.specfile.default_sum,
"Vi IMproved - enhanced vi editor")
def test_update_summary_if_not_default(self):
"""
Test that if a bitbake file does NOT have a summary variable, but
instead has a description variable, that overwrites the specfile"
"""
self.specfile.default_sum = "No detailed summary available"
self.bb_dict["DESCRIPTION"] = "Super awesome VIM description"
infile_update_spec.update_summary(self.bb_dict, self.specfile)
self.assertEqual(self.specfile.default_sum,
"Super awesome VIM description")
def test_update_summary_if_no_bb_summary_or_description(self):
"""
Test that if a bitbake file has neither a summary or description
that the default specfile summary is written
"""
self.specfile.default_sum = "No detailed summary available"
infile_update_spec.update_summary(self.bb_dict, self.specfile)
self.assertEqual(self.specfile.default_sum,
"No detailed summary available")
def test_update_license_if_not_in_licenses_list(self):
"""
Test that if a license is scraped from the bb file, and not in the
licenses specfile list, that it should be added to the list.
"""
self.specfile.licenses = ['random', 'license']
infile_update_spec.update_licenses(self.bb_dict, self.specfile)
self.assertEqual(self.specfile.licenses, ['random', 'license', 'new'])
def test_update_license_if_in_license_list_case(self):
"""
Test that if a license is already in the specfile licenses list, not
case sensitive, then it should not be duplicated.
"""
self.specfile.licenses = ['random', 'New']
infile_update_spec.update_licenses(self.bb_dict, self.specfile)
self.assertEqual(self.specfile.licenses, ['random', 'New'])
def test_update_build_deps_append_normal(self):
"""
Test that if a set if multiple items are scraped from the bb file, and
they are not already in the specfile, they will be added to the set of
buildreqs. If the bb depends ends in '-native' that should be removed
as well.
"""
self.specfile.buildreqs = {'gmp-dev', 'lua-dev'}
infile_update_spec.update_build_deps(self.bb_dict, self.specfile)
self.assertEqual(self.specfile.buildreqs, {'gmp-dev', 'lua-dev',
'ncurses', 'gettext'})
def test_update_build_deps_append_duplicates(self):
"""
Test that if a set if multiple items are scraped from the bb file, and
they are already in the specfile, the resulting set with be the union
of set 1 and set 2.
"""
self.specfile.buildreqs = {'gmp-dev', 'ncurses'}
infile_update_spec.update_build_deps(self.bb_dict, self.specfile)
self.assertEqual(self.specfile.buildreqs, {'gmp-dev', 'ncurses',
'gettext'})
if __name__ == '__main__':
unittest.main(buffer=True)
+69 -2
View File
@@ -65,6 +65,30 @@ class TestLicense(unittest.TestCase):
self.assertIn('GPL-3.0', license.licenses)
def test_license_from_copying_hash_no_license_show(self):
"""
Test license_from_copying_hash with invalid hash and no license_show
set
"""
# Calls out to tarball.get_sha1sum to get the hash of the license
# we might as well test that is returning what it should because it
# doesn't call any external resources, it just calculates the hash.
open_name = 'tarball.open'
with open('tests/COPYING_TEST', 'rb') as copyingf:
content = copyingf.read()
bkup_hash = license.config.license_hashes[license.tarball.get_sha1sum('tests/COPYING_TEST')]
# remove the hash from license_hashes
del(license.config.license_hashes[license.tarball.get_sha1sum('tests/COPYING_TEST')])
license.config.license_show = "license.show.url"
m_open = mock_open(read_data=content)
with patch(open_name, m_open, create=True):
license.license_from_copying_hash('copying.txt')
# restore the hash
license.config.license_hashes[license.tarball.get_sha1sum('tests/COPYING_TEST')] = bkup_hash
self.assertEquals(license.licenses, [])
def test_license_from_copying_hash_bad_license(self):
"""
Test license_from_copying_hash with invalid license file
@@ -83,6 +107,51 @@ class TestLicense(unittest.TestCase):
self.assertEquals(license.licenses, [])
@patch('pycurl.Curl')
def test_license_from_copying_hash_license_server_excep(self, mock_pycurl_curl):
"""
Test license_from_copying_hash with license server when pycurl raises
an exception.
"""
class MockCurl():
URL = None
WRITEDATA = None
POSTFIELDS = None
FOLLOWLOCATION = 0
def setopt(_, __, ___):
pass
def perform(_):
raise Exception('Test Exception')
def close(_):
pass
# set the mock curl
license.pycurl.Curl = MockCurl
license.config.license_fetch = 'license.server.url'
with open('tests/COPYING_TEST', 'rb') as copyingf:
content = copyingf.read()
# Calls out to tarball.get_sha1sum to get the hash of the license
# we might as well test that is returning what it should because it
# doesn't call any external resources, it just calculates the hash.
# Also patch the open in license.py
m_open = mock_open(read_data=content)
with patch('tarball.open', m_open, create=True):
with patch('license.open', m_open, create=True):
# let's check that the proper thing is being printed as well
out = StringIO()
with redirect_stdout(out):
with self.assertRaises(SystemExit):
license.license_from_copying_hash('copying.txt')
self.assertIn('Failed to fetch license from ', out.getvalue())
# unset the manual mock
license.pycurl.Curl = pycurl.Curl
@patch('pycurl.Curl')
def test_license_from_copying_hash_license_server(self, mock_pycurl_curl):
"""
@@ -97,12 +166,10 @@ class TestLicense(unittest.TestCase):
return 'GPL-3.0'.encode('utf-8')
# set the mocks
mock_pycurl_curl.return_value = MagicMock()
license.BytesIO = MockBytesIO
license.config.license_fetch = 'license.server.url'
with open('tests/COPYING_TEST', 'rb') as copyingf:
# note the replace corrupting the file contents
content = copyingf.read()
# Calls out to tarball.get_sha1sum to get the hash of the license
+35 -81
View File
@@ -1,13 +1,18 @@
import os
import shutil
import mock
import unittest
import tempfile
import pkg_integrity
TESTDIR = os.path.join(os.getcwd(), "tests/testfiles/pkg_integrity")
PACKAGE_URL = "http://pkgconfig.freedesktop.org/releases/pkg-config-0.29.1.tar.gz"
XATTR_PKT_URL = "http://pypi.debian.net/xattr/xattr-0.9.1.tar.gz"
NO_SIGN_PKT_URL = "http://www.ferzkopp.net/Software/SDL_gfx-2.0/SDL_gfx-2.0.25.tar.gz"
GEM_PKT = "https://rubygems.org/downloads/hoe-debugging-1.2.1.gem"
NOSIGN_PKT_URL_BAD = "http://gnu.mirrors.pair.com/savannah/savannah/quagga/bad_quagga-1.1.0.tar.gz"
NOSIGN_PKT_URL = "http://download.savannah.gnu.org/releases/quagga/quagga-1.1.0.tar.gz"
NOSIGN_SIGN_URL = "http://download.savannah.gnu.org/releases/quagga/quagga-1.1.0.tar.gz.asc"
PYPI_MD5_ONLY_PKG = "http://pypi.debian.net/tappy/tappy-0.9.2.tar.gz"
@@ -15,36 +20,23 @@ GNOME_SHA256_PKG = "https://download.gnome.org/sources/pygobject/3.24/pygobject-
KEYID = "EC2392F2EDE74488680DA3CF5F2B4756ED873D23"
class TestGPGCli(unittest.TestCase):
def mock_attempt_to_download(path, dest=None):
if dest:
shutil.copyfile(os.path.join(TESTDIR, os.path.basename(path)), dest)
return 200
def test_import_export(self):
with pkg_integrity.cli_gpg_ctx() as ctx:
err, output = ctx.export_key(KEYID)
self.assertTrue(err is not None)
err, output = ctx.import_key(KEYID)
self.assertTrue(err is None)
err, output = ctx.export_key(KEYID)
self.assertTrue(err is None)
self.assertTrue('PGP PUBLIC KEY' in output)
def mock_head_request(url):
bad_sigs = ["http://pkgconfig.freedesktop.org/releases/pkg-config-0.29.1.tar.gz.sig",
"http://www.ferzkopp.net/Software/SDL_gfx-2.0/SDL_gfx-2.0.25.tar.gz.sig",
"http://www.ferzkopp.net/Software/SDL_gfx-2.0/SDL_gfx-2.0.25.tar.gz.asc"]
def test_import_non_existing_key(self):
with pkg_integrity.cli_gpg_ctx() as ctx:
keyid = '0' + KEYID[1:]
err, output = ctx.import_key(keyid)
self.assertTrue(err is not None)
def test_display_key_info(self):
with pkg_integrity.cli_gpg_ctx() as ctx:
err, output = ctx.import_key(KEYID)
self.assertTrue(err is None)
err, output = ctx.export_key(KEYID)
with open('key_test.pkey', 'w') as out_key:
out_key.write(output)
err, output = ctx.display_keyinfo('key_test.pkey')
os.remove('key_test.pkey')
self.assertTrue('keyid' in output)
if url in bad_sigs:
return 404
return 200
@mock.patch('pkg_integrity.attempt_to_download', mock_attempt_to_download)
@mock.patch('pkg_integrity.head_request', mock_head_request)
class TestCheckFn(unittest.TestCase):
def setUp(self):
@@ -53,8 +45,6 @@ class TestCheckFn(unittest.TestCase):
pkg_integrity.config.rewrite_config_opts = mock_rewrite
pkg_integrity.config.config_opts['verify_required'] = False
@unittest.skipIf("TRAVIS" in os.environ and os.environ["TRAVIS"] == "true",
"Skipping this test on Travis CI.")
def test_check_matching_sign_url(self):
with tempfile.TemporaryDirectory() as tmpd:
out_file = os.path.join(tmpd, os.path.basename(PACKAGE_URL))
@@ -73,6 +63,7 @@ class TestCheckFn(unittest.TestCase):
self.assertTrue(result)
@mock.patch('pkg_integrity.attempt_to_download', mock_attempt_to_download)
class TestDomainBasedVerifiers(unittest.TestCase):
def run_test_for_domain(self, Verifier, url):
@@ -85,8 +76,6 @@ class TestDomainBasedVerifiers(unittest.TestCase):
return None
@unittest.skipIf("TRAVIS" in os.environ and os.environ["TRAVIS"] == "true",
"Skipping this test on Travis CI.")
def test_pypi(self):
result = self.run_test_for_domain(pkg_integrity.PyPiVerifier, PYPI_MD5_ONLY_PKG)
self.assertTrue(result)
@@ -96,6 +85,7 @@ class TestDomainBasedVerifiers(unittest.TestCase):
self.assertTrue(result)
@mock.patch('pkg_integrity.attempt_to_download', mock_attempt_to_download)
class TestGEMShaVerifier(unittest.TestCase):
def setUp(self):
@@ -122,6 +112,8 @@ class TestGEMShaVerifier(unittest.TestCase):
self.assertEqual(a.exception.code, 1)
@mock.patch('pkg_integrity.attempt_to_download', mock_attempt_to_download)
@mock.patch('pkg_integrity.head_request', mock_head_request)
class TestGPGVerifier(unittest.TestCase):
def setUp(self):
@@ -130,8 +122,6 @@ class TestGPGVerifier(unittest.TestCase):
pkg_integrity.config.rewrite_config_opts = mock_rewrite
pkg_integrity.config.config_opts['verify_required'] = False
@unittest.skipIf("TRAVIS" in os.environ and os.environ["TRAVIS"] == "true",
"Skipping this test on Travis CI.")
def test_from_url(self):
with tempfile.TemporaryDirectory() as tmpd:
out_file = os.path.join(tmpd, os.path.basename(PACKAGE_URL))
@@ -143,12 +133,14 @@ class TestGPGVerifier(unittest.TestCase):
def test_check_quit(self):
with tempfile.TemporaryDirectory() as tmpd:
#with self.assertRaises(SystemExit) as a:
pkg_integrity.check(NO_SIGN_PKT_URL, tmpd, interactive=False)
#self.assertEqual(a.exception.code, 1)
with self.assertRaises(SystemExit) as a:
out_file = os.path.join(tmpd, os.path.basename(NOSIGN_PKT_URL_BAD))
pkg_integrity.attempt_to_download(NOSIGN_PKT_URL_BAD, out_file)
key_file = os.path.join(tmpd, os.path.basename(NOSIGN_PKT_URL_BAD))
pkg_integrity.attempt_to_download(NOSIGN_SIGN_URL, key_file + '.asc')
result = pkg_integrity.check(NOSIGN_PKT_URL_BAD, tmpd)
self.assertEqual(a.exception.code, 1)
@unittest.skipIf("TRAVIS" in os.environ and os.environ["TRAVIS"] == "true",
"Skipping this test on Travis CI.")
def test_from_disk(self):
with tempfile.TemporaryDirectory() as tmpd:
out_file = os.path.join(tmpd, os.path.basename(PACKAGE_URL))
@@ -158,8 +150,6 @@ class TestGPGVerifier(unittest.TestCase):
result = pkg_integrity.from_disk(PACKAGE_URL, out_file, out_key)
self.assertTrue(result)
@unittest.skipIf("TRAVIS" in os.environ and os.environ["TRAVIS"] == "true",
"Skipping this test on Travis CI.")
def test_non_matchingsig(self):
with tempfile.TemporaryDirectory() as tmpd:
out_file = os.path.join(tmpd, os.path.basename(PACKAGE_URL))
@@ -174,35 +164,14 @@ class TestGPGVerifier(unittest.TestCase):
result = pkg_integrity.from_disk('http://nokey.com/package.tar.gz',
'NonExistentPKG.tar.gz',
'NonExistentKey.asc')
self.assertTrue(result is None)
self.assertIsNone(result)
def test_result_on_nosign_package(self):
with tempfile.TemporaryDirectory() as tmpd:
out_file = os.path.join(tmpd, os.path.basename(NO_SIGN_PKT_URL))
pkg_integrity.attempt_to_download(NO_SIGN_PKT_URL, out_file)
result = pkg_integrity.check(NO_SIGN_PKT_URL, tmpd)
self.assertTrue(result is None)
@unittest.skipIf("TRAVIS" in os.environ and os.environ["TRAVIS"] == "true",
"Skipping this test on Travis CI.")
def test_pubkey_import(self):
def say_yes(_):
return True
_ = pkg_integrity.InputGetter.get_answer
pkg_integrity.InputGetter.get_answer = say_yes
keyid = '0' + KEYID[1:]
result = pkg_integrity.attempt_key_import(keyid)
self.assertTrue(result is False)
result = pkg_integrity.attempt_key_import(KEYID)
self.assertTrue(result)
pkg_integrity.InputGetter.get_answer = _
self.removeKey()
def removeKey(self):
key_path = os.path.dirname(os.path.realpath(__file__))
key_path = os.path.dirname(key_path) + '/autospec/keyring/{}.pkey'.format(KEYID)
if os.path.exists(key_path):
os.unlink(key_path)
self.assertIsNone(result)
class TestInputGetter(unittest.TestCase):
@@ -212,12 +181,14 @@ class TestInputGetter(unittest.TestCase):
def test_timput(self):
ig = pkg_integrity.InputGetter(default='N', timeout=2)
answer = ig.get_answer()
self.assertTrue(answer is None)
self.assertIsNone(answer)
ig = pkg_integrity.InputGetter(default='Y', timeout=2)
answer = ig.get_answer()
self.assertTrue(answer is None)
self.assertIsNone(answer)
@mock.patch('pkg_integrity.attempt_to_download', mock_attempt_to_download)
@mock.patch('pkg_integrity.head_request', mock_head_request)
class TestUtils(unittest.TestCase):
def setUp(self):
@@ -252,23 +223,6 @@ class TestUtils(unittest.TestCase):
false_name = '/false/name'
self.assertTrue(pkg_integrity.get_keyid(false_name) is None)
@unittest.skipIf("TRAVIS" in os.environ and os.environ["TRAVIS"] == "true",
"Skipping this test on Travis CI.")
def test_attempt_to_download(self):
fakeURL = "https://download.my.url.com/file.tar.gz"
realURLnoFile = "http://pypi.debian.net/alembic/alembic-0.8.8.non-existent.tar.gz"
realURL = "http://pypi.debian.net/alembic/alembic-0.8.8.tar.gz"
tmpf = tempfile.NamedTemporaryFile()
fname = tmpf.name
tmpf.close()
self.assertEqual(pkg_integrity.attempt_to_download(fakeURL, fname), None)
self.assertEqual(pkg_integrity.attempt_to_download(realURLnoFile, fname), 404)
self.assertEqual(pkg_integrity.attempt_to_download(realURL, fname), 200)
os.unlink(fname)
def test_get_signature_url(self):
url_from_gnu = "http://ftp.gnu.org/pub/gnu/gperf/gperf-3.0.4.tar.gz"
+10 -26
View File
@@ -3,6 +3,7 @@ import unittest
from unittest.mock import patch, Mock, mock_open, call
import build # needs to be imported before tarball due to dependencies
import tarball
import re
class FileManager():
@@ -27,10 +28,17 @@ def test_generator(url, name, version):
"""
tarball.name = ''
tarball.version = ''
tarball.giturl = ''
tarball.url = url
tarball.name_and_version('', '', FileManager())
self.assertEqual(tarball.name, name)
self.assertEqual(tarball.version, version)
self.assertEqual(name, tarball.name)
self.assertEqual(version, tarball.version)
if re.match("https?://github.com", url) != None:
self.assertIsNotNone(tarball.giturl)
self.assertNotEqual('', tarball.giturl, "giturl should not be empty")
self.assertIsNotNone(
re.match("https://github.com/[^/]+/"+tarball.repo+".git",
tarball.giturl), "%s looks incorrect" % tarball.giturl)
return test_packageurl
@@ -160,30 +168,6 @@ class TestTarballVersionName(unittest.TestCase):
tarball.build_gem_unpack = build_gem_unpack_backup
tarball.build_untar = build_untar_backup
def test_write_makefile(self):
"""
Test write_makefile for correct archive format
"""
archives = ['archive1', 'dest1', 'archive2', 'dest2']
build.download_path = '.'
tarball.name = 'test'
tarball.url = 'url'
m_open = mock_open()
with patch('tarball.open', m_open, create=True):
tarball.write_makefile(archives)
exp_calls = [call().write('PKG_NAME := test\n'),
call().write('URL := url\n'),
call().write('ARCHIVES := archive1'),
call().write(' dest1'),
call().write(' \\\n\tarchive2'),
call().write(' dest2'),
call().write('\n'),
call().write('\n'),
call().write('include ../common/Makefile.common\n')]
for m_call in exp_calls:
self.assertIn(m_call, m_open.mock_calls)
TAR_OUT = 'libjpeg-turbo-1.5.1/\n' \
'libjpeg-turbo-1.5.1/md5/\n' \
@@ -0,0 +1,30 @@
ROS_SPN = "catkin"
require catkin.inc
SRC_URI += "\
file://0001-ignore-LD_LIBRARY_PATH-set-in-environment_cache.py.patch \
"
S = "${WORKDIR}/catkin-${PV}"
# This package includes ONLY the python packages AND catkin_find
# The catkin_${PV} package includes all other files
# from the catkin tool.
FILES_${PN} = "${PYTHON_SITEPACKAGES_DIR} ${ros_bindir}/catkin_find"
RDEPENDS_${PN}_class-native = ""
RDEPENDS_${PN} = "\
${PYTHON_PN}-catkin-pkg ${PYTHON_PN}-argparse ${PYTHON_PN}-misc ${PYTHON_PN}-multiprocessing \
${PYTHON_PN}-shell ${PYTHON_PN}-subprocess ${PYTHON_PN}-xml ${PYTHON_PN}-pkgutil"
# Delete everything but the python packages in order to avoid
# that the QA error [installed-vs-shipped] hits on us.
do_install_append() {
rm ${D}${ros_bindir}/catkin_*_*
rm ${D}${ros_bindir}/catkin_make
rm -rf ${D}${ros_datadir}
rm -rf ${D}${ros_libdir}/pkgconfig
}
BBCLASSEXTEND += "native"
+32
View File
@@ -0,0 +1,32 @@
DESCRIPTION = "Low-level build system macros and infrastructure for ROS"
SECTION = "devel"
LICENSE = "BSD"
LIC_FILES_CHKSUM = "file://package.xml;beginline=7;endline=7;md5=d566ef916e9dedc494f5f793a6690ba5"
DEPENDS = "cmake ${PYTHON_PN}-empy-native ${PYTHON_PN}-catkin-pkg-native"
SRC_URI = "https://github.com/ros/${ROS_SPN}/archive/${PV}.tar.gz;downloadfilename=${ROS_SP}.tar.gz"
SRC_URI[md5sum] = "d58460cc9112812d8c4e6ecf98bbcc85"
SRC_URI[sha256sum] = "90a639d67db7f9039487af555e432a5b4b6e339f22892d75d03b823b3f38c947"
SRC_URI += "\
file://0001-CATKIN_WORKSPACES-Don-t-require-.catkin-file.patch \
file://0001-use-python-provided-by-environment-instead-of-the-ge.patch \
file://0001-avoid-using-host-s-paths-when-cross-compiling.patch \
file://0001-relocate-dependency-s-headers-to-current-sysroot.patch \
${@'file://0001-python.cmake-look-for-python3-first.patch' if d.getVar('PYTHON_PN', True) == 'python3' else ''} \
"
inherit catkin
FILES_${PN}-dev += "\
${ros_datadir}/eigen/cmake \
${ros_datadir}/ros/cmake \
${ros_datadir}/.catkin \
${ros_prefix}/.catkin \
${ros_prefix}/.rosinstall \
${ros_prefix}/_setup_util.py \
${ros_prefix}/env.sh \
${ros_prefix}/setup.* \
"
+20
View File
@@ -0,0 +1,20 @@
require catkin.inc
DEPENDS_class-native += "catkin-runtime"
RDEPENDS_${PN}_class-native = "${PYTHON_PN}-catkin-pkg"
RDEPENDS_${PN} = "cmake make binutils binutils-symlinks gcc gcc-symlinks g++ g++-symlinks \
catkin-runtime"
# The files in ${PYTHON_SITEPACKAGES_DIR} and catkin_find are
# installed by the catkin-runtime package. Therefore, we remove
# them here so that they are not installed.
# Moreover: the ${ros_libdir}/python2.7 is empty. We need to
# remove it, otherwise the QA error [installed-vs-shipped] will hit on us.
do_install_append() {
rm ${D}${ros_bindir}/catkin_find
rm -rf ${D}${PYTHON_SITEPACKAGES_DIR}
rmdir ${D}${ros_libdir}/${PYTHON_DIR}
}
BBCLASSEXTEND += "native"
+22
View File
@@ -0,0 +1,22 @@
SUMMARY = "htop process monitor"
HOMEPAGE = "http://htop.sf.net"
SECTION = "console/utils"
LICENSE = "GPLv2"
LIC_FILES_CHKSUM = "file://COPYING;md5=c312653532e8e669f30e5ec8bdc23be3"
DEPENDS = "ncurses"
RDEPENDS_${PN} = "ncurses-terminfo"
SRC_URI = "http://hisham.hm/htop/releases/${PV}/htop-${PV}.tar.gz"
SRC_URI[md5sum] = "e768b9b55c033d9c1dffda72db3a6ac7"
SRC_URI[sha256sum] = "055c57927f75847fdc222b5258b079a9542811a9dcf5421c615c7e17f55d1829"
LDFLAGS_append_libc-uclibc = " -lubacktrace"
do_configure_prepend () {
rm -rf ${S}/config.h
}
inherit autotools
+17
View File
@@ -0,0 +1,17 @@
ONE ??= "first value"
ONE ?= "second value"
TWO ?= "first value"
TWO ??= "second value"
THREE ??= "first value"
THREE ?= "second value"
THREE = "third value"
FOUR = "first value"
FOUR += "second value"
FOUR =+ "third value"
FIVE = "first value"
FIVE .= "second value"
FIVE =. "third value"
+112
View File
@@ -0,0 +1,112 @@
SUMMARY = "Vi IMproved - enhanced vi editor"
SECTION = "console/utils"
DEPENDS = "ncurses gettext-native"
# vimdiff doesn't like busybox diff
RSUGGESTS_${PN} = "diffutils"
LICENSE = "vim"
LIC_FILES_CHKSUM = "file://../runtime/doc/uganda.txt;md5=eea32ac1424bba14096736a494ae9045"
SRC_URI = "git://github.com/vim/vim.git \
file://disable_acl_header_check.patch;patchdir=.. \
file://vim-add-knob-whether-elf.h-are-checked.patch;patchdir=.. \
"
SRCREV = "3f9a1ff141412e9e85f7dff47d02946cb9be9228"
S = "${WORKDIR}/git/src"
VIMDIR = "vim${@d.getVar('PV').split('.')[0]}${@d.getVar('PV').split('.')[1]}"
inherit autotools update-alternatives
inherit autotools-brokensep
# vim configure.in contains functions which got 'dropped' by autotools.bbclass
do_configure () {
rm -f auto/*
touch auto/config.mk
aclocal
autoconf
oe_runconf
touch auto/configure
touch auto/config.mk auto/config.h
}
#Available PACKAGECONFIG options are gtkgui, acl, x11, tiny
PACKAGECONFIG ??= ""
PACKAGECONFIG += "${@bb.utils.filter('DISTRO_FEATURES', 'acl selinux', d)}"
PACKAGECONFIG[gtkgui] = "--enable-gtk2-test --enable-gui=gtk2,--enable-gui=no,gtk+,"
PACKAGECONFIG[acl] = "--enable-acl,--disable-acl,acl,"
PACKAGECONFIG[x11] = "--with-x,--without-x,xt,"
PACKAGECONFIG[tiny] = "--with-features=tiny,--with-features=big,,"
PACKAGECONFIG[selinux] = "--enable-selinux,--disable-selinux,libselinux,"
PACKAGECONFIG[elfutils] = "--enable-elf-check,,elfutils,"
EXTRA_OECONF = " \
--disable-gpm \
--disable-gtktest \
--disable-xim \
--disable-netbeans \
--with-tlib=ncurses \
ac_cv_small_wchar_t=no \
vim_cv_getcwd_broken=no \
vim_cv_memmove_handles_overlap=yes \
vim_cv_stat_ignores_slash=no \
vim_cv_terminfo=yes \
vim_cv_tgent=non-zero \
vim_cv_toupper_broken=no \
vim_cv_tty_group=world \
STRIP=/bin/true \
"
do_install() {
autotools_do_install
# Work around file-rdeps picking up csh, awk, perl or python as a dep
chmod -x ${D}${datadir}/${BPN}/${VIMDIR}/tools/vim132
chmod -x ${D}${datadir}/${BPN}/${VIMDIR}/tools/mve.awk
chmod -x ${D}${datadir}/${BPN}/${VIMDIR}/tools/*.pl
chmod -x ${D}${datadir}/${BPN}/${VIMDIR}/tools/*.py
# Install example vimrc from runtime files
install -m 0644 ../runtime/vimrc_example.vim ${D}/${datadir}/${BPN}/vimrc
# we use --with-features=big as default
mv ${D}${bindir}/${BPN} ${D}${bindir}/${BPN}.${BPN}
}
PARALLEL_MAKEINST = ""
PACKAGES =+ "${PN}-common ${PN}-syntax ${PN}-help ${PN}-tutor ${PN}-vimrc ${PN}-tools"
FILES_${PN}-syntax = "${datadir}/${BPN}/${VIMDIR}/syntax"
FILES_${PN}-help = "${datadir}/${BPN}/${VIMDIR}/doc"
FILES_${PN}-tutor = "${datadir}/${BPN}/${VIMDIR}/tutor ${bindir}/${BPN}tutor"
FILES_${PN}-vimrc = "${datadir}/${BPN}/vimrc"
FILES_${PN}-data = "${datadir}/${BPN}"
FILES_${PN}-tools = "${datadir}/${BPN}/${VIMDIR}/tools"
FILES_${PN}-common = " \
${datadir}/${BPN}/${VIMDIR}/*.vim \
${datadir}/${BPN}/${VIMDIR}/autoload \
${datadir}/${BPN}/${VIMDIR}/colors \
${datadir}/${BPN}/${VIMDIR}/compiler \
${datadir}/${BPN}/${VIMDIR}/ftplugin \
${datadir}/${BPN}/${VIMDIR}/indent \
${datadir}/${BPN}/${VIMDIR}/keymap \
${datadir}/${BPN}/${VIMDIR}/lang \
${datadir}/${BPN}/${VIMDIR}/macros \
${datadir}/${BPN}/${VIMDIR}/plugin \
${datadir}/${BPN}/${VIMDIR}/print \
${datadir}/${BPN}/${VIMDIR}/spell \
${datadir}/icons \
"
RDEPENDS_${BPN} = "ncurses-terminfo-base"
# Recommend that runtime data is installed along with vim
RRECOMMENDS_${BPN} = "${PN}-syntax ${PN}-help ${PN}-tutor ${PN}-vimrc ${PN}-common"
ALTERNATIVE_${PN} = "vi vim"
ALTERNATIVE_TARGET = "${bindir}/${BPN}.${BPN}"
ALTERNATIVE_LINK_NAME[vi] = "${base_bindir}/vi"
ALTERNATIVE_LINK_NAME[vim] = "${bindir}/vim"
ALTERNATIVE_PRIORITY = "100"
BBCLASSEXTEND = "native"
-9
View File
@@ -1,9 +0,0 @@
DESTDIR ?=
PREFIX ?= /usr/local
helloworld:
gcc main.c -o helloworld
install: helloworld
install -m 0755 -d $(DESTDIR)$(PREFIX)/bin
install -m 0755 helloworld $(DESTDIR)$(PREFIX)/bin
@@ -1,3 +0,0 @@
# This file contains additional build requirements that did not get
# picked up automatically. One name per line, no whitespace.
xz
@@ -1,2 +0,0 @@
# This file contains build requirements that get picked up but are
# undesirable. One entry per line, no whitespace.
@@ -1 +0,0 @@
GPL-3.0
@@ -1,11 +0,0 @@
[autospec]
32bit = true
allow_test_failures = false
asneeded = false
broken_c++ = false
broken_parallel_build = false
conservative_flags = false
fast-math = false
funroll-loops = false
insecure_build = false
@@ -1,2 +0,0 @@
# This file contains additional pkgconfig build requirements that did
# not get picked up automatically. One name per line, no whitespace.
@@ -1,2 +0,0 @@
# This file contains pkgconfig build requirements that get picked up
# but are undesirable. One entry per line, no whitespace.
@@ -1,44 +0,0 @@
[autospec]
# build 32 bit libraries
32bit = true
# allow package to build with test failures
allow_test_failures = false
# unset %build ld_as_needed variable
asneeded = false
# extend flags with '-std=gnu++98
broken_c++ = false
# disable parallelization during build
broken_parallel_build = false
# set conservative build flags
conservative_flags = false
# pass -ffast-math to compiler
fast-math = false
# optimize build for speed over size
funroll-loops = false
# set flags to smallest -02 flags possible
insecure_build = false
# do not remove static libraries
keepstatic = false
# do not require autostart subpackage
no_autostart = false
# disable stripping binaries
nostrip = false
# optimize build for size over speed
optimize_size = false
# set profile for pgo
pgo = false
# set flags for security-sensitive builds
security_sensitive = false
# do not run test suite
skip_tests = false
# add .so files to the lib package instead of dev
so_to_lib = false
# configure build for avx2
use_avx2 = false
# add clang flags
use_clang = false
# configure build for lto
use_lto = false
# require package verification for build
verify_required = false
@@ -1,23 +0,0 @@
"""
This file, expectations.py, defines expected test results and is not added to
the test source tarball.
"""
import os
buildreqs = ['xz',
'gcc-dev32',
'gcc-libgcc32',
'gcc-libstdc++32',
'glibc-dev32',
'glibc-libc32']
license = 'GPL-3.0'
with open('tests/testfiles/c-helloworld-32/spec-expectations', 'r') as spec:
specfile = spec.read()
specfile = specfile.replace('{}', os.getcwd()).split('\n')
with open('tests/testfiles/c-helloworld-32/conf-expectations', 'r') as conf:
conffile = conf.read()
conffile = conffile.split('\n')
output_strings = []
-3
View File
@@ -1,3 +0,0 @@
#include<stdio.h>
int main(){printf("Hello World\n");}
@@ -1,53 +0,0 @@
#
# This file is auto-generated. DO NOT EDIT
# Generated by: autospec.py
#
Name : c-helloworld-32
Version : 32
Release : 1
URL : file://{}/tests/testfiles/c-helloworld-32.tar.gz
Source0 : file://{}/tests/testfiles/c-helloworld-32.tar.gz
Summary : No detailed summary available
Group : Development/Tools
License : GPL-3.0
BuildRequires : gcc-dev32
BuildRequires : gcc-libgcc32
BuildRequires : gcc-libstdc++32
BuildRequires : glibc-dev32
BuildRequires : glibc-libc32
BuildRequires : xz
%description
No detailed description available
%prep
%setup -q -n c-helloworld-32
pushd ..
cp -a c-helloworld-32 build32
popd
%build
export http_proxy=http://127.0.0.1:9/
export https_proxy=http://127.0.0.1:9/
export no_proxy=localhost,127.0.0.1,0.0.0.0
export LANG=C
export SOURCE_DATE_EPOCH=1
make V=1 %{?_smp_mflags}
%install
export SOURCE_DATE_EPOCH=1
rm -rf %{buildroot}
pushd ../build32/
%make_install32
if [ -d %{buildroot}/usr/lib32/pkgconfig ]
then
pushd %{buildroot}/usr/lib32/pkgconfig
for i in *.pc ; do ln -s $i 32$i ; done
popd
fi
popd
%make_install
%files
%defattr(-,root,root,-)
/usr/local/bin/helloworld
@@ -1,12 +0,0 @@
DESTDIR ?=
PREFIX ?= /usr/local
helloworld:
gcc main.c -o helloworld
clean:
rm helloworld
install: helloworld
install -m 0755 -d $(DESTDIR)$(PREFIX)/bin
install -m 0755 helloworld $(DESTDIR)$(PREFIX)/bin
@@ -1 +0,0 @@
These README.clear contents should be printed on a successful autospec run.
@@ -1,3 +0,0 @@
# This file contains additional build requirements that did not get
# picked up automatically. One name per line, no whitespace.
xz
@@ -1,2 +0,0 @@
# This file contains build requirements that get picked up but are
# undesirable. One entry per line, no whitespace.
@@ -1 +0,0 @@
GPL-3.0
@@ -1,2 +0,0 @@
# This file contains additional pkgconfig build requirements that did
# not get picked up automatically. One name per line, no whitespace.
@@ -1,2 +0,0 @@
# This file contains pkgconfig build requirements that get picked up
# but are undesirable. One entry per line, no whitespace.
@@ -1,44 +0,0 @@
[autospec]
# build 32 bit libraries
32bit = false
# allow package to build with test failures
allow_test_failures = true
# unset %build ld_as_needed variable
asneeded = true
# extend flags with '-std=gnu++98
broken_c++ = true
# disable parallelization during build
broken_parallel_build = false
# set conservative build flags
conservative_flags = false
# pass -ffast-math to compiler
fast-math = true
# optimize build for speed over size
funroll-loops = true
# set flags to smallest -02 flags possible
insecure_build = false
# do not remove static libraries
keepstatic = true
# do not require autostart subpackage
no_autostart = true
# disable stripping binaries
nostrip = false
# optimize build for size over speed
optimize_size = true
# set profile for pgo
pgo = false
# set flags for security-sensitive builds
security_sensitive = true
# do not run test suite
skip_tests = true
# add .so files to the lib package instead of dev
so_to_lib = false
# configure build for avx2
use_avx2 = false
# add clang flags
use_clang = false
# configure build for lto
use_lto = true
# require package verification for build
verify_required = false
@@ -1,17 +0,0 @@
"""
This file, expectations.py, defines expected test results and is not added to
the test source tarball.
"""
import os
buildreqs = ['xz']
license = 'GPL-3.0'
with open('tests/testfiles/c-helloworld-opts/spec-expectations', 'r') as spec:
specfile = spec.read()
specfile = specfile.replace('{}', os.getcwd()).split('\n')
with open('tests/testfiles/c-helloworld-opts/conf-expectations', 'r') as conf:
conffile = conf.read()
conffile = conffile.split('\n')
output_strings = ['These README.clear contents should be printed on a successful autospec run.']
-3
View File
@@ -1,3 +0,0 @@
#include<stdio.h>
int main(){printf("Hello World\n");}
@@ -1,45 +0,0 @@
#
# This file is auto-generated. DO NOT EDIT
# Generated by: autospec.py
#
%define keepstatic 1
Name : c-helloworld-opts
Version : 1
Release : 1
URL : file://{}/tests/testfiles/c-helloworld-opts.tar.gz
Source0 : file://{}/tests/testfiles/c-helloworld-opts.tar.gz
Summary : No detailed summary available
Group : Development/Tools
License : GPL-3.0
BuildRequires : xz
%description
No detailed description available
%prep
%setup -q -n c-helloworld-opts
%build
export http_proxy=http://127.0.0.1:9/
export https_proxy=http://127.0.0.1:9/
export no_proxy=localhost,127.0.0.1,0.0.0.0
export LANG=C
export SOURCE_DATE_EPOCH=1
unset LD_AS_NEEDED
export AR=gcc-ar
export RANLIB=gcc-ranlib
export NM=gcc-nm
export CFLAGS="$CFLAGS -O3 -Os -falign-functions=32 -fdata-sections -ffast-math -ffat-lto-objects -ffunction-sections -flto -fno-semantic-interposition -fstack-protector-strong -ftree-loop-vectorize "
export FCFLAGS="$CFLAGS -O3 -Os -falign-functions=32 -fdata-sections -ffast-math -ffat-lto-objects -ffunction-sections -flto -fno-semantic-interposition -fstack-protector-strong -ftree-loop-vectorize "
export FFLAGS="$CFLAGS -O3 -Os -falign-functions=32 -fdata-sections -ffast-math -ffat-lto-objects -ffunction-sections -flto -fno-semantic-interposition -fstack-protector-strong -ftree-loop-vectorize "
export CXXFLAGS="$CXXFLAGS -O3 -Os -falign-functions=32 -fdata-sections -ffast-math -ffat-lto-objects -ffunction-sections -flto -fno-semantic-interposition -fstack-protector-strong -ftree-loop-vectorize -std=gnu++98"
make V=1 %{?_smp_mflags}
%install
export SOURCE_DATE_EPOCH=1
rm -rf %{buildroot}
%make_install
%files
%defattr(-,root,root,-)
/usr/local/bin/helloworld
-9
View File
@@ -1,9 +0,0 @@
DESTDIR ?=
PREFIX ?= /usr/local
helloworld:
gcc main.c -o helloworld
install: helloworld
install -m 0755 -d $(DESTDIR)$(PREFIX)/bin
install -m 0755 helloworld $(DESTDIR)$(PREFIX)/bin
@@ -1,3 +0,0 @@
# This file contains additional build requirements that did not get
# picked up automatically. One name per line, no whitespace.
xz
@@ -1,2 +0,0 @@
# This file contains build requirements that get picked up but are
# undesirable. One entry per line, no whitespace.
@@ -1 +0,0 @@
GPL-3.0
@@ -1,10 +0,0 @@
[autospec]
allow_test_failures = false
asneeded = false
broken_c++ = false
broken_parallel_build = false
conservative_flags = false
fast-math = false
funroll-loops = false
insecure_build = false
@@ -1,2 +0,0 @@
# This file contains additional pkgconfig build requirements that did
# not get picked up automatically. One name per line, no whitespace.
@@ -1,2 +0,0 @@
# This file contains pkgconfig build requirements that get picked up
# but are undesirable. One entry per line, no whitespace.
@@ -1,44 +0,0 @@
[autospec]
# build 32 bit libraries
32bit = false
# allow package to build with test failures
allow_test_failures = false
# unset %build ld_as_needed variable
asneeded = false
# extend flags with '-std=gnu++98
broken_c++ = false
# disable parallelization during build
broken_parallel_build = false
# set conservative build flags
conservative_flags = false
# pass -ffast-math to compiler
fast-math = false
# optimize build for speed over size
funroll-loops = false
# set flags to smallest -02 flags possible
insecure_build = false
# do not remove static libraries
keepstatic = false
# do not require autostart subpackage
no_autostart = false
# disable stripping binaries
nostrip = false
# optimize build for size over speed
optimize_size = false
# set profile for pgo
pgo = false
# set flags for security-sensitive builds
security_sensitive = false
# do not run test suite
skip_tests = false
# add .so files to the lib package instead of dev
so_to_lib = false
# configure build for avx2
use_avx2 = false
# add clang flags
use_clang = false
# configure build for lto
use_lto = false
# require package verification for build
verify_required = false
@@ -1,17 +0,0 @@
"""
This file, expectations.py, defines expected test results and is not added to
the test source tarball.
"""
import os
buildreqs = ['xz']
license = 'GPL-3.0'
with open('tests/testfiles/c-helloworld/spec-expectations', 'r') as spec:
specfile = spec.read()
specfile = specfile.replace('{}', os.getcwd()).split('\n')
with open('tests/testfiles/c-helloworld/conf-expectations', 'r') as conf:
conffile = conf.read()
conffile = conffile.split('\n')
output_strings = []
-3
View File
@@ -1,3 +0,0 @@
#include<stdio.h>
int main(){printf("Hello World\n");}
@@ -1,36 +0,0 @@
#
# This file is auto-generated. DO NOT EDIT
# Generated by: autospec.py
#
Name : c-helloworld
Version : 1
Release : 1
URL : file://{}/tests/testfiles/c-helloworld.tar.gz
Source0 : file://{}/tests/testfiles/c-helloworld.tar.gz
Summary : No detailed summary available
Group : Development/Tools
License : GPL-3.0
BuildRequires : xz
%description
No detailed description available
%prep
%setup -q -n c-helloworld
%build
export http_proxy=http://127.0.0.1:9/
export https_proxy=http://127.0.0.1:9/
export no_proxy=localhost,127.0.0.1,0.0.0.0
export LANG=C
export SOURCE_DATE_EPOCH=1
make V=1 %{?_smp_mflags}
%install
export SOURCE_DATE_EPOCH=1
rm -rf %{buildroot}
%make_install
%files
%defattr(-,root,root,-)
/usr/local/bin/helloworld
-857
View File
@@ -1,857 +0,0 @@
Building on Un*x Platforms (including Cygwin and OS X)
=======================================================
Build Requirements
------------------
- autoconf 2.56 or later
- automake 1.7 or later
- libtool 1.4 or later
* If using Xcode 4.3 or later on OS X, autoconf and automake are no longer
provided. The easiest way to obtain them is from
[MacPorts](http://www.MacPorts.org).
- NASM or YASM (if building x86 or x86-64 SIMD extensions)
* If using NASM, 0.98, or 2.01 or later is required for an x86 build (0.99
and 2.00 do not work properly with libjpeg-turbo's x86 SIMD code.)
* If using NASM, 2.00 or later is required for an x86-64 build.
* If using NASM, 2.07 or later (except 2.11.08) is required for an x86-64
Mac build (2.11.08 does not work properly with libjpeg-turbo's x86-64 SIMD
code when building macho64 objects.) NASM or YASM can be obtained from
[MacPorts](http://www.macports.org/).
The binary RPMs released by the NASM project do not work on older Linux
systems, such as Red Hat Enterprise Linux 4. On such systems, you can
easily build and install NASM from a source RPM by downloading one of the
SRPMs from
<http://www.nasm.us/pub/nasm/releasebuilds>
and executing the following as root:
ARCH=`uname -m`
rpmbuild --rebuild nasm-{version}.src.rpm
rpm -Uvh /usr/src/redhat/RPMS/$ARCH/nasm-{version}.$ARCH.rpm
NOTE: the NASM build will fail if texinfo is not installed.
- GCC v4.1 (or later) or clang recommended for best performance
- If building the TurboJPEG Java wrapper, JDK or OpenJDK 1.5 or later is
required. Some systems, such as Solaris 10 and later and Red Hat Enterprise
Linux 5 and later, have this pre-installed. On OS X 10.5 and 10.6, it will
be necessary to install the Java Developer Package, which can be downloaded
from <http://developer.apple.com/downloads> (Apple ID required.) For other
systems, you can obtain the Oracle Java Development Kit from
<http://www.java.com>.
Out-of-Tree Builds
------------------
Binary objects, libraries, and executables are generated in the same directory
from which `configure` was executed (the "binary directory"), and this
directory need not necessarily be the same as the libjpeg-turbo source
directory. You can create multiple independent binary directories, in which
different versions of libjpeg-turbo can be built from the same source tree
using different compilers or settings. In the sections below,
*{build_directory}* refers to the binary directory, whereas
*{source_directory}* refers to the libjpeg-turbo source directory. For in-tree
builds, these directories are the same.
Building libjpeg-turbo
----------------------
The following procedure will build libjpeg-turbo on Linux, FreeBSD, Cygwin, and
Solaris/x86 systems (on Solaris, this generates a 32-bit library. See below
for 64-bit build instructions.)
cd {source_directory}
autoreconf -fiv
cd {build_directory}
sh {source_directory}/configure [additional configure flags]
make
NOTE: Running autoreconf in the source directory is not necessary if building
libjpeg-turbo from one of the official release tarballs.
This will generate the following files under .libs/:
**libjpeg.a**
Static link library for the libjpeg API
**libjpeg.so.{version}** (Linux, Unix)
**libjpeg.{version}.dylib** (OS X)
**cygjpeg-{version}.dll** (Cygwin)
Shared library for the libjpeg API
By default, *{version}* is 62.1.0, 7.1.0, or 8.0.2, depending on whether
libjpeg v6b (default), v7, or v8 emulation is enabled. If using Cygwin,
*{version}* is 62, 7, or 8.
**libjpeg.so** (Linux, Unix)
**libjpeg.dylib** (OS X)
Development symlink for the libjpeg API
**libjpeg.dll.a** (Cygwin)
Import library for the libjpeg API
**libturbojpeg.a**
Static link library for the TurboJPEG API
**libturbojpeg.so.0.1.0** (Linux, Unix)
**libturbojpeg.0.1.0.dylib** (OS X)
**cygturbojpeg-0.dll** (Cygwin)
Shared library for the TurboJPEG API
**libturbojpeg.so** (Linux, Unix)
**libturbojpeg.dylib** (OS X)
Development symlink for the TurboJPEG API
**libturbojpeg.dll.a** (Cygwin)
Import library for the TurboJPEG API
### libjpeg v7 or v8 API/ABI Emulation
Add `--with-jpeg7` to the `configure` command line to build a version of
libjpeg-turbo that is API/ABI-compatible with libjpeg v7. Add `--with-jpeg8`
to the `configure` command to build a version of libjpeg-turbo that is
API/ABI-compatible with libjpeg v8. See [README.md](README.md) for more
information on libjpeg v7 and v8 emulation.
### In-Memory Source/Destination Managers
When using libjpeg v6b or v7 API/ABI emulation, add `--without-mem-srcdst` to
the `configure` command line to build a version of libjpeg-turbo that lacks the
`jpeg_mem_src()` and `jpeg_mem_dest()` functions. These functions were not
part of the original libjpeg v6b and v7 APIs, so removing them ensures strict
conformance with those APIs. See [README.md](README.md) for more information.
### Arithmetic Coding Support
Since the patent on arithmetic coding has expired, this functionality has been
included in this release of libjpeg-turbo. libjpeg-turbo's implementation is
based on the implementation in libjpeg v8, but it works when emulating libjpeg
v7 or v6b as well. The default is to enable both arithmetic encoding and
decoding, but those who have philosophical objections to arithmetic coding can
add `--without-arith-enc` or `--without-arith-dec` to the `configure` command
line to disable encoding or decoding (respectively.)
### TurboJPEG Java Wrapper
Add `--with-java` to the `configure` command line to incorporate an optional
Java Native Interface wrapper into the TurboJPEG shared library and build the
Java front-end classes to support it. This allows the TurboJPEG shared library
to be used directly from Java applications. See [java/README](java/README) for
more details.
You can set the `JAVAC`, `JAR`, and `JAVA` configure variables to specify
alternate commands for javac, jar, and java (respectively.) You can also
set the `JAVACFLAGS` configure variable to specify arguments that should be
passed to the Java compiler when building the front-end classes, and
`JNI_CFLAGS` to specify arguments that should be passed to the C compiler when
building the JNI wrapper. Run `configure --help` for more details.
Installing libjpeg-turbo
------------------------
If you intend to install these libraries and the associated header files, then
replace 'make' in the instructions above with
make install prefix={base dir} libdir={library directory}
For example,
make install prefix=/usr/local libdir=/usr/local/lib64
will install the header files in /usr/local/include and the library files in
/usr/local/lib64. If `prefix` and `libdir` are not specified, then the default
is to install the header files in /opt/libjpeg-turbo/include and the library
files in /opt/libjpeg-turbo/lib32 (32-bit) or /opt/libjpeg-turbo/lib64
(64-bit.)
NOTE: You can specify a prefix of /usr and a libdir of, for instance,
/usr/lib64 to overwrite the system's version of libjpeg. If you do this,
however, then be sure to BACK UP YOUR SYSTEM'S INSTALLATION OF LIBJPEG before
overwriting it. It is recommended that you instead install libjpeg-turbo into
a non-system directory and manipulate the `LD_LIBRARY_PATH` or create symlinks
to force applications to use libjpeg-turbo instead of libjpeg. See
[README.md](README.md) for more information.
Build Recipes
-------------
### 32-bit Build on 64-bit Linux
Add
--host i686-pc-linux-gnu CFLAGS='-O3 -m32' LDFLAGS=-m32
to the `configure` command line.
### 64-bit Build on 64-bit OS X
Add
--host x86_64-apple-darwin NASM=/opt/local/bin/nasm
to the `configure` command line. NASM 2.07 or later from MacPorts must be
installed.
### 32-bit Build on 64-bit OS X
Add
--host i686-apple-darwin CFLAGS='-O3 -m32' LDFLAGS=-m32
to the `configure` command line.
### 64-bit Backward-Compatible Build on 64-bit OS X
Add
--host x86_64-apple-darwin NASM=/opt/local/bin/nasm \
CFLAGS='-mmacosx-version-min=10.5 -O3' \
LDFLAGS='-mmacosx-version-min=10.5'
to the `configure` command line. NASM 2.07 or later from MacPorts must be
installed.
### 32-bit Backward-Compatible Build on OS X
Add
--host i686-apple-darwin \
CFLAGS='-mmacosx-version-min=10.5 -O3 -m32' \
LDFLAGS='-mmacosx-version-min=10.5 -m32'
to the `configure` command line.
### 64-bit Build on 64-bit Solaris
Add
--host x86_64-pc-solaris CFLAGS='-O3 -m64' LDFLAGS=-m64
to the `configure` command line.
### 32-bit Build on 64-bit FreeBSD
Add
--host i386-unknown-freebsd CC='gcc -B /usr/lib32' CFLAGS='-O3 -m32' \
LDFLAGS='-B/usr/lib32'
to the `configure` command line. NASM 2.07 or later from FreeBSD ports must be
installed.
### Oracle Solaris Studio
Add
CC=cc
to the `configure` command line. libjpeg-turbo will automatically be built
with the maximum optimization level (-xO5) unless you override `CFLAGS`.
To build a 64-bit version of libjpeg-turbo using Oracle Solaris Studio, add
--host x86_64-pc-solaris CC=cc CFLAGS='-xO5 -m64' LDFLAGS=-m64
to the `configure` command line.
### MinGW Build on Cygwin
Use CMake (see recipes below)
ARM Support
-----------
This release of libjpeg-turbo can use ARM NEON SIMD instructions to accelerate
JPEG compression/decompression by approximately 2-4x on ARMv7 and later
platforms. If libjpeg-turbo is configured on an ARM Linux platform, then the
build system will automatically include the NEON SIMD routines, if they are
supported. Build instructions for other ARM-based platforms follow.
### Building libjpeg-turbo for iOS
iOS platforms, such as the iPhone and iPad, use ARM processors, some of which
support NEON instructions. Additional steps are required in order to build
libjpeg-turbo for these platforms.
#### Additional build requirements
- [gas-preprocessor.pl]
(https://raw.githubusercontent.com/libjpeg-turbo/gas-preprocessor/master/gas-preprocessor.pl)
should be installed in your `PATH`.
#### ARM 32-bit Build (Xcode 4.6.x and earlier, LLVM-GCC)
Set the following shell variables for simplicity:
*Xcode 4.2 and earlier*
IOS_PLATFORMDIR=/Developer/Platforms/iPhoneOS.platform`
*Xcode 4.3 and later*
IOS_PLATFORMDIR=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
*All Xcode versions*
IOS_SYSROOT=$IOS_PLATFORMDIR/Developer/SDKs/iPhoneOS*.sdk
IOS_GCC=$IOS_PLATFORMDIR/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2
*ARMv7 (code will run on iPhone 3GS-4S/iPad 1st-3rd Generation and newer)*
IOS_CFLAGS="-march=armv7 -mcpu=cortex-a8 -mtune=cortex-a8 -mfpu=neon"
*ARMv7s (code will run on iPhone 5/iPad 4th Generation and newer)*
[NOTE: Requires Xcode 4.5 or later]
IOS_CFLAGS="-march=armv7s -mcpu=swift -mtune=swift -mfpu=neon"
Follow the procedure under "Building libjpeg-turbo" above, adding
--host arm-apple-darwin10 \
CC="$IOS_GCC" LD="$IOS_GCC" \
CFLAGS="-mfloat-abi=softfp -isysroot $IOS_SYSROOT -O3 $IOS_CFLAGS" \
LDFLAGS="-mfloat-abi=softfp -isysroot $IOS_SYSROOT $IOS_CFLAGS"
to the `configure` command line.
#### ARM 32-bit Build (Xcode 5.0.x and later, Clang)
Set the following shell variables for simplicity:
IOS_PLATFORMDIR=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
IOS_SYSROOT=$IOS_PLATFORMDIR/Developer/SDKs/iPhoneOS*.sdk
IOS_GCC=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
*ARMv7 (code will run on iPhone 3GS-4S/iPad 1st-3rd Generation and newer)*
IOS_CFLAGS="-arch armv7"
*ARMv7s (code will run on iPhone 5/iPad 4th Generation and newer)*
IOS_CFLAGS="-arch armv7s"
Follow the procedure under "Building libjpeg-turbo" above, adding
--host arm-apple-darwin10 \
CC="$IOS_GCC" LD="$IOS_GCC" \
CFLAGS="-mfloat-abi=softfp -isysroot $IOS_SYSROOT -O3 $IOS_CFLAGS" \
LDFLAGS="-mfloat-abi=softfp -isysroot $IOS_SYSROOT $IOS_CFLAGS" \
CCASFLAGS="-no-integrated-as $IOS_CFLAGS"
to the `configure` command line.
#### ARMv8 64-bit Build (Xcode 5.0.x and later, Clang)
Code will run on iPhone 5S/iPad Mini 2/iPad Air and newer.
Set the following shell variables for simplicity:
IOS_PLATFORMDIR=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
IOS_SYSROOT=$IOS_PLATFORMDIR/Developer/SDKs/iPhoneOS*.sdk
IOS_GCC=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
IOS_CFLAGS="-arch arm64"
Follow the procedure under "Building libjpeg-turbo" above, adding
--host aarch64-apple-darwin \
CC="$IOS_GCC" LD="$IOS_GCC" \
CFLAGS="-isysroot $IOS_SYSROOT -O3 $IOS_CFLAGS" \
LDFLAGS="-isysroot $IOS_SYSROOT $IOS_CFLAGS"
to the `configure` command line.
NOTE: You can also add `-miphoneos-version-min={version}` to `$IOS_CFLAGS`
above in order to support older versions of iOS than the default version
supported by the SDK.
Once built, lipo can be used to combine the ARMv7, v7s, and/or v8 variants into
a universal library.
### Building libjpeg-turbo for Android
Building libjpeg-turbo for Android platforms requires the
{Android NDK}(https://developer.android.com/tools/sdk/ndk)
and autotools. The following is a general recipe script that can be modified for your specific needs.
# Set these variables to suit your needs
NDK_PATH={full path to the "ndk" directory-- for example, /opt/android/ndk}
BUILD_PLATFORM={the platform name for the NDK package you installed--
for example, "windows-x86" or "linux-x86_64" or "darwin-x86_64"}
TOOLCHAIN_VERSION={"4.8", "4.9", "clang3.5", etc. This corresponds to a
toolchain directory under ${NDK_PATH}/toolchains/.}
ANDROID_VERSION={The minimum version of Android to support-- for example,
"16", "19", etc. "21" or later is required for a 64-bit build.}
# 32-bit ARMv7 build
HOST=arm-linux-androideabi
SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-arm
ANDROID_CFLAGS="-march=armv7-a -mfloat-abi=softfp -fprefetch-loop-arrays \
--sysroot=${SYSROOT}"
# 64-bit ARMv8 build
HOST=aarch64-linux-android
SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-arm64
ANDROID_CFLAGS="--sysroot=${SYSROOT}"
TOOLCHAIN=${NDK_PATH}/toolchains/${HOST}-${TOOLCHAIN_VERSION}/prebuilt/${BUILD_PLATFORM}
ANDROID_INCLUDES="-I${SYSROOT}/usr/include -I${TOOLCHAIN}/include"
export CPP=${TOOLCHAIN}/bin/${HOST}-cpp
export AR=${TOOLCHAIN}/bin/${HOST}-ar
export AS=${TOOLCHAIN}/bin/${HOST}-as
export NM=${TOOLCHAIN}/bin/${HOST}-nm
export CC=${TOOLCHAIN}/bin/${HOST}-gcc
export LD=${TOOLCHAIN}/bin/${HOST}-ld
export RANLIB=${TOOLCHAIN}/bin/${HOST}-ranlib
export OBJDUMP=${TOOLCHAIN}/bin/${HOST}-objdump
export STRIP=${TOOLCHAIN}/bin/${HOST}-strip
cd {build_directory}
sh {source_directory}/configure --host=${HOST} \
CFLAGS="${ANDROID_INCLUDES} ${ANDROID_CFLAGS} -O3 -fPIE" \
CPPFLAGS="${ANDROID_INCLUDES} ${ANDROID_CFLAGS}" \
LDFLAGS="${ANDROID_CFLAGS} -pie" --with-simd ${1+"$@"}
make
If building for Android 4.0.x (API level < 16) or earlier, remove `-fPIE` from
`CFLAGS` and `-pie` from `LDFLAGS`.
Building on Windows (Visual C++ or MinGW)
=========================================
Build Requirements
------------------
- [CMake](http://www.cmake.org) v2.8.11 or later
- [NASM](http://www.nasm.us) or [YASM](http://yasm.tortall.net)
* If using NASM, 0.98 or later is required for an x86 build.
* If using NASM, 2.05 or later is required for an x86-64 build.
* nasm.exe/yasm.exe should be in your `PATH`.
- Microsoft Visual C++ 2005 or later
If you don't already have Visual C++, then the easiest way to get it is by
installing the
[Windows SDK](http://msdn.microsoft.com/en-us/windows/bb980924.aspx).
The Windows SDK includes both 32-bit and 64-bit Visual C++ compilers and
everything necessary to build libjpeg-turbo.
* You can also use Microsoft Visual Studio Express/Community Edition, which
is a free download. (NOTE: versions prior to 2012 can only be used to
build 32-bit code.)
* If you intend to build libjpeg-turbo from the command line, then add the
appropriate compiler and SDK directories to the `INCLUDE`, `LIB`, and
`PATH` environment variables. This is generally accomplished by
executing `vcvars32.bat` or `vcvars64.bat` and `SetEnv.cmd`.
`vcvars32.bat` and `vcvars64.bat` are part of Visual C++ and are located in
the same directory as the compiler. `SetEnv.cmd` is part of the Windows
SDK. You can pass optional arguments to `SetEnv.cmd` to specify a 32-bit
or 64-bit build environment.
... OR ...
- MinGW
[MinGW-builds](http://sourceforge.net/projects/mingwbuilds/) or
[tdm-gcc](http://tdm-gcc.tdragon.net/) recommended if building on a Windows
machine. Both distributions install a Start Menu link that can be used to
launch a command prompt with the appropriate compiler paths automatically
set.
- If building the TurboJPEG Java wrapper, JDK 1.5 or later is required. This
can be downloaded from <http://www.java.com>.
Out-of-Tree Builds
------------------
Binary objects, libraries, and executables are generated in the same directory
from which `cmake` was executed (the "binary directory"), and this directory
need not necessarily be the same as the libjpeg-turbo source directory. You
can create multiple independent binary directories, in which different versions
of libjpeg-turbo can be built from the same source tree using different
compilers or settings. In the sections below, *{build_directory}* refers to
the binary directory, whereas *{source_directory}* refers to the libjpeg-turbo
source directory. For in-tree builds, these directories are the same.
Building libjpeg-turbo
----------------------
### Visual C++ (Command Line)
cd {build_directory}
cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release {source_directory}
nmake
This will build either a 32-bit or a 64-bit version of libjpeg-turbo, depending
on which version of cl.exe is in the `PATH`.
The following files will be generated under *{build_directory}*:
**jpeg-static.lib**
Static link library for the libjpeg API
**sharedlib/jpeg{version}.dll**
DLL for the libjpeg API
**sharedlib/jpeg.lib**
Import library for the libjpeg API
**turbojpeg-static.lib**
Static link library for the TurboJPEG API
**turbojpeg.dll**
DLL for the TurboJPEG API
**turbojpeg.lib**
Import library for the TurboJPEG API
*{version}* is 62, 7, or 8, depending on whether libjpeg v6b (default), v7, or
v8 emulation is enabled.
### Visual C++ (IDE)
Choose the appropriate CMake generator option for your version of Visual Studio
(run `cmake` with no arguments for a list of available generators.) For
instance:
cd {build_directory}
cmake -G "Visual Studio 10" {source_directory}
NOTE: Add "Win64" to the generator name (for example, "Visual Studio 10
Win64") to build a 64-bit version of libjpeg-turbo. Recent versions of CMake
no longer document that. A separate build directory must be used for 32-bit
and 64-bit builds.
You can then open ALL_BUILD.vcproj in Visual Studio and build one of the
configurations in that project ("Debug", "Release", etc.) to generate a full
build of libjpeg-turbo.
This will generate the following files under *{build_directory}*:
**{configuration}/jpeg-static.lib**
Static link library for the libjpeg API
**sharedlib/{configuration}/jpeg{version}.dll**
DLL for the libjpeg API
**sharedlib/{configuration}/jpeg.lib**
Import library for the libjpeg API
**{configuration}/turbojpeg-static.lib**
Static link library for the TurboJPEG API
**{configuration}/turbojpeg.dll**
DLL for the TurboJPEG API
**{configuration}/turbojpeg.lib**
Import library for the TurboJPEG API
*{configuration}* is Debug, Release, RelWithDebInfo, or MinSizeRel, depending
on the configuration you built in the IDE, and *{version}* is 62, 7, or 8,
depending on whether libjpeg v6b (default), v7, or v8 emulation is enabled.
### MinGW
NOTE: This assumes that you are building on a Windows machine. If you are
cross-compiling on a Linux/Unix machine, then see "Build Recipes" below.
cd {build_directory}
cmake -G "MinGW Makefiles" {source_directory}
mingw32-make
This will generate the following files under *{build_directory}*:
**libjpeg.a**
Static link library for the libjpeg API
**sharedlib/libjpeg-{version}.dll**
DLL for the libjpeg API
**sharedlib/libjpeg.dll.a**
Import library for the libjpeg API
**libturbojpeg.a**
Static link library for the TurboJPEG API
**libturbojpeg.dll**
DLL for the TurboJPEG API
**libturbojpeg.dll.a**
Import library for the TurboJPEG API
*{version}* is 62, 7, or 8, depending on whether libjpeg v6b (default), v7, or
v8 emulation is enabled.
### Debug Build
Add `-DCMAKE_BUILD_TYPE=Debug` to the `cmake` command line. Or, if building
with NMake, remove `-DCMAKE_BUILD_TYPE=Release` (Debug builds are the default
with NMake.)
### libjpeg v7 or v8 API/ABI Emulation
Add `-DWITH_JPEG7=1` to the `cmake` command line to build a version of
libjpeg-turbo that is API/ABI-compatible with libjpeg v7. Add `-DWITH_JPEG8=1`
to the `cmake` command line to build a version of libjpeg-turbo that is
API/ABI-compatible with libjpeg v8. See [README.md](README.md) for more
information on libjpeg v7 and v8 emulation.
### In-Memory Source/Destination Managers
When using libjpeg v6b or v7 API/ABI emulation, add `-DWITH_MEM_SRCDST=0` to
the `cmake` command line to build a version of libjpeg-turbo that lacks the
`jpeg_mem_src()` and `jpeg_mem_dest()` functions. These functions were not
part of the original libjpeg v6b and v7 APIs, so removing them ensures strict
conformance with those APIs. See [README.md](README.md) for more information.
### Arithmetic Coding Support
Since the patent on arithmetic coding has expired, this functionality has been
included in this release of libjpeg-turbo. libjpeg-turbo's implementation is
based on the implementation in libjpeg v8, but it works when emulating libjpeg
v7 or v6b as well. The default is to enable both arithmetic encoding and
decoding, but those who have philosophical objections to arithmetic coding can
add `-DWITH_ARITH_ENC=0` or `-DWITH_ARITH_DEC=0` to the `cmake` command line to
disable encoding or decoding (respectively.)
### TurboJPEG Java Wrapper
Add `-DWITH_JAVA=1` to the `cmake` command line to incorporate an optional Java
Native Interface wrapper into the TurboJPEG shared library and build the Java
front-end classes to support it. This allows the TurboJPEG shared library to
be used directly from Java applications. See [java/README](java/README) for
more details.
You can set the `Java_JAVAC_EXECUTABLE`, `Java_JAVA_EXECUTABLE`, and
`Java_JAR_EXECUTABLE` CMake variables to specify alternate commands or
locations for javac, jar, and java (respectively.) You can also set the
`JAVACFLAGS` CMake variable to specify arguments that should be passed to the
Java compiler when building the front-end classes.
Installing libjpeg-turbo
------------------------
You can use the build system to install libjpeg-turbo into a directory of your
choosing (as opposed to creating an installer.) To do this, add:
-DCMAKE_INSTALL_PREFIX={install_directory}
to the cmake command line.
For example,
cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=c:\libjpeg-turbo {source_directory}
nmake install
will install the header files in c:\libjpeg-turbo\include, the library files
in c:\libjpeg-turbo\lib, the DLL's in c:\libjpeg-turbo\bin, and the
documentation in c:\libjpeg-turbo\doc.
Build Recipes
-------------
### 64-bit MinGW Build on Cygwin
cd {build_directory}
CC=/usr/bin/x86_64-w64-mingw32-gcc \
cmake -G "Unix Makefiles" -DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_RC_COMPILER=/usr/bin/x86_64-w64-mingw32-windres.exe \
{source_directory}
make
This produces a 64-bit build of libjpeg-turbo that does not depend on
cygwin1.dll or other Cygwin DLL's. The mingw64-x86\_64-gcc-core and
mingw64-x86\_64-gcc-g++ packages (and their dependencies) must be installed.
### 32-bit MinGW Build on Cygwin
cd {build_directory}
CC=/usr/bin/i686-w64-mingw32-gcc \
cmake -G "Unix Makefiles" -DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_RC_COMPILER=/usr/bin/i686-w64-mingw32-windres.exe \
{source_directory}
make
This produces a 32-bit build of libjpeg-turbo that does not depend on
cygwin1.dll or other Cygwin DLL's. The mingw64-i686-gcc-core and
mingw64-i686-gcc-g++ packages (and their dependencies) must be installed.
### MinGW Build on Linux
cd {build_directory}
CC={mingw_binary_path}/i686-pc-mingw32-gcc \
cmake -G "Unix Makefiles" -DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_RC_COMPILER={mingw_binary_path}/i686-pc-mingw32-windres \
-DCMAKE_AR={mingw_binary_path}/i686-pc-mingw32-ar \
-DCMAKE_RANLIB={mingw_binary_path}/i686-pc-mingw32-ranlib \
{source_directory}
make
Creating Release Packages
=========================
The following commands can be used to create various types of release packages:
Unix/Linux
----------
make rpm
Create Red Hat-style binary RPM package. Requires RPM v4 or later.
make srpm
This runs `make dist` to create a pristine source tarball, then creates a
Red Hat-style source RPM package from the tarball. Requires RPM v4 or later.
make deb
Create Debian-style binary package. Requires dpkg.
make dmg
Create Macintosh package/disk image. This requires pkgbuild and
productbuild, which are installed by default on OS X 10.7 and later and which
can be obtained by installing Xcode 3.2.6 (with the "Unix Development"
option) on OS X 10.6. Packages built in this manner can be installed on OS X
10.5 and later, but they must be built on OS X 10.6 or later.
make udmg [BUILDDIR32={32-bit build directory}]
On 64-bit OS X systems, this creates a Macintosh package and disk image that
contains universal i386/x86-64 binaries. You should first configure a 32-bit
out-of-tree build of libjpeg-turbo, then configure a 64-bit out-of-tree
build, then run `make udmg` from the 64-bit build directory. The build
system will look for the 32-bit build under *{source_directory}*/osxx86 by
default, but you can override this by setting the `BUILDDIR32` variable on the
make command line as shown above.
make iosdmg [BUILDDIR32={32-bit build directory}] \
[BUILDDIRARMV7={ARMv7 build directory}] \
[BUILDDIRARMV7S={ARMv7s build directory}] \
[BUILDDIRARMV8={ARMv8 build directory}]
On OS X systems, this creates a Macintosh package and disk image in which the
libjpeg-turbo static libraries contain ARM architectures necessary to build
iOS applications. If building on an x86-64 system, the binaries will also
contain the i386 architecture, as with `make udmg` above. You should first
configure ARMv7, ARMv7s, and/or ARMv8 out-of-tree builds of libjpeg-turbo (see
"Building libjpeg-turbo for iOS" above.) If you are building an x86-64 version
of libjpeg-turbo, you should configure a 32-bit out-of-tree build as well.
Next, build libjpeg-turbo as you would normally, using an out-of-tree build.
When it is built, run `make iosdmg` from the build directory. The build system
will look for the ARMv7 build under *{source_directory}*/iosarmv7 by default,
the ARMv7s build under *{source_directory}*/iosarmv7s by default, the ARMv8
build under *{source_directory}*/iosarmv8 by default, and (if applicable) the
32-bit build under *{source_directory}*/osxx86 by default, but you can override
this by setting the `BUILDDIR32`, `BUILDDIRARMV7`, `BUILDDIRARMV7S`, and/or
`BUILDDIRARMV8` variables on the `make` command line as shown above.
NOTE: If including an ARMv8 build in the package, then you may need to use
Xcode's version of lipo instead of the operating system's. To do this, pass
an argument of `LIPO="xcrun lipo"` on the make command line.
make cygwinpkg
Build a Cygwin binary package.
Windows
-------
If using NMake:
cd {build_directory}
nmake installer
If using MinGW:
cd {build_directory}
make installer
If using the Visual Studio IDE, build the "installer" project.
The installer package (libjpeg-turbo[-gcc][64].exe) will be located under
*{build_directory}*. If building using the Visual Studio IDE, then the
installer package will be located in a subdirectory with the same name as the
configuration you built (such as *{build_directory}*\Debug\ or
*{build_directory}*\Release\).
Building a Windows installer requires the Nullsoft Install System
(http://nsis.sourceforge.net/.) makensis.exe should be in your `PATH`.
Regression testing
==================
The most common way to test libjpeg-turbo is by invoking `make test` on
Unix/Linux platforms or `ctest` on Windows platforms, once the build has
completed. This runs a series of tests to ensure that mathematical
compatibility has been maintained between libjpeg-turbo and libjpeg v6b. This
also invokes the TurboJPEG unit tests, which ensure that the colorspace
extensions, YUV encoding, decompression scaling, and other features of the
TurboJPEG C and Java APIs are working properly (and, by extension, that the
equivalent features of the underlying libjpeg API are also working.)
Invoking `make testclean` or `nmake testclean` (if using NMake) or building
the 'testclean' target (if using the Visual Studio IDE) will clean up the
output images generated by `make test`.
On Unix/Linux platforms, more extensive tests of the TurboJPEG C and Java
wrappers can be run by invoking `make tjtest`. These extended TurboJPEG tests
essentially iterate through all of the available features of the TurboJPEG APIs
that are not covered by the TurboJPEG unit tests (this includes the lossless
transform options) and compare the images generated by each feature to images
generated using the equivalent feature in the libjpeg API. The extended
TurboJPEG tests are meant to test for regressions in the TurboJPEG wrappers,
not in the underlying libjpeg API library.
@@ -1,935 +0,0 @@
#
# Setup
#
cmake_minimum_required(VERSION 2.8.11)
# Use LINK_INTERFACE_LIBRARIES instead of INTERFACE_LINK_LIBRARIES
if(POLICY CMP0022)
cmake_policy(SET CMP0022 OLD)
endif()
project(libjpeg-turbo C)
set(VERSION 1.5.1)
string(REPLACE "." ";" VERSION_TRIPLET ${VERSION})
list(GET VERSION_TRIPLET 0 VERSION_MAJOR)
list(GET VERSION_TRIPLET 1 VERSION_MINOR)
list(GET VERSION_TRIPLET 2 VERSION_REVISION)
function(pad_number NUMBER OUTPUT_LEN)
string(LENGTH "${${NUMBER}}" INPUT_LEN)
if(INPUT_LEN LESS OUTPUT_LEN)
math(EXPR ZEROES "${OUTPUT_LEN} - ${INPUT_LEN} - 1")
set(NUM ${${NUMBER}})
foreach(C RANGE ${ZEROES})
set(NUM "0${NUM}")
endforeach()
set(${NUMBER} ${NUM} PARENT_SCOPE)
endif()
endfunction()
pad_number(VERSION_MINOR 3)
pad_number(VERSION_REVISION 3)
set(LIBJPEG_TURBO_VERSION_NUMBER ${VERSION_MAJOR}${VERSION_MINOR}${VERSION_REVISION})
if(NOT WIN32)
message(FATAL_ERROR "Platform not supported by this build system. Use autotools instead.")
endif()
string(TIMESTAMP BUILD "%Y%m%d")
# This does nothing except when using MinGW. CMAKE_BUILD_TYPE has no meaning
# in Visual Studio, and it always defaults to Debug when using NMake.
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
message(STATUS "CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}")
# This only works if building from the command line. There is currently no way
# to set a variable's value based on the build type when using Visual Studio.
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(BUILD "${BUILD}d")
endif()
message(STATUS "VERSION = ${VERSION}, BUILD = ${BUILD}")
option(WITH_SIMD "Include SIMD extensions" TRUE)
option(WITH_ARITH_ENC "Include arithmetic encoding support when emulating the libjpeg v6b API/ABI" TRUE)
option(WITH_ARITH_DEC "Include arithmetic decoding support when emulating the libjpeg v6b API/ABI" TRUE)
option(WITH_JPEG7 "Emulate libjpeg v7 API/ABI (this makes libjpeg-turbo backward incompatible with libjpeg v6b)" FALSE)
option(WITH_JPEG8 "Emulate libjpeg v8 API/ABI (this makes libjpeg-turbo backward incompatible with libjpeg v6b)" FALSE)
option(WITH_MEM_SRCDST "Include in-memory source/destination manager functions when emulating the libjpeg v6b or v7 API/ABI" TRUE)
option(WITH_TURBOJPEG "Include the TurboJPEG wrapper library and associated test programs" TRUE)
option(WITH_JAVA "Build Java wrapper for the TurboJPEG library" FALSE)
option(WITH_12BIT "Encode/decode JPEG images with 12-bit samples (implies WITH_SIMD=0 WITH_TURBOJPEG=0 WITH_ARITH_ENC=0 WITH_ARITH_DEC=0)" FALSE)
option(ENABLE_STATIC "Build static libraries" TRUE)
option(ENABLE_SHARED "Build shared libraries" TRUE)
if(WITH_12BIT)
set(WITH_SIMD FALSE)
set(WITH_TURBOJPEG FALSE)
set(WITH_JAVA FALSE)
set(WITH_ARITH_ENC FALSE)
set(WITH_ARITH_DEC FALSE)
set(BITS_IN_JSAMPLE 12)
message(STATUS "12-bit JPEG support enabled")
else()
set(BITS_IN_JSAMPLE 8)
endif()
if(WITH_JPEG8 OR WITH_JPEG7)
set(WITH_ARITH_ENC 1)
set(WITH_ARITH_DEC 1)
endif()
if(WITH_JPEG8)
set(WITH_MEM_SRCDST 1)
endif()
if(WITH_ARITH_ENC)
set(C_ARITH_CODING_SUPPORTED 1)
message(STATUS "Arithmetic encoding support enabled")
else()
message(STATUS "Arithmetic encoding support disabled")
endif()
if(WITH_ARITH_DEC)
set(D_ARITH_CODING_SUPPORTED 1)
message(STATUS "Arithmetic decoding support enabled")
else()
message(STATUS "Arithmetic decoding support disabled")
endif()
if(WITH_TURBOJPEG)
message(STATUS "TurboJPEG C wrapper enabled")
else()
message(STATUS "TurboJPEG C wrapper disabled")
endif()
if(WITH_JAVA)
message(STATUS "TurboJPEG Java wrapper enabled")
else()
message(STATUS "TurboJPEG Java wrapper disabled")
endif()
set(SO_AGE 0)
if(WITH_MEM_SRCDST)
set(SO_AGE 1)
endif()
set(JPEG_LIB_VERSION 62)
set(DLL_VERSION ${JPEG_LIB_VERSION})
set(FULLVERSION ${DLL_VERSION}.${SO_AGE}.0)
if(WITH_JPEG8)
set(JPEG_LIB_VERSION 80)
set(DLL_VERSION 8)
set(FULLVERSION ${DLL_VERSION}.0.2)
message(STATUS "Emulating libjpeg v8 API/ABI")
elseif(WITH_JPEG7)
set(JPEG_LIB_VERSION 70)
set(DLL_VERSION 7)
set(FULLVERSION ${DLL_VERSION}.${SO_AGE}.0)
message(STATUS "Emulating libjpeg v7 API/ABI")
endif(WITH_JPEG8)
if(WITH_MEM_SRCDST)
set(MEM_SRCDST_SUPPORTED 1)
message(STATUS "In-memory source/destination managers enabled")
else()
message(STATUS "In-memory source/destination managers disabled")
endif()
if(MSVC)
option(WITH_CRT_DLL
"Link all libjpeg-turbo libraries and executables with the C run-time DLL (msvcr*.dll) instead of the static C run-time library (libcmt*.lib.) The default is to use the C run-time DLL only with the libraries and executables that need it."
FALSE)
if(NOT WITH_CRT_DLL)
# Use the static C library for all build types
foreach(var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
if(${var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${var} "${${var}}")
endif()
endforeach()
endif()
add_definitions(-W3 -wd4996)
endif()
# Detect whether compiler is 64-bit
if(MSVC AND CMAKE_CL_64)
set(SIMD_X86_64 1)
set(64BIT 1)
elseif(CMAKE_SIZEOF_VOID_P MATCHES 8)
set(SIMD_X86_64 1)
set(64BIT 1)
endif()
if(64BIT)
message(STATUS "64-bit build")
else()
message(STATUS "32-bit build")
endif()
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
if(MSVC)
set(CMAKE_INSTALL_PREFIX_DEFAULT ${CMAKE_PROJECT_NAME})
else()
set(CMAKE_INSTALL_PREFIX_DEFAULT ${CMAKE_PROJECT_NAME}-gcc)
endif()
if(64BIT)
set(CMAKE_INSTALL_PREFIX_DEFAULT ${CMAKE_INSTALL_PREFIX_DEFAULT}64)
endif()
set(CMAKE_INSTALL_PREFIX "c:/${CMAKE_INSTALL_PREFIX_DEFAULT}" CACHE PATH
"Directory into which to install libjpeg-turbo (default: c:/${CMAKE_INSTALL_PREFIX_DEFAULT})"
FORCE)
endif()
message(STATUS "Install directory = ${CMAKE_INSTALL_PREFIX}")
configure_file(win/jconfig.h.in jconfig.h)
configure_file(win/jconfigint.h.in jconfigint.h)
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR})
string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
set(EFFECTIVE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
message(STATUS "Compiler flags = ${EFFECTIVE_C_FLAGS}")
set(EFFECTIVE_LD_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
message(STATUS "Linker flags = ${EFFECTIVE_LD_FLAGS}")
if(WITH_JAVA)
find_package(Java)
find_package(JNI)
if(DEFINED JAVACFLAGS)
message(STATUS "Java compiler flags = ${JAVACFLAGS}")
endif()
endif()
#
# Targets
#
set(JPEG_SOURCES jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c
jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c jcphuff.c
jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c jdatadst.c jdatasrc.c
jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c
jdmaster.c jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c jerror.c
jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c
jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c)
if(WITH_ARITH_ENC OR WITH_ARITH_DEC)
set(JPEG_SOURCES ${JPEG_SOURCES} jaricom.c)
endif()
if(WITH_ARITH_ENC)
set(JPEG_SOURCES ${JPEG_SOURCES} jcarith.c)
endif()
if(WITH_ARITH_DEC)
set(JPEG_SOURCES ${JPEG_SOURCES} jdarith.c)
endif()
if(WITH_SIMD)
add_definitions(-DWITH_SIMD)
add_subdirectory(simd)
if(SIMD_X86_64)
set(JPEG_SOURCES ${JPEG_SOURCES} simd/jsimd_x86_64.c)
else()
set(JPEG_SOURCES ${JPEG_SOURCES} simd/jsimd_i386.c)
endif()
# This tells CMake that the "source" files haven't been generated yet
set_source_files_properties(${SIMD_OBJS} PROPERTIES GENERATED 1)
else()
set(JPEG_SOURCES ${JPEG_SOURCES} jsimd_none.c)
message(STATUS "Not using SIMD acceleration")
endif()
if(WITH_JAVA)
add_subdirectory(java)
set(ENABLE_SHARED TRUE)
endif()
if(ENABLE_SHARED)
add_subdirectory(sharedlib)
endif()
if(ENABLE_STATIC OR WITH_TURBOJPEG)
add_library(jpeg-static STATIC ${JPEG_SOURCES} ${SIMD_OBJS})
if(NOT MSVC)
set_target_properties(jpeg-static PROPERTIES OUTPUT_NAME jpeg)
endif()
if(WITH_SIMD)
add_dependencies(jpeg-static simd)
endif()
endif()
if(WITH_TURBOJPEG)
set(TURBOJPEG_SOURCES turbojpeg.c transupp.c jdatadst-tj.c jdatasrc-tj.c)
if(WITH_JAVA)
set(TURBOJPEG_SOURCES ${TURBOJPEG_SOURCES} turbojpeg-jni.c)
include_directories(${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2})
endif()
if(ENABLE_SHARED)
add_library(turbojpeg SHARED ${TURBOJPEG_SOURCES})
set_target_properties(turbojpeg PROPERTIES DEFINE_SYMBOL DLLDEFINE)
if(MINGW)
set_target_properties(turbojpeg PROPERTIES LINK_FLAGS -Wl,--kill-at)
endif()
target_link_libraries(turbojpeg jpeg-static)
set_target_properties(turbojpeg PROPERTIES LINK_INTERFACE_LIBRARIES "")
add_executable(tjunittest tjunittest.c tjutil.c)
target_link_libraries(tjunittest turbojpeg)
add_executable(tjbench tjbench.c bmp.c tjutil.c rdbmp.c rdppm.c wrbmp.c
wrppm.c)
target_link_libraries(tjbench turbojpeg jpeg-static)
set_property(TARGET tjbench PROPERTY COMPILE_FLAGS
"-DBMP_SUPPORTED -DPPM_SUPPORTED")
endif()
if(ENABLE_STATIC)
add_library(turbojpeg-static STATIC ${JPEG_SOURCES} ${SIMD_OBJS}
turbojpeg.c transupp.c jdatadst-tj.c jdatasrc-tj.c)
if(NOT MSVC)
set_target_properties(turbojpeg-static PROPERTIES OUTPUT_NAME turbojpeg)
endif()
if(WITH_SIMD)
add_dependencies(turbojpeg-static simd)
endif()
add_executable(tjunittest-static tjunittest.c tjutil.c)
target_link_libraries(tjunittest-static turbojpeg-static)
add_executable(tjbench-static tjbench.c bmp.c tjutil.c rdbmp.c rdppm.c
wrbmp.c wrppm.c)
target_link_libraries(tjbench-static turbojpeg-static jpeg-static)
set_property(TARGET tjbench-static PROPERTY COMPILE_FLAGS
"-DBMP_SUPPORTED -DPPM_SUPPORTED")
endif()
endif()
if(WITH_12BIT)
set(COMPILE_FLAGS "-DGIF_SUPPORTED -DPPM_SUPPORTED -DUSE_SETMODE")
else()
set(COMPILE_FLAGS "-DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED -DTARGA_SUPPORTED -DUSE_SETMODE")
set(CJPEG_BMP_SOURCES rdbmp.c rdtarga.c)
set(DJPEG_BMP_SOURCES wrbmp.c wrtarga.c)
endif()
if(ENABLE_STATIC)
add_executable(cjpeg-static cjpeg.c cdjpeg.c rdgif.c rdppm.c rdswitch.c
${CJPEG_BMP_SOURCES})
set_property(TARGET cjpeg-static PROPERTY COMPILE_FLAGS ${COMPILE_FLAGS})
target_link_libraries(cjpeg-static jpeg-static)
add_executable(djpeg-static djpeg.c cdjpeg.c rdcolmap.c rdswitch.c wrgif.c
wrppm.c ${DJPEG_BMP_SOURCES})
set_property(TARGET djpeg-static PROPERTY COMPILE_FLAGS ${COMPILE_FLAGS})
target_link_libraries(djpeg-static jpeg-static)
add_executable(jpegtran-static jpegtran.c cdjpeg.c rdswitch.c transupp.c)
target_link_libraries(jpegtran-static jpeg-static)
set_property(TARGET jpegtran-static PROPERTY COMPILE_FLAGS "-DUSE_SETMODE")
endif()
add_executable(rdjpgcom rdjpgcom.c)
add_executable(wrjpgcom wrjpgcom.c)
#
# Tests
#
add_subdirectory(md5)
if(MSVC_IDE)
set(OBJDIR "\${CTEST_CONFIGURATION_TYPE}/")
else()
set(OBJDIR "")
endif()
enable_testing()
if(WITH_12BIT)
set(TESTORIG testorig12.jpg)
set(MD5_JPEG_RGB_ISLOW 9620f424569594bb9242b48498ad801f)
set(MD5_PPM_RGB_ISLOW f3301d2219783b8b3d942b7239fa50c0)
set(MD5_JPEG_422_IFAST_OPT 7322e3bd2f127f7de4b40d4480ce60e4)
set(MD5_PPM_422_IFAST 79807fa552899e66a04708f533e16950)
set(MD5_PPM_422M_IFAST 07737bfe8a7c1c87aaa393a0098d16b0)
set(MD5_JPEG_420_IFAST_Q100_PROG a1da220b5604081863a504297ed59e55)
set(MD5_PPM_420_Q100_IFAST 1b3730122709f53d007255e8dfd3305e)
set(MD5_PPM_420M_Q100_IFAST 980a1a3c5bf9510022869d30b7d26566)
set(MD5_JPEG_GRAY_ISLOW 235c90707b16e2e069f37c888b2636d9)
set(MD5_PPM_GRAY_ISLOW 7213c10af507ad467da5578ca5ee1fca)
set(MD5_PPM_GRAY_ISLOW_RGB e96ee81c30a6ed422d466338bd3de65d)
set(MD5_JPEG_420S_IFAST_OPT 7af8e60be4d9c227ec63ac9b6630855e)
set(MD5_JPEG_3x2_FLOAT_PROG a8c17daf77b457725ec929e215b603f8)
set(MD5_PPM_3x2_FLOAT 42876ab9e5c2f76a87d08db5fbd57956)
set(MD5_PPM_420M_ISLOW_2_1 4ca6be2a6f326ff9eaab63e70a8259c0)
set(MD5_PPM_420M_ISLOW_15_8 12aa9f9534c1b3d7ba047322226365eb)
set(MD5_PPM_420M_ISLOW_13_8 f7e22817c7b25e1393e4ec101e9d4e96)
set(MD5_PPM_420M_ISLOW_11_8 800a16f9f4dc9b293197bfe11be10a82)
set(MD5_PPM_420M_ISLOW_9_8 06b7a92a9bc69f4dc36ec40f1937d55c)
set(MD5_PPM_420M_ISLOW_7_8 3ec444a14a4ab4eab88ffc49c48eca43)
set(MD5_PPM_420M_ISLOW_3_4 3e726b7ea872445b19437d1c1d4f0d93)
set(MD5_PPM_420M_ISLOW_5_8 a8a771abdc94301d20ffac119b2caccd)
set(MD5_PPM_420M_ISLOW_1_2 b419124dd5568b085787234866102866)
set(MD5_PPM_420M_ISLOW_3_8 343d19015531b7bbe746124127244fa8)
set(MD5_PPM_420M_ISLOW_1_4 35fd59d866e44659edfa3c18db2a3edb)
set(MD5_PPM_420M_ISLOW_1_8 ccaed48ac0aedefda5d4abe4013f4ad7)
set(MD5_PPM_420_ISLOW_SKIP15_31 86664cd9dc956536409e44e244d20a97)
set(MD5_PPM_420_ISLOW_PROG_CROP62x62_71_71 452a21656115a163029cfba5c04fa76a)
set(MD5_PPM_444_ISLOW_SKIP1_6 ef63901f71ef7a75cd78253fc0914f84)
set(MD5_PPM_444_ISLOW_PROG_CROP98x98_13_13 15b173fb5872d9575572fbcc1b05956f)
set(MD5_JPEG_CROP cdb35ff4b4519392690ea040c56ea99c)
else()
set(TESTORIG testorig.jpg)
set(MD5_JPEG_RGB_ISLOW 768e970dd57b340ff1b83c9d3d47c77b)
set(MD5_PPM_RGB_ISLOW 00a257f5393fef8821f2b88ac7421291)
set(MD5_BMP_RGB_ISLOW_565 f07d2e75073e4bb10f6c6f4d36e2e3be)
set(MD5_BMP_RGB_ISLOW_565D 4cfa0928ef3e6bb626d7728c924cfda4)
set(MD5_JPEG_422_IFAST_OPT 2540287b79d913f91665e660303ab2c8)
set(MD5_PPM_422_IFAST 35bd6b3f833bad23de82acea847129fa)
set(MD5_PPM_422M_IFAST 8dbc65323d62cca7c91ba02dd1cfa81d)
set(MD5_BMP_422M_IFAST_565 3294bd4d9a1f2b3d08ea6020d0db7065)
set(MD5_BMP_422M_IFAST_565D da98c9c7b6039511be4a79a878a9abc1)
set(MD5_JPEG_420_IFAST_Q100_PROG 990cbe0329c882420a2094da7e5adade)
set(MD5_PPM_420_Q100_IFAST 5a732542015c278ff43635e473a8a294)
set(MD5_PPM_420M_Q100_IFAST ff692ee9323a3b424894862557c092f1)
set(MD5_JPEG_GRAY_ISLOW 72b51f894b8f4a10b3ee3066770aa38d)
set(MD5_PPM_GRAY_ISLOW 8d3596c56eace32f205deccc229aa5ed)
set(MD5_PPM_GRAY_ISLOW_RGB 116424ac07b79e5e801f00508eab48ec)
set(MD5_BMP_GRAY_ISLOW_565 12f78118e56a2f48b966f792fedf23cc)
set(MD5_BMP_GRAY_ISLOW_565D bdbbd616441a24354c98553df5dc82db)
set(MD5_JPEG_420S_IFAST_OPT 388708217ac46273ca33086b22827ed8)
if(WITH_SIMD)
set(MD5_JPEG_3x2_FLOAT_PROG 343e3f8caf8af5986ebaf0bdc13b5c71)
set(MD5_PPM_3x2_FLOAT 1a75f36e5904d6fc3a85a43da9ad89bb)
else()
set(MD5_JPEG_3x2_FLOAT_PROG 9bca803d2042bd1eb03819e2bf92b3e5)
set(MD5_PPM_3x2_FLOAT f6bfab038438ed8f5522fbd33595dcdc)
endif()
set(MD5_JPEG_420_ISLOW_ARI e986fb0a637a8d833d96e8a6d6d84ea1)
set(MD5_JPEG_444_ISLOW_PROGARI 0a8f1c8f66e113c3cf635df0a475a617)
set(MD5_PPM_420M_IFAST_ARI 72b59a99bcf1de24c5b27d151bde2437)
set(MD5_JPEG_420_ISLOW 9a68f56bc76e466aa7e52f415d0f4a5f)
set(MD5_PPM_420M_ISLOW_2_1 9f9de8c0612f8d06869b960b05abf9c9)
set(MD5_PPM_420M_ISLOW_15_8 b6875bc070720b899566cc06459b63b7)
set(MD5_PPM_420M_ISLOW_13_8 bc3452573c8152f6ae552939ee19f82f)
set(MD5_PPM_420M_ISLOW_11_8 d8cc73c0aaacd4556569b59437ba00a5)
set(MD5_PPM_420M_ISLOW_9_8 d25e61bc7eac0002f5b393aa223747b6)
set(MD5_PPM_420M_ISLOW_7_8 ddb564b7c74a09494016d6cd7502a946)
set(MD5_PPM_420M_ISLOW_3_4 8ed8e68808c3fbc4ea764fc9d2968646)
set(MD5_PPM_420M_ISLOW_5_8 a3363274999da2366a024efae6d16c9b)
set(MD5_PPM_420M_ISLOW_1_2 e692a315cea26b988c8e8b29a5dbcd81)
set(MD5_PPM_420M_ISLOW_3_8 79eca9175652ced755155c90e785a996)
set(MD5_PPM_420M_ISLOW_1_4 79cd778f8bf1a117690052cacdd54eca)
set(MD5_PPM_420M_ISLOW_1_8 391b3d4aca640c8567d6f8745eb2142f)
set(MD5_BMP_420_ISLOW_256 4980185e3776e89bd931736e1cddeee6)
set(MD5_BMP_420_ISLOW_565 bf9d13e16c4923b92e1faa604d7922cb)
set(MD5_BMP_420_ISLOW_565D 6bde71526acc44bcff76f696df8638d2)
set(MD5_BMP_420M_ISLOW_565 8dc0185245353cfa32ad97027342216f)
set(MD5_BMP_420M_ISLOW_565D d1be3a3339166255e76fa50a0d70d73e)
set(MD5_PPM_420_ISLOW_SKIP15_31 c4c65c1e43d7275cd50328a61e6534f0)
set(MD5_PPM_420_ISLOW_ARI_SKIP16_139 087c6b123db16ac00cb88c5b590bb74a)
set(MD5_PPM_420_ISLOW_PROG_CROP62x62_71_71 26eb36ccc7d1f0cb80cdabb0ac8b5d99)
set(MD5_PPM_420_ISLOW_ARI_CROP53x53_4_4 886c6775af22370257122f8b16207e6d)
set(MD5_PPM_444_ISLOW_SKIP1_6 5606f86874cf26b8fcee1117a0a436a6)
set(MD5_PPM_444_ISLOW_PROG_CROP98x98_13_13 db87dc7ce26bcdc7a6b56239ce2b9d6c)
set(MD5_PPM_444_ISLOW_ARI_CROP37x37_0_0 cb57b32bd6d03e35432362f7bf184b6d)
set(MD5_JPEG_CROP b4197f377e621c4e9b1d20471432610d)
endif()
if(WITH_JAVA)
add_test(TJUnitTest
${JAVA_RUNTIME} -cp java/${OBJDIR}turbojpeg.jar
-Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR}
TJUnitTest)
add_test(TJUnitTest-yuv
${JAVA_RUNTIME} -cp java/${OBJDIR}turbojpeg.jar
-Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR}
TJUnitTest -yuv)
add_test(TJUnitTest-yuv-nopad
${JAVA_RUNTIME} -cp java/${OBJDIR}turbojpeg.jar
-Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR}
TJUnitTest -yuv -noyuvpad)
add_test(TJUnitTest-bi
${JAVA_RUNTIME} -cp java/${OBJDIR}turbojpeg.jar
-Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR}
TJUnitTest -bi)
add_test(TJUnitTest-bi-yuv
${JAVA_RUNTIME} -cp java/${OBJDIR}turbojpeg.jar
-Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR}
TJUnitTest -bi -yuv)
add_test(TJUnitTest-bi-yuv-nopad
${JAVA_RUNTIME} -cp java/${OBJDIR}turbojpeg.jar
-Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR}
TJUnitTest -bi -yuv -noyuvpad)
endif()
set(TEST_LIBTYPES "")
if(ENABLE_SHARED)
set(TEST_LIBTYPES ${TEST_LIBTYPES} shared)
endif()
if(ENABLE_STATIC)
set(TEST_LIBTYPES ${TEST_LIBTYPES} static)
endif()
set(TESTIMAGES ${CMAKE_SOURCE_DIR}/testimages)
set(MD5CMP ${CMAKE_CURRENT_BINARY_DIR}/md5/md5cmp)
if(CMAKE_CROSSCOMPILING)
file(RELATIVE_PATH TESTIMAGES ${CMAKE_CURRENT_BINARY_DIR} ${TESTIMAGES})
file(RELATIVE_PATH MD5CMP ${CMAKE_CURRENT_BINARY_DIR} ${MD5CMP})
endif()
foreach(libtype ${TEST_LIBTYPES})
if(libtype STREQUAL "shared")
set(dir sharedlib/)
else()
set(dir "")
set(suffix -static)
endif()
if(WITH_TURBOJPEG)
add_test(tjunittest${suffix} tjunittest${suffix})
add_test(tjunittest${suffix}-alloc tjunittest${suffix} -alloc)
add_test(tjunittest${suffix}-yuv tjunittest${suffix} -yuv)
add_test(tjunittest${suffix}-yuv-alloc tjunittest${suffix} -yuv -alloc)
add_test(tjunittest${suffix}-yuv-nopad tjunittest${suffix} -yuv -noyuvpad)
endif()
# These tests are carefully chosen to provide full coverage of as many of the
# underlying algorithms as possible (including all of the SIMD-accelerated
# ones.)
# CC: null SAMP: fullsize FDCT: islow ENT: huff
add_test(cjpeg${suffix}-rgb-islow
${dir}cjpeg${suffix} -rgb -dct int
-outfile testout_rgb_islow.jpg ${TESTIMAGES}/testorig.ppm)
add_test(cjpeg${suffix}-rgb-islow-cmp
${MD5CMP} ${MD5_JPEG_RGB_ISLOW} testout_rgb_islow.jpg)
# CC: null SAMP: fullsize IDCT: islow ENT: huff
add_test(djpeg${suffix}-rgb-islow
${dir}djpeg${suffix} -dct int -ppm
-outfile testout_rgb_islow.ppm testout_rgb_islow.jpg)
add_test(djpeg${suffix}-rgb-islow-cmp
${MD5CMP} ${MD5_PPM_RGB_ISLOW} testout_rgb_islow.ppm)
if(NOT WITH_12BIT)
# CC: RGB->RGB565 SAMP: fullsize IDCT: islow ENT: huff
add_test(djpeg${suffix}-rgb-islow-565
${dir}djpeg${suffix} -dct int -rgb565 -dither none -bmp
-outfile testout_rgb_islow_565.bmp testout_rgb_islow.jpg)
add_test(djpeg${suffix}-rgb-islow-565-cmp
${MD5CMP} ${MD5_BMP_RGB_ISLOW_565} testout_rgb_islow_565.bmp)
# CC: RGB->RGB565 (dithered) SAMP: fullsize IDCT: islow ENT: huff
add_test(djpeg${suffix}-rgb-islow-565D
${dir}djpeg${suffix} -dct int -rgb565 -bmp
-outfile testout_rgb_islow_565D.bmp testout_rgb_islow.jpg)
add_test(djpeg${suffix}-rgb-islow-565D-cmp
${MD5CMP} ${MD5_BMP_RGB_ISLOW_565D} testout_rgb_islow_565D.bmp)
endif()
# CC: RGB->YCC SAMP: fullsize/h2v1 FDCT: ifast ENT: 2-pass huff
add_test(cjpeg${suffix}-422-ifast-opt
${dir}cjpeg${suffix} -sample 2x1 -dct fast -opt
-outfile testout_422_ifast_opt.jpg ${TESTIMAGES}/testorig.ppm)
add_test(cjpeg${suffix}-422-ifast-opt-cmp
${MD5CMP} ${MD5_JPEG_422_IFAST_OPT} testout_422_ifast_opt.jpg)
# CC: YCC->RGB SAMP: fullsize/h2v1 fancy IDCT: ifast ENT: huff
add_test(djpeg${suffix}-422-ifast
${dir}djpeg${suffix} -dct fast
-outfile testout_422_ifast.ppm testout_422_ifast_opt.jpg)
add_test(djpeg${suffix}-422-ifast-cmp
${MD5CMP} ${MD5_PPM_422_IFAST} testout_422_ifast.ppm)
# CC: YCC->RGB SAMP: h2v1 merged IDCT: ifast ENT: huff
add_test(djpeg${suffix}-422m-ifast
${dir}djpeg${suffix} -dct fast -nosmooth
-outfile testout_422m_ifast.ppm testout_422_ifast_opt.jpg)
add_test(djpeg${suffix}-422m-ifast-cmp
${MD5CMP} ${MD5_PPM_422M_IFAST} testout_422m_ifast.ppm)
if(NOT WITH_12BIT)
# CC: YCC->RGB565 SAMP: h2v1 merged IDCT: ifast ENT: huff
add_test(djpeg${suffix}-422m-ifast-565
${dir}djpeg${suffix} -dct int -nosmooth -rgb565 -dither none -bmp
-outfile testout_422m_ifast_565.bmp testout_422_ifast_opt.jpg)
add_test(djpeg${suffix}-422m-ifast-565-cmp
${MD5CMP} ${MD5_BMP_422M_IFAST_565} testout_422m_ifast_565.bmp)
# CC: YCC->RGB565 (dithered) SAMP: h2v1 merged IDCT: ifast ENT: huff
add_test(djpeg${suffix}-422m-ifast-565D
${dir}djpeg${suffix} -dct int -nosmooth -rgb565 -bmp
-outfile testout_422m_ifast_565D.bmp testout_422_ifast_opt.jpg)
add_test(djpeg${suffix}-422m-ifast-565D-cmp
${MD5CMP} ${MD5_BMP_422M_IFAST_565D} testout_422m_ifast_565D.bmp)
endif()
# CC: RGB->YCC SAMP: fullsize/h2v2 FDCT: ifast ENT: prog huff
add_test(cjpeg${suffix}-420-q100-ifast-prog
${dir}cjpeg${suffix} -sample 2x2 -quality 100 -dct fast -prog
-outfile testout_420_q100_ifast_prog.jpg ${TESTIMAGES}/testorig.ppm)
add_test(cjpeg${suffix}-420-q100-ifast-prog-cmp
${MD5CMP} ${MD5_JPEG_420_IFAST_Q100_PROG} testout_420_q100_ifast_prog.jpg)
# CC: YCC->RGB SAMP: fullsize/h2v2 fancy IDCT: ifast ENT: prog huff
add_test(djpeg${suffix}-420-q100-ifast-prog
${dir}djpeg${suffix} -dct fast
-outfile testout_420_q100_ifast.ppm testout_420_q100_ifast_prog.jpg)
add_test(djpeg${suffix}-420-q100-ifast-prog-cmp
${MD5CMP} ${MD5_PPM_420_Q100_IFAST} testout_420_q100_ifast.ppm)
# CC: YCC->RGB SAMP: h2v2 merged IDCT: ifast ENT: prog huff
add_test(djpeg${suffix}-420m-q100-ifast-prog
${dir}djpeg${suffix} -dct fast -nosmooth
-outfile testout_420m_q100_ifast.ppm testout_420_q100_ifast_prog.jpg)
add_test(djpeg${suffix}-420m-q100-ifast-prog-cmp
${MD5CMP} ${MD5_PPM_420M_Q100_IFAST} testout_420m_q100_ifast.ppm)
# CC: RGB->Gray SAMP: fullsize FDCT: islow ENT: huff
add_test(cjpeg${suffix}-gray-islow
${dir}cjpeg${suffix} -gray -dct int
-outfile testout_gray_islow.jpg ${TESTIMAGES}/testorig.ppm)
add_test(cjpeg${suffix}-gray-islow-cmp
${MD5CMP} ${MD5_JPEG_GRAY_ISLOW} testout_gray_islow.jpg)
# CC: Gray->Gray SAMP: fullsize IDCT: islow ENT: huff
add_test(djpeg${suffix}-gray-islow
${dir}djpeg${suffix} -dct int
-outfile testout_gray_islow.ppm testout_gray_islow.jpg)
add_test(djpeg${suffix}-gray-islow-cmp
${MD5CMP} ${MD5_PPM_GRAY_ISLOW} testout_gray_islow.ppm)
# CC: Gray->RGB SAMP: fullsize IDCT: islow ENT: huff
add_test(djpeg${suffix}-gray-islow-rgb
${dir}djpeg${suffix} -dct int -rgb
-outfile testout_gray_islow_rgb.ppm testout_gray_islow.jpg)
add_test(djpeg${suffix}-gray-islow-rgb-cmp
${MD5CMP} ${MD5_PPM_GRAY_ISLOW_RGB} testout_gray_islow_rgb.ppm)
if(NOT WITH_12BIT)
# CC: Gray->RGB565 SAMP: fullsize IDCT: islow ENT: huff
add_test(djpeg${suffix}-gray-islow-565
${dir}djpeg${suffix} -dct int -rgb565 -dither none -bmp
-outfile testout_gray_islow_565.bmp testout_gray_islow.jpg)
add_test(djpeg${suffix}-gray-islow-565-cmp
${MD5CMP} ${MD5_BMP_GRAY_ISLOW_565} testout_gray_islow_565.bmp)
# CC: Gray->RGB565 (dithered) SAMP: fullsize IDCT: islow ENT: huff
add_test(djpeg${suffix}-gray-islow-565D
${dir}djpeg${suffix} -dct int -rgb565 -bmp
-outfile testout_gray_islow_565D.bmp testout_gray_islow.jpg)
add_test(djpeg${suffix}-gray-islow-565D-cmp
${MD5CMP} ${MD5_BMP_GRAY_ISLOW_565D} testout_gray_islow_565D.bmp)
endif()
# CC: RGB->YCC SAMP: fullsize smooth/h2v2 smooth FDCT: islow
# ENT: 2-pass huff
add_test(cjpeg${suffix}-420s-ifast-opt
${dir}cjpeg${suffix} -sample 2x2 -smooth 1 -dct int -opt
-outfile testout_420s_ifast_opt.jpg ${TESTIMAGES}/testorig.ppm)
add_test(cjpeg${suffix}-420s-ifast-opt-cmp
${MD5CMP} ${MD5_JPEG_420S_IFAST_OPT} testout_420s_ifast_opt.jpg)
# CC: RGB->YCC SAMP: fullsize/int FDCT: float ENT: prog huff
add_test(cjpeg${suffix}-3x2-float-prog
${dir}cjpeg${suffix} -sample 3x2 -dct float -prog
-outfile testout_3x2_float_prog.jpg ${TESTIMAGES}/testorig.ppm)
add_test(cjpeg${suffix}-3x2-float-prog-cmp
${MD5CMP} ${MD5_JPEG_3x2_FLOAT_PROG} testout_3x2_float_prog.jpg)
# CC: YCC->RGB SAMP: fullsize/int IDCT: float ENT: prog huff
add_test(djpeg${suffix}-3x2-float-prog
${dir}djpeg${suffix} -dct float
-outfile testout_3x2_float.ppm testout_3x2_float_prog.jpg)
add_test(djpeg${suffix}-3x2-float-prog-cmp
${MD5CMP} ${MD5_PPM_3x2_FLOAT} testout_3x2_float.ppm)
if(WITH_ARITH_ENC)
# CC: YCC->RGB SAMP: fullsize/h2v2 FDCT: islow ENT: arith
add_test(cjpeg${suffix}-420-islow-ari
${dir}cjpeg${suffix} -dct int -arithmetic
-outfile testout_420_islow_ari.jpg ${TESTIMAGES}/testorig.ppm)
add_test(cjpeg${suffix}-420-islow-ari-cmp
${MD5CMP} ${MD5_JPEG_420_ISLOW_ARI} testout_420_islow_ari.jpg)
add_test(jpegtran${suffix}-420-islow-ari
${dir}jpegtran${suffix} -arithmetic
-outfile testout_420_islow_ari.jpg ${TESTIMAGES}/testimgint.jpg)
add_test(jpegtran${suffix}-420-islow-ari-cmp
${MD5CMP} ${MD5_JPEG_420_ISLOW_ARI} testout_420_islow_ari.jpg)
# CC: YCC->RGB SAMP: fullsize FDCT: islow ENT: prog arith
add_test(cjpeg${suffix}-444-islow-progari
${dir}cjpeg${suffix} -sample 1x1 -dct int -prog -arithmetic
-outfile testout_444_islow_progari.jpg ${TESTIMAGES}/testorig.ppm)
add_test(cjpeg${suffix}-444-islow-progari-cmp
${MD5CMP} ${MD5_JPEG_444_ISLOW_PROGARI} testout_444_islow_progari.jpg)
endif()
if(WITH_ARITH_DEC)
# CC: RGB->YCC SAMP: h2v2 merged IDCT: ifast ENT: arith
add_test(djpeg${suffix}-420m-ifast-ari
${dir}djpeg${suffix} -fast -ppm
-outfile testout_420m_ifast_ari.ppm ${TESTIMAGES}/testimgari.jpg)
add_test(djpeg${suffix}-420m-ifast-ari-cmp
${MD5CMP} ${MD5_PPM_420M_IFAST_ARI} testout_420m_ifast_ari.ppm)
add_test(jpegtran${suffix}-420-islow
${dir}jpegtran${suffix}
-outfile testout_420_islow.jpg ${TESTIMAGES}/testimgari.jpg)
add_test(jpegtran${suffix}-420-islow-cmp
${MD5CMP} ${MD5_JPEG_420_ISLOW} testout_420_islow.jpg)
endif()
# 2/1-- CC: YCC->RGB SAMP: h2v2 merged IDCT: 16x16 islow ENT: huff
# 15/8-- CC: YCC->RGB SAMP: h2v2 merged IDCT: 15x15 islow ENT: huff
# 13/8-- CC: YCC->RGB SAMP: h2v2 merged IDCT: 13x13 islow ENT: huff
# 11/8-- CC: YCC->RGB SAMP: h2v2 merged IDCT: 11x11 islow ENT: huff
# 9/8-- CC: YCC->RGB SAMP: h2v2 merged IDCT: 9x9 islow ENT: huff
# 7/8-- CC: YCC->RGB SAMP: h2v2 merged IDCT: 7x7 islow/14x14 islow
# ENT: huff
# 3/4-- CC: YCC->RGB SAMP: h2v2 merged IDCT: 6x6 islow/12x12 islow
# ENT: huff
# 5/8-- CC: YCC->RGB SAMP: h2v2 merged IDCT: 5x5 islow/10x10 islow
# ENT: huff
# 1/2-- CC: YCC->RGB SAMP: h2v2 merged IDCT: 4x4 islow/8x8 islow
# ENT: huff
# 3/8-- CC: YCC->RGB SAMP: h2v2 merged IDCT: 3x3 islow/6x6 islow
# ENT: huff
# 1/4-- CC: YCC->RGB SAMP: h2v2 merged IDCT: 2x2 islow/4x4 islow
# ENT: huff
# 1/8-- CC: YCC->RGB SAMP: h2v2 merged IDCT: 1x1 islow/2x2 islow
# ENT: huff
foreach(scale 2_1 15_8 13_8 11_8 9_8 7_8 3_4 5_8 1_2 3_8 1_4 1_8)
string(REGEX REPLACE "_" "/" scalearg ${scale})
add_test(djpeg${suffix}-420m-islow-${scale}
${dir}djpeg${suffix} -dct int -scale ${scalearg} -nosmooth -ppm
-outfile testout_420m_islow_${scale}.ppm ${TESTIMAGES}/${TESTORIG})
add_test(djpeg${suffix}-420m-islow-${scale}-cmp
${MD5CMP} ${MD5_PPM_420M_ISLOW_${scale}} testout_420m_islow_${scale}.ppm)
endforeach()
if(NOT WITH_12BIT)
# CC: YCC->RGB (dithered) SAMP: h2v2 fancy IDCT: islow ENT: huff
add_test(djpeg${suffix}-420-islow-256
${dir}djpeg${suffix} -dct int -colors 256 -bmp
-outfile testout_420_islow_256.bmp ${TESTIMAGES}/${TESTORIG})
add_test(djpeg${suffix}-420-islow-256-cmp
${MD5CMP} ${MD5_BMP_420_ISLOW_256} testout_420_islow_256.bmp)
# CC: YCC->RGB565 SAMP: h2v2 fancy IDCT: islow ENT: huff
add_test(djpeg${suffix}-420-islow-565
${dir}djpeg${suffix} -dct int -rgb565 -dither none -bmp
-outfile testout_420_islow_565.bmp ${TESTIMAGES}/${TESTORIG})
add_test(djpeg${suffix}-420-islow-565-cmp
${MD5CMP} ${MD5_BMP_420_ISLOW_565} testout_420_islow_565.bmp)
# CC: YCC->RGB565 (dithered) SAMP: h2v2 fancy IDCT: islow ENT: huff
add_test(djpeg${suffix}-420-islow-565D
${dir}djpeg${suffix} -dct int -rgb565 -bmp
-outfile testout_420_islow_565D.bmp ${TESTIMAGES}/${TESTORIG})
add_test(djpeg${suffix}-420-islow-565D-cmp
${MD5CMP} ${MD5_BMP_420_ISLOW_565D} testout_420_islow_565D.bmp)
# CC: YCC->RGB565 SAMP: h2v2 merged IDCT: islow ENT: huff
add_test(djpeg${suffix}-420m-islow-565
${dir}djpeg${suffix} -dct int -nosmooth -rgb565 -dither none -bmp
-outfile testout_420m_islow_565.bmp ${TESTIMAGES}/${TESTORIG})
add_test(djpeg${suffix}-420m-islow-565-cmp
${MD5CMP} ${MD5_BMP_420M_ISLOW_565} testout_420m_islow_565.bmp)
# CC: YCC->RGB565 (dithered) SAMP: h2v2 merged IDCT: islow ENT: huff
add_test(djpeg${suffix}-420m-islow-565D
${dir}djpeg${suffix} -dct int -nosmooth -rgb565 -bmp
-outfile testout_420m_islow_565D.bmp ${TESTIMAGES}/${TESTORIG})
add_test(djpeg${suffix}-420m-islow-565D-cmp
${MD5CMP} ${MD5_BMP_420M_ISLOW_565D} testout_420m_islow_565D.bmp)
endif()
# Partial decode tests. These tests are designed to cover all of the
# possible code paths in jpeg_skip_scanlines().
# Context rows: Yes Intra-iMCU row: Yes iMCU row prefetch: No ENT: huff
add_test(djpeg${suffix}-420-islow-skip15_31
${dir}djpeg${suffix} -dct int -skip 15,31 -ppm
-outfile testout_420_islow_skip15,31.ppm ${TESTIMAGES}/${TESTORIG})
add_test(djpeg${suffix}-420-islow-skip15_31-cmp
${MD5CMP} ${MD5_PPM_420_ISLOW_SKIP15_31} testout_420_islow_skip15,31.ppm)
# Context rows: Yes Intra-iMCU row: No iMCU row prefetch: Yes ENT: arith
if(WITH_ARITH_DEC)
add_test(djpeg${suffix}-420-islow-ari-skip16_139
${dir}djpeg${suffix} -dct int -skip 16,139 -ppm
-outfile testout_420_islow_ari_skip16,139.ppm
${TESTIMAGES}/testimgari.jpg)
add_test(djpeg${suffix}-420-islow-ari_skip16_139-cmp
${MD5CMP} ${MD5_PPM_420_ISLOW_ARI_SKIP16_139}
testout_420_islow_ari_skip16,139.ppm)
endif()
# Context rows: Yes Intra-iMCU row: No iMCU row prefetch: No ENT: prog huff
add_test(cjpeg${suffix}-420-islow-prog
${dir}cjpeg${suffix} -dct int -prog
-outfile testout_420_islow_prog.jpg ${TESTIMAGES}/testorig.ppm)
add_test(djpeg${suffix}-420-islow-prog-crop62x62_71_71
${dir}djpeg${suffix} -dct int -crop 62x62+71+71 -ppm
-outfile testout_420_islow_prog_crop62x62,71,71.ppm
testout_420_islow_prog.jpg)
add_test(djpeg${suffix}-420-islow-prog-crop62x62_71_71-cmp
${MD5CMP} ${MD5_PPM_420_ISLOW_PROG_CROP62x62_71_71}
testout_420_islow_prog_crop62x62,71,71.ppm)
# Context rows: Yes Intra-iMCU row: No iMCU row prefetch: No ENT: arith
if(WITH_ARITH_DEC)
add_test(djpeg${suffix}-420-islow-ari-crop53x53_4_4
${dir}djpeg${suffix} -dct int -crop 53x53+4+4 -ppm
-outfile testout_420_islow_ari_crop53x53,4,4.ppm
${TESTIMAGES}/testimgari.jpg)
add_test(djpeg${suffix}-420-islow-ari-crop53x53_4_4-cmp
${MD5CMP} ${MD5_PPM_420_ISLOW_ARI_CROP53x53_4_4}
testout_420_islow_ari_crop53x53,4,4.ppm)
endif()
# Context rows: No Intra-iMCU row: Yes ENT: huff
add_test(cjpeg${suffix}-444-islow
${dir}cjpeg${suffix} -dct int -sample 1x1
-outfile testout_444_islow.jpg ${TESTIMAGES}/testorig.ppm)
add_test(djpeg${suffix}-444-islow-skip1_6
${dir}djpeg${suffix} -dct int -skip 1,6 -ppm
-outfile testout_444_islow_skip1,6.ppm testout_444_islow.jpg)
add_test(djpeg${suffix}-444-islow-skip1_6-cmp
${MD5CMP} ${MD5_PPM_444_ISLOW_SKIP1_6} testout_444_islow_skip1,6.ppm)
# Context rows: No Intra-iMCU row: No ENT: prog huff
add_test(cjpeg${suffix}-444-islow-prog
${dir}cjpeg${suffix} -dct int -prog -sample 1x1
-outfile testout_444_islow_prog.jpg ${TESTIMAGES}/testorig.ppm)
add_test(djpeg${suffix}-444-islow-prog-crop98x98_13_13
${dir}djpeg${suffix} -dct int -crop 98x98+13+13 -ppm
-outfile testout_444_islow_prog_crop98x98,13,13.ppm
testout_444_islow_prog.jpg)
add_test(djpeg${suffix}-444-islow-prog_crop98x98_13_13-cmp
${MD5CMP} ${MD5_PPM_444_ISLOW_PROG_CROP98x98_13_13}
testout_444_islow_prog_crop98x98,13,13.ppm)
# Context rows: No Intra-iMCU row: No ENT: arith
if(WITH_ARITH_ENC)
add_test(cjpeg${suffix}-444-islow-ari
${dir}cjpeg${suffix} -dct int -arithmetic -sample 1x1
-outfile testout_444_islow_ari.jpg ${TESTIMAGES}/testorig.ppm)
if(WITH_ARITH_DEC)
add_test(djpeg${suffix}-444-islow-ari-crop37x37_0_0
${dir}djpeg${suffix} -dct int -crop 37x37+0+0 -ppm
-outfile testout_444_islow_ari_crop37x37,0,0.ppm
testout_444_islow_ari.jpg)
add_test(djpeg${suffix}-444-islow-ari-crop37x37_0_0-cmp
${MD5CMP} ${MD5_PPM_444_ISLOW_ARI_CROP37x37_0_0}
testout_444_islow_ari_crop37x37,0,0.ppm)
endif()
endif()
add_test(jpegtran${suffix}-crop
${dir}jpegtran${suffix} -crop 120x90+20+50 -transpose -perfect
-outfile testout_crop.jpg ${TESTIMAGES}/${TESTORIG})
add_test(jpegtran${suffix}-crop-cmp
${MD5CMP} ${MD5_JPEG_CROP} testout_crop.jpg)
endforeach()
add_custom_target(testclean COMMAND ${MD5CMP} -P
${CMAKE_SOURCE_DIR}/cmakescripts/testclean.cmake)
#
# Installer
#
if(MSVC)
set(INST_PLATFORM "Visual C++")
set(INST_NAME ${CMAKE_PROJECT_NAME}-${VERSION}-vc)
set(INST_REG_NAME ${CMAKE_PROJECT_NAME})
elseif(MINGW)
set(INST_PLATFORM GCC)
set(INST_NAME ${CMAKE_PROJECT_NAME}-${VERSION}-gcc)
set(INST_REG_NAME ${CMAKE_PROJECT_NAME}-gcc)
set(INST_DEFS -DGCC)
endif()
if(64BIT)
set(INST_PLATFORM "${INST_PLATFORM} 64-bit")
set(INST_NAME ${INST_NAME}64)
set(INST_REG_NAME ${INST_DIR}64)
set(INST_DEFS ${INST_DEFS} -DWIN64)
endif()
if(WITH_JAVA)
set(INST_DEFS ${INST_DEFS} -DJAVA)
endif()
if(MSVC_IDE)
set(INST_DEFS ${INST_DEFS} "-DBUILDDIR=${CMAKE_CFG_INTDIR}\\")
else()
set(INST_DEFS ${INST_DEFS} "-DBUILDDIR=")
endif()
STRING(REGEX REPLACE "/" "\\\\" INST_DIR ${CMAKE_INSTALL_PREFIX})
configure_file(release/libjpeg-turbo.nsi.in libjpeg-turbo.nsi @ONLY)
if(WITH_JAVA)
set(JAVA_DEPEND java)
endif()
add_custom_target(installer
makensis -nocd ${INST_DEFS} libjpeg-turbo.nsi
DEPENDS jpeg jpeg-static turbojpeg turbojpeg-static rdjpgcom wrjpgcom
cjpeg djpeg jpegtran tjbench ${JAVA_DEPEND}
SOURCES libjpeg-turbo.nsi)
if(WITH_TURBOJPEG)
if(ENABLE_SHARED)
install(TARGETS turbojpeg tjbench
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin)
endif()
if(ENABLE_STATIC)
install(TARGETS turbojpeg-static ARCHIVE DESTINATION lib)
if(NOT ENABLE_SHARED)
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/tjbench-static.exe
DESTINATION bin RENAME tjbench.exe)
endif()
endif()
install(FILES ${CMAKE_SOURCE_DIR}/turbojpeg.h DESTINATION include)
endif()
if(ENABLE_STATIC)
install(TARGETS jpeg-static ARCHIVE DESTINATION lib)
if(NOT ENABLE_SHARED)
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/cjpeg-static.exe
DESTINATION bin RENAME cjpeg.exe)
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/djpeg-static.exe
DESTINATION bin RENAME djpeg.exe)
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/jpegtran-static.exe
DESTINATION bin RENAME jpegtran.exe)
endif()
endif()
install(TARGETS rdjpgcom wrjpgcom RUNTIME DESTINATION bin)
install(FILES ${CMAKE_SOURCE_DIR}/README.ijg ${CMAKE_SOURCE_DIR}/README.md
${CMAKE_SOURCE_DIR}/example.c ${CMAKE_SOURCE_DIR}/libjpeg.txt
${CMAKE_SOURCE_DIR}/structure.txt ${CMAKE_SOURCE_DIR}/usage.txt
${CMAKE_SOURCE_DIR}/wizard.txt
DESTINATION doc)
install(FILES ${CMAKE_BINARY_DIR}/jconfig.h ${CMAKE_SOURCE_DIR}/jerror.h
${CMAKE_SOURCE_DIR}/jmorecfg.h ${CMAKE_SOURCE_DIR}/jpeglib.h
DESTINATION include)
File diff suppressed because it is too large Load Diff
-88
View File
@@ -1,88 +0,0 @@
libjpeg-turbo Licenses
======================
libjpeg-turbo is covered by three compatible BSD-style open source licenses:
- The IJG (Independent JPEG Group) License, which is listed in
[README.ijg](README.ijg)
This license applies to the libjpeg API library and associated programs
(any code inherited from libjpeg, and any modifications to that code.)
- The Modified (3-clause) BSD License, which is listed in
[turbojpeg.c](turbojpeg.c)
This license covers the TurboJPEG API library and associated programs.
- The zlib License, which is listed in [simd/jsimdext.inc](simd/jsimdext.inc)
This license is a subset of the other two, and it covers the libjpeg-turbo
SIMD extensions.
Complying with the libjpeg-turbo Licenses
=========================================
This section provides a roll-up of the libjpeg-turbo licensing terms, to the
best of our understanding.
1. If you are distributing a modified version of the libjpeg-turbo source,
then:
1. You cannot alter or remove any existing copyright or license notices
from the source.
**Origin**
- Clause 1 of the IJG License
- Clause 1 of the Modified BSD License
- Clauses 1 and 3 of the zlib License
2. You must add your own copyright notice to the header of each source
file you modified, so others can tell that you modified that file (if
there is not an existing copyright header in that file, then you can
simply add a notice stating that you modified the file.)
**Origin**
- Clause 1 of the IJG License
- Clause 2 of the zlib License
3. You must include the IJG README file, and you must not alter any of the
copyright or license text in that file.
**Origin**
- Clause 1 of the IJG License
2. If you are distributing only libjpeg-turbo binaries without the source, or
if you are distributing an application that statically links with
libjpeg-turbo, then:
1. Your product documentation must include a message stating:
This software is based in part on the work of the Independent JPEG
Group.
**Origin**
- Clause 2 of the IJG license
2. If your binary distribution includes or uses the TurboJPEG API, then
your product documentation must include the text of the Modified BSD
License.
**Origin**
- Clause 2 of the Modified BSD License
3. You cannot use the name of the IJG or The libjpeg-turbo Project or the
contributors thereof in advertising, publicity, etc.
**Origin**
- IJG License
- Clause 3 of the Modified BSD License
4. The IJG and The libjpeg-turbo Project do not warrant libjpeg-turbo to be
free of defects, nor do we accept any liability for undesirable
consequences resulting from your use of the software.
**Origin**
- IJG License
- Modified BSD License
- zlib License

Some files were not shown because too many files have changed in this diff Show More