mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
Merging gst-build
This commit is contained in:
commit
d975e07edc
98 changed files with 3699 additions and 0 deletions
93
.gitignore
vendored
Normal file
93
.gitignore
vendored
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
*build*/
|
||||||
|
cscope.in.out
|
||||||
|
cscope.out
|
||||||
|
cscope.po.out
|
||||||
|
gst-devtools
|
||||||
|
gst-editing-services
|
||||||
|
gst-examples
|
||||||
|
gst-integration-testsuites
|
||||||
|
gst-libav
|
||||||
|
gst-omx
|
||||||
|
gst-plugins-bad
|
||||||
|
gst-plugins-base
|
||||||
|
gst-plugins-good
|
||||||
|
gst-plugins-rs
|
||||||
|
gst-plugins-ugly
|
||||||
|
gst-python
|
||||||
|
gst-rtsp-server
|
||||||
|
gstreamer
|
||||||
|
gstreamer-sharp
|
||||||
|
gstreamer-vaapi
|
||||||
|
libnice
|
||||||
|
__pycache__
|
||||||
|
meson/
|
||||||
|
subprojects/packagecache/
|
||||||
|
subprojects/gst-integration-testsuites
|
||||||
|
subprojects/gst-devtools
|
||||||
|
subprojects/gst-docs
|
||||||
|
subprojects/gst-editing-services
|
||||||
|
subprojects/gst-examples
|
||||||
|
subprojects/gst-libav
|
||||||
|
subprojects/gst-omx
|
||||||
|
subprojects/gst-plugins-bad
|
||||||
|
subprojects/gst-plugins-base
|
||||||
|
subprojects/gst-plugins-good
|
||||||
|
subprojects/gst-plugins-rs
|
||||||
|
subprojects/gst-plugins-ugly
|
||||||
|
subprojects/gst-python
|
||||||
|
subprojects/gst-rtsp-server
|
||||||
|
subprojects/gstreamer
|
||||||
|
subprojects/gstreamer-sharp
|
||||||
|
subprojects/gstreamer-vaapi
|
||||||
|
subprojects/glib
|
||||||
|
subprojects/glib-networking
|
||||||
|
subprojects/gl-headers
|
||||||
|
subprojects/bindinator
|
||||||
|
subprojects/dssim
|
||||||
|
subprojects/gtk-sharp
|
||||||
|
subprojects/libffi
|
||||||
|
subprojects/libnice
|
||||||
|
subprojects/libunwind
|
||||||
|
subprojects/proxy-libintl
|
||||||
|
subprojects/zlib*
|
||||||
|
subprojects/openh264
|
||||||
|
subprojects/pygobject
|
||||||
|
subprojects/pycairo
|
||||||
|
subprojects/json-glib
|
||||||
|
subprojects/orc
|
||||||
|
subprojects/libsoup
|
||||||
|
subprojects/FFmpeg
|
||||||
|
subprojects/x264
|
||||||
|
subprojects/libxml2-*
|
||||||
|
subprojects/sqlite-*
|
||||||
|
subprojects/libdrm-*
|
||||||
|
subprojects/openjpeg*
|
||||||
|
subprojects/avtp
|
||||||
|
subprojects/graphene
|
||||||
|
subprojects/libmicrodns
|
||||||
|
subprojects/libpsl
|
||||||
|
subprojects/libwpe
|
||||||
|
subprojects/wpebackend-fdo
|
||||||
|
subprojects/cairo
|
||||||
|
subprojects/expat-*
|
||||||
|
subprojects/fontconfig
|
||||||
|
subprojects/freetype2
|
||||||
|
subprojects/fribidi
|
||||||
|
subprojects/gobject-introspection.wrap
|
||||||
|
subprojects/gobject-introspection
|
||||||
|
subprojects/googletest-*
|
||||||
|
subprojects/gperf.wrap
|
||||||
|
subprojects/gperf
|
||||||
|
subprojects/gtest.wrap
|
||||||
|
subprojects/harfbuzz
|
||||||
|
subprojects/libpng-*
|
||||||
|
subprojects/libpng.wrap
|
||||||
|
subprojects/pango
|
||||||
|
subprojects/pixman
|
||||||
|
subprojects/webrtc-audio-processing
|
||||||
|
subprojects/dv
|
||||||
|
subprojects/opus
|
||||||
|
subprojects/libjpeg-turbo-*
|
||||||
|
prefix/
|
||||||
|
pygobject
|
||||||
|
.gdbinit
|
1
.gitlab-ci.yml
Normal file
1
.gitlab-ci.yml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
include: 'https://gitlab.freedesktop.org/gstreamer/gst-ci/raw/master/gitlab/ci_template.yml'
|
32
.gitlab/issue_templates/Bug.md
Normal file
32
.gitlab/issue_templates/Bug.md
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
### Describe your issue
|
||||||
|
<!-- a clear and concise summary of the bug. -->
|
||||||
|
<!-- For any GStreamer usage question, please contact the community using the #gstreamer channel on IRC https://www.oftc.net/ or the mailing list on https://gstreamer.freedesktop.org/lists/ -->
|
||||||
|
|
||||||
|
#### Expected Behavior
|
||||||
|
<!-- What did you expect to happen -->
|
||||||
|
|
||||||
|
#### Observed Behavior
|
||||||
|
<!-- What actually happened -->
|
||||||
|
|
||||||
|
#### Setup
|
||||||
|
- **Operating System:**
|
||||||
|
- **Device:** Computer / Tablet / Mobile / Virtual Machine <!-- Delete as appropriate !-->
|
||||||
|
- **GStreamer Version:**
|
||||||
|
- **Command line:**
|
||||||
|
|
||||||
|
### Steps to reproduce the bug
|
||||||
|
<!-- please fill in exact steps which reproduce the bug on your system, for example: -->
|
||||||
|
1. open terminal
|
||||||
|
2. type `command`
|
||||||
|
|
||||||
|
### How reproducible is the bug?
|
||||||
|
<!-- The reproducibility of the bug is Always/Intermittent/Only once after doing a very specific set of steps-->
|
||||||
|
|
||||||
|
### Screenshots if relevant
|
||||||
|
|
||||||
|
### Solutions you have tried
|
||||||
|
|
||||||
|
### Related non-duplicate issues
|
||||||
|
|
||||||
|
### Additional Information
|
||||||
|
<!-- Any other information such as logs. Make use of <details> for long output -->
|
0
.gitmodules
vendored
Normal file
0
.gitmodules
vendored
Normal file
481
LICENSE
Normal file
481
LICENSE
Normal file
|
@ -0,0 +1,481 @@
|
||||||
|
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||||
|
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the library GPL. It is
|
||||||
|
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
Licenses are intended to guarantee your freedom to share and change
|
||||||
|
free software--to make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Library General Public License, applies to some
|
||||||
|
specially designated Free Software Foundation software, and to any
|
||||||
|
other libraries whose authors decide to use it. You can use it for
|
||||||
|
your libraries, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if
|
||||||
|
you distribute copies of the library, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis
|
||||||
|
or for a fee, you must give the recipients all the rights that we gave
|
||||||
|
you. You must make sure that they, too, receive or can get the source
|
||||||
|
code. If you link a program with the library, you must provide
|
||||||
|
complete object files to the recipients so that they can relink them
|
||||||
|
with the library, after making changes to the library and recompiling
|
||||||
|
it. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
|
Our method of protecting your rights has two steps: (1) copyright
|
||||||
|
the library, and (2) offer you this license which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
Also, for each distributor's protection, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
library. If the library is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original
|
||||||
|
version, so that any problems introduced by others will not reflect on
|
||||||
|
the original authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that companies distributing free
|
||||||
|
software will individually obtain patent licenses, thus in effect
|
||||||
|
transforming the program into proprietary software. To prevent this,
|
||||||
|
we have made it clear that any patent must be licensed for everyone's
|
||||||
|
free use or not licensed at all.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the ordinary
|
||||||
|
GNU General Public License, which was designed for utility programs. This
|
||||||
|
license, the GNU Library General Public License, applies to certain
|
||||||
|
designated libraries. This license is quite different from the ordinary
|
||||||
|
one; be sure to read it in full, and don't assume that anything in it is
|
||||||
|
the same as in the ordinary license.
|
||||||
|
|
||||||
|
The reason we have a separate public license for some libraries is that
|
||||||
|
they blur the distinction we usually make between modifying or adding to a
|
||||||
|
program and simply using it. Linking a program with a library, without
|
||||||
|
changing the library, is in some sense simply using the library, and is
|
||||||
|
analogous to running a utility program or application program. However, in
|
||||||
|
a textual and legal sense, the linked executable is a combined work, a
|
||||||
|
derivative of the original library, and the ordinary General Public License
|
||||||
|
treats it as such.
|
||||||
|
|
||||||
|
Because of this blurred distinction, using the ordinary General
|
||||||
|
Public License for libraries did not effectively promote software
|
||||||
|
sharing, because most developers did not use the libraries. We
|
||||||
|
concluded that weaker conditions might promote sharing better.
|
||||||
|
|
||||||
|
However, unrestricted linking of non-free programs would deprive the
|
||||||
|
users of those programs of all benefit from the free status of the
|
||||||
|
libraries themselves. This Library General Public License is intended to
|
||||||
|
permit developers of non-free programs to use free libraries, while
|
||||||
|
preserving your freedom as a user of such programs to change the free
|
||||||
|
libraries that are incorporated in them. (We have not seen how to achieve
|
||||||
|
this as regards changes in header files, but we have achieved it as regards
|
||||||
|
changes in the actual functions of the Library.) The hope is that this
|
||||||
|
will lead to faster development of free libraries.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow. Pay close attention to the difference between a
|
||||||
|
"work based on the library" and a "work that uses the library". The
|
||||||
|
former contains code derived from the library, while the latter only
|
||||||
|
works together with the library.
|
||||||
|
|
||||||
|
Note that it is possible for a library to be covered by the ordinary
|
||||||
|
General Public License rather than by this special one.
|
||||||
|
|
||||||
|
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library which
|
||||||
|
contains a notice placed by the copyright holder or other authorized
|
||||||
|
party saying it may be distributed under the terms of this Library
|
||||||
|
General Public License (also called "this License"). Each licensee is
|
||||||
|
addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work
|
||||||
|
which has been distributed under these terms. A "work based on the
|
||||||
|
Library" means either the Library or any derivative work under
|
||||||
|
copyright law: that is to say, a work containing the Library or a
|
||||||
|
portion of it, either verbatim or with modifications and/or translated
|
||||||
|
straightforwardly into another language. (Hereinafter, translation is
|
||||||
|
included without limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For a library, complete source code means
|
||||||
|
all the source code for all modules it contains, plus any associated
|
||||||
|
interface definition files, plus the scripts used to control compilation
|
||||||
|
and installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running a program using the Library is not restricted, and output from
|
||||||
|
such a program is covered only if its contents constitute a work based
|
||||||
|
on the Library (independent of the use of the Library in a tool for
|
||||||
|
writing it). Whether that is true depends on what the Library does
|
||||||
|
and what the program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's
|
||||||
|
complete source code as you receive it, in any medium, provided that
|
||||||
|
you conspicuously and appropriately publish on each copy an
|
||||||
|
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||||
|
all the notices that refer to this License and to the absence of any
|
||||||
|
warranty; and distribute a copy of this License along with the
|
||||||
|
Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy,
|
||||||
|
and you may at your option offer warranty protection in exchange for a
|
||||||
|
fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion
|
||||||
|
of it, thus forming a work based on the Library, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no
|
||||||
|
charge to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a
|
||||||
|
table of data to be supplied by an application program that uses
|
||||||
|
the facility, other than as an argument passed when the facility
|
||||||
|
is invoked, then you must make a good faith effort to ensure that,
|
||||||
|
in the event an application does not supply such function or
|
||||||
|
table, the facility still operates, and performs whatever part of
|
||||||
|
its purpose remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has
|
||||||
|
a purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must
|
||||||
|
be optional: if the application does not supply it, the square
|
||||||
|
root function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Library, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote
|
||||||
|
it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so
|
||||||
|
that they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in
|
||||||
|
these notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for
|
||||||
|
that copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of
|
||||||
|
the Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or
|
||||||
|
derivative of it, under Section 2) in object code or executable form
|
||||||
|
under the terms of Sections 1 and 2 above provided that you accompany
|
||||||
|
it with the complete corresponding machine-readable source code, which
|
||||||
|
must be distributed under the terms of Sections 1 and 2 above on a
|
||||||
|
medium customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy
|
||||||
|
from a designated place, then offering equivalent access to copy the
|
||||||
|
source code from the same place satisfies the requirement to
|
||||||
|
distribute the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the
|
||||||
|
Library, but is designed to work with the Library by being compiled or
|
||||||
|
linked with it, is called a "work that uses the Library". Such a
|
||||||
|
work, in isolation, is not a derivative work of the Library, and
|
||||||
|
therefore falls outside the scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library
|
||||||
|
creates an executable that is a derivative of the Library (because it
|
||||||
|
contains portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License.
|
||||||
|
Section 6 states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is not.
|
||||||
|
Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data
|
||||||
|
structure layouts and accessors, and small macros and small inline
|
||||||
|
functions (ten lines or less in length), then the use of the object
|
||||||
|
file is unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section 6.
|
||||||
|
Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also compile or
|
||||||
|
link a "work that uses the Library" with the Library to produce a
|
||||||
|
work containing portions of the Library, and distribute that work
|
||||||
|
under terms of your choice, provided that the terms permit
|
||||||
|
modification of the work for the customer's own use and reverse
|
||||||
|
engineering for debugging such modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work
|
||||||
|
during execution displays copyright notices, you must include the
|
||||||
|
copyright notice for the Library among them, as well as a reference
|
||||||
|
directing the user to the copy of this License. Also, you must do one
|
||||||
|
of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding
|
||||||
|
machine-readable source code for the Library including whatever
|
||||||
|
changes were used in the work (which must be distributed under
|
||||||
|
Sections 1 and 2 above); and, if the work is an executable linked
|
||||||
|
with the Library, with the complete machine-readable "work that
|
||||||
|
uses the Library", as object code and/or source code, so that the
|
||||||
|
user can modify the Library and then relink to produce a modified
|
||||||
|
executable containing the modified Library. (It is understood
|
||||||
|
that the user who changes the contents of definitions files in the
|
||||||
|
Library will not necessarily be able to recompile the application
|
||||||
|
to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Accompany the work with a written offer, valid for at
|
||||||
|
least three years, to give the same user the materials
|
||||||
|
specified in Subsection 6a, above, for a charge no more
|
||||||
|
than the cost of performing this distribution.
|
||||||
|
|
||||||
|
c) If distribution of the work is made by offering access to copy
|
||||||
|
from a designated place, offer equivalent access to copy the above
|
||||||
|
specified materials from the same place.
|
||||||
|
|
||||||
|
d) Verify that the user has already received a copy of these
|
||||||
|
materials or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the
|
||||||
|
Library" must include any data and utility programs needed for
|
||||||
|
reproducing the executable from it. However, as a special exception,
|
||||||
|
the source code distributed need not include anything that is normally
|
||||||
|
distributed (in either source or binary form) with the major
|
||||||
|
components (compiler, kernel, and so on) of the operating system on
|
||||||
|
which the executable runs, unless that component itself accompanies
|
||||||
|
the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license
|
||||||
|
restrictions of other proprietary libraries that do not normally
|
||||||
|
accompany the operating system. Such a contradiction means you cannot
|
||||||
|
use both them and the Library together in an executable that you
|
||||||
|
distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the
|
||||||
|
Library side-by-side in a single library together with other library
|
||||||
|
facilities not covered by this License, and distribute such a combined
|
||||||
|
library, provided that the separate distribution of the work based on
|
||||||
|
the Library and of the other library facilities is otherwise
|
||||||
|
permitted, and provided that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work
|
||||||
|
based on the Library, uncombined with any other library
|
||||||
|
facilities. This must be distributed under the terms of the
|
||||||
|
Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact
|
||||||
|
that part of it is a work based on the Library, and explaining
|
||||||
|
where to find the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute
|
||||||
|
the Library except as expressly provided under this License. Any
|
||||||
|
attempt otherwise to copy, modify, sublicense, link with, or
|
||||||
|
distribute the Library is void, and will automatically terminate your
|
||||||
|
rights under this License. However, parties who have received copies,
|
||||||
|
or rights, from you under this License will not have their licenses
|
||||||
|
terminated so long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Library or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Library (or any work based on the
|
||||||
|
Library), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Library or works based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Library by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under any
|
||||||
|
particular circumstance, the balance of the section is intended to apply,
|
||||||
|
and the section as a whole is intended to apply in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Library under this License may add
|
||||||
|
an explicit geographical distribution limitation excluding those countries,
|
||||||
|
so that distribution is permitted only in or among countries not thus
|
||||||
|
excluded. In such case, this License incorporates the limitation as if
|
||||||
|
written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new
|
||||||
|
versions of the Library General Public License from time to time.
|
||||||
|
Such new versions will be similar in spirit to the present version,
|
||||||
|
but may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and
|
||||||
|
"any later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a
|
||||||
|
license version number, you may choose any version ever published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free
|
||||||
|
Software Foundation; we sometimes make exceptions for this. Our
|
||||||
|
decision will be guided by the two goals of preserving the free status
|
||||||
|
of all derivatives of our free software and of promoting the sharing
|
||||||
|
and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||||
|
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||||
|
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||||
|
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||||
|
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||||
|
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||||
|
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||||
|
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||||
|
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||||
|
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||||
|
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||||
|
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||||
|
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||||
|
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||||
|
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
Appendix: How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the library's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public
|
||||||
|
License along with this library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||||
|
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
That's all there is to it!
|
459
README.md
Normal file
459
README.md
Normal file
|
@ -0,0 +1,459 @@
|
||||||
|
# gst-build
|
||||||
|
|
||||||
|
GStreamer [meson](http://mesonbuild.com/) based repositories aggregrator.
|
||||||
|
|
||||||
|
Check out this module and run meson on it, and it will git clone the other
|
||||||
|
GStreamer modules as [meson subprojects](http://mesonbuild.com/Subprojects.html)
|
||||||
|
and build everything in one go. Once that is done you can switch into an
|
||||||
|
development environment which allows you to easily develop and test the latest
|
||||||
|
version of GStreamer without the need to install anything or touch an existing
|
||||||
|
GStreamer system installation.
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
### Install git and python 3.5+
|
||||||
|
|
||||||
|
If you're on Linux, you probably already have these. On macOS, you can use the
|
||||||
|
[official Python installer](https://www.python.org/downloads/mac-osx/).
|
||||||
|
|
||||||
|
You can find [instructions for Windows below](#windows-prerequisites-setup).
|
||||||
|
|
||||||
|
### Install meson and ninja
|
||||||
|
|
||||||
|
Meson 0.52 or newer is required.
|
||||||
|
|
||||||
|
For cross-compilation Meson 0.54 or newer is required.
|
||||||
|
|
||||||
|
On Linux and macOS you can get meson through your package manager or using:
|
||||||
|
|
||||||
|
$ pip3 install --user meson
|
||||||
|
|
||||||
|
This will install meson into `~/.local/bin` which may or may not be included
|
||||||
|
automatically in your PATH by default.
|
||||||
|
|
||||||
|
You should get `ninja` using your package manager or download the [official
|
||||||
|
release](https://github.com/ninja-build/ninja/releases) and put the `ninja`
|
||||||
|
binary in your PATH.
|
||||||
|
|
||||||
|
You can find [instructions for Windows below](#windows-prerequisites-setup).
|
||||||
|
|
||||||
|
### Build GStreamer and its modules
|
||||||
|
|
||||||
|
You can get all GStreamer built running:
|
||||||
|
|
||||||
|
```
|
||||||
|
meson builddir
|
||||||
|
ninja -C builddir
|
||||||
|
```
|
||||||
|
|
||||||
|
This will automatically create the `build` directory and build everything
|
||||||
|
inside it.
|
||||||
|
|
||||||
|
NOTE: On Windows, you *must* run this from [inside the Visual Studio command
|
||||||
|
prompt](#running-meson-on-windows) of the appropriate architecture and version.
|
||||||
|
|
||||||
|
### External dependencies
|
||||||
|
|
||||||
|
All mandatory dependencies of GStreamer are included as [meson subprojects](https://mesonbuild.com/Subprojects.html):
|
||||||
|
libintl, zlib, libffi, glib. Some optional dependencies are also included as
|
||||||
|
subprojects, such as ffmpeg, x264, json-glib, graphene, openh264, orc, etc.
|
||||||
|
|
||||||
|
Mandatory dependencies will be automatically built if meson cannot find them on
|
||||||
|
your system using pkg-config. The same is true for optional dependencies that
|
||||||
|
are included as subprojects. You can find a full list by looking at the
|
||||||
|
`subprojects` directory.
|
||||||
|
|
||||||
|
Plugins that need optional dependencies that aren't included can only be built
|
||||||
|
if they are provided by the system. Instructions on how to build some common
|
||||||
|
ones such as Qt5/QML are listed below. If you do not know how to provide an
|
||||||
|
optional dependency needed by a plugin, you should use [Cerbero](https://gitlab.freedesktop.org/gstreamer/cerbero/#description)
|
||||||
|
which handles this for you automatically.
|
||||||
|
|
||||||
|
Plugins will be automatically enabled if possible, but you can ensure that
|
||||||
|
a particular plugin (especially if it has external dependencies) is built by
|
||||||
|
enabling the gstreamer repository that ships it and the plugin inside it. For
|
||||||
|
example, to enable the Qt5 plugin in the gst-plugins-good repository, you need
|
||||||
|
to run meson as follows:
|
||||||
|
|
||||||
|
```
|
||||||
|
meson -Dgood=enabled -Dgst-plugins-good:qt5=enabled builddir
|
||||||
|
```
|
||||||
|
|
||||||
|
This will cause Meson to error out if the plugin could not be enabled. You can
|
||||||
|
also flip the default and disable all plugins except those explicitly enabled
|
||||||
|
like so:
|
||||||
|
|
||||||
|
```
|
||||||
|
meson -Dauto_features=disabled -Dgstreamer:tools=enabled -Dbad=enabled -Dgst-plugins-bad:openh264=enabled
|
||||||
|
```
|
||||||
|
|
||||||
|
This will disable all optional features and then enable the `openh264` plugin
|
||||||
|
and the tools that ship with the core gstreamer repository: `gst-inspect-1.0`,
|
||||||
|
`gst-launch-1.0`, etc. As usual, you can change these values on a builddir that
|
||||||
|
has already been setup with `meson configure -Doption=value`.
|
||||||
|
|
||||||
|
### Building the Qt5 QML plugin
|
||||||
|
|
||||||
|
If `qmake` is not in `PATH` and pkgconfig files are not available, you can
|
||||||
|
point the `QMAKE` env var to the Qt5 installation of your choosing before
|
||||||
|
running `meson` as shown above.
|
||||||
|
|
||||||
|
The plugin will be automatically enabled if possible, but you can ensure that
|
||||||
|
it is built by passing `-Dgood=enabled -Dgst-plugins-good:qt5=enabled` to `meson`.
|
||||||
|
|
||||||
|
### Building the Intel MSDK plugin
|
||||||
|
|
||||||
|
On Linux, you need to have development files for `libmfx` installed. On
|
||||||
|
Windows, if you have the [Intel Media SDK](https://software.intel.com/en-us/media-sdk),
|
||||||
|
it will set the `INTELMEDIASDKROOT` environment variable, which will be used by
|
||||||
|
the build files to find `libmfx`.
|
||||||
|
|
||||||
|
The plugin will be automatically enabled if possible, but you can ensure it by
|
||||||
|
passing `-Dbad=enabled -Dgst-plugins-bad:msdk=enabled` to `meson`.
|
||||||
|
|
||||||
|
### Static build
|
||||||
|
|
||||||
|
Since *1.18.0* when doing a static build using `--default-library=static`, a
|
||||||
|
shared library `gstreamer-full-1.0` will be produced and includes all enabled
|
||||||
|
GStreamer plugins and libraries. A list of libraries that needs to be exposed in
|
||||||
|
`gstreamer-full-1.0` ABI can be set using `gst-full-libraries` option. glib-2.0,
|
||||||
|
gobject-2.0 and gstreamer-1.0 are always included.
|
||||||
|
|
||||||
|
```
|
||||||
|
meson --default-library=static -Dgst-full-libraries=app,video builddir
|
||||||
|
```
|
||||||
|
|
||||||
|
GStreamer *1.18* requires applications using gstreamer-full-1.0 to initialize
|
||||||
|
static plugins by calling `gst_init_static_plugins()` after `gst_init()`. That
|
||||||
|
function is defined in `gst/gstinitstaticplugins.h` header file.
|
||||||
|
|
||||||
|
Since *1.20.0* `gst_init_static_plugins()` is called automatically by
|
||||||
|
`gst_init()` and applications must not call it manually any more. The header
|
||||||
|
file has been removed from public API.
|
||||||
|
|
||||||
|
One can use the `gst-full-version-script` option to pass a
|
||||||
|
[version script](https://www.gnu.org/software/gnulib/manual/html_node/LD-Version-Scripts.html)
|
||||||
|
to the linker. This can be used to control the exact symbols that are exported by
|
||||||
|
the gstreamer-full library, allowing the linker to garbage collect unused code
|
||||||
|
and so reduce the total library size. A default script `gstreamer-full-default.map`
|
||||||
|
declares only glib/gstreamer symbols as public.
|
||||||
|
|
||||||
|
One can use the `gst-full-plugins` option to pass a list of plugins to be registered
|
||||||
|
in the gstreamer-full library. The default value is '*' which means that all the plugins selected
|
||||||
|
during the build process will be registered statically. An empty value will prevent any plugins to
|
||||||
|
be registered.
|
||||||
|
|
||||||
|
One can select a specific set of features with `gst-full-elements`, `gst-full-typefind-functions`, `gst-full-device-providers` or `gst-full-dynamic-types` to select specific feature from a plugin.
|
||||||
|
When a feature has been listed in one of those options, the other features from its plugin will no longer be automatically included, even if the plugin is listed in `gst-full-plugins`.
|
||||||
|
|
||||||
|
The user must insure that all selected plugins and features (element, typefind, etc.) have been
|
||||||
|
enabled during the build configuration.
|
||||||
|
|
||||||
|
To register features, the syntax is the following:
|
||||||
|
plugins are separated by ';' and features from a plugin starts after ':' and are ',' separated.
|
||||||
|
|
||||||
|
As an example:
|
||||||
|
* `-Dgst-full-plugins=coreelements;playback;typefindfunctions;alsa;pbtypes`: enable only `coreelements`, `playback`, `typefindfunctions`, `alsa`, `pbtypes` plugins.
|
||||||
|
* `-Dgst-full-elements=coreelements:filesrc,fakesink,identity;alsa:alsasrc`: enable only `filesrc`, `identity` and `fakesink` elements from `coreelements` and `alsasrc` element from `alsa` plugin.
|
||||||
|
* `-Dgst-full-typefind-functions=typefindfunctions:wav,flv`: enable only typefind func `wav` and `flv` from `typefindfunctions`
|
||||||
|
* `-Dgst-full-device-providers=alsa:alsadeviceprovider`: enable `alsadeviceprovider` from `alsa`.
|
||||||
|
* `-Dgst-full-dynamic-types=pbtypes:video_multiview_flagset`: enable `video_multiview_flagset` from `pbtypes
|
||||||
|
|
||||||
|
All features from the `playback` plugin will be enabled and the other plugins will be restricted to the specific features requested.
|
||||||
|
|
||||||
|
All the selected features will be registered into a dedicated `NULL` plugin name.
|
||||||
|
|
||||||
|
This will cause the features/plugins that are not registered to not be included in the final gstreamer-full library.
|
||||||
|
|
||||||
|
This is an experimental feature, backward uncompatible changes could still be
|
||||||
|
made in the future.
|
||||||
|
|
||||||
|
# Development environment
|
||||||
|
|
||||||
|
## Development environment target
|
||||||
|
|
||||||
|
gst-build also contains a special `devenv` target that lets you enter an
|
||||||
|
development environment where you will be able to work on GStreamer
|
||||||
|
easily. You can get into that environment running:
|
||||||
|
|
||||||
|
```
|
||||||
|
ninja -C builddir devenv
|
||||||
|
```
|
||||||
|
|
||||||
|
If your operating system handles symlinks, built modules source code will be
|
||||||
|
available at the root of `gst-build/` for example GStreamer core will be in
|
||||||
|
`gstreamer/`. Otherwise they will be present in `subprojects/`. You can simply
|
||||||
|
hack in there and to rebuild you just need to rerun `ninja -C builddir`.
|
||||||
|
|
||||||
|
NOTE: In the development environment, a fully usable prefix is also configured
|
||||||
|
in `gst-build/prefix` where you can install any extra dependency/project.
|
||||||
|
|
||||||
|
An external script can be run in development environment with:
|
||||||
|
|
||||||
|
```
|
||||||
|
./gst-env.py external_script.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Update git subprojects
|
||||||
|
|
||||||
|
We added a special `update` target to update subprojects (it uses `git pull
|
||||||
|
--rebase` meaning you should always make sure the branches you work on are
|
||||||
|
following the right upstream branch, you can set it with `git branch
|
||||||
|
--set-upstream-to origin/master` if you are working on `gst-build` master
|
||||||
|
branch).
|
||||||
|
|
||||||
|
Update all GStreamer modules and rebuild:
|
||||||
|
|
||||||
|
```
|
||||||
|
ninja -C builddir update
|
||||||
|
```
|
||||||
|
|
||||||
|
Update all GStreamer modules without rebuilding:
|
||||||
|
|
||||||
|
```
|
||||||
|
ninja -C builddir git-update
|
||||||
|
```
|
||||||
|
|
||||||
|
## Custom subprojects
|
||||||
|
|
||||||
|
We also added a meson option, `custom_subprojects`, that allows the user
|
||||||
|
to provide a comma-separated list of subprojects that should be built
|
||||||
|
alongside the default ones.
|
||||||
|
|
||||||
|
To use it:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd subprojects
|
||||||
|
git clone my_subproject
|
||||||
|
cd ../build
|
||||||
|
rm -rf * && meson .. -Dcustom_subprojects=my_subproject
|
||||||
|
ninja
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run tests
|
||||||
|
|
||||||
|
You can easily run the test of all the components:
|
||||||
|
|
||||||
|
```
|
||||||
|
meson test -C build
|
||||||
|
```
|
||||||
|
|
||||||
|
To list all available tests:
|
||||||
|
|
||||||
|
```
|
||||||
|
meson test -C builddir --list
|
||||||
|
```
|
||||||
|
|
||||||
|
To run all the tests of a specific component:
|
||||||
|
|
||||||
|
```
|
||||||
|
meson test -C builddir --suite gst-plugins-base
|
||||||
|
```
|
||||||
|
|
||||||
|
Or to run a specific test file:
|
||||||
|
|
||||||
|
```
|
||||||
|
meson test -C builddir --suite gstreamer gst_gstbuffer
|
||||||
|
```
|
||||||
|
|
||||||
|
Run a specific test from a specific test file:
|
||||||
|
|
||||||
|
```
|
||||||
|
GST_CHECKS=test_subbuffer meson test -C builddir --suite gstreamer gst_gstbuffer
|
||||||
|
```
|
||||||
|
|
||||||
|
## Optional Installation
|
||||||
|
|
||||||
|
`gst-build` has been created primarily for [development usage](#development-environment-target),
|
||||||
|
but you can also install everything that is built into a predetermined prefix like so:
|
||||||
|
|
||||||
|
```
|
||||||
|
meson --prefix=/path/to/install/prefix builddir
|
||||||
|
ninja -C builddir
|
||||||
|
meson install -C builddir
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the installed files have `RPATH` stripped, so you will need to set
|
||||||
|
`LD_LIBRARY_PATH`, `DYLD_LIBRARY_PATH`, or `PATH` as appropriate for your
|
||||||
|
platform for things to work.
|
||||||
|
|
||||||
|
## Checkout another branch using worktrees
|
||||||
|
|
||||||
|
If you need to have several versions of GStreamer coexisting (eg. `master` and `1.16`),
|
||||||
|
you can use the `gst-worktree.py` script provided by `gst-build`. It allows you
|
||||||
|
to create a new `gst-build` environment with new checkout of all the GStreamer modules as
|
||||||
|
[git worktrees](https://git-scm.com/docs/git-worktree).
|
||||||
|
|
||||||
|
For example to get a fresh checkout of `gst-1.16` from a `gst-build` repository
|
||||||
|
that is checked out at master, you can run:
|
||||||
|
|
||||||
|
```
|
||||||
|
./gst-worktree.py add gst-build-1.16 origin/1.16
|
||||||
|
```
|
||||||
|
|
||||||
|
This will create a new ``gst-build-1.16`` directory pointing to the given branch `1.16`
|
||||||
|
for all the subprojects (gstreamer, gst-plugins-base, etc.)
|
||||||
|
|
||||||
|
|
||||||
|
## Add information about GStreamer development environment in your prompt line
|
||||||
|
|
||||||
|
### Bash prompt
|
||||||
|
|
||||||
|
We automatically handle `bash` and set `$PS1` accordingly.
|
||||||
|
|
||||||
|
If the automatic `$PS1` override is not desired (maybe you have a fancy custom prompt), set the `$GST_BUILD_DISABLE_PS1_OVERRIDE` environment variable to `TRUE` and use `$GST_ENV` when setting the custom prompt, for example with a snippet like the following:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
...
|
||||||
|
if [[ -n "${GST_ENV-}" ]];
|
||||||
|
then
|
||||||
|
PS1+="[ ${GST_ENV} ]"
|
||||||
|
fi
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using powerline
|
||||||
|
|
||||||
|
In your powerline theme configuration file (by default in
|
||||||
|
`{POWERLINE INSTALLATION DIR}/config_files/themes/shell/default.json`)
|
||||||
|
you should add a new environment segment as follow:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"function": "powerline.segments.common.env.environment",
|
||||||
|
"args": { "variable": "GST_ENV" },
|
||||||
|
"priority": 50
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
## Windows Prerequisites Setup
|
||||||
|
|
||||||
|
On Windows, some of the components may require special care.
|
||||||
|
|
||||||
|
### Git for Windows
|
||||||
|
|
||||||
|
Use the [Git for Windows](https://gitforwindows.org/) installer. It will
|
||||||
|
install a `bash` prompt with basic shell utils and up-to-date git binaries.
|
||||||
|
|
||||||
|
During installation, when prompted about `PATH`, you should select the
|
||||||
|
following option:
|
||||||
|
|
||||||
|
![Select "Git from the command line and also from 3rd-party software"](/data/images/git-installer-PATH.png)
|
||||||
|
|
||||||
|
### Python 3.5+ on Windows
|
||||||
|
|
||||||
|
Use the [official Python installer](https://www.python.org/downloads/windows/).
|
||||||
|
You must ensure that Python is installed into `PATH`:
|
||||||
|
|
||||||
|
![Enable Add Python to PATH, then click Customize Installation](/data/images/py-installer-page1.png)
|
||||||
|
|
||||||
|
You may also want to customize the installation and install it into
|
||||||
|
a system-wide location such as `C:\PythonXY`, but this is not required.
|
||||||
|
|
||||||
|
### Ninja on Windows
|
||||||
|
|
||||||
|
The easiest way to install Ninja on Windows is with `pip3`, which will download
|
||||||
|
the compiled binary and place it into the `Scripts` directory inside your
|
||||||
|
Python installation:
|
||||||
|
|
||||||
|
```
|
||||||
|
pip3 install ninja
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also download the [official release](https://github.com/ninja-build/ninja/releases)
|
||||||
|
and place it into `PATH`.
|
||||||
|
|
||||||
|
### Meson on Windows
|
||||||
|
|
||||||
|
**IMPORTANT**: Do not use the Meson MSI installer since it is experimental and known to not
|
||||||
|
work with `gst-build`.
|
||||||
|
|
||||||
|
You can use `pip3` to install Meson, same as Ninja above:
|
||||||
|
|
||||||
|
```
|
||||||
|
pip3 install meson
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that Meson is written entirely in Python, so you can also run it as-is
|
||||||
|
from the [git repository](https://github.com/mesonbuild/meson/) if you want to
|
||||||
|
use the latest master branch for some reason.
|
||||||
|
|
||||||
|
**ARM64 native only**: You might need
|
||||||
|
[native upstream ARM64 support fix](https://github.com/mesonbuild/meson/pull/7432)
|
||||||
|
which is expected to be a part of Meson 0.55.1.
|
||||||
|
If your Meson package version which was installed via `pip3` is lower than 0.55.1,
|
||||||
|
then you need to use [the latest master branch](https://github.com/mesonbuild/meson/).
|
||||||
|
|
||||||
|
### Running Meson on Windows
|
||||||
|
|
||||||
|
At present, to build with Visual Studio, you need to run Meson from inside the
|
||||||
|
VS 2019 command prompt. Press `Start`, and search for `VS 2019`, and click on
|
||||||
|
`x64 Native Tools Command Prompt for VS 2019`, or a prompt named similar to
|
||||||
|
that:
|
||||||
|
|
||||||
|
![x64 Native Tools Command Prompt for VS 2019](/data/images/vs-2019-dev-prompt.png)
|
||||||
|
|
||||||
|
**ARM64 native only**: Since Visual Studio might not install dedicated command
|
||||||
|
prompt for native ARM64 build, you might need to run `vcvarsx86_arm64.bat` on CMD.
|
||||||
|
Please refer to [this document](https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=vs-2019#developer_command_file_locations)
|
||||||
|
|
||||||
|
### Setup a mingw/wine based development environment on linux
|
||||||
|
|
||||||
|
#### Install wine and mingw
|
||||||
|
|
||||||
|
##### On fedora x64
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
sudo dnf install mingw64-gcc mingw64-gcc-c++ mingw64-pkg-config mingw64-winpthreads wine
|
||||||
|
```
|
||||||
|
|
||||||
|
FIXME: Figure out what needs to be installed on other distros
|
||||||
|
|
||||||
|
#### Get meson from git
|
||||||
|
|
||||||
|
This simplifies the process and allows us to use the cross files
|
||||||
|
defined in meson itself.
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
git clone https://github.com/mesonbuild/meson.git
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Build and install
|
||||||
|
|
||||||
|
```
|
||||||
|
BUILDDIR=$PWD/winebuild/
|
||||||
|
export WINEPREFIX=$BUILDDIR/wine-prefix/ && mkdir -p $WINEPREFIX
|
||||||
|
# Setting the prefix is mandatory as it is used to setup symlinks during uninstalled development
|
||||||
|
meson/meson.py $BUILDDIR --cross-file meson/cross/linux-mingw-w64-64bit.txt -Dgst-plugins-bad:vulkan=disabled -Dorc:gtk_doc=disabled --prefix=$BUILDDIR/wininstall/ -Djson-glib:gtk_doc=disabled
|
||||||
|
meson/meson.py install -C $BUILDDIR/
|
||||||
|
```
|
||||||
|
|
||||||
|
> __NOTE__: You should use `meson install -C $BUILDDIR` each time you make a change
|
||||||
|
> instead of the usual `ninja -C build` as the environment is not uninstalled.
|
||||||
|
|
||||||
|
#### The development environment
|
||||||
|
|
||||||
|
You can get into the development environment the usual way:
|
||||||
|
|
||||||
|
```
|
||||||
|
ninja -C $BUILDDIR/ devenv
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, if you'd rather not start a shell in your workflow, you
|
||||||
|
can mutate the current environment into a suitable state like so:
|
||||||
|
|
||||||
|
```
|
||||||
|
gst-env.py --only-environment
|
||||||
|
```
|
||||||
|
|
||||||
|
This will print output suitable for an sh-compatible `eval` function,
|
||||||
|
just like `ssh-agent -s`.
|
||||||
|
|
||||||
|
After setting up [binfmt] to use wine for windows binaries,
|
||||||
|
you can run GStreamer tools under wine by running:
|
||||||
|
|
||||||
|
```
|
||||||
|
gst-launch-1.0.exe videotestsrc ! glimagesink
|
||||||
|
```
|
||||||
|
|
||||||
|
[binfmt]: http://man7.org/linux/man-pages/man5/binfmt.d.5.html
|
19
cmd_or_ps.ps1
Normal file
19
cmd_or_ps.ps1
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
$i=1
|
||||||
|
$ppid=(gwmi win32_process -Filter "processid='$pid'").parentprocessid
|
||||||
|
$pname=(Get-Process -id $ppid).Name
|
||||||
|
While($true) {
|
||||||
|
if($pname -eq "cmd" -Or $pname -eq "powershell") {
|
||||||
|
Write-Host ("{0}.exe" -f $pname)
|
||||||
|
Break
|
||||||
|
}
|
||||||
|
|
||||||
|
# 10 times iteration seems to be sufficient
|
||||||
|
if($i -gt 10) {
|
||||||
|
Break
|
||||||
|
}
|
||||||
|
|
||||||
|
# not found yet, find grand parant
|
||||||
|
$ppid=(gwmi win32_process -Filter "processid='$ppid'").parentprocessid
|
||||||
|
$pname=(Get-Process -id $ppid).Name
|
||||||
|
$i++
|
||||||
|
}
|
39
data/cross-files/README.md
Normal file
39
data/cross-files/README.md
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# Cross compiling GStreamer with gst-build
|
||||||
|
|
||||||
|
GStreamer can be cross compiled for various platforms using gst-build. However,
|
||||||
|
only dependencies that are ported to the Meson build system will be built. It is
|
||||||
|
recommended to use Cerbero to cross compile GStreamer when other external
|
||||||
|
dependencies are required.
|
||||||
|
|
||||||
|
Once the toolchain is installed and a Meson cross file is created, to build
|
||||||
|
GStreamer simply run for example: `meson --cross-file data/cross-files/mingw_w64_x86-64.txt builddir`.
|
||||||
|
|
||||||
|
## Android
|
||||||
|
|
||||||
|
Requires Android API level >= 28, previous versions are missing *iconv* dependency.
|
||||||
|
|
||||||
|
- Download and extract the [NDK](https://developer.android.com/ndk/)
|
||||||
|
- Create a Meson cross file, you can use `android_arm64_api28.txt` as example
|
||||||
|
and change CPU architectures and toolchain path using the prebuilt toolchains
|
||||||
|
from the NDK.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- On fedora the Android NDK requires the `ncurses-compat-libs` package.
|
||||||
|
|
||||||
|
## Windows
|
||||||
|
|
||||||
|
GStreamer can be cross compiled for Windows using mingw packaged in most
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
The Meson cross file `mingw_w64_x86-64.txt` can be used when targeting amd64
|
||||||
|
architecture, or adapted for i686 arch.
|
||||||
|
|
||||||
|
### Fedora
|
||||||
|
|
||||||
|
- Install the toolchain packages: `mingw64-gcc`, `mingw64-gcc-c++`. Fedora
|
||||||
|
provides many other optional dependencies that could be installed as well.
|
||||||
|
For example: `mingw64-gettext`, `mingw64-libffi`, `mingw64-zlib`.
|
||||||
|
|
||||||
|
### Ubuntu
|
||||||
|
|
||||||
|
- Install the toolchain package: `gcc-mingw-w64`.
|
20
data/cross-files/android_arm64_api28.txt
Normal file
20
data/cross-files/android_arm64_api28.txt
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
[host_machine]
|
||||||
|
system = 'android'
|
||||||
|
cpu_family = 'aarch64'
|
||||||
|
cpu = 'aarch64'
|
||||||
|
endian = 'little'
|
||||||
|
|
||||||
|
[properties]
|
||||||
|
sys_root = '/path/to/android-ndk-r21/sysroot'
|
||||||
|
c_link_args = ['-fuse-ld=gold']
|
||||||
|
cpp_link_args = ['-fuse-ld=gold']
|
||||||
|
# Starting with 0.53.1, you can replace the above *_link_args:
|
||||||
|
# c_ld = 'gold'
|
||||||
|
# cpp_ld = 'gold'
|
||||||
|
|
||||||
|
[binaries]
|
||||||
|
c = '/path/to/android-ndk-r21/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android28-clang'
|
||||||
|
cpp = '/path/to/android-ndk-r21/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android28-clang++'
|
||||||
|
ar = '/path/to/android-ndk-r21/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar'
|
||||||
|
strip = '/path/to/android-ndk-r21/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-strip'
|
||||||
|
pkgconfig = 'false'
|
17
data/cross-files/mingw_w64_x86-64.txt
Normal file
17
data/cross-files/mingw_w64_x86-64.txt
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
[host_machine]
|
||||||
|
system = 'windows'
|
||||||
|
cpu_family = 'x86_64'
|
||||||
|
cpu = 'x86_64'
|
||||||
|
endian = 'little'
|
||||||
|
|
||||||
|
[properties]
|
||||||
|
c_args = []
|
||||||
|
c_link_args = []
|
||||||
|
|
||||||
|
[binaries]
|
||||||
|
c = 'x86_64-w64-mingw32-gcc'
|
||||||
|
cpp = 'x86_64-w64-mingw32-g++'
|
||||||
|
ar = 'x86_64-w64-mingw32-ar'
|
||||||
|
strip = 'x86_64-w64-mingw32-strip'
|
||||||
|
pkgconfig = 'x86_64-w64-mingw32-pkg-config'
|
||||||
|
windres = 'x86_64-w64-mingw32-windres'
|
BIN
data/images/git-installer-PATH.png
Normal file
BIN
data/images/git-installer-PATH.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
BIN
data/images/py-installer-page1.png
Normal file
BIN
data/images/py-installer-page1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 76 KiB |
BIN
data/images/vs-2019-dev-prompt.png
Normal file
BIN
data/images/vs-2019-dev-prompt.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 50 KiB |
241
git-update
Executable file
241
git-update
Executable file
|
@ -0,0 +1,241 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from scripts.common import git
|
||||||
|
from scripts.common import Colors
|
||||||
|
from scripts.common import accept_command
|
||||||
|
from scripts.common import get_meson
|
||||||
|
|
||||||
|
|
||||||
|
SCRIPTDIR = os.path.normpath(os.path.dirname(__file__))
|
||||||
|
# Force a checkout to happen and throw away local changes
|
||||||
|
FORCE_CHECKOUT = False
|
||||||
|
CI = os.environ.get('CI', False)
|
||||||
|
|
||||||
|
|
||||||
|
def manifest_get_commits(manifest):
|
||||||
|
res = {}
|
||||||
|
tree = ET.parse(manifest)
|
||||||
|
root = tree.getroot()
|
||||||
|
remotes = {}
|
||||||
|
for child in root:
|
||||||
|
if child.tag == 'remote':
|
||||||
|
remotes[child.attrib['name']] = child.attrib['fetch']
|
||||||
|
if child.tag == 'project':
|
||||||
|
name = child.attrib['name']
|
||||||
|
path = child.attrib.get('path', name)
|
||||||
|
|
||||||
|
remote = child.attrib.get('remote')
|
||||||
|
if remote:
|
||||||
|
res[path] = [child.attrib["revision"], [os.path.join(remotes[remote], name), child.attrib.get('refname', child.attrib["revision"])]]
|
||||||
|
else:
|
||||||
|
res[path] = [child.attrib["revision"], []]
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def get_branch_name(repo_dir):
|
||||||
|
return git('-C', repo_dir, 'rev-parse', '--symbolic-full-name', 'HEAD').strip()
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_revision_if_necessary(repo_dir, revision):
|
||||||
|
"""
|
||||||
|
Makes sure that @revision is set if the current repo is detached.
|
||||||
|
"""
|
||||||
|
if not revision:
|
||||||
|
if get_branch_name(repo_dir) == 'HEAD':
|
||||||
|
revision = git('-C', repo_dir, 'rev-parse', 'HEAD').strip()
|
||||||
|
|
||||||
|
return revision
|
||||||
|
|
||||||
|
|
||||||
|
def update_subprojects(manifest, no_interaction=False, status=False):
|
||||||
|
subprojects_dir = os.path.join(SCRIPTDIR, "subprojects")
|
||||||
|
for repo_name in os.listdir(subprojects_dir):
|
||||||
|
repo_dir = os.path.normpath(os.path.join(SCRIPTDIR, subprojects_dir, repo_name))
|
||||||
|
if not os.path.exists(os.path.join(repo_dir, '.git')):
|
||||||
|
continue
|
||||||
|
|
||||||
|
revision, args = repos_commits.get(repo_name, [None, []])
|
||||||
|
if not update_repo(repo_name, repo_dir, revision, no_interaction, fetch_args=args, status=status):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def repo_status(commit_message):
|
||||||
|
status = "clean"
|
||||||
|
for message in commit_message:
|
||||||
|
if message.startswith('??'):
|
||||||
|
status = "%sclean but untracked files%s" % (Colors.WARNING,Colors.ENDC)
|
||||||
|
elif message.startswith(' M'):
|
||||||
|
status = "%shas local modifications%s" % (Colors.WARNING,Colors.ENDC)
|
||||||
|
break;
|
||||||
|
return status
|
||||||
|
|
||||||
|
def check_repo_status(repo_name, worktree_dir):
|
||||||
|
branch_message = git("status", repository_path=worktree_dir).split("\n")
|
||||||
|
commit_message = git("status", "--porcelain", repository_path=worktree_dir).split("\n")
|
||||||
|
|
||||||
|
print(u"%s%s%s - %s - %s" % (Colors.HEADER, repo_name, Colors.ENDC,
|
||||||
|
branch_message[0].strip(), repo_status(commit_message)))
|
||||||
|
return True
|
||||||
|
|
||||||
|
def fatal_git_fetches(repo_dir):
|
||||||
|
'''
|
||||||
|
When running on the CI, we usually have a cache, in which case we don't
|
||||||
|
want the git update to be fatal since we don't want our CI to fail when
|
||||||
|
there's downtime on external repos.
|
||||||
|
'''
|
||||||
|
if not CI:
|
||||||
|
return True
|
||||||
|
remote = git("remote", "get-url", "origin", repository_path=repo_dir)
|
||||||
|
if 'gitlab.freedesktop.org' in remote:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def update_repo(repo_name, repo_dir, revision, no_interaction, fetch_args=None, recurse_i=0, status=False):
|
||||||
|
if status:
|
||||||
|
return check_repo_status(repo_name, repo_dir)
|
||||||
|
revision = ensure_revision_if_necessary(repo_dir, revision)
|
||||||
|
git("config", "rebase.autoStash", "true", repository_path=repo_dir)
|
||||||
|
|
||||||
|
fetch_args = fetch_args if fetch_args is not None else []
|
||||||
|
fetch_args.append('--tags')
|
||||||
|
fatal = fatal_git_fetches(repo_dir)
|
||||||
|
try:
|
||||||
|
if revision:
|
||||||
|
print("Checking out %s in %s" % (revision, repo_name))
|
||||||
|
git("fetch", *fetch_args, repository_path=repo_dir, fatal=fatal)
|
||||||
|
checkout_args = ["--force"] if FORCE_CHECKOUT else []
|
||||||
|
checkout_args += ["--detach", revision]
|
||||||
|
git("checkout", *checkout_args, repository_path=repo_dir)
|
||||||
|
else:
|
||||||
|
print("Updating branch %s in %s" % (get_branch_name(repo_dir), repo_name))
|
||||||
|
git("pull", "--rebase", repository_path=repo_dir, fatal=fatal)
|
||||||
|
git("submodule", "update", repository_path=repo_dir)
|
||||||
|
except Exception as e:
|
||||||
|
out = getattr(e, "output", b"").decode()
|
||||||
|
if not no_interaction:
|
||||||
|
print("====================================="
|
||||||
|
"\n%s\nEntering a shell in %s to fix that"
|
||||||
|
" just `exit 0` once done, or `exit 255`"
|
||||||
|
" to skip update for that repository"
|
||||||
|
"\n=====================================" % (
|
||||||
|
out, repo_dir))
|
||||||
|
try:
|
||||||
|
if os.name == 'nt':
|
||||||
|
shell = os.environ.get("COMSPEC", r"C:\WINDOWS\system32\cmd.exe")
|
||||||
|
else:
|
||||||
|
shell = os.environ.get("SHELL", os.path.realpath("/bin/sh"))
|
||||||
|
subprocess.check_call(shell, cwd=repo_dir)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
if e.returncode == 255:
|
||||||
|
print("Skipping '%s' update" % repo_name)
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
# Result of subshell does not really matter
|
||||||
|
pass
|
||||||
|
|
||||||
|
if recurse_i < 3:
|
||||||
|
return update_repo(repo_name, repo_dir, revision, no_interaction,
|
||||||
|
recurse_i=recurse_i + 1)
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
print("\nCould not rebase %s, please fix and try again."
|
||||||
|
" Error:\n\n%s %s" % (repo_dir, out, e))
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
commit_message = git("show", "--shortstat", repository_path=repo_dir).split("\n")
|
||||||
|
print(u" -> %s%s%s - %s" % (Colors.HEADER, commit_message[0][7:14], Colors.ENDC,
|
||||||
|
commit_message[4].strip()))
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
# Update gst-plugins-rs dependencies
|
||||||
|
def update_cargo(build_dir):
|
||||||
|
cargo_toml = os.path.join('subprojects', 'gst-plugins-rs', 'Cargo.toml')
|
||||||
|
if not os.path.exists(cargo_toml):
|
||||||
|
return True
|
||||||
|
|
||||||
|
cmd = ['cargo', 'update', '--manifest-path', cargo_toml]
|
||||||
|
|
||||||
|
try:
|
||||||
|
ret = subprocess.run(cmd)
|
||||||
|
except FileNotFoundError:
|
||||||
|
# silenty ignore if cargo isn't installed
|
||||||
|
return False
|
||||||
|
|
||||||
|
return ret == 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(prog="git-update")
|
||||||
|
|
||||||
|
parser.add_argument("--no-color",
|
||||||
|
default=False,
|
||||||
|
action='store_true',
|
||||||
|
help="Do not output ansi colors.")
|
||||||
|
parser.add_argument("--builddir",
|
||||||
|
default=None,
|
||||||
|
help="Specifies the build directory where to"
|
||||||
|
" invoke ninja after updating.")
|
||||||
|
parser.add_argument("--no-interaction",
|
||||||
|
default=False,
|
||||||
|
action='store_true',
|
||||||
|
help="Do not allow interaction with the user.")
|
||||||
|
parser.add_argument("--status",
|
||||||
|
default=False,
|
||||||
|
action='store_true',
|
||||||
|
help="Check repositories status only.")
|
||||||
|
parser.add_argument("--manifest",
|
||||||
|
default=None,
|
||||||
|
help="Use a android repo manifest to sync repositories"
|
||||||
|
" Note that it will let all repositories in detached state")
|
||||||
|
options = parser.parse_args()
|
||||||
|
if options.no_color or not Colors.can_enable():
|
||||||
|
Colors.disable()
|
||||||
|
|
||||||
|
if options.no_interaction:
|
||||||
|
sys.stdin.close()
|
||||||
|
|
||||||
|
if options.manifest:
|
||||||
|
meson = get_meson()
|
||||||
|
try:
|
||||||
|
targets_s = subprocess.check_output(meson + ['subprojects', 'download'], shell=False, universal_newlines=True)
|
||||||
|
except subprocess.CalledProcessError as err:
|
||||||
|
print(f"Subproject download Failed")
|
||||||
|
print(f"Output: {err.output}")
|
||||||
|
print(f"Exit code: {err.returncode}")
|
||||||
|
exit(err.returncode)
|
||||||
|
|
||||||
|
repos_commits = manifest_get_commits(options.manifest)
|
||||||
|
FORCE_CHECKOUT = True
|
||||||
|
else:
|
||||||
|
repos_commits = {}
|
||||||
|
|
||||||
|
revision, args = repos_commits.get('gst-build', [None, []])
|
||||||
|
if not update_repo('gst-build', SCRIPTDIR, revision, options.no_interaction, fetch_args=args, status=options.status):
|
||||||
|
exit(1)
|
||||||
|
if not update_subprojects(options.manifest, options.no_interaction, status=options.status):
|
||||||
|
exit(1)
|
||||||
|
if not options.status:
|
||||||
|
update_cargo(options.builddir)
|
||||||
|
|
||||||
|
if options.builddir:
|
||||||
|
ninja = accept_command(["ninja", "ninja-build"])
|
||||||
|
if not ninja:
|
||||||
|
print("Can't find ninja, other backends are not supported for rebuilding")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
if not os.path.exists(os.path.join (options.builddir, 'build.ninja')):
|
||||||
|
print("Can't rebuild in %s as no build.ninja file found." % options.builddir)
|
||||||
|
|
||||||
|
print("Rebuilding all GStreamer modules.")
|
||||||
|
exit(subprocess.call([ninja, '-C', options.builddir]))
|
587
gst-env.py
Executable file
587
gst-env.py
Executable file
|
@ -0,0 +1,587 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import contextlib
|
||||||
|
import glob
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import re
|
||||||
|
import site
|
||||||
|
import shlex
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import pathlib
|
||||||
|
import signal
|
||||||
|
from functools import lru_cache
|
||||||
|
from pathlib import PurePath, Path
|
||||||
|
|
||||||
|
from distutils.sysconfig import get_python_lib
|
||||||
|
from distutils.util import strtobool
|
||||||
|
|
||||||
|
from scripts.common import get_meson
|
||||||
|
from scripts.common import git
|
||||||
|
from scripts.common import win32_get_short_path_name
|
||||||
|
from scripts.common import get_wine_shortpath
|
||||||
|
|
||||||
|
SCRIPTDIR = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
PREFIX_DIR = os.path.join(SCRIPTDIR, 'prefix')
|
||||||
|
# Look for the following build dirs: `build` `_build` `builddir`
|
||||||
|
DEFAULT_BUILDDIR = os.path.join(SCRIPTDIR, 'build')
|
||||||
|
if not os.path.exists(DEFAULT_BUILDDIR):
|
||||||
|
DEFAULT_BUILDDIR = os.path.join(SCRIPTDIR, '_build')
|
||||||
|
if not os.path.exists(DEFAULT_BUILDDIR):
|
||||||
|
DEFAULT_BUILDDIR = os.path.join(SCRIPTDIR, 'builddir')
|
||||||
|
|
||||||
|
TYPELIB_REG = re.compile(r'.*\.typelib$')
|
||||||
|
SHAREDLIB_REG = re.compile(r'\.so|\.dylib|\.dll')
|
||||||
|
|
||||||
|
# libdir is expanded from option of the same name listed in the `meson
|
||||||
|
# introspect --buildoptions` output.
|
||||||
|
GSTPLUGIN_FILEPATH_REG_TEMPLATE = r'.*/{libdir}/gstreamer-1.0/[^/]+$'
|
||||||
|
GSTPLUGIN_FILEPATH_REG = None
|
||||||
|
|
||||||
|
BC_RC = '''
|
||||||
|
BASH_COMPLETION_SCRIPTS="{bash_completions}"
|
||||||
|
BASH_COMPLETION_PATHS="{bash_completions_paths}"
|
||||||
|
for p in $BASH_COMPLETION_PATHS; do
|
||||||
|
for f in $BASH_COMPLETION_SCRIPTS; do
|
||||||
|
[ -f "$p/$f" ] && . "$p/$f"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
'''
|
||||||
|
BASH_COMPLETION_PATHS = [SCRIPTDIR + '/subprojects/gstreamer/data/bash-completion/completions']
|
||||||
|
BASH_COMPLETION_PATHS += [SCRIPTDIR + '/subprojects/gst-devtools/validate/data/bash-completion/completions']
|
||||||
|
|
||||||
|
def listify(o):
|
||||||
|
if isinstance(o, str):
|
||||||
|
return [o]
|
||||||
|
if isinstance(o, list):
|
||||||
|
return o
|
||||||
|
raise AssertionError('Object {!r} must be a string or a list'.format(o))
|
||||||
|
|
||||||
|
def stringify(o):
|
||||||
|
if isinstance(o, str):
|
||||||
|
return o
|
||||||
|
if isinstance(o, list):
|
||||||
|
if len(o) == 1:
|
||||||
|
return o[0]
|
||||||
|
raise AssertionError('Did not expect object {!r} to have more than one element'.format(o))
|
||||||
|
raise AssertionError('Object {!r} must be a string or a list'.format(o))
|
||||||
|
|
||||||
|
def prepend_env_var(env, var, value, sysroot):
|
||||||
|
if var is None:
|
||||||
|
return
|
||||||
|
if value.startswith(sysroot):
|
||||||
|
value = value[len(sysroot):]
|
||||||
|
# Try not to exceed maximum length limits for env vars on Windows
|
||||||
|
if os.name == 'nt':
|
||||||
|
value = win32_get_short_path_name(value)
|
||||||
|
env_val = env.get(var, '')
|
||||||
|
val = os.pathsep + value + os.pathsep
|
||||||
|
# Don't add the same value twice
|
||||||
|
if val in env_val or env_val.startswith(value + os.pathsep):
|
||||||
|
return
|
||||||
|
env[var] = val + env_val
|
||||||
|
env[var] = env[var].replace(os.pathsep + os.pathsep, os.pathsep).strip(os.pathsep)
|
||||||
|
|
||||||
|
def get_target_install_filename(target, filename):
|
||||||
|
'''
|
||||||
|
Checks whether this file is one of the files installed by the target
|
||||||
|
'''
|
||||||
|
basename = os.path.basename(filename)
|
||||||
|
for install_filename in listify(target['install_filename']):
|
||||||
|
if install_filename.endswith(basename):
|
||||||
|
return install_filename
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_pkgconfig_variable_from_pcfile(pcfile, varname):
|
||||||
|
variables = {}
|
||||||
|
substre = re.compile('\$\{[^${}]+\}')
|
||||||
|
with pcfile.open('r', encoding='utf-8') as f:
|
||||||
|
for line in f:
|
||||||
|
if '=' not in line:
|
||||||
|
continue
|
||||||
|
key, value = line[:-1].split('=', 1)
|
||||||
|
subst = {}
|
||||||
|
for each in substre.findall(value):
|
||||||
|
substkey = each[2:-1]
|
||||||
|
subst[each] = variables.get(substkey, '')
|
||||||
|
for k, v in subst.items():
|
||||||
|
value = value.replace(k, v)
|
||||||
|
variables[key] = value
|
||||||
|
return variables.get(varname, '')
|
||||||
|
|
||||||
|
@lru_cache()
|
||||||
|
def get_pkgconfig_variable(builddir, pcname, varname):
|
||||||
|
'''
|
||||||
|
Parsing isn't perfect, but it's good enough.
|
||||||
|
'''
|
||||||
|
pcfile = Path(builddir) / 'meson-private' / (pcname + '.pc')
|
||||||
|
if pcfile.is_file():
|
||||||
|
return get_pkgconfig_variable_from_pcfile(pcfile, varname)
|
||||||
|
return subprocess.check_output(['pkg-config', pcname, '--variable=' + varname],
|
||||||
|
universal_newlines=True, encoding='utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
def is_gio_module(target, filename, builddir):
|
||||||
|
if target['type'] != 'shared module':
|
||||||
|
return False
|
||||||
|
install_filename = get_target_install_filename(target, filename)
|
||||||
|
if not install_filename:
|
||||||
|
return False
|
||||||
|
giomoduledir = PurePath(get_pkgconfig_variable(builddir, 'gio-2.0', 'giomoduledir'))
|
||||||
|
fpath = PurePath(install_filename)
|
||||||
|
if fpath.parent != giomoduledir:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def is_library_target_and_not_plugin(target, filename):
|
||||||
|
'''
|
||||||
|
Don't add plugins to PATH/LD_LIBRARY_PATH because:
|
||||||
|
1. We don't need to
|
||||||
|
2. It causes us to exceed the PATH length limit on Windows and Wine
|
||||||
|
'''
|
||||||
|
if target['type'] != 'shared library':
|
||||||
|
return False
|
||||||
|
# Check if this output of that target is a shared library
|
||||||
|
if not SHAREDLIB_REG.search(filename):
|
||||||
|
return False
|
||||||
|
# Check if it's installed to the gstreamer plugin location
|
||||||
|
install_filename = get_target_install_filename(target, filename)
|
||||||
|
if not install_filename:
|
||||||
|
return False
|
||||||
|
global GSTPLUGIN_FILEPATH_REG
|
||||||
|
if GSTPLUGIN_FILEPATH_REG is None:
|
||||||
|
GSTPLUGIN_FILEPATH_REG = re.compile(GSTPLUGIN_FILEPATH_REG_TEMPLATE)
|
||||||
|
if GSTPLUGIN_FILEPATH_REG.search(install_filename.replace('\\', '/')):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def is_binary_target_and_in_path(target, filename, bindir):
|
||||||
|
if target['type'] != 'executable':
|
||||||
|
return False
|
||||||
|
# Check if this file installed by this target is installed to bindir
|
||||||
|
install_filename = get_target_install_filename(target, filename)
|
||||||
|
if not install_filename:
|
||||||
|
return False
|
||||||
|
fpath = PurePath(install_filename)
|
||||||
|
if fpath.parent != bindir:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def get_wine_subprocess_env(options, env):
|
||||||
|
with open(os.path.join(options.builddir, 'meson-info', 'intro-buildoptions.json')) as f:
|
||||||
|
buildoptions = json.load(f)
|
||||||
|
|
||||||
|
prefix, = [o for o in buildoptions if o['name'] == 'prefix']
|
||||||
|
path = os.path.normpath(os.path.join(prefix['value'], 'bin'))
|
||||||
|
prepend_env_var(env, "PATH", path, options.sysroot)
|
||||||
|
wine_path = get_wine_shortpath(
|
||||||
|
options.wine.split(' '),
|
||||||
|
[path] + env.get('WINEPATH', '').split(';')
|
||||||
|
)
|
||||||
|
if options.winepath:
|
||||||
|
wine_path += ';' + options.winepath
|
||||||
|
env['WINEPATH'] = wine_path
|
||||||
|
env['WINEDEBUG'] = 'fixme-all'
|
||||||
|
|
||||||
|
return env
|
||||||
|
|
||||||
|
def setup_gdb(options):
|
||||||
|
python_paths = set()
|
||||||
|
|
||||||
|
if not shutil.which('gdb'):
|
||||||
|
return python_paths
|
||||||
|
|
||||||
|
bdir = pathlib.Path(options.builddir).resolve()
|
||||||
|
for libpath, gdb_path in [
|
||||||
|
(os.path.join("subprojects", "gstreamer", "gst"),
|
||||||
|
os.path.join("subprojects", "gstreamer", "libs", "gst", "helpers")),
|
||||||
|
(os.path.join("subprojects", "glib", "gobject"), None),
|
||||||
|
(os.path.join("subprojects", "glib", "glib"), None)]:
|
||||||
|
|
||||||
|
if not gdb_path:
|
||||||
|
gdb_path = libpath
|
||||||
|
|
||||||
|
autoload_path = (pathlib.Path(bdir) / 'gdb-auto-load').joinpath(*bdir.parts[1:]) / libpath
|
||||||
|
autoload_path.mkdir(parents=True, exist_ok=True)
|
||||||
|
for gdb_helper in glob.glob(str(bdir / gdb_path / "*-gdb.py")):
|
||||||
|
python_paths.add(str(bdir / gdb_path))
|
||||||
|
python_paths.add(os.path.join(options.srcdir, gdb_path))
|
||||||
|
try:
|
||||||
|
if os.name == 'nt':
|
||||||
|
shutil.copy(gdb_helper, str(autoload_path / os.path.basename(gdb_helper)))
|
||||||
|
else:
|
||||||
|
os.symlink(gdb_helper, str(autoload_path / os.path.basename(gdb_helper)))
|
||||||
|
except (FileExistsError, shutil.SameFileError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
gdbinit_line = 'add-auto-load-scripts-directory {}\n'.format(bdir / 'gdb-auto-load')
|
||||||
|
try:
|
||||||
|
with open(os.path.join(options.srcdir, '.gdbinit'), 'r') as f:
|
||||||
|
if gdbinit_line in f.readlines():
|
||||||
|
return python_paths
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
with open(os.path.join(options.srcdir, '.gdbinit'), 'a') as f:
|
||||||
|
f.write(gdbinit_line)
|
||||||
|
|
||||||
|
return python_paths
|
||||||
|
|
||||||
|
def is_bash_completion_available (options):
|
||||||
|
return os.path.exists(os.path.join(options.builddir, 'subprojects/gstreamer/data/bash-completion/helpers/gst'))
|
||||||
|
|
||||||
|
def get_subprocess_env(options, gst_version):
|
||||||
|
env = os.environ.copy()
|
||||||
|
|
||||||
|
env["CURRENT_GST"] = os.path.normpath(SCRIPTDIR)
|
||||||
|
env["GST_VERSION"] = gst_version
|
||||||
|
prepend_env_var (env, "GST_VALIDATE_SCENARIOS_PATH", os.path.normpath(
|
||||||
|
"%s/subprojects/gst-devtools/validate/data/scenarios" % SCRIPTDIR),
|
||||||
|
options.sysroot)
|
||||||
|
env["GST_VALIDATE_PLUGIN_PATH"] = os.path.normpath(
|
||||||
|
"%s/subprojects/gst-devtools/validate/plugins" % options.builddir)
|
||||||
|
prepend_env_var (env, "GST_VALIDATE_APPS_DIR", os.path.normpath(
|
||||||
|
"%s/subprojects/gst-editing-services/tests/validate" % SCRIPTDIR),
|
||||||
|
options.sysroot)
|
||||||
|
env["GST_ENV"] = 'gst-' + gst_version
|
||||||
|
env["GST_REGISTRY"] = os.path.normpath(options.builddir + "/registry.dat")
|
||||||
|
prepend_env_var(env, "PATH", os.path.normpath(
|
||||||
|
"%s/subprojects/gst-devtools/validate/tools" % options.builddir),
|
||||||
|
options.sysroot)
|
||||||
|
|
||||||
|
prepend_env_var (env, "GST_VALIDATE_SCENARIOS_PATH", os.path.normpath(
|
||||||
|
"%s/subprojects/gst-examples/webrtc/check/validate/scenarios" %
|
||||||
|
SCRIPTDIR), options.sysroot)
|
||||||
|
prepend_env_var (env, "GST_VALIDATE_APPS_DIR", os.path.normpath(
|
||||||
|
"%s/subprojects/gst-examples/webrtc/check/validate/apps" %
|
||||||
|
SCRIPTDIR), options.sysroot)
|
||||||
|
|
||||||
|
if options.wine:
|
||||||
|
return get_wine_subprocess_env(options, env)
|
||||||
|
|
||||||
|
prepend_env_var(env, "PATH", os.path.join(SCRIPTDIR, 'meson'),
|
||||||
|
options.sysroot)
|
||||||
|
|
||||||
|
env["GST_PLUGIN_SYSTEM_PATH"] = ""
|
||||||
|
env["GST_PLUGIN_SCANNER"] = os.path.normpath(
|
||||||
|
"%s/subprojects/gstreamer/libs/gst/helpers/gst-plugin-scanner" % options.builddir)
|
||||||
|
env["GST_PTP_HELPER"] = os.path.normpath(
|
||||||
|
"%s/subprojects/gstreamer/libs/gst/helpers/gst-ptp-helper" % options.builddir)
|
||||||
|
|
||||||
|
if os.name == 'nt':
|
||||||
|
lib_path_envvar = 'PATH'
|
||||||
|
elif platform.system() == 'Darwin':
|
||||||
|
# RPATH is sufficient on macOS, and DYLD_LIBRARY_PATH can cause issues with dynamic linker path priority
|
||||||
|
lib_path_envvar = None
|
||||||
|
else:
|
||||||
|
lib_path_envvar = 'LD_LIBRARY_PATH'
|
||||||
|
|
||||||
|
prepend_env_var(env, "GST_PLUGIN_PATH", os.path.join(SCRIPTDIR, 'subprojects',
|
||||||
|
'gst-python', 'plugin'),
|
||||||
|
options.sysroot)
|
||||||
|
prepend_env_var(env, "GST_PLUGIN_PATH", os.path.join(PREFIX_DIR, 'lib',
|
||||||
|
'gstreamer-1.0'),
|
||||||
|
options.sysroot)
|
||||||
|
prepend_env_var(env, "GST_PLUGIN_PATH", os.path.join(options.builddir, 'subprojects',
|
||||||
|
'libnice', 'gst'),
|
||||||
|
options.sysroot)
|
||||||
|
prepend_env_var(env, "GST_VALIDATE_SCENARIOS_PATH",
|
||||||
|
os.path.join(PREFIX_DIR, 'share', 'gstreamer-1.0',
|
||||||
|
'validate', 'scenarios'),
|
||||||
|
options.sysroot)
|
||||||
|
prepend_env_var(env, "GI_TYPELIB_PATH", os.path.join(PREFIX_DIR, 'lib',
|
||||||
|
'lib', 'girepository-1.0'),
|
||||||
|
options.sysroot)
|
||||||
|
prepend_env_var(env, "PKG_CONFIG_PATH", os.path.join(PREFIX_DIR, 'lib', 'pkgconfig'),
|
||||||
|
options.sysroot)
|
||||||
|
|
||||||
|
# gst-indent
|
||||||
|
prepend_env_var(env, "PATH", os.path.join(SCRIPTDIR, 'gstreamer', 'tools'),
|
||||||
|
options.sysroot)
|
||||||
|
|
||||||
|
# tools: gst-launch-1.0, gst-inspect-1.0
|
||||||
|
prepend_env_var(env, "PATH", os.path.join(options.builddir, 'subprojects',
|
||||||
|
'gstreamer', 'tools'),
|
||||||
|
options.sysroot)
|
||||||
|
prepend_env_var(env, "PATH", os.path.join(options.builddir, 'subprojects',
|
||||||
|
'gst-plugins-base', 'tools'),
|
||||||
|
options.sysroot)
|
||||||
|
|
||||||
|
# Library and binary search paths
|
||||||
|
prepend_env_var(env, "PATH", os.path.join(PREFIX_DIR, 'bin'),
|
||||||
|
options.sysroot)
|
||||||
|
if lib_path_envvar != 'PATH':
|
||||||
|
prepend_env_var(env, lib_path_envvar, os.path.join(PREFIX_DIR, 'lib'),
|
||||||
|
options.sysroot)
|
||||||
|
prepend_env_var(env, lib_path_envvar, os.path.join(PREFIX_DIR, 'lib64'),
|
||||||
|
options.sysroot)
|
||||||
|
elif 'QMAKE' in os.environ:
|
||||||
|
# There's no RPATH on Windows, so we need to set PATH for the qt5 DLLs
|
||||||
|
prepend_env_var(env, 'PATH', os.path.dirname(os.environ['QMAKE']),
|
||||||
|
options.sysroot)
|
||||||
|
|
||||||
|
meson = get_meson()
|
||||||
|
targets_s = subprocess.check_output(meson + ['introspect', options.builddir, '--targets'])
|
||||||
|
targets = json.loads(targets_s.decode())
|
||||||
|
paths = set()
|
||||||
|
mono_paths = set()
|
||||||
|
srcdir_path = pathlib.Path(options.srcdir)
|
||||||
|
|
||||||
|
build_options_s = subprocess.check_output(meson + ['introspect', options.builddir, '--buildoptions'])
|
||||||
|
build_options = json.loads(build_options_s.decode())
|
||||||
|
libdir, = [o['value'] for o in build_options if o['name'] == 'libdir']
|
||||||
|
libdir = PurePath(libdir)
|
||||||
|
prefix, = [o['value'] for o in build_options if o['name'] == 'prefix']
|
||||||
|
bindir, = [o['value'] for o in build_options if o['name'] == 'bindir']
|
||||||
|
prefix = PurePath(prefix)
|
||||||
|
bindir = prefix / bindir
|
||||||
|
|
||||||
|
global GSTPLUGIN_FILEPATH_REG_TEMPLATE
|
||||||
|
GSTPLUGIN_FILEPATH_REG_TEMPLATE = GSTPLUGIN_FILEPATH_REG_TEMPLATE.format(libdir=libdir.as_posix())
|
||||||
|
|
||||||
|
for target in targets:
|
||||||
|
filenames = listify(target['filename'])
|
||||||
|
if not target['installed']:
|
||||||
|
continue
|
||||||
|
for filename in filenames:
|
||||||
|
root = os.path.dirname(filename)
|
||||||
|
if srcdir_path / "subprojects/gst-devtools/validate/plugins" in (srcdir_path / root).parents:
|
||||||
|
continue
|
||||||
|
if filename.endswith('.dll'):
|
||||||
|
mono_paths.add(os.path.join(options.builddir, root))
|
||||||
|
if TYPELIB_REG.search(filename):
|
||||||
|
prepend_env_var(env, "GI_TYPELIB_PATH",
|
||||||
|
os.path.join(options.builddir, root),
|
||||||
|
options.sysroot)
|
||||||
|
elif is_library_target_and_not_plugin(target, filename):
|
||||||
|
prepend_env_var(env, lib_path_envvar,
|
||||||
|
os.path.join(options.builddir, root),
|
||||||
|
options.sysroot)
|
||||||
|
elif is_binary_target_and_in_path(target, filename, bindir):
|
||||||
|
paths.add(os.path.join(options.builddir, root))
|
||||||
|
elif is_gio_module(target, filename, options.builddir):
|
||||||
|
prepend_env_var(env, 'GIO_EXTRA_MODULES',
|
||||||
|
os.path.join(options.builddir, root),
|
||||||
|
options.sysroot)
|
||||||
|
|
||||||
|
with open(os.path.join(options.gstbuilddir, 'GstPluginsPath.json')) as f:
|
||||||
|
for plugin_path in json.load(f):
|
||||||
|
prepend_env_var(env, 'GST_PLUGIN_PATH', plugin_path,
|
||||||
|
options.sysroot)
|
||||||
|
|
||||||
|
# Sort to iterate in a consistent order (`set`s and `hash`es are randomized)
|
||||||
|
for p in sorted(paths):
|
||||||
|
prepend_env_var(env, 'PATH', p, options.sysroot)
|
||||||
|
|
||||||
|
if os.name != 'nt':
|
||||||
|
for p in sorted(mono_paths):
|
||||||
|
prepend_env_var(env, "MONO_PATH", p, options.sysroot)
|
||||||
|
|
||||||
|
presets = set()
|
||||||
|
encoding_targets = set()
|
||||||
|
python_dirs = setup_gdb(options)
|
||||||
|
if '--installed' in subprocess.check_output(meson + ['introspect', '-h']).decode():
|
||||||
|
installed_s = subprocess.check_output(meson + ['introspect', options.builddir, '--installed'])
|
||||||
|
for path, installpath in json.loads(installed_s.decode()).items():
|
||||||
|
installpath_parts = pathlib.Path(installpath).parts
|
||||||
|
path_parts = pathlib.Path(path).parts
|
||||||
|
|
||||||
|
# We want to add all python modules to the PYTHONPATH
|
||||||
|
# in a manner consistent with the way they would be imported:
|
||||||
|
# For example if the source path /home/meh/foo/bar.py
|
||||||
|
# is to be installed in /usr/lib/python/site-packages/foo/bar.py,
|
||||||
|
# we want to add /home/meh to the PYTHONPATH.
|
||||||
|
# This will only work for projects where the paths to be installed
|
||||||
|
# mirror the installed directory layout, for example if the path
|
||||||
|
# is /home/meh/baz/bar.py and the install path is
|
||||||
|
# /usr/lib/site-packages/foo/bar.py , we will not add anything
|
||||||
|
# to PYTHONPATH, but the current approach works with pygobject
|
||||||
|
# and gst-python at least.
|
||||||
|
if 'site-packages' in installpath_parts:
|
||||||
|
install_subpath = os.path.join(*installpath_parts[installpath_parts.index('site-packages') + 1:])
|
||||||
|
if path.endswith(install_subpath):
|
||||||
|
python_dirs.add(path[:len (install_subpath) * -1])
|
||||||
|
|
||||||
|
if path.endswith('.prs'):
|
||||||
|
presets.add(os.path.dirname(path))
|
||||||
|
elif path.endswith('.gep'):
|
||||||
|
encoding_targets.add(
|
||||||
|
os.path.abspath(os.path.join(os.path.dirname(path), '..')))
|
||||||
|
|
||||||
|
if path.endswith('gstomx.conf'):
|
||||||
|
prepend_env_var(env, 'GST_OMX_CONFIG_DIR', os.path.dirname(path),
|
||||||
|
options.sysroot)
|
||||||
|
|
||||||
|
for p in sorted(presets):
|
||||||
|
prepend_env_var(env, 'GST_PRESET_PATH', p, options.sysroot)
|
||||||
|
|
||||||
|
for t in sorted(encoding_targets):
|
||||||
|
prepend_env_var(env, 'GST_ENCODING_TARGET_PATH', t, options.sysroot)
|
||||||
|
|
||||||
|
# Check if meson has generated -uninstalled pkgconfig files
|
||||||
|
meson_uninstalled = pathlib.Path(options.builddir) / 'meson-uninstalled'
|
||||||
|
if meson_uninstalled.is_dir():
|
||||||
|
prepend_env_var(env, 'PKG_CONFIG_PATH', str(meson_uninstalled), options.sysroot)
|
||||||
|
|
||||||
|
for python_dir in sorted(python_dirs):
|
||||||
|
prepend_env_var(env, 'PYTHONPATH', python_dir, options.sysroot)
|
||||||
|
|
||||||
|
mesonpath = os.path.join(SCRIPTDIR, "meson")
|
||||||
|
if os.path.join(mesonpath):
|
||||||
|
# Add meson/ into PYTHONPATH if we are using a local meson
|
||||||
|
prepend_env_var(env, 'PYTHONPATH', mesonpath, options.sysroot)
|
||||||
|
|
||||||
|
# For devhelp books
|
||||||
|
if 'XDG_DATA_DIRS' not in env or not env['XDG_DATA_DIRS']:
|
||||||
|
# Preserve default paths when empty
|
||||||
|
prepend_env_var(env, 'XDG_DATA_DIRS', '/usr/local/share/:/usr/share/', '')
|
||||||
|
|
||||||
|
prepend_env_var (env, 'XDG_DATA_DIRS', os.path.join(options.builddir,
|
||||||
|
'subprojects',
|
||||||
|
'gst-docs',
|
||||||
|
'GStreamer-doc'),
|
||||||
|
options.sysroot)
|
||||||
|
|
||||||
|
if 'XDG_CONFIG_DIRS' not in env or not env['XDG_CONFIG_DIRS']:
|
||||||
|
# Preserve default paths when empty
|
||||||
|
prepend_env_var(env, 'XDG_CONFIG_DIRS', '/etc/local/xdg:/etc/xdg', '')
|
||||||
|
|
||||||
|
prepend_env_var(env, "XDG_CONFIG_DIRS", os.path.join(PREFIX_DIR, 'etc', 'xdg'),
|
||||||
|
options.sysroot)
|
||||||
|
|
||||||
|
return env
|
||||||
|
|
||||||
|
def get_windows_shell():
|
||||||
|
command = ['powershell.exe' ,'-noprofile', '-executionpolicy', 'bypass', '-file', 'cmd_or_ps.ps1']
|
||||||
|
result = subprocess.check_output(command, cwd=SCRIPTDIR)
|
||||||
|
return result.decode().strip()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(prog="gst-env")
|
||||||
|
|
||||||
|
parser.add_argument("--builddir",
|
||||||
|
default=DEFAULT_BUILDDIR,
|
||||||
|
help="The meson build directory")
|
||||||
|
parser.add_argument("--gstbuilddir",
|
||||||
|
default=None,
|
||||||
|
help="The meson gst-build build directory (defaults to builddir)")
|
||||||
|
parser.add_argument("--srcdir",
|
||||||
|
default=SCRIPTDIR,
|
||||||
|
help="The top level source directory")
|
||||||
|
parser.add_argument("--sysroot",
|
||||||
|
default='',
|
||||||
|
help="The sysroot path used during cross-compilation")
|
||||||
|
parser.add_argument("--wine",
|
||||||
|
default='',
|
||||||
|
help="Build a wine env based on specified wine command")
|
||||||
|
parser.add_argument("--winepath",
|
||||||
|
default='',
|
||||||
|
help="Extra path to set to WINEPATH.")
|
||||||
|
parser.add_argument("--only-environment",
|
||||||
|
action='store_true',
|
||||||
|
default=False,
|
||||||
|
help="Do not start a shell, only print required environment.")
|
||||||
|
options, args = parser.parse_known_args()
|
||||||
|
|
||||||
|
if not os.path.exists(options.builddir):
|
||||||
|
print("GStreamer not built in %s\n\nBuild it and try again" %
|
||||||
|
options.builddir)
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
if options.gstbuilddir and not os.path.exists(options.gstbuilddir):
|
||||||
|
print("gst-build is not built in %s\n\nBuild it and try again" %
|
||||||
|
options.gstbuilddir)
|
||||||
|
exit(1)
|
||||||
|
elif not options.gstbuilddir:
|
||||||
|
options.gstbuilddir = options.builddir
|
||||||
|
|
||||||
|
options.builddir = os.path.abspath(options.builddir)
|
||||||
|
options.gstbuilddir = os.path.abspath(options.gstbuilddir)
|
||||||
|
|
||||||
|
if not os.path.exists(options.srcdir):
|
||||||
|
print("The specified source dir does not exist" %
|
||||||
|
options.srcdir)
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
# The following incantation will retrieve the current branch name.
|
||||||
|
try:
|
||||||
|
gst_version = git("rev-parse", "--symbolic-full-name", "--abbrev-ref", "HEAD",
|
||||||
|
repository_path=options.srcdir).strip('\n')
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
gst_version = "unknown"
|
||||||
|
|
||||||
|
if options.wine:
|
||||||
|
gst_version += '-' + os.path.basename(options.wine)
|
||||||
|
|
||||||
|
env = get_subprocess_env(options, gst_version)
|
||||||
|
if not args:
|
||||||
|
if os.name == 'nt':
|
||||||
|
shell = get_windows_shell()
|
||||||
|
if shell == 'powershell.exe':
|
||||||
|
args = ['powershell.exe']
|
||||||
|
args += ['-NoLogo', '-NoExit']
|
||||||
|
prompt = 'function global:prompt { "[gst-' + gst_version + '"+"] PS " + $PWD + "> "}'
|
||||||
|
args += ['-Command', prompt]
|
||||||
|
else:
|
||||||
|
args = [os.environ.get("COMSPEC", r"C:\WINDOWS\system32\cmd.exe")]
|
||||||
|
args += ['/k', 'prompt [gst-{}] $P$G'.format(gst_version)]
|
||||||
|
else:
|
||||||
|
args = [os.environ.get("SHELL", os.path.realpath("/bin/sh"))]
|
||||||
|
if args[0].endswith('bash') and not strtobool(os.environ.get("GST_BUILD_DISABLE_PS1_OVERRIDE", r"FALSE")):
|
||||||
|
# Let the GC remove the tmp file
|
||||||
|
tmprc = tempfile.NamedTemporaryFile(mode='w')
|
||||||
|
bashrc = os.path.expanduser('~/.bashrc')
|
||||||
|
if os.path.exists(bashrc):
|
||||||
|
with open(bashrc, 'r') as src:
|
||||||
|
shutil.copyfileobj(src, tmprc)
|
||||||
|
tmprc.write('\nexport PS1="[gst-%s] $PS1"' % gst_version)
|
||||||
|
tmprc.flush()
|
||||||
|
if is_bash_completion_available(options):
|
||||||
|
bash_completions_files = []
|
||||||
|
for p in BASH_COMPLETION_PATHS:
|
||||||
|
if os.path.exists(p):
|
||||||
|
bash_completions_files += os.listdir(path=p)
|
||||||
|
bc_rc = BC_RC.format(bash_completions=' '.join(bash_completions_files), bash_completions_paths=' '.join(BASH_COMPLETION_PATHS))
|
||||||
|
tmprc.write(bc_rc)
|
||||||
|
tmprc.flush()
|
||||||
|
args.append("--rcfile")
|
||||||
|
args.append(tmprc.name)
|
||||||
|
elif args[0].endswith('fish'):
|
||||||
|
# Ignore SIGINT while using fish as the shell to make it behave
|
||||||
|
# like other shells such as bash and zsh.
|
||||||
|
# See: https://gitlab.freedesktop.org/gstreamer/gst-build/issues/18
|
||||||
|
signal.signal(signal.SIGINT, lambda x, y: True)
|
||||||
|
# Set the prompt
|
||||||
|
args.append('--init-command')
|
||||||
|
prompt_cmd = '''functions --copy fish_prompt original_fish_prompt
|
||||||
|
function fish_prompt
|
||||||
|
echo -n '[gst-{}] '(original_fish_prompt)
|
||||||
|
end'''.format(gst_version)
|
||||||
|
args.append(prompt_cmd)
|
||||||
|
elif args[0].endswith('zsh'):
|
||||||
|
tmpdir = tempfile.TemporaryDirectory()
|
||||||
|
# Let the GC remove the tmp file
|
||||||
|
tmprc = open(os.path.join(tmpdir.name, '.zshrc'), 'w')
|
||||||
|
zshrc = os.path.expanduser('~/.zshrc')
|
||||||
|
if os.path.exists(zshrc):
|
||||||
|
with open(zshrc, 'r') as src:
|
||||||
|
shutil.copyfileobj(src, tmprc)
|
||||||
|
tmprc.write('\nexport PROMPT="[gst-{}] $PROMPT"'.format(gst_version))
|
||||||
|
tmprc.flush()
|
||||||
|
env['ZDOTDIR'] = tmpdir.name
|
||||||
|
try:
|
||||||
|
if options.only_environment:
|
||||||
|
for name, value in env.items():
|
||||||
|
print('{}={}'.format(name, shlex.quote(value)))
|
||||||
|
print('export {}'.format(name))
|
||||||
|
else:
|
||||||
|
exit(subprocess.call(args, close_fds=False, env=env))
|
||||||
|
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
exit(e.returncode)
|
1
gst-uninstalled.py
Symbolic link
1
gst-uninstalled.py
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
gst-env.py
|
161
gst-worktree.py
Executable file
161
gst-worktree.py
Executable file
|
@ -0,0 +1,161 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import argparse
|
||||||
|
import subprocess
|
||||||
|
import configparser
|
||||||
|
|
||||||
|
from scripts.common import git
|
||||||
|
from scripts.common import Colors
|
||||||
|
|
||||||
|
|
||||||
|
SCRIPTDIR = os.path.normpath(os.path.dirname(__file__))
|
||||||
|
SUBPROJECTS_DIR = os.path.normpath(os.path.join(SCRIPTDIR, "subprojects"))
|
||||||
|
|
||||||
|
|
||||||
|
def repo_has_branch(repo_dir, branch):
|
||||||
|
if not branch:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
git("describe", branch, repository_path=repo_dir)
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def parse_wrapfile(wrapf):
|
||||||
|
cgp = configparser.ConfigParser()
|
||||||
|
cgp.read(wrapf)
|
||||||
|
if 'wrap-git' not in cgp:
|
||||||
|
return None
|
||||||
|
section = cgp['wrap-git']
|
||||||
|
# Default to the wrapper filename if 'directory' field is missing
|
||||||
|
directory = section.get('directory', os.path.splitext(os.path.basename(wrapf))[0])
|
||||||
|
return directory, section['revision']
|
||||||
|
|
||||||
|
def get_wrap_subprojects(srcdir, gst_branch):
|
||||||
|
'''
|
||||||
|
Parses wrap files in the subprojects directory for the specified source
|
||||||
|
tree and gets the revisions for all common repos.
|
||||||
|
'''
|
||||||
|
for wrapf in glob.glob(os.path.join(srcdir, 'subprojects', '*.wrap')):
|
||||||
|
entries = parse_wrapfile(wrapf)
|
||||||
|
if not entries:
|
||||||
|
continue
|
||||||
|
|
||||||
|
repo_name, repo_branch = entries
|
||||||
|
parent_repo_dir = os.path.join(SUBPROJECTS_DIR, repo_name)
|
||||||
|
if not os.path.exists(os.path.join(parent_repo_dir, '.git')):
|
||||||
|
continue
|
||||||
|
# If a branch of the same name exists in the gst subproject, use it
|
||||||
|
if repo_name.startswith('gst') and repo_has_branch(parent_repo_dir, gst_branch):
|
||||||
|
repo_branch = gst_branch
|
||||||
|
|
||||||
|
yield repo_name, repo_branch, parent_repo_dir
|
||||||
|
|
||||||
|
def checkout_worktree(repo_name, repo_dir, worktree_dir, branch, new_branch, force=False):
|
||||||
|
print('Checking out worktree for project {!r} into {!r} '
|
||||||
|
'(branch {})'.format(repo_name, worktree_dir, branch))
|
||||||
|
try:
|
||||||
|
args = ["worktree", "add"]
|
||||||
|
if force:
|
||||||
|
args += ["-f", "-f"]
|
||||||
|
args += [worktree_dir, branch]
|
||||||
|
if new_branch:
|
||||||
|
args += ["-b", new_branch]
|
||||||
|
git(*args, repository_path=repo_dir)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
out = getattr(e, "output", b"").decode()
|
||||||
|
print("\nCould not checkout worktree %s, please fix and try again."
|
||||||
|
" Error:\n\n%s %s" % (repo_dir, out, e))
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
commit_message = git("show", "--format=medium", "--shortstat", repository_path=repo_dir).split("\n")
|
||||||
|
print(u" -> %s%s%s - %s" % (Colors.HEADER, repo_dir, Colors.ENDC,
|
||||||
|
commit_message[4].strip()))
|
||||||
|
return True
|
||||||
|
|
||||||
|
def checkout_subprojects(worktree_dir, branch, new_branch):
|
||||||
|
worktree_subdir = os.path.join(worktree_dir, "subprojects")
|
||||||
|
|
||||||
|
for repo_name, repo_branch, parent_repo_dir in get_wrap_subprojects(worktree_dir, branch):
|
||||||
|
workdir = os.path.normpath(os.path.join(worktree_subdir, repo_name))
|
||||||
|
if not checkout_worktree(repo_name, parent_repo_dir, workdir, repo_branch, new_branch, force=True):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def remove_worktree(worktree_dir):
|
||||||
|
worktree_subdir = os.path.join(worktree_dir, "subprojects")
|
||||||
|
|
||||||
|
for repo_name, _, parent_repo_dir in get_wrap_subprojects(worktree_dir, None):
|
||||||
|
workdir = os.path.normpath(os.path.join(worktree_subdir, repo_name))
|
||||||
|
if not os.path.exists(workdir):
|
||||||
|
continue
|
||||||
|
|
||||||
|
subprojdir = os.path.normpath(os.path.join(SUBPROJECTS_DIR, repo_name))
|
||||||
|
if not os.path.exists(subprojdir):
|
||||||
|
continue
|
||||||
|
|
||||||
|
print('Removing worktree {!r}'.format(workdir))
|
||||||
|
try:
|
||||||
|
git('worktree', 'remove', '-f', workdir, repository_path=subprojdir)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
out = getattr(e, "output", b"").decode()
|
||||||
|
print('Ignoring error while removing worktree {!r}:\n\n{}'.format(workdir, out))
|
||||||
|
|
||||||
|
try:
|
||||||
|
git('worktree', 'remove', '-f', worktree_dir, repository_path=SCRIPTDIR)
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
print('Failed to remove worktree {!r}'.format(worktree_dir))
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(prog="gst-worktree")
|
||||||
|
parser.add_argument("--no-color", default=False, action='store_true',
|
||||||
|
help="Do not output ANSI colors")
|
||||||
|
|
||||||
|
subparsers = parser.add_subparsers(help='The sub-command to run', dest='command')
|
||||||
|
|
||||||
|
parser_add = subparsers.add_parser('add',
|
||||||
|
help='Create a worktree for gst-build and all subprojects')
|
||||||
|
parser_add.add_argument('worktree_dir', type=str,
|
||||||
|
help='Directory where to create the new worktree')
|
||||||
|
parser_add.add_argument('branch', type=str, default=None,
|
||||||
|
help='Branch to checkout')
|
||||||
|
parser_add.add_argument('-b', '--new-branch', type=str, default=None,
|
||||||
|
help='Branch to create')
|
||||||
|
|
||||||
|
parser_rm = subparsers.add_parser('rm',
|
||||||
|
help='Remove a gst-build worktree and the subproject worktrees inside it')
|
||||||
|
parser_rm.add_argument('worktree_dir', type=str,
|
||||||
|
help='Worktree directory to remove')
|
||||||
|
|
||||||
|
options = parser.parse_args()
|
||||||
|
|
||||||
|
if options.no_color or not Colors.can_enable():
|
||||||
|
Colors.disable()
|
||||||
|
|
||||||
|
if not options.command:
|
||||||
|
parser.print_usage()
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
worktree_dir = os.path.abspath(options.worktree_dir)
|
||||||
|
|
||||||
|
if options.command == 'add':
|
||||||
|
if not checkout_worktree('gst-build', SCRIPTDIR, worktree_dir, options.branch, options.new_branch):
|
||||||
|
exit(1)
|
||||||
|
if not checkout_subprojects(worktree_dir, options.branch, options.new_branch):
|
||||||
|
exit(1)
|
||||||
|
elif options.command == 'rm':
|
||||||
|
if not os.path.exists(worktree_dir):
|
||||||
|
print('Cannot remove worktree directory {!r}, it does not exist'.format(worktree_dir))
|
||||||
|
exit(1)
|
||||||
|
if not remove_worktree(worktree_dir):
|
||||||
|
exit(1)
|
||||||
|
else:
|
||||||
|
# Unreachable code
|
||||||
|
raise AssertionError
|
10
gstreamer-full-default.map
Normal file
10
gstreamer-full-default.map
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
global:
|
||||||
|
gst_*;
|
||||||
|
GST_*;
|
||||||
|
_gst_*;
|
||||||
|
g_*;
|
||||||
|
glib_*;
|
||||||
|
local:
|
||||||
|
*;
|
||||||
|
};
|
390
meson.build
Normal file
390
meson.build
Normal file
|
@ -0,0 +1,390 @@
|
||||||
|
project('All GStreamer modules', 'c',
|
||||||
|
version : '1.19.1.1',
|
||||||
|
meson_version : '>= 0.54.0',
|
||||||
|
default_options : ['buildtype=debugoptimized'])
|
||||||
|
|
||||||
|
gst_version = '>= @0@'.format(meson.project_version())
|
||||||
|
gst_branch = 'master'
|
||||||
|
|
||||||
|
build_system = build_machine.system()
|
||||||
|
cc = meson.get_compiler('c')
|
||||||
|
|
||||||
|
pkgconfig = import('pkgconfig')
|
||||||
|
python3 = import('python').find_installation()
|
||||||
|
# Ensure that we're not being run from inside the gst-uninstalled env
|
||||||
|
# because that will confuse meson, and it might find the already-built
|
||||||
|
# gstreamer. It's fine if people run `ninja` as long as it doesn't run
|
||||||
|
# reconfigure because ninja doesn't care about the env.
|
||||||
|
ensure_not_uninstalled = '''
|
||||||
|
import os
|
||||||
|
assert('GST_ENV' not in os.environ)
|
||||||
|
'''
|
||||||
|
cmdres = run_command(python3, '-c', ensure_not_uninstalled)
|
||||||
|
if cmdres.returncode() != 0
|
||||||
|
error('Do not run `ninja` or `meson` for gst-build inside the uninstalled environment, you will run into problems')
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Ensure that the user does not have Strawberry Perl in PATH, since it ships
|
||||||
|
# with a pkg-config.bat and broken pkgconfig files for libffi and zlib. Will
|
||||||
|
# cause a build error, such as in
|
||||||
|
# https://gitlab.freedesktop.org/gstreamer/gst-build/-/issues/41
|
||||||
|
ensure_no_strawberry_perl = '''
|
||||||
|
import os
|
||||||
|
assert(r'Strawberry\perl\bin' not in os.environ['PATH'])
|
||||||
|
'''
|
||||||
|
if build_system == 'windows'
|
||||||
|
cmdres = run_command(python3, '-c', ensure_no_strawberry_perl)
|
||||||
|
if cmdres.returncode() != 0
|
||||||
|
error('You have Strawberry Perl in PATH which is known to cause build issues with gst-build. Please remove it from PATH or uninstall it.')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
documented_projects = ''
|
||||||
|
# Make it possible to use msys2 built zlib which fails
|
||||||
|
# when not using the mingw toolchain as it uses unistd.h
|
||||||
|
if not meson.is_subproject() and cc.get_id() == 'msvc'
|
||||||
|
uname = find_program('uname', required: false)
|
||||||
|
if uname.found()
|
||||||
|
ret = run_command(uname, '-o')
|
||||||
|
if ret.returncode() == 0 and ret.stdout().to_lower() == 'msys'
|
||||||
|
ret = run_command(uname, '-r')
|
||||||
|
# The kernel version returned by uname is actually the msys version
|
||||||
|
if ret.returncode() == 0 and ret.stdout().startswith('2')
|
||||||
|
# If a system zlib is found, disable UNIX features in zlib.h and zconf.h
|
||||||
|
if cc.find_library('z').found()
|
||||||
|
add_global_arguments('-DZ_SOLO', language: 'c')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Ensure that MSVC interprets all source code as UTF-8. Only do this when we're
|
||||||
|
# not a subproject, because subprojects are not allowed to call
|
||||||
|
# add_global_arguments().
|
||||||
|
if not meson.is_subproject() and cc.get_id() == 'msvc'
|
||||||
|
add_global_arguments(
|
||||||
|
cc.get_supported_arguments(['/utf-8']), # set the input encoding to utf-8
|
||||||
|
language: ['c', 'cpp'])
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Ordered list of subprojects (dict has no ordering guarantees)
|
||||||
|
subprojects = [
|
||||||
|
['gstreamer', {'build-hotdoc': true}],
|
||||||
|
['gst-plugins-base', {'option': get_option('base'), 'build-hotdoc': true}],
|
||||||
|
['gst-plugins-good', {'option': get_option('good'), 'build-hotdoc': true}],
|
||||||
|
['libnice', { 'option': get_option('libnice'), 'match_gst_version': false}],
|
||||||
|
['gst-plugins-bad', { 'option': get_option('bad'), 'build-hotdoc': true}],
|
||||||
|
['gst-plugins-ugly', { 'option': get_option('ugly'), 'build-hotdoc': true}],
|
||||||
|
['gst-libav', { 'option': get_option('libav'), 'build-hotdoc': true}],
|
||||||
|
['gst-rtsp-server', { 'option': get_option('rtsp_server'), 'build-hotdoc': true}],
|
||||||
|
['gst-devtools', { 'option': get_option('devtools'), 'build-hotdoc': true }],
|
||||||
|
['gst-integration-testsuites', { 'option': get_option('devtools') }],
|
||||||
|
['gst-editing-services', { 'option': get_option('ges'), 'build-hotdoc': true}],
|
||||||
|
['gstreamer-vaapi', { 'option': get_option('vaapi'), 'build-hotdoc': true}],
|
||||||
|
['gst-omx', { 'option': get_option('omx'), 'build-hotdoc': true}],
|
||||||
|
['gstreamer-sharp', { 'option': get_option('sharp') }],
|
||||||
|
['pygobject', { 'option': get_option('python'), 'match_gst_version': false }],
|
||||||
|
['gst-python', { 'option': get_option('python')}],
|
||||||
|
['gst-examples', { 'option': get_option('gst-examples'), 'match_gst_versions': false}],
|
||||||
|
['gst-plugins-rs', { 'option': get_option('rs'), 'match_gst_version': false}],
|
||||||
|
]
|
||||||
|
|
||||||
|
symlink = '''
|
||||||
|
import os
|
||||||
|
|
||||||
|
os.symlink(os.path.join('@1@', 'subprojects', '@0@'),
|
||||||
|
os.path.join('@1@', '@0@'))
|
||||||
|
'''
|
||||||
|
|
||||||
|
if build_system == 'windows'
|
||||||
|
subproject('win-flex-bison-binaries')
|
||||||
|
subproject('win-nasm')
|
||||||
|
elif build_system == 'darwin'
|
||||||
|
subproject('macos-bison-binary')
|
||||||
|
endif
|
||||||
|
|
||||||
|
orc_subproject = subproject('orc', required: get_option('orc'))
|
||||||
|
|
||||||
|
subprojects_names = []
|
||||||
|
plugins_doc_caches = []
|
||||||
|
orc_update_targets = []
|
||||||
|
all_plugins = []
|
||||||
|
foreach sp : subprojects
|
||||||
|
project_name = sp[0]
|
||||||
|
build_infos = sp[1]
|
||||||
|
is_required = build_infos.get('option', true)
|
||||||
|
match_gst_version = build_infos.get('match_gst_version', true)
|
||||||
|
|
||||||
|
if match_gst_version
|
||||||
|
subproj = subproject(project_name, version: gst_version, required: is_required)
|
||||||
|
else
|
||||||
|
subproj = subproject(project_name, required: is_required)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if subproj.found()
|
||||||
|
plugins = subproj.get_variable('plugins', [])
|
||||||
|
all_plugins += plugins
|
||||||
|
|
||||||
|
orc_update_targets += subproj.get_variable('orc_update_targets', [])
|
||||||
|
|
||||||
|
subprojects_names += [project_name]
|
||||||
|
cmdres = run_command(python3, '-c', symlink.format(project_name, meson.current_source_dir()))
|
||||||
|
if cmdres.returncode() == 0
|
||||||
|
message('Created symlink to ' + project_name)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if not meson.is_cross_build() and build_infos.get('build-hotdoc', false)
|
||||||
|
if plugins.length() > 0
|
||||||
|
plugins_doc_caches += [subproj.get_variable('plugins_doc_dep')]
|
||||||
|
endif
|
||||||
|
if documented_projects != ''
|
||||||
|
documented_projects += ','
|
||||||
|
endif
|
||||||
|
documented_projects += project_name
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
# Check if we need to also build glib-networking for TLS modules
|
||||||
|
glib_dep = dependency('glib-2.0')
|
||||||
|
if glib_dep.type_name() == 'internal'
|
||||||
|
subproject('glib-networking', required : get_option('tls'),
|
||||||
|
default_options: ['gnutls=auto', 'openssl=auto'])
|
||||||
|
endif
|
||||||
|
|
||||||
|
plugins_doc_dep = custom_target('plugins-doc-cache',
|
||||||
|
command: [python3, '-c', 'print("Built all doc caches")'],
|
||||||
|
input: plugins_doc_caches,
|
||||||
|
output: 'plugins_doc_caches',
|
||||||
|
capture: true,
|
||||||
|
)
|
||||||
|
|
||||||
|
if meson.is_cross_build() or build_machine.system() == 'windows'
|
||||||
|
if get_option('doc').enabled()
|
||||||
|
error('Documentation enabled but building the doc while cross building or building on windows is not supported yet.')
|
||||||
|
endif
|
||||||
|
|
||||||
|
documented_projects = ''
|
||||||
|
message('Documentation not built as building the documentation while cross building or building on windows is not supported yet.')
|
||||||
|
else
|
||||||
|
hotdoc_p = find_program('hotdoc', required : get_option('doc'))
|
||||||
|
if not hotdoc_p.found()
|
||||||
|
documented_projects = ''
|
||||||
|
message('Not building documentation as hotdoc was not found')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
write_file_contents = '''
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
assert len(sys.argv) >= 3
|
||||||
|
fname = sys.argv[1]
|
||||||
|
contents = sys.argv[2]
|
||||||
|
|
||||||
|
with open(fname, 'w') as f:
|
||||||
|
f.write(contents)
|
||||||
|
'''
|
||||||
|
|
||||||
|
configure_file(
|
||||||
|
output : 'GstDocumentedSubprojects',
|
||||||
|
command : [python3,
|
||||||
|
'-c', write_file_contents,
|
||||||
|
'@OUTPUT@',
|
||||||
|
documented_projects]
|
||||||
|
)
|
||||||
|
|
||||||
|
if documented_projects != ''
|
||||||
|
subproject('gst-docs', required: get_option('doc').enabled())
|
||||||
|
message('Gst docs subprojects: ' + documented_projects)
|
||||||
|
endif
|
||||||
|
|
||||||
|
all_plugins_paths = []
|
||||||
|
foreach plugin: all_plugins
|
||||||
|
all_plugins_paths += plugin.full_path()
|
||||||
|
endforeach
|
||||||
|
# Work around meson bug: https://github.com/mesonbuild/meson/pull/6770
|
||||||
|
pathsep = host_machine.system() == 'windows' ? ';' : ':'
|
||||||
|
all_plugins_paths = pathsep.join(all_plugins_paths)
|
||||||
|
|
||||||
|
generate_plugins_paths = find_program('scripts/generate_plugins_path.py')
|
||||||
|
configure_file(
|
||||||
|
output : 'GstPluginsPath.json',
|
||||||
|
command : [generate_plugins_paths,
|
||||||
|
'@OUTPUT@',
|
||||||
|
all_plugins_paths]
|
||||||
|
)
|
||||||
|
|
||||||
|
# FIXME: Create a 'libraries' list in each subproject like we do for 'plugins'
|
||||||
|
libraries_map = {
|
||||||
|
# name: [subproject_name, variable_name]
|
||||||
|
'gstreamer': ['gstreamer', 'libgst'],
|
||||||
|
'base': ['gstreamer', 'gst_base'],
|
||||||
|
'check': ['gstreamer', 'gst_check'],
|
||||||
|
'controller': ['gstreamer', 'gst_controller'],
|
||||||
|
'net': ['gstreamer', 'gst_net'],
|
||||||
|
|
||||||
|
'allocators': ['gst-plugins-base', 'gstallocators'],
|
||||||
|
'app': ['gst-plugins-base', 'gstapp'],
|
||||||
|
'audio': ['gst-plugins-base', 'gstaudio'],
|
||||||
|
'fft': ['gst-plugins-base', 'gstfft'],
|
||||||
|
'pbutils': ['gst-plugins-base', 'pbutils'],
|
||||||
|
'riff': ['gst-plugins-base', 'gstriff'],
|
||||||
|
'rtp': ['gst-plugins-base', 'gst_rtp'],
|
||||||
|
'rtsp': ['gst-plugins-base', 'gst_rtsp'],
|
||||||
|
'sdp': ['gst-plugins-base', 'gstsdp'],
|
||||||
|
'tag': ['gst-plugins-base', 'gsttag'],
|
||||||
|
'video': ['gst-plugins-base', 'gstvideo'],
|
||||||
|
'gl': ['gst-plugins-base', 'gstgl'],
|
||||||
|
|
||||||
|
'bad-audio': ['gst-plugins-bad', 'gstbadaudio'],
|
||||||
|
'bad-transcoder': ['gst-plugins-bad', 'gst_transcoder'],
|
||||||
|
'codecparsers': ['gst-plugins-bad', 'gstcodecparsers'],
|
||||||
|
'insertbin': ['gst-plugins-bad', 'gstinsertbin'],
|
||||||
|
'mpegts': ['gst-plugins-bad', 'gstmpegts'],
|
||||||
|
'player': ['gst-plugins-bad', 'gstplayer'],
|
||||||
|
'sctp': ['gst-plugins-bad', 'libgstsctp'],
|
||||||
|
'webrtc': ['gst-plugins-bad', 'gstwebrtc'],
|
||||||
|
'vulkan': ['gst-plugins-bad', 'gstvulkan'],
|
||||||
|
|
||||||
|
'rtsp-server': ['gst-rtsp-server', 'gst_rtsp_server'],
|
||||||
|
}
|
||||||
|
|
||||||
|
if get_option('default_library') == 'static'
|
||||||
|
if not get_option('introspection').disabled()
|
||||||
|
error('GObject Introspection is not supported in static builds. Please use -Dintrospection=disabled')
|
||||||
|
endif
|
||||||
|
# Generate a .c file which declare and register all built plugins
|
||||||
|
plugins_names = []
|
||||||
|
foreach plugin: all_plugins
|
||||||
|
plugins_names += plugin.full_path()
|
||||||
|
endforeach
|
||||||
|
all_plugin_names = ';'.join(plugins_names)
|
||||||
|
|
||||||
|
static_plugins = get_option('gst-full-plugins')
|
||||||
|
if static_plugins == '*'
|
||||||
|
static_plugins = all_plugin_names
|
||||||
|
endif
|
||||||
|
generate_init_static_plugins = find_program('scripts/generate_init_static_plugins.py')
|
||||||
|
init_static_plugins_c = configure_file(
|
||||||
|
output: 'gstinitstaticplugins.c',
|
||||||
|
command : [generate_init_static_plugins,
|
||||||
|
'-o ' + '@OUTPUT@',
|
||||||
|
'-p ' + static_plugins,
|
||||||
|
'-e ' + get_option('gst-full-elements'),
|
||||||
|
'-t ' + get_option('gst-full-typefind-functions'),
|
||||||
|
'-d ' + get_option('gst-full-device-providers'),
|
||||||
|
'-T ' + get_option('gst-full-dynamic-types')
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
gstfull_link_args = cc.get_supported_link_arguments(['-Wl,-Bsymbolic-functions'])
|
||||||
|
|
||||||
|
# Get a list of libraries that needs to be exposed in the ABI.
|
||||||
|
exposed_libs = []
|
||||||
|
incdir_deps = []
|
||||||
|
foreach name : get_option('gst-full-libraries') + ['gstreamer']
|
||||||
|
info = libraries_map[name]
|
||||||
|
exposed_libs += subproject(info[0]).get_variable(info[1])
|
||||||
|
depname = name == 'gstreamer' ? 'gstreamer-1.0' : 'gstreamer-@0@-1.0'.format(name)
|
||||||
|
incdir_deps += dependency(depname).partial_dependency(includes: true, sources: true)
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
# glib and gobject are part of our public API. If we are using glib from the
|
||||||
|
# system then our pkg-config file must require it. If we built it as
|
||||||
|
# subproject then we need to link_whole it.
|
||||||
|
glib_deps = []
|
||||||
|
glib_dep = dependency('glib-2.0')
|
||||||
|
gobject_dep = dependency('gobject-2.0')
|
||||||
|
if gobject_dep.type_name() == 'internal'
|
||||||
|
glib_subproject = subproject('glib')
|
||||||
|
exposed_libs += glib_subproject.get_variable('libglib')
|
||||||
|
exposed_libs += glib_subproject.get_variable('libgobject')
|
||||||
|
incdir_deps += [
|
||||||
|
glib_dep.partial_dependency(includes: true),
|
||||||
|
gobject_dep.partial_dependency(includes: true),
|
||||||
|
]
|
||||||
|
else
|
||||||
|
glib_deps = [glib_dep, gobject_dep]
|
||||||
|
endif
|
||||||
|
|
||||||
|
link_deps = []
|
||||||
|
if get_option('gst-full-version-script') != ''
|
||||||
|
symbol_map = meson.current_source_dir() / get_option('gst-full-version-script')
|
||||||
|
link_arg = '-Wl,--version-script=' + symbol_map
|
||||||
|
if cc.has_link_argument(link_arg)
|
||||||
|
gstfull_link_args += link_arg
|
||||||
|
link_deps += symbol_map
|
||||||
|
elif cc.get_id() == 'msvc'
|
||||||
|
warning('FIXME: Provide a def file to publish the public symbols')
|
||||||
|
else
|
||||||
|
error('Failed to link with version script (' + symbol_map + '), check logs for details')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Build both shared and static library
|
||||||
|
gstfull = both_libraries('gstreamer-full-1.0',
|
||||||
|
init_static_plugins_c,
|
||||||
|
link_with : all_plugins,
|
||||||
|
link_args: gstfull_link_args,
|
||||||
|
link_whole : exposed_libs,
|
||||||
|
dependencies : incdir_deps + glib_deps,
|
||||||
|
link_depends : link_deps,
|
||||||
|
install : true,
|
||||||
|
)
|
||||||
|
|
||||||
|
gst_full_dep = declare_dependency(link_with: gstfull.get_shared_lib(),
|
||||||
|
dependencies : incdir_deps + glib_deps,
|
||||||
|
include_directories: include_directories('.')
|
||||||
|
)
|
||||||
|
gst_full_libs_private = cc.get_supported_link_arguments(['-Wl,--undefined=gst_init_static_plugins'])
|
||||||
|
if gst_full_libs_private == []
|
||||||
|
warning('The compiler does not support `-Wl,--undefined` linker flag. The method `gst_init_static_plugins` might be dropped during the link stage of an application using libgstreamer-full-1.0.a, preventing plugins registration.')
|
||||||
|
endif
|
||||||
|
pkgconfig.generate(gstfull,
|
||||||
|
requires: glib_deps,
|
||||||
|
libraries_private: gst_full_libs_private,
|
||||||
|
subdirs : 'gstreamer-1.0')
|
||||||
|
meson.override_dependency('gstreamer-full-1.0', gst_full_dep)
|
||||||
|
endif
|
||||||
|
|
||||||
|
foreach custom_subproj: get_option('custom_subprojects').split(',')
|
||||||
|
if custom_subproj != ''
|
||||||
|
message ('Adding custom subproject ' + custom_subproj)
|
||||||
|
subproject(custom_subproj)
|
||||||
|
subprojects_names += [custom_subproj]
|
||||||
|
endif
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
message('Building subprojects: ' + ', '.join(subprojects_names))
|
||||||
|
|
||||||
|
subdir('tests')
|
||||||
|
|
||||||
|
setenv = find_program('gst-env.py')
|
||||||
|
|
||||||
|
devenv_cmd = [setenv, '--builddir=@0@'.format(meson.build_root()),
|
||||||
|
'--gstbuilddir=@0@'.format(meson.current_build_dir()),
|
||||||
|
'--srcdir=@0@'.format(meson.source_root())]
|
||||||
|
|
||||||
|
if meson.has_exe_wrapper() and build_machine.system() == 'linux' and host_machine.system() == 'windows'
|
||||||
|
# FIXME: Ideally we could get the wrapper directly from meson
|
||||||
|
devenv_cmd += ['--wine', host_machine.cpu_family() == 'x86_64' ? 'wine64' : 'wine32']
|
||||||
|
sysroot = meson.get_cross_property('sys_root')
|
||||||
|
if sysroot != ''
|
||||||
|
# Logic from meson
|
||||||
|
devenv_cmd += ['--winepath', 'Z:' + join_paths(sysroot, 'bin')]
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
run_target('uninstalled', command : devenv_cmd)
|
||||||
|
run_target('devenv', command : devenv_cmd)
|
||||||
|
|
||||||
|
update = find_program('git-update')
|
||||||
|
run_target('git-update', command : [update])
|
||||||
|
run_target('update', command : [update,
|
||||||
|
'--builddir=@0@'.format(meson.current_build_dir())])
|
||||||
|
|
||||||
|
if orc_subproject.found() and orc_update_targets.length() > 0
|
||||||
|
alias_target('update-orc-dist', orc_update_targets)
|
||||||
|
endif
|
44
meson_options.txt
Normal file
44
meson_options.txt
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# Subproject options
|
||||||
|
option('python', type : 'feature', value : 'auto')
|
||||||
|
option('libav', type : 'feature', value : 'auto')
|
||||||
|
option('libnice', type : 'feature', value : 'auto')
|
||||||
|
option('base', type : 'feature', value : 'enabled')
|
||||||
|
option('good', type : 'feature', value : 'enabled')
|
||||||
|
option('ugly', type : 'feature', value : 'auto')
|
||||||
|
option('bad', type : 'feature', value : 'auto')
|
||||||
|
option('devtools', type : 'feature', value : 'auto')
|
||||||
|
option('ges', type : 'feature', value : 'auto')
|
||||||
|
option('rtsp_server', type : 'feature', value : 'auto')
|
||||||
|
option('omx', type : 'feature', value : 'disabled')
|
||||||
|
option('vaapi', type : 'feature', value : 'disabled')
|
||||||
|
option('sharp', type : 'feature', value : 'disabled')
|
||||||
|
option('rs', type : 'feature', value : 'disabled')
|
||||||
|
option('gst-examples', type : 'feature', value : 'auto', description : 'Build gst-examples')
|
||||||
|
option('tls', type : 'feature', value : 'auto', description : 'TLS support using glib-networking')
|
||||||
|
option('qt5', type : 'feature', value : 'auto', description : 'Qt5 Support')
|
||||||
|
|
||||||
|
# Other options
|
||||||
|
option('custom_subprojects', type : 'string', value : '', description : 'Comma-separated project names')
|
||||||
|
option('gst-full-libraries', type : 'array', value : [],
|
||||||
|
description : '''List of libraries to expose in gstreamer-full's ABI. gstreamer, glib and gobject are always included.''')
|
||||||
|
option('gst-full-version-script', type : 'string', value: 'gstreamer-full-default.map',
|
||||||
|
description : 'path of the version script to be used by the linker, see https://www.gnu.org/software/gnulib/manual/html_node/LD-Version-Scripts.html')
|
||||||
|
option('gst-full-plugins', type : 'string', value : '*',
|
||||||
|
description : '''List of plugins to expose in gstreamer-full's ABI with the syntax plugin1;plugin2. By default '*' will export all plugins enabled by the build process.''')
|
||||||
|
option('gst-full-elements', type : 'string', value : '',
|
||||||
|
description : '''List of elements to expose in gstreamer-full's ABI with the syntax plugin1;plugin2:element1,element2. By default '' will export all element of the enabled plugin.''')
|
||||||
|
option('gst-full-typefind-functions', type : 'string', value : '',
|
||||||
|
description : '''List of typefind functions to expose in gstreamer-full's ABI with the syntax plugin:func1,func2. By default '' will export all typefind functions of the enabled plugin.''')
|
||||||
|
option('gst-full-device-providers', type : 'string', value : '',
|
||||||
|
description : '''List of device providers to expose in gstreamer-full's ABI with the syntax plugin1:dp1;plugin2:dp1:dp2. By default '' will export all device provider of the enabled plugin.''')
|
||||||
|
option('gst-full-dynamic-types', type : 'string', value : '',
|
||||||
|
description : '''List of dynamic types to expose in gstreamer-full's ABI with the syntax plugin:dt1,dt2. By default '' will export all device provider of the enabled plugin.''')
|
||||||
|
|
||||||
|
# Common options, automatically inherited by subprojects
|
||||||
|
option('tests', type : 'feature', value : 'auto', description : 'Build tests')
|
||||||
|
option('examples', type : 'feature', value : 'auto', description : 'Build examples')
|
||||||
|
option('introspection', type : 'feature', value : 'auto', description : 'Generate introspection data')
|
||||||
|
option('nls', type : 'feature', value : 'auto', description : 'Enable native language support (translations)')
|
||||||
|
option('orc', type : 'feature', value : 'auto', description : 'Enable Optimized Inner Loop Runtime Compiler')
|
||||||
|
option('doc', type : 'feature', value : 'auto', description : 'Generate API documentation with hotdoc')
|
||||||
|
option('gtk_doc', type : 'feature', value : 'disabled', description : 'Generate API documentation with gtk-doc')
|
0
scripts/__init__.py
Normal file
0
scripts/__init__.py
Normal file
27
scripts/check-clean-repos.py
Executable file
27
scripts/check-clean-repos.py
Executable file
|
@ -0,0 +1,27 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from common import git
|
||||||
|
|
||||||
|
|
||||||
|
SCRIPTDIR = os.path.realpath(os.path.dirname(__file__))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
subprojects_dir = os.path.join(SCRIPTDIR, "..", "subprojects")
|
||||||
|
exitcode = 0
|
||||||
|
for repo_name in os.listdir(subprojects_dir):
|
||||||
|
repo_dir = os.path.normpath(os.path.join(SCRIPTDIR, subprojects_dir, repo_name))
|
||||||
|
if not os.path.exists(os.path.join(repo_dir, '.git')):
|
||||||
|
continue
|
||||||
|
|
||||||
|
diff = git('diff', repository_path=repo_dir).strip('\n')
|
||||||
|
if diff:
|
||||||
|
print('ERROR: Repository %s is not clean' % repo_dir)
|
||||||
|
print('NOTE: Make sure to commit necessary changes in the gst_plugins_cache.json files')
|
||||||
|
print(diff)
|
||||||
|
exitcode += 1
|
||||||
|
|
||||||
|
sys.exit(exitcode)
|
159
scripts/common.py
Normal file
159
scripts/common.py
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import shlex
|
||||||
|
import shutil
|
||||||
|
import argparse
|
||||||
|
import platform
|
||||||
|
import subprocess
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
ROOTDIR = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
|
||||||
|
|
||||||
|
if os.name == 'nt':
|
||||||
|
import ctypes
|
||||||
|
from ctypes import wintypes
|
||||||
|
_GetShortPathNameW = ctypes.windll.kernel32.GetShortPathNameW
|
||||||
|
_GetShortPathNameW.argtypes = [wintypes.LPCWSTR, wintypes.LPWSTR, wintypes.DWORD]
|
||||||
|
_GetShortPathNameW.restype = wintypes.DWORD
|
||||||
|
|
||||||
|
def win32_get_short_path_name(long_name):
|
||||||
|
"""
|
||||||
|
Gets the short path name of a given long path.
|
||||||
|
http://stackoverflow.com/a/23598461/200291
|
||||||
|
"""
|
||||||
|
output_buf_size = 0
|
||||||
|
while True:
|
||||||
|
output_buf = ctypes.create_unicode_buffer(output_buf_size)
|
||||||
|
needed = _GetShortPathNameW(long_name, output_buf, output_buf_size)
|
||||||
|
if output_buf_size >= needed:
|
||||||
|
return output_buf.value
|
||||||
|
else:
|
||||||
|
output_buf_size = needed
|
||||||
|
|
||||||
|
|
||||||
|
def get_wine_shortpath(winecmd, wine_paths):
|
||||||
|
seen = set()
|
||||||
|
wine_paths += [p for p in wine_paths if not (p in seen or seen.add(p))]
|
||||||
|
|
||||||
|
getShortPathScript = '%s.bat' % str(uuid.uuid4()).lower()[:5]
|
||||||
|
with open(getShortPathScript, mode='w') as f:
|
||||||
|
f.write("@ECHO OFF\nfor %%x in (%*) do (\n echo|set /p=;%~sx\n)\n")
|
||||||
|
f.flush()
|
||||||
|
try:
|
||||||
|
with open(os.devnull, 'w') as stderr:
|
||||||
|
wine_path = subprocess.check_output(
|
||||||
|
winecmd +
|
||||||
|
['cmd', '/C', getShortPathScript] + wine_paths,
|
||||||
|
stderr=stderr).decode('utf-8')
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print("Could not get short paths: %s" % e)
|
||||||
|
wine_path = ';'.join(wine_paths)
|
||||||
|
finally:
|
||||||
|
os.remove(getShortPathScript)
|
||||||
|
if len(wine_path) > 2048:
|
||||||
|
raise AssertionError('WINEPATH size {} > 2048'
|
||||||
|
' this will cause random failure.'.format(
|
||||||
|
len(wine_path)))
|
||||||
|
return wine_path
|
||||||
|
|
||||||
|
|
||||||
|
class Colors:
|
||||||
|
HEADER = '\033[95m'
|
||||||
|
OKBLUE = '\033[94m'
|
||||||
|
OKGREEN = '\033[92m'
|
||||||
|
WARNING = '\033[93m'
|
||||||
|
FAIL = '\033[91m'
|
||||||
|
ENDC = '\033[0m'
|
||||||
|
|
||||||
|
force_disable = False
|
||||||
|
|
||||||
|
def _windows_ansi():
|
||||||
|
from ctypes import windll, byref
|
||||||
|
from ctypes.wintypes import DWORD
|
||||||
|
|
||||||
|
kernel = windll.kernel32
|
||||||
|
stdout = kernel.GetStdHandle(-11)
|
||||||
|
mode = DWORD()
|
||||||
|
if not kernel.GetConsoleMode(stdout, byref(mode)):
|
||||||
|
return False
|
||||||
|
# Try setting ENABLE_VIRTUAL_TERMINAL_PROCESSING (0x4)
|
||||||
|
# If that fails (returns 0), we disable colors
|
||||||
|
return kernel.SetConsoleMode(stdout, mode.value | 0x4) or os.environ.get('ANSICON')
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def can_enable(cls):
|
||||||
|
if not os.isatty(sys.stdout.fileno()):
|
||||||
|
return False
|
||||||
|
if platform.system().lower() == 'windows':
|
||||||
|
return cls._windows_ansi()
|
||||||
|
return os.environ.get('TERM') != 'dumb'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def disable(cls):
|
||||||
|
cls.HEADER = ''
|
||||||
|
cls.OKBLUE = ''
|
||||||
|
cls.OKGREEN = ''
|
||||||
|
cls.WARNING = ''
|
||||||
|
cls.FAIL = ''
|
||||||
|
cls.ENDC = ''
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def enable(cls):
|
||||||
|
if cls.force_disable:
|
||||||
|
return
|
||||||
|
|
||||||
|
cls.HEADER = '\033[95m'
|
||||||
|
cls.OKBLUE = '\033[94m'
|
||||||
|
cls.OKGREEN = '\033[92m'
|
||||||
|
cls.WARNING = '\033[93m'
|
||||||
|
cls.FAIL = '\033[91m'
|
||||||
|
cls.ENDC = '\033[0m'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def git(*args, repository_path='.', fatal=True):
|
||||||
|
try:
|
||||||
|
ret = subprocess.check_output(["git"] + list(args), cwd=repository_path,
|
||||||
|
stdin=subprocess.DEVNULL,
|
||||||
|
stderr=subprocess.STDOUT).decode()
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
if fatal:
|
||||||
|
raise e
|
||||||
|
print("Non-fatal error running git {}:\n{}".format(' '.join(args), e))
|
||||||
|
return None
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def accept_command(commands):
|
||||||
|
"""Search @commands and returns the first found absolute path."""
|
||||||
|
for command in commands:
|
||||||
|
command = shutil.which(command)
|
||||||
|
if command:
|
||||||
|
return command
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_meson():
|
||||||
|
meson = os.path.join(ROOTDIR, 'meson', 'meson.py')
|
||||||
|
if os.path.exists(meson):
|
||||||
|
return [sys.executable, meson]
|
||||||
|
|
||||||
|
mesonintrospect = os.environ.get('MESONINTROSPECT', '')
|
||||||
|
for comp in shlex.split (mesonintrospect):
|
||||||
|
# mesonintrospect might look like "/usr/bin/python /somewhere/meson introspect",
|
||||||
|
# let's not get tricked
|
||||||
|
if 'python' in os.path.basename (comp):
|
||||||
|
continue
|
||||||
|
if os.path.exists(comp):
|
||||||
|
if comp.endswith('.py'):
|
||||||
|
return [sys.executable, comp]
|
||||||
|
else:
|
||||||
|
return [comp]
|
||||||
|
|
||||||
|
meson = accept_command(['meson.py'])
|
||||||
|
if meson:
|
||||||
|
return [sys.executable, meson]
|
||||||
|
meson = accept_command(['meson'])
|
||||||
|
if meson:
|
||||||
|
return [meson]
|
||||||
|
raise RuntimeError('Could not find Meson')
|
118
scripts/generate_init_static_plugins.py
Normal file
118
scripts/generate_init_static_plugins.py
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
from string import Template
|
||||||
|
|
||||||
|
TEMPLATE = Template('''
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
$elements_declaration
|
||||||
|
$typefind_funcs_declaration
|
||||||
|
$device_providers_declaration
|
||||||
|
$dynamic_types_declaration
|
||||||
|
$plugins_declaration
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_init_static_plugins (void)
|
||||||
|
{
|
||||||
|
static gsize initialization_value = 0;
|
||||||
|
if (g_once_init_enter (&initialization_value)) {
|
||||||
|
$elements_registration
|
||||||
|
$typefind_funcs_registration
|
||||||
|
$device_providers_registration
|
||||||
|
$dynamic_types_registration
|
||||||
|
$plugins_registration
|
||||||
|
|
||||||
|
g_once_init_leave (&initialization_value, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''')
|
||||||
|
# Retrieve the plugin name as it can be a plugin filename
|
||||||
|
def get_plugin_name(name):
|
||||||
|
for p in plugins:
|
||||||
|
if name in p:
|
||||||
|
return p
|
||||||
|
return ''
|
||||||
|
|
||||||
|
def process_features(features_list, plugins, feature_prefix):
|
||||||
|
plugins_list = plugins
|
||||||
|
feature_declaration = []
|
||||||
|
feature_registration = []
|
||||||
|
if features_list is not None:
|
||||||
|
feature_plugins = features_list.split(';')
|
||||||
|
for plugin in feature_plugins:
|
||||||
|
split = plugin.split(':')
|
||||||
|
plugin_name = split[0].strip()
|
||||||
|
if len(split) == 2:
|
||||||
|
if (get_plugin_name(plugin_name)) != '':
|
||||||
|
plugins_list.remove(get_plugin_name(plugin_name))
|
||||||
|
features = split[1].split(',')
|
||||||
|
for feature in features:
|
||||||
|
feature = feature.replace("-", "_")
|
||||||
|
feature_declaration += ['%s_REGISTER_DECLARE(%s);' % (feature_prefix, feature)]
|
||||||
|
feature_registration += ['%s_REGISTER(%s, NULL);' % (feature_prefix, feature)]
|
||||||
|
return (plugins_list, feature_declaration, feature_registration)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('-o', dest="output", help="Output file")
|
||||||
|
parser.add_argument('-p','--plugins', nargs='?', default='', dest="plugins", help="The list of plugins")
|
||||||
|
parser.add_argument('-e', '--elements', nargs='?', default='', dest="elements", help="The list of plugin:elements")
|
||||||
|
parser.add_argument('-t', '--type-finds', nargs='?', default='', dest="typefindfuncs", help="The list of plugin:typefinds")
|
||||||
|
parser.add_argument('-d', '--devide-providers', nargs='?', default='', dest="deviceproviders", help="The list of plugin:deviceproviders")
|
||||||
|
parser.add_argument('-T', '--dynamic-types', nargs='?', default='', dest="dynamictypes", help="The list of plugin:dynamictypes")
|
||||||
|
options = parser.parse_args()
|
||||||
|
if options.output is None:
|
||||||
|
output_file = 'gstinitstaticplugins.c'
|
||||||
|
else:
|
||||||
|
output_file = options.output
|
||||||
|
enable_staticelements_plugin = 0;
|
||||||
|
elements_declaration = []
|
||||||
|
elements_registration = []
|
||||||
|
typefind_funcs_declaration = []
|
||||||
|
typefind_funcs_registration = []
|
||||||
|
device_providers_declaration = []
|
||||||
|
device_providers_registration = []
|
||||||
|
dynamic_types_declaration = []
|
||||||
|
dynamic_types_registration = []
|
||||||
|
plugins_declaration = []
|
||||||
|
plugins_registration = []
|
||||||
|
|
||||||
|
if options.plugins is None or options.plugins.isspace():
|
||||||
|
plugins = []
|
||||||
|
else:
|
||||||
|
plugins = options.plugins.split(';')
|
||||||
|
|
||||||
|
# process the features
|
||||||
|
(plugins, elements_declaration, elements_registration) = process_features(options.elements, plugins, 'GST_ELEMENT')
|
||||||
|
(plugins, typefind_funcs_declaration, typefind_funcs_registration) = process_features(options.typefindfuncs, plugins, 'GST_TYPE_FIND')
|
||||||
|
(plugins, device_providers_declaration, device_providers_registration) = process_features(options.deviceproviders, plugins, 'GST_DEVICE_PROVIDER')
|
||||||
|
(plugins, dynamic_types_declaration, dynamic_types_registration) = process_features(options.dynamictypes, plugins, 'GST_DYNAMIC_TYPE')
|
||||||
|
|
||||||
|
# Enable plugin or elements according to the ';' separated list.
|
||||||
|
for plugin in plugins:
|
||||||
|
split = plugin.split(':')
|
||||||
|
plugin_name = split[0]
|
||||||
|
if plugin_name == '':
|
||||||
|
continue
|
||||||
|
filename = os.path.basename(plugin)
|
||||||
|
if filename.startswith('libgst') and filename.endswith('.a'):
|
||||||
|
plugin_name = filename[len('libgst'):-len('.a')]
|
||||||
|
plugins_registration += ['GST_PLUGIN_STATIC_REGISTER(%s);' % (plugin_name)]
|
||||||
|
plugins_declaration += ['GST_PLUGIN_STATIC_DECLARE(%s);' % (plugin_name)]
|
||||||
|
|
||||||
|
with open(output_file.strip(), "w") as f:
|
||||||
|
static_elements_plugin = ''
|
||||||
|
f.write(TEMPLATE.substitute({
|
||||||
|
'elements_declaration': '\n'.join(elements_declaration),
|
||||||
|
'elements_registration': '\n '.join(elements_registration),
|
||||||
|
'typefind_funcs_declaration': '\n'.join(typefind_funcs_declaration),
|
||||||
|
'typefind_funcs_registration': '\n '.join(typefind_funcs_registration),
|
||||||
|
'device_providers_declaration': '\n'.join(device_providers_declaration),
|
||||||
|
'device_providers_registration': '\n '.join(device_providers_registration),
|
||||||
|
'dynamic_types_declaration': '\n'.join(dynamic_types_declaration),
|
||||||
|
'dynamic_types_registration': '\n '.join(dynamic_types_registration),
|
||||||
|
'plugins_declaration': '\n'.join(plugins_declaration),
|
||||||
|
'plugins_registration': '\n '.join(plugins_registration),
|
||||||
|
}))
|
19
scripts/generate_plugins_path.py
Normal file
19
scripts/generate_plugins_path.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument(dest="output", help="Output file")
|
||||||
|
parser.add_argument(dest="plugins", help="The list of plugins")
|
||||||
|
|
||||||
|
options = parser.parse_args()
|
||||||
|
|
||||||
|
all_paths = set()
|
||||||
|
for plugin in options.plugins.split(os.pathsep):
|
||||||
|
all_paths.add(os.path.dirname(plugin))
|
||||||
|
|
||||||
|
with open(options.output, "w") as f:
|
||||||
|
json.dump(list(all_paths), f, indent=4, sort_keys=True)
|
5
subprojects/FFmpeg.wrap
Normal file
5
subprojects/FFmpeg.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=FFmpeg
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/meson-ports/ffmpeg.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/meson-ports/ffmpeg.git
|
||||||
|
revision=meson-4.3.1
|
4
subprojects/avtp.wrap
Normal file
4
subprojects/avtp.wrap
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=avtp
|
||||||
|
url=https://github.com/Avnu/libavtp.git
|
||||||
|
revision=9482c1143d2bca1303c4c0eeff30674eb468d357
|
4
subprojects/bindinator.wrap
Normal file
4
subprojects/bindinator.wrap
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=bindinator
|
||||||
|
url=https://github.com/GLibSharp/bindinator.git
|
||||||
|
revision=master
|
5
subprojects/cairo.wrap
Normal file
5
subprojects/cairo.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=cairo
|
||||||
|
url=https://gitlab.freedesktop.org/cairo/cairo.git
|
||||||
|
depth=1
|
||||||
|
revision=master
|
5
subprojects/dav1d.wrap
Normal file
5
subprojects/dav1d.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=dav1d
|
||||||
|
url=https://code.videolan.org/videolan/dav1d.git
|
||||||
|
push-url=git@code.videolan.org:videolan/dav1d.git
|
||||||
|
revision=0.6.0
|
4
subprojects/dssim.wrap
Normal file
4
subprojects/dssim.wrap
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=dssim
|
||||||
|
url=https://github.com/kornelski/dssim.git
|
||||||
|
revision=dssim1-c
|
7
subprojects/dv.wrap
Normal file
7
subprojects/dv.wrap
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=dv
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/meson-ports/libdv.git
|
||||||
|
revision=meson
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
libdv=dv_dep
|
8
subprojects/expat.wrap
Normal file
8
subprojects/expat.wrap
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[wrap-file]
|
||||||
|
directory = expat-2.2.9
|
||||||
|
source_url = https://github.com/libexpat/libexpat/releases/download/R_2_2_9/expat-2.2.9.tar.xz
|
||||||
|
source_filename = expat-2.2.9.tar.bz2
|
||||||
|
source_hash = 1ea6965b15c2106b6bbe883397271c80dfa0331cdf821b2c319591b55eadc0a4
|
||||||
|
patch_url = https://wrapdb.mesonbuild.com/v1/projects/expat/2.2.9/3/get_zip
|
||||||
|
patch_filename = expat-2.2.9-3-wrap.zip
|
||||||
|
patch_hash = e9aaace62e9a158b5e96f5c38c9f81f369179206acd87697653d777c0d3975d3
|
6
subprojects/fontconfig.wrap
Normal file
6
subprojects/fontconfig.wrap
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=fontconfig
|
||||||
|
url=https://gitlab.freedesktop.org/fontconfig/fontconfig
|
||||||
|
push-url=git@gitlab.freedesktop.org:fontconfig/fontconfig.git
|
||||||
|
depth=1
|
||||||
|
revision=main
|
6
subprojects/freetype2.wrap
Normal file
6
subprojects/freetype2.wrap
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=freetype2
|
||||||
|
url=https://github.com/centricular/freetype2.git
|
||||||
|
depth=1
|
||||||
|
push-url=git@github.com:centricular/freetype2.git
|
||||||
|
revision=meson
|
6
subprojects/fribidi.wrap
Normal file
6
subprojects/fribidi.wrap
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=fribidi
|
||||||
|
url=https://github.com/fribidi/fribidi.git
|
||||||
|
push-url=git@github.com:fribidi/fribidi.git
|
||||||
|
revision=master
|
||||||
|
depth=1
|
5
subprojects/gl-headers.wrap
Normal file
5
subprojects/gl-headers.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=gl-headers
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/meson-ports/gl-headers.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/meson-ports/gl-headers.git
|
||||||
|
revision=5c8c7c0d3ca1f0b783272dac0b95e09414e49bc8
|
5
subprojects/glib-networking.wrap
Normal file
5
subprojects/glib-networking.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=glib-networking
|
||||||
|
url=https://gitlab.gnome.org/GNOME/glib-networking.git
|
||||||
|
push-url=git@gitlab.gnome.org:GNOME/glib-networking.git
|
||||||
|
revision=glib-2-68
|
5
subprojects/glib.wrap
Normal file
5
subprojects/glib.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=glib
|
||||||
|
url=https://gitlab.gnome.org/GNOME/glib.git
|
||||||
|
push-url=git@gitlab.gnome.org:GNOME/glib.git
|
||||||
|
revision=glib-2-68
|
4
subprojects/graphene.wrap
Normal file
4
subprojects/graphene.wrap
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=graphene
|
||||||
|
url=https://github.com/ebassi/graphene.git
|
||||||
|
revision=master
|
5
subprojects/gst-devtools.wrap
Normal file
5
subprojects/gst-devtools.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=gst-devtools
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/gst-devtools.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/gst-devtools.git
|
||||||
|
revision=master
|
5
subprojects/gst-docs.wrap
Normal file
5
subprojects/gst-docs.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=gst-docs
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/gst-docs.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/gst-docs.git
|
||||||
|
revision=master
|
5
subprojects/gst-editing-services.wrap
Normal file
5
subprojects/gst-editing-services.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=gst-editing-services
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/gst-editing-services.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/gst-editing-services.git
|
||||||
|
revision=master
|
5
subprojects/gst-examples.wrap
Normal file
5
subprojects/gst-examples.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=gst-examples
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/gst-examples.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/gst-examples.git
|
||||||
|
revision=master
|
5
subprojects/gst-integration-testsuites.wrap
Normal file
5
subprojects/gst-integration-testsuites.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=gst-integration-testsuites
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/gst-integration-testsuites.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/gst-integration-testsuites.git
|
||||||
|
revision=master
|
5
subprojects/gst-libav.wrap
Normal file
5
subprojects/gst-libav.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=gst-libav
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/gst-libav.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/gst-libav.git
|
||||||
|
revision=master
|
5
subprojects/gst-omx.wrap
Normal file
5
subprojects/gst-omx.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=gst-omx
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/gst-omx.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/gst-omx.git
|
||||||
|
revision=master
|
5
subprojects/gst-plugins-bad.wrap
Normal file
5
subprojects/gst-plugins-bad.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=gst-plugins-bad
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/gst-plugins-bad.git
|
||||||
|
revision=master
|
5
subprojects/gst-plugins-base.wrap
Normal file
5
subprojects/gst-plugins-base.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=gst-plugins-base
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/gst-plugins-base.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/gst-plugins-base.git
|
||||||
|
revision=master
|
5
subprojects/gst-plugins-good.wrap
Normal file
5
subprojects/gst-plugins-good.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=gst-plugins-good
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/gst-plugins-good.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/gst-plugins-good.git
|
||||||
|
revision=master
|
5
subprojects/gst-plugins-rs.wrap
Normal file
5
subprojects/gst-plugins-rs.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=gst-plugins-rs
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/gst-plugins-rs.git
|
||||||
|
revision=master
|
5
subprojects/gst-plugins-ugly.wrap
Normal file
5
subprojects/gst-plugins-ugly.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=gst-plugins-ugly
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/gst-plugins-ugly.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/gst-plugins-ugly.git
|
||||||
|
revision=master
|
5
subprojects/gst-python.wrap
Normal file
5
subprojects/gst-python.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=gst-python
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/gst-python.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/gst-python.git
|
||||||
|
revision=master
|
5
subprojects/gst-rtsp-server.wrap
Normal file
5
subprojects/gst-rtsp-server.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=gst-rtsp-server
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/gst-rtsp-server.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/gst-rtsp-server.git
|
||||||
|
revision=master
|
5
subprojects/gstreamer-sharp.wrap
Normal file
5
subprojects/gstreamer-sharp.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=gstreamer-sharp
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/gstreamer-sharp.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/gstreamer-sharp.git
|
||||||
|
revision=master
|
5
subprojects/gstreamer-vaapi.wrap
Normal file
5
subprojects/gstreamer-vaapi.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=gstreamer-vaapi
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/gstreamer-vaapi.git
|
||||||
|
revision=master
|
5
subprojects/gstreamer.wrap
Normal file
5
subprojects/gstreamer.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=gstreamer
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/gstreamer.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/gstreamer.git
|
||||||
|
revision=master
|
4
subprojects/gtk-sharp.wrap
Normal file
4
subprojects/gtk-sharp.wrap
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=gtk-sharp
|
||||||
|
url=https://github.com/gtk-sharp/gtk-sharp.git
|
||||||
|
revision=master
|
6
subprojects/harfbuzz.wrap
Normal file
6
subprojects/harfbuzz.wrap
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=harfbuzz
|
||||||
|
url=https://github.com/harfbuzz/harfbuzz.git
|
||||||
|
push-url=git@github.com:harfbuzz/harfbuzz.git
|
||||||
|
revision=2.8.1
|
||||||
|
depth=1
|
4
subprojects/json-glib.wrap
Normal file
4
subprojects/json-glib.wrap
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=json-glib
|
||||||
|
url=https://gitlab.gnome.org/GNOME/json-glib.git
|
||||||
|
revision=master
|
5
subprojects/libdrm.wrap
Normal file
5
subprojects/libdrm.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-file]
|
||||||
|
directory=libdrm-2.4.100
|
||||||
|
source_url=https://dri.freedesktop.org/libdrm/libdrm-2.4.100.tar.bz2
|
||||||
|
source_filename=libdrm-2.4.100.tar.bz2
|
||||||
|
source_hash=c77cc828186c9ceec3e56ae202b43ee99eb932b4a87255038a80e8a1060d0a5d
|
5
subprojects/libffi.wrap
Normal file
5
subprojects/libffi.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=libffi
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/meson-ports/libffi.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/meson-ports/libffi.git
|
||||||
|
revision=meson
|
12
subprojects/libjpeg-turbo.wrap
Normal file
12
subprojects/libjpeg-turbo.wrap
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[wrap-file]
|
||||||
|
directory = libjpeg-turbo-2.1.0
|
||||||
|
source_url = https://sourceforge.net/projects/libjpeg-turbo/files/2.1.0/libjpeg-turbo-2.1.0.tar.gz
|
||||||
|
source_filename = libjpeg-turbo-2.1.0.tar.gz
|
||||||
|
source_hash = bef89803e506f27715c5627b1e3219c95b80fc31465d4452de2a909d382e4444
|
||||||
|
patch_filename = libjpeg-turbo_2.1.0-2_patch.zip
|
||||||
|
patch_url = https://wrapdb.mesonbuild.com/v2/libjpeg-turbo_2.1.0-2/get_patch
|
||||||
|
patch_hash = e2a6957bdece284e2c14c7665be4fcd5a880ec637c2acae076511f9efe28fdf5
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
dependency_names = libjpeg
|
||||||
|
|
4
subprojects/libmicrodns.wrap
Normal file
4
subprojects/libmicrodns.wrap
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=libmicrodns
|
||||||
|
url=https://github.com/videolabs/libmicrodns.git
|
||||||
|
revision=0.1.2
|
4
subprojects/libnice.wrap
Normal file
4
subprojects/libnice.wrap
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=libnice
|
||||||
|
url=https://gitlab.freedesktop.org/libnice/libnice.git
|
||||||
|
revision=master
|
12
subprojects/libopenjp2.wrap
Normal file
12
subprojects/libopenjp2.wrap
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[wrap-file]
|
||||||
|
directory = openjpeg-2.3.1
|
||||||
|
source_url = https://github.com/uclouvain/openjpeg/archive/v2.3.1.tar.gz
|
||||||
|
source_filename = openjpeg-2.3.1.tar.gz
|
||||||
|
source_hash = 63f5a4713ecafc86de51bfad89cc07bb788e9bba24ebbf0c4ca637621aadb6a9
|
||||||
|
patch_filename = libopenjp2_2.3.1-6_patch.zip
|
||||||
|
patch_url = https://wrapdb.mesonbuild.com/v2/libopenjp2_2.3.1-6/get_patch
|
||||||
|
patch_hash = 153e4b6a0addb20ceceac9f1562588c7f4b03c91282ac55d3b63df8743f6e873
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
libopenjp2 = libopenjp2_dep
|
||||||
|
|
5
subprojects/libpsl.wrap
Normal file
5
subprojects/libpsl.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=libpsl
|
||||||
|
url=https://github.com/rockdaboot/libpsl.git
|
||||||
|
revision=0.21.1
|
||||||
|
clone-recursive=true
|
4
subprojects/libsoup.wrap
Normal file
4
subprojects/libsoup.wrap
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=libsoup
|
||||||
|
url=https://gitlab.gnome.org/gnome/libsoup.git
|
||||||
|
revision=e190e70298be1186ad1a8a5dd0ac430463f76fee
|
4
subprojects/libwpe.wrap
Normal file
4
subprojects/libwpe.wrap
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=libwpe
|
||||||
|
url=https://github.com/WebPlatformForEmbedded/libwpe
|
||||||
|
revision=8cce32deb48b91f18c5e920fb3666dc409a11219
|
9
subprojects/libxml2.wrap
Normal file
9
subprojects/libxml2.wrap
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[wrap-file]
|
||||||
|
directory = libxml2-2.9.7
|
||||||
|
|
||||||
|
source_url = http://xmlsoft.org/sources/libxml2-2.9.7.tar.gz
|
||||||
|
source_filename = libxml2-2.9.7.tar.gz
|
||||||
|
source_hash = f63c5e7d30362ed28b38bfa1ac6313f9a80230720b7fb6c80575eeab3ff5900c
|
||||||
|
patch_url = https://github.com/mesonbuild/libxml2/releases/download/2.9.7-6/libxml2.zip
|
||||||
|
patch_filename = libxml2.zip
|
||||||
|
patch_hash = 4f56174fef39fdcc83f235e7021f18ec638403ab3ee2c314fb2509a8bf599b27
|
4
subprojects/macos-bison-binary/.gitignore
vendored
Normal file
4
subprojects/macos-bison-binary/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
*.sw[op]
|
||||||
|
*~
|
||||||
|
*.tar.*
|
||||||
|
bison-3.7.6-macos-x86_64/
|
14
subprojects/macos-bison-binary/README.md
Normal file
14
subprojects/macos-bison-binary/README.md
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
## How to generate binaries and update build files
|
||||||
|
|
||||||
|
1. Download the latest bison source tarball
|
||||||
|
1. Extract, then build it with --prefix=/
|
||||||
|
1. Install into some dir using `DESTDIR`
|
||||||
|
1. Delete all files except the following subdirs: `bin` `lib` `share/bison` `share/aclocal`
|
||||||
|
1. Rename installdir to `bison-$version-macos-$arch` where `$arch` follows Meson's CPU families list:
|
||||||
|
https://mesonbuild.com/Reference-tables.html#cpu-families
|
||||||
|
1. `tar -cvjf bison-$version-macos-$arch.tar.bz2 bison-$version-macos-$arch/`
|
||||||
|
1. Fetch sha256sum: `shasum -256 bison-$version-macos-$arch.tar.bz2`
|
||||||
|
1. Update sha256sum in `meson.build`
|
||||||
|
1. Update `project()` version in `meson.build`
|
||||||
|
|
||||||
|
That's it!
|
14
subprojects/macos-bison-binary/bison.py.in
Executable file
14
subprojects/macos-bison-binary/bison.py.in
Executable file
|
@ -0,0 +1,14 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import pathlib
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
srcdir = pathlib.Path("@SRCDIR@")
|
||||||
|
extractdir = pathlib.Path("@EXTRACTDIR@")
|
||||||
|
bison_path = srcdir / extractdir / 'bin/bison'
|
||||||
|
env = os.environ.copy()
|
||||||
|
env['BISON_PKGDATADIR'] = str(srcdir / extractdir / 'share/bison')
|
||||||
|
ret = subprocess.run([str(bison_path)] + sys.argv[1:], check=False, env=env)
|
||||||
|
sys.exit(ret.returncode)
|
77
subprojects/macos-bison-binary/download-binary.py
Normal file
77
subprojects/macos-bison-binary/download-binary.py
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import ssl
|
||||||
|
import tarfile
|
||||||
|
import hashlib
|
||||||
|
import urllib.request
|
||||||
|
import urllib.error
|
||||||
|
|
||||||
|
# Disable certificate checking because it requires custom Python setup on macOS
|
||||||
|
ctx = ssl.create_default_context()
|
||||||
|
ctx.check_hostname = False
|
||||||
|
ctx.verify_mode = ssl.CERT_NONE
|
||||||
|
|
||||||
|
EXTRACTDIR = 'bison-{}-macos-{}'
|
||||||
|
BASENAME = '{}.tar.bz2'.format(EXTRACTDIR)
|
||||||
|
GSTREAMER_URL = 'https://gstreamer.freedesktop.org/src/mirror/{}'
|
||||||
|
|
||||||
|
version = sys.argv[1]
|
||||||
|
arch = sys.argv[2]
|
||||||
|
tar_sha256 = sys.argv[3]
|
||||||
|
source_dir = os.path.join(os.environ['MESON_SOURCE_ROOT'], os.environ['MESON_SUBDIR'])
|
||||||
|
dest = BASENAME.format(version, arch)
|
||||||
|
dest_path = os.path.join(source_dir, dest)
|
||||||
|
extract_path = EXTRACTDIR.format(version, arch)
|
||||||
|
|
||||||
|
def get_sha256(tarf):
|
||||||
|
hasher = hashlib.sha256()
|
||||||
|
with open(tarf, 'rb') as f:
|
||||||
|
hasher.update(f.read())
|
||||||
|
return hasher.hexdigest()
|
||||||
|
|
||||||
|
def download():
|
||||||
|
for url in (GSTREAMER_URL.format(dest),):
|
||||||
|
print('Downloading {} to {}'.format(url, dest), file=sys.stderr)
|
||||||
|
try:
|
||||||
|
with open(dest_path, 'wb') as d:
|
||||||
|
f = urllib.request.urlopen(url, context=ctx)
|
||||||
|
d.write(f.read())
|
||||||
|
break
|
||||||
|
except urllib.error.URLError as ex:
|
||||||
|
print(ex, file=sys.stderr)
|
||||||
|
print('Failed to download from {!r}, trying mirror...'.format(url), file=sys.stderr)
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
curdir = os.path.dirname(sys.argv[0])
|
||||||
|
print('Couldn\'t download {!r}! Try downloading it manually and '
|
||||||
|
'placing it into {!r}'.format(dest, curdir), file=sys.stderr)
|
||||||
|
|
||||||
|
def print_extract_dir():
|
||||||
|
'Print the extracted directory name'
|
||||||
|
print(extract_path, end='')
|
||||||
|
|
||||||
|
if os.path.isfile(dest_path):
|
||||||
|
found_sha256 = get_sha256(dest_path)
|
||||||
|
if found_sha256 == tar_sha256:
|
||||||
|
if os.path.isdir(os.path.join(source_dir, extract_path)):
|
||||||
|
print('{} already downloaded and extracted'.format(dest), file=sys.stderr)
|
||||||
|
print_extract_dir()
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
print('{} checksum mismatch, redownloading'.format(dest), file=sys.stderr)
|
||||||
|
download()
|
||||||
|
else:
|
||||||
|
download()
|
||||||
|
|
||||||
|
found_sha256 = get_sha256(dest_path)
|
||||||
|
if found_sha256 != tar_sha256:
|
||||||
|
print('SHA256 of downloaded file {} was {} instead of {}'
|
||||||
|
''.format(dest, found_sha256, tar_sha256), file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print('Extracting {}'.format(dest), file=sys.stderr)
|
||||||
|
tf = tarfile.open(dest_path, "r")
|
||||||
|
tf.extractall(path=source_dir)
|
||||||
|
print_extract_dir()
|
28
subprojects/macos-bison-binary/meson.build
Normal file
28
subprojects/macos-bison-binary/meson.build
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
project('win-flex-bison-binary', version : '3.7.6')
|
||||||
|
|
||||||
|
py3 = import('python3').find_python()
|
||||||
|
|
||||||
|
message('Downloading and extracting bison for macOS x64...')
|
||||||
|
|
||||||
|
arch = host_machine.cpu_family()
|
||||||
|
tar_hash = '932f91d7c7fa0121abc3e5f8e54a7234b03d3de468c254ab8063ff8e6eb92a09'
|
||||||
|
if arch != 'x86_64'
|
||||||
|
warning('bison binary is untested on non-x86_64, please report whether this worked or not')
|
||||||
|
arch = 'x86_64'
|
||||||
|
endif
|
||||||
|
|
||||||
|
ret = run_command(py3, files('download-binary.py'), meson.project_version(), arch, tar_hash)
|
||||||
|
if ret.returncode() != 0
|
||||||
|
message(ret.stdout())
|
||||||
|
error(ret.stderr())
|
||||||
|
endif
|
||||||
|
|
||||||
|
conf = configuration_data()
|
||||||
|
conf.set('SRCDIR', meson.project_source_root())
|
||||||
|
conf.set('EXTRACTDIR', ret.stdout())
|
||||||
|
bison_py = configure_file(
|
||||||
|
input: 'bison.py.in',
|
||||||
|
output: 'bison.py',
|
||||||
|
configuration: conf)
|
||||||
|
|
||||||
|
meson.override_find_program('bison', find_program(bison_py))
|
4
subprojects/openh264.wrap
Normal file
4
subprojects/openh264.wrap
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=openh264
|
||||||
|
url=https://github.com/cisco/openh264.git
|
||||||
|
revision=v2.1.1
|
7
subprojects/opus.wrap
Normal file
7
subprojects/opus.wrap
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=opus
|
||||||
|
url=https://gitlab.xiph.org/xiph/opus.git
|
||||||
|
revision=master
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
opus=opus_dep
|
5
subprojects/orc.wrap
Normal file
5
subprojects/orc.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=orc
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/orc.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/orc.git
|
||||||
|
revision=master
|
4
subprojects/pango.wrap
Normal file
4
subprojects/pango.wrap
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[wrap-git]
|
||||||
|
url=https://gitlab.gnome.org/GNOME/pango.git
|
||||||
|
push-url=git@gitlab.gnome.org:GNOME/pango.git
|
||||||
|
revision=1.48.7
|
6
subprojects/pixman.wrap
Normal file
6
subprojects/pixman.wrap
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=pixman
|
||||||
|
url=https://gitlab.freedesktop.org/pixman/pixman
|
||||||
|
push-url=git@gitlab.freedesktop.org:pixman/pixman.git
|
||||||
|
depth=1
|
||||||
|
revision=master
|
5
subprojects/proxy-libintl.wrap
Normal file
5
subprojects/proxy-libintl.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=proxy-libintl
|
||||||
|
url=https://github.com/frida/proxy-libintl.git
|
||||||
|
push-url=git@github.com:frida/proxy-libintl.git
|
||||||
|
revision=0.1
|
4
subprojects/pycairo.wrap
Normal file
4
subprojects/pycairo.wrap
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=pycairo
|
||||||
|
url=https://github.com/pygobject/pycairo.git
|
||||||
|
revision=v1.19.1
|
5
subprojects/pygobject.wrap
Normal file
5
subprojects/pygobject.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=pygobject
|
||||||
|
url=https://gitlab.gnome.org/GNOME/pygobject.git
|
||||||
|
push-url=git@gitlab.gnome.org:GNOME/pygobject.git
|
||||||
|
revision=pygobject-3-38
|
12
subprojects/sqlite3.wrap
Normal file
12
subprojects/sqlite3.wrap
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[wrap-file]
|
||||||
|
directory = sqlite-amalgamation-3340100
|
||||||
|
source_url = https://www.sqlite.org/2021/sqlite-amalgamation-3340100.zip
|
||||||
|
source_filename = sqlite-amalgamation-3340100.zip
|
||||||
|
source_hash = e0b1c0345fe4338b936e17da8e1bd88366cd210e576834546977f040c12a8f68
|
||||||
|
patch_url = https://wrapdb.mesonbuild.com/v2/sqlite3_3.34.1-1/get_patch
|
||||||
|
patch_filename = sqlite3-3.34.1-1-wrap.zip
|
||||||
|
patch_hash = cba9e47bdb4c02f88fadaae8deab357218d32562c6b86ce7ba0c72f107044360
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
sqlite3 = sqlite3_dep
|
||||||
|
|
8
subprojects/webrtc-audio-processing.wrap
Normal file
8
subprojects/webrtc-audio-processing.wrap
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=webrtc-audio-processing
|
||||||
|
url=https://gitlab.freedesktop.org/pulseaudio/webrtc-audio-processing.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:pulseaudio/webrtc-audio-processing.git
|
||||||
|
revision=master
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
dependency_names = webrtc-audio-coding-1, webrtc-audio-processing-1
|
10
subprojects/win-flex-bison-binaries/.gitignore
vendored
Normal file
10
subprojects/win-flex-bison-binaries/.gitignore
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
*.sw[op]
|
||||||
|
*~
|
||||||
|
/custom_build_rules/
|
||||||
|
/data/
|
||||||
|
/FlexLexer.h
|
||||||
|
/README.md
|
||||||
|
/changelog.md
|
||||||
|
/UNISTD_ERROR.readme
|
||||||
|
*.exe
|
||||||
|
*.zip
|
65
subprojects/win-flex-bison-binaries/download-binary.py
Normal file
65
subprojects/win-flex-bison-binaries/download-binary.py
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import ssl
|
||||||
|
import zipfile
|
||||||
|
import hashlib
|
||||||
|
import urllib.request
|
||||||
|
import urllib.error
|
||||||
|
|
||||||
|
# Disable certificate checking because it always fails on Windows
|
||||||
|
# We verify the checksum anyway.
|
||||||
|
ctx = ssl.create_default_context()
|
||||||
|
ctx.check_hostname = False
|
||||||
|
ctx.verify_mode = ssl.CERT_NONE
|
||||||
|
|
||||||
|
BASENAME = 'win_flex_bison-{}.zip'
|
||||||
|
UPSTREAM_URL = 'https://github.com/lexxmark/winflexbison/releases/download/v{}/{}'
|
||||||
|
GSTREAMER_URL = 'https://gstreamer.freedesktop.org/src/mirror/{}'
|
||||||
|
|
||||||
|
version = sys.argv[1]
|
||||||
|
zip_sha256 = sys.argv[2]
|
||||||
|
source_dir = os.path.join(os.environ['MESON_SOURCE_ROOT'], os.environ['MESON_SUBDIR'])
|
||||||
|
dest = BASENAME.format(version)
|
||||||
|
dest_path = os.path.join(source_dir, dest)
|
||||||
|
|
||||||
|
def get_sha256(zipf):
|
||||||
|
hasher = hashlib.sha256()
|
||||||
|
with open(zipf, 'rb') as f:
|
||||||
|
hasher.update(f.read())
|
||||||
|
return hasher.hexdigest()
|
||||||
|
|
||||||
|
if os.path.isfile(dest_path):
|
||||||
|
found_sha256 = get_sha256(dest_path)
|
||||||
|
if found_sha256 == zip_sha256:
|
||||||
|
print('{} already downloaded'.format(dest))
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
print('{} checksum mismatch, redownloading'.format(dest))
|
||||||
|
|
||||||
|
for url in (GSTREAMER_URL.format(dest), UPSTREAM_URL.format(version, dest)):
|
||||||
|
print('Downloading {} to {}'.format(url, dest))
|
||||||
|
try:
|
||||||
|
with open(dest_path, 'wb') as d:
|
||||||
|
f = urllib.request.urlopen(url, context=ctx)
|
||||||
|
d.write(f.read())
|
||||||
|
break
|
||||||
|
except urllib.error.URLError as ex:
|
||||||
|
print(ex)
|
||||||
|
print('Failed to download from {!r}, trying mirror...'.format(url))
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
curdir = os.path.dirname(sys.argv[0])
|
||||||
|
print('Couldn\'t download {!r}! Try downloading it manually and '
|
||||||
|
'placing it into {!r}'.format(dest, curdir))
|
||||||
|
|
||||||
|
found_sha256 = get_sha256(dest_path)
|
||||||
|
if found_sha256 != zip_sha256:
|
||||||
|
print('SHA256 of downloaded file {} was {} instead of {}'
|
||||||
|
''.format(dest, found_sha256, zip_sha256))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print('Extracting {}'.format(dest))
|
||||||
|
zf = zipfile.ZipFile(dest_path, "r")
|
||||||
|
zf.extractall(path=source_dir)
|
16
subprojects/win-flex-bison-binaries/meson.build
Normal file
16
subprojects/win-flex-bison-binaries/meson.build
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
project('win-flex-bison-binary', version : '2.5.18')
|
||||||
|
|
||||||
|
py3 = import('python3').find_python()
|
||||||
|
|
||||||
|
message('Downloading and extracting win-flex-bison binaries...')
|
||||||
|
|
||||||
|
zip_hash = '095cf65cb3f12ee5888022f93109acbe6264e5f18f6ffce0bda77feb31b65bd8'
|
||||||
|
|
||||||
|
ret = run_command(py3, files('download-binary.py'), meson.project_version(), zip_hash)
|
||||||
|
if ret.returncode() != 0
|
||||||
|
message(ret.stdout())
|
||||||
|
error(ret.stderr())
|
||||||
|
endif
|
||||||
|
|
||||||
|
meson.override_find_program('flex', find_program('win_flex'))
|
||||||
|
meson.override_find_program('bison', find_program('win_bison'))
|
2
subprojects/win-nasm/.gitignore
vendored
Normal file
2
subprojects/win-nasm/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
nasm-*/
|
||||||
|
nasm-*.zip
|
66
subprojects/win-nasm/download-binary.py
Normal file
66
subprojects/win-nasm/download-binary.py
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import ssl
|
||||||
|
import zipfile
|
||||||
|
import hashlib
|
||||||
|
import urllib.request
|
||||||
|
import urllib.error
|
||||||
|
|
||||||
|
# Disable certificate checking because it always fails on Windows
|
||||||
|
# We verify the checksum anyway.
|
||||||
|
ctx = ssl.create_default_context()
|
||||||
|
ctx.check_hostname = False
|
||||||
|
ctx.verify_mode = ssl.CERT_NONE
|
||||||
|
|
||||||
|
BASENAME = 'nasm-{}-{}.zip'
|
||||||
|
UPSTREAM_URL = 'https://www.nasm.us/pub/nasm/releasebuilds/{}/{}/{}'
|
||||||
|
GSTREAMER_URL = 'https://gstreamer.freedesktop.org/src/mirror/{}'
|
||||||
|
|
||||||
|
version = sys.argv[1]
|
||||||
|
arch = 'win64' if sys.argv[2] == 'x86_64' else 'win32'
|
||||||
|
zip_sha256 = sys.argv[3]
|
||||||
|
source_dir = os.path.join(os.environ['MESON_SOURCE_ROOT'], os.environ['MESON_SUBDIR'])
|
||||||
|
dest = BASENAME.format(version, arch)
|
||||||
|
dest_path = os.path.join(source_dir, dest)
|
||||||
|
|
||||||
|
def get_sha256(zipf):
|
||||||
|
hasher = hashlib.sha256()
|
||||||
|
with open(zipf, 'rb') as f:
|
||||||
|
hasher.update(f.read())
|
||||||
|
return hasher.hexdigest()
|
||||||
|
|
||||||
|
if os.path.isfile(dest_path):
|
||||||
|
found_sha256 = get_sha256(dest_path)
|
||||||
|
if found_sha256 == zip_sha256:
|
||||||
|
print('{} already downloaded'.format(dest))
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
print('{} checksum mismatch, redownloading'.format(dest))
|
||||||
|
|
||||||
|
for url in (GSTREAMER_URL.format(dest), UPSTREAM_URL.format(version, arch, dest)):
|
||||||
|
print('Downloading {} to {}'.format(url, dest))
|
||||||
|
try:
|
||||||
|
with open(dest_path, 'wb') as d:
|
||||||
|
f = urllib.request.urlopen(url, context=ctx)
|
||||||
|
d.write(f.read())
|
||||||
|
break
|
||||||
|
except urllib.error.URLError as ex:
|
||||||
|
print(ex)
|
||||||
|
print('Failed to download from {!r}, trying mirror...'.format(url))
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
curdir = os.path.dirname(sys.argv[0])
|
||||||
|
print('Couldn\'t download {!r}! Try downloading it manually and '
|
||||||
|
'placing it into {!r}'.format(dest, curdir))
|
||||||
|
|
||||||
|
found_sha256 = get_sha256(dest_path)
|
||||||
|
if found_sha256 != zip_sha256:
|
||||||
|
print('SHA256 of downloaded file {} was {} instead of {}'
|
||||||
|
''.format(dest, found_sha256, zip_sha256))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print('Extracting {}'.format(dest))
|
||||||
|
zf = zipfile.ZipFile(dest_path, "r")
|
||||||
|
zf.extractall(path=source_dir)
|
24
subprojects/win-nasm/meson.build
Normal file
24
subprojects/win-nasm/meson.build
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
project('win-nasm', version : '2.14.02')
|
||||||
|
|
||||||
|
py3 = import('python3').find_python()
|
||||||
|
|
||||||
|
if host_machine.system() != 'windows'
|
||||||
|
error('Can only download nasm for Windows, sorry')
|
||||||
|
endif
|
||||||
|
|
||||||
|
message('Downloading and extracting nasm binaries for Windows...')
|
||||||
|
|
||||||
|
arch = host_machine.cpu_family()
|
||||||
|
if arch == 'x86_64'
|
||||||
|
zip_hash = '18918ac906e29417b936466e7a2517068206c8db8c04b9762a5befa18bfea5f0'
|
||||||
|
else
|
||||||
|
zip_hash = '250f9b5eeb2111e8c7b494a977490985b8604fe7518a6f5041cde37cc727a067'
|
||||||
|
endif
|
||||||
|
|
||||||
|
ret = run_command(py3, files('download-binary.py'), meson.project_version(), arch, zip_hash)
|
||||||
|
if ret.returncode() != 0
|
||||||
|
message(ret.stdout())
|
||||||
|
error(ret.stderr())
|
||||||
|
endif
|
||||||
|
|
||||||
|
meson.override_find_program('nasm', find_program(join_paths('nasm-@0@'.format(meson.project_version()), 'nasm')))
|
4
subprojects/wpebackend-fdo.wrap
Normal file
4
subprojects/wpebackend-fdo.wrap
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=wpebackend-fdo
|
||||||
|
url=https://github.com/Igalia/WPEBackend-FDO.git
|
||||||
|
revision=3a76a810c0787ad5d515e49de50ffb956f3a04cd
|
5
subprojects/x264.wrap
Normal file
5
subprojects/x264.wrap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[wrap-git]
|
||||||
|
directory=x264
|
||||||
|
url=https://gitlab.freedesktop.org/gstreamer/meson-ports/x264.git
|
||||||
|
push-url=git@gitlab.freedesktop.org:gstreamer/meson-ports/x264.git
|
||||||
|
revision=160.3011-meson
|
12
subprojects/zlib.wrap
Normal file
12
subprojects/zlib.wrap
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[wrap-file]
|
||||||
|
directory = zlib-1.2.11
|
||||||
|
source_url = http://zlib.net/fossils/zlib-1.2.11.tar.gz
|
||||||
|
source_filename = zlib-1.2.11.tar.gz
|
||||||
|
source_hash = c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1
|
||||||
|
patch_url = https://wrapdb.mesonbuild.com/v1/projects/zlib/1.2.11/5/get_zip
|
||||||
|
patch_filename = zlib-1.2.11-5-wrap.zip
|
||||||
|
patch_hash = 728c8e24acbc2e6682fbd950fec39e2fc77528af361adb87259f8a8511434004
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
zlib = zlib_dep
|
||||||
|
|
4
tests/meson.build
Normal file
4
tests/meson.build
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
if get_option('tests').disabled()
|
||||||
|
subdir_done()
|
||||||
|
endif
|
||||||
|
subdir('static-plugins')
|
8
tests/static-plugins/meson.build
Normal file
8
tests/static-plugins/meson.build
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
dep = dependency('gstreamer-full-1.0', required: get_option('default_library') == 'static')
|
||||||
|
if dep.found()
|
||||||
|
test_gst_full_features = executable('test-gst-full-features', 'test-gst-full-features.c', dependencies : gst_full_dep)
|
||||||
|
test('test-gst-full-features', test_gst_full_features)
|
||||||
|
test_gst_full = executable('test-gst-full', 'test-gst-full.c', dependencies : gst_full_dep)
|
||||||
|
test('test-gst-full', test_gst_full)
|
||||||
|
endif
|
108
tests/static-plugins/test-gst-full-features.c
Normal file
108
tests/static-plugins/test-gst-full-features.c
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
assert_feature_names (gchar * names, GType feature_type, gboolean spook)
|
||||||
|
{
|
||||||
|
GstPluginFeature *feature = NULL;
|
||||||
|
gchar **split = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (names)
|
||||||
|
split = g_strsplit (names, ",", 0);
|
||||||
|
if (split) {
|
||||||
|
for (i = 0; split[i]; i++) {
|
||||||
|
feature = gst_registry_find_feature (gst_registry_get (),
|
||||||
|
split[i], feature_type);
|
||||||
|
if (spook)
|
||||||
|
g_assert_null (feature);
|
||||||
|
else
|
||||||
|
g_assert_nonnull (feature);
|
||||||
|
if (feature)
|
||||||
|
gst_object_unref (feature);
|
||||||
|
}
|
||||||
|
g_strfreev (split);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
GOptionContext *ctx;
|
||||||
|
GError *err = NULL;
|
||||||
|
gchar *elements, *typefinds, *deviceproviders, *dynamictypes;
|
||||||
|
gchar *spook_elements, *spook_typefinds, *spook_deviceproviders,
|
||||||
|
*spook_dynamictypes;
|
||||||
|
|
||||||
|
elements = typefinds = deviceproviders = dynamictypes = NULL;
|
||||||
|
spook_elements = spook_typefinds = spook_deviceproviders =
|
||||||
|
spook_dynamictypes = NULL;
|
||||||
|
|
||||||
|
GOptionEntry options[] = {
|
||||||
|
{"elements", 'e', 0, G_OPTION_ARG_STRING, &elements,
|
||||||
|
"Element(s) which should be available. Specify multiple ones using ',' as separator",
|
||||||
|
NULL},
|
||||||
|
{"spook-elements", 'E', 0, G_OPTION_ARG_STRING, &spook_elements,
|
||||||
|
"Element(s) which should NOT be available. Specify multiple ones using ',' as separator",
|
||||||
|
NULL},
|
||||||
|
{"typefinds", 't', 0, G_OPTION_ARG_STRING, &typefinds,
|
||||||
|
"Typefind(s) which should be available. Specify multiple ones using ',' as separator",
|
||||||
|
NULL},
|
||||||
|
{"spook-typefinds", 'T', 0, G_OPTION_ARG_STRING, &spook_typefinds,
|
||||||
|
"Typefind(s) which should NOT be available. Specify multiple ones using ',' as separator",
|
||||||
|
NULL},
|
||||||
|
{"deviceproviders", 'd', 0, G_OPTION_ARG_STRING, &deviceproviders,
|
||||||
|
"Deviceprovider(s) which should be available. Specify multiple ones using ',' as separator",
|
||||||
|
NULL},
|
||||||
|
{"spook-deviceproviders", 'D', 0, G_OPTION_ARG_STRING,
|
||||||
|
&spook_deviceproviders,
|
||||||
|
"Deviceprovider(s) which should NOT be available. Specify multiple ones using ',' as separator",
|
||||||
|
NULL},
|
||||||
|
{"dynamictypes", 'l', 0, G_OPTION_ARG_STRING, &dynamictypes,
|
||||||
|
"Dynamictype(s) which should be available. Specify multiple ones using ',' as separator",
|
||||||
|
NULL},
|
||||||
|
{"spook-dynamictypes", 'L', 0, G_OPTION_ARG_STRING, &spook_dynamictypes,
|
||||||
|
"Dynamictype(s) which should NOT be available. Specify multiple ones using ',' as separator",
|
||||||
|
NULL},
|
||||||
|
{NULL}
|
||||||
|
};
|
||||||
|
ctx = g_option_context_new ("elements ...");
|
||||||
|
g_option_context_add_main_entries (ctx, options, NULL);
|
||||||
|
g_option_context_add_group (ctx, gst_init_get_option_group ());
|
||||||
|
if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
|
||||||
|
g_print ("Error initializing: %s\n", GST_STR_NULL (err->message));
|
||||||
|
g_clear_error (&err);
|
||||||
|
g_option_context_free (ctx);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
g_option_context_free (ctx);
|
||||||
|
|
||||||
|
gst_init (&argc, &argv);
|
||||||
|
|
||||||
|
/* Test that elements are instanciable. */
|
||||||
|
assert_feature_names (elements, GST_TYPE_ELEMENT_FACTORY, FALSE);
|
||||||
|
/* Test that elements are NOT instanciable. */
|
||||||
|
assert_feature_names (spook_elements, GST_TYPE_ELEMENT_FACTORY, TRUE);
|
||||||
|
|
||||||
|
/* Test that typefinds are instanciable. */
|
||||||
|
assert_feature_names (typefinds, GST_TYPE_TYPE_FIND_FACTORY, FALSE);
|
||||||
|
/* Test that typefinds are NOT instanciable. */
|
||||||
|
assert_feature_names (spook_typefinds, GST_TYPE_TYPE_FIND_FACTORY, TRUE);
|
||||||
|
|
||||||
|
/* Test that device providers are instanciable. */
|
||||||
|
assert_feature_names (deviceproviders, GST_TYPE_DEVICE_PROVIDER_FACTORY,
|
||||||
|
FALSE);
|
||||||
|
/* Test that device providers are NOT instanciable. */
|
||||||
|
assert_feature_names (spook_deviceproviders, GST_TYPE_DEVICE_PROVIDER_FACTORY,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
|
/* Test that dynamic types are instanciable. */
|
||||||
|
assert_feature_names (dynamictypes, GST_TYPE_DYNAMIC_TYPE_FACTORY, FALSE);
|
||||||
|
/* Test that dynamic types are NOT instanciable. */
|
||||||
|
assert_feature_names (spook_dynamictypes, GST_TYPE_DYNAMIC_TYPE_FACTORY,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
|
gst_deinit ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
18
tests/static-plugins/test-gst-full.c
Normal file
18
tests/static-plugins/test-gst-full.c
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
GstElement *e;
|
||||||
|
|
||||||
|
gst_init (&argc, &argv);
|
||||||
|
|
||||||
|
/* -Bsymbolic option is introducing a regression where this variable
|
||||||
|
* were duplicated over the use in a dynamical use of libgstreamer-full.so */
|
||||||
|
g_assert_nonnull (_gst_caps_features_any);
|
||||||
|
g_assert_nonnull (_gst_caps_features_memory_system_memory);
|
||||||
|
|
||||||
|
e = gst_element_factory_make ("pipeline", NULL);
|
||||||
|
g_assert_nonnull (e);
|
||||||
|
g_object_unref (e);
|
||||||
|
}
|
Loading…
Reference in a new issue