mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-30 11:04:25 +00:00
Merge branch 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild
Pull kconfig updates from Michal Marek: - 'make xconfig' ported to Qt5, dropping support for Qt3 - merge_config.sh supports a single-input-file mode and also respects $KCONFIG_CONFIG - Fix for incorrect display of >= and > in dependency expressions * 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild: (44 commits) Add current selection check. Use pkg-config to find Qt 4 and 5 instead of direct qmake kconfig: Fix copy&paste error kconfig/merge_config.sh: Accept a single file kconfig/merge_config.sh: Support KCONFIG_CONFIG Update the buildsystem for KConfig finding Qt Port xconfig to Qt5 - Update copyright. Port xconfig to Qt5 - Fix goParent issue. Port xconfig to Qt5 - on Back clicked, deselect old item. Port xconfig to Qt5 - Add(back) one click checkbox toggle. Port xconfig to Qt5 - Add(back) lineedit editing. Port xconfig to Qt5 - Remove some commented code. Port xconfig to Qt5 - Source format. Port xconfig to Qt5 - Add horizontal scrollbar, and scroll per pixel. Port xconfig to Qt5 - Change ConfigItem constructor parent type. Port xconfig to Qt5 - Disable ConfigList soring Port xconfig to Qt5 - Remove ConfigList::updateMenuList template. Port xconfig to Qt5 - Add ConfigList::mode to initializer list. Port xconfig to Qt5 - Add ConfigItem::nextItem to initializer list. Port xconfig to Qt5 - Tree widget set column titles. ...
This commit is contained in:
commit
152813e6e4
10 changed files with 791 additions and 433 deletions
57
Documentation/kbuild/Kconfig.recursion-issue-01
Normal file
57
Documentation/kbuild/Kconfig.recursion-issue-01
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
# Simple Kconfig recursive issue
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
#
|
||||||
|
# Test with:
|
||||||
|
#
|
||||||
|
# make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-01 allnoconfig
|
||||||
|
#
|
||||||
|
# This Kconfig file has a simple recursive dependency issue. In order to
|
||||||
|
# understand why this recursive dependency issue occurs lets consider what
|
||||||
|
# Kconfig needs to address. We iterate over what Kconfig needs to address
|
||||||
|
# by stepping through the questions it needs to address sequentially.
|
||||||
|
#
|
||||||
|
# * What values are possible for CORE?
|
||||||
|
#
|
||||||
|
# CORE_BELL_A_ADVANCED selects CORE, which means that it influences the values
|
||||||
|
# that are possible for CORE. So for example if CORE_BELL_A_ADVANCED is 'y',
|
||||||
|
# CORE must be 'y' too.
|
||||||
|
#
|
||||||
|
# * What influences CORE_BELL_A_ADVANCED ?
|
||||||
|
#
|
||||||
|
# As the name implies CORE_BELL_A_ADVANCED is an advanced feature of
|
||||||
|
# CORE_BELL_A so naturally it depends on CORE_BELL_A. So if CORE_BELL_A is 'y'
|
||||||
|
# we know CORE_BELL_A_ADVANCED can be 'y' too.
|
||||||
|
#
|
||||||
|
# * What influences CORE_BELL_A ?
|
||||||
|
#
|
||||||
|
# CORE_BELL_A depends on CORE, so CORE influences CORE_BELL_A.
|
||||||
|
#
|
||||||
|
# But that is a problem, because this means that in order to determine
|
||||||
|
# what values are possible for CORE we ended up needing to address questions
|
||||||
|
# regarding possible values of CORE itself again. Answering the original
|
||||||
|
# question of what are the possible values of CORE would make the kconfig
|
||||||
|
# tools run in a loop. When this happens Kconfig exits and complains about
|
||||||
|
# the "recursive dependency detected" error.
|
||||||
|
#
|
||||||
|
# Reading the Documentation/kbuild/Kconfig.recursion-issue-01 file it may be
|
||||||
|
# obvious that an easy to solution to this problem should just be the removal
|
||||||
|
# of the "select CORE" from CORE_BELL_A_ADVANCED as that is implicit already
|
||||||
|
# since CORE_BELL_A depends on CORE. Recursive dependency issues are not always
|
||||||
|
# so trivial to resolve, we provide another example below of practical
|
||||||
|
# implications of this recursive issue where the solution is perhaps not so
|
||||||
|
# easy to understand. Note that matching semantics on the dependency on
|
||||||
|
# CORE also consist of a solution to this recursive problem.
|
||||||
|
|
||||||
|
mainmenu "Simple example to demo kconfig recursive dependency issue"
|
||||||
|
|
||||||
|
config CORE
|
||||||
|
tristate
|
||||||
|
|
||||||
|
config CORE_BELL_A
|
||||||
|
tristate
|
||||||
|
depends on CORE
|
||||||
|
|
||||||
|
config CORE_BELL_A_ADVANCED
|
||||||
|
tristate
|
||||||
|
depends on CORE_BELL_A
|
||||||
|
select CORE
|
63
Documentation/kbuild/Kconfig.recursion-issue-02
Normal file
63
Documentation/kbuild/Kconfig.recursion-issue-02
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
# Cumulative Kconfig recursive issue
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
#
|
||||||
|
# Test with:
|
||||||
|
#
|
||||||
|
# make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-02 allnoconfig
|
||||||
|
#
|
||||||
|
# The recursive limitations with Kconfig has some non intuitive implications on
|
||||||
|
# kconfig sematics which are documented here. One known practical implication
|
||||||
|
# of the recursive limitation is that drivers cannot negate features from other
|
||||||
|
# drivers if they share a common core requirement and use disjoint semantics to
|
||||||
|
# annotate those requirements, ie, some drivers use "depends on" while others
|
||||||
|
# use "select". For instance it means if a driver A and driver B share the same
|
||||||
|
# core requirement, and one uses "select" while the other uses "depends on" to
|
||||||
|
# annotate this, all features that driver A selects cannot now be negated by
|
||||||
|
# driver B.
|
||||||
|
#
|
||||||
|
# A perhaps not so obvious implication of this is that, if semantics on these
|
||||||
|
# core requirements are not carefully synced, as drivers evolve features
|
||||||
|
# they select or depend on end up becoming shared requirements which cannot be
|
||||||
|
# negated by other drivers.
|
||||||
|
#
|
||||||
|
# The example provided in Documentation/kbuild/Kconfig.recursion-issue-02
|
||||||
|
# describes a simple driver core layout of example features a kernel might
|
||||||
|
# have. Let's assume we have some CORE functionality, then the kernel has a
|
||||||
|
# series of bells and whistles it desires to implement, its not so advanced so
|
||||||
|
# it only supports bells at this time: CORE_BELL_A and CORE_BELL_B. If
|
||||||
|
# CORE_BELL_A has some advanced feature CORE_BELL_A_ADVANCED which selects
|
||||||
|
# CORE_BELL_A then CORE_BELL_A ends up becoming a common BELL feature which
|
||||||
|
# other bells in the system cannot negate. The reason for this issue is
|
||||||
|
# due to the disjoint use of semantics on expressing each bell's relationship
|
||||||
|
# with CORE, one uses "depends on" while the other uses "select". Another
|
||||||
|
# more important reason is that kconfig does not check for dependencies listed
|
||||||
|
# under 'select' for a symbol, when such symbols are selected kconfig them
|
||||||
|
# as mandatory required symbols. For more details on the heavy handed nature
|
||||||
|
# of select refer to Documentation/kbuild/Kconfig.select-break
|
||||||
|
#
|
||||||
|
# To fix this the "depends on CORE" must be changed to "select CORE", or the
|
||||||
|
# "select CORE" must be changed to "depends on CORE".
|
||||||
|
#
|
||||||
|
# For an example real world scenario issue refer to the attempt to remove
|
||||||
|
# "select FW_LOADER" [0], in the end the simple alternative solution to this
|
||||||
|
# problem consisted on matching semantics with newly introduced features.
|
||||||
|
#
|
||||||
|
# [0] http://lkml.kernel.org/r/1432241149-8762-1-git-send-email-mcgrof@do-not-panic.com
|
||||||
|
|
||||||
|
mainmenu "Simple example to demo cumulative kconfig recursive dependency implication"
|
||||||
|
|
||||||
|
config CORE
|
||||||
|
tristate
|
||||||
|
|
||||||
|
config CORE_BELL_A
|
||||||
|
tristate
|
||||||
|
depends on CORE
|
||||||
|
|
||||||
|
config CORE_BELL_A_ADVANCED
|
||||||
|
tristate
|
||||||
|
select CORE_BELL_A
|
||||||
|
|
||||||
|
config CORE_BELL_B
|
||||||
|
tristate
|
||||||
|
depends on !CORE_BELL_A
|
||||||
|
select CORE
|
33
Documentation/kbuild/Kconfig.select-break
Normal file
33
Documentation/kbuild/Kconfig.select-break
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# Select broken dependency issue
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
#
|
||||||
|
# Test with:
|
||||||
|
#
|
||||||
|
# make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.select-break menuconfig
|
||||||
|
#
|
||||||
|
# kconfig will not complain and enable this layout for configuration. This is
|
||||||
|
# currently a feature of kconfig, given select was designed to be heavy handed.
|
||||||
|
# Kconfig currently does not check the list of symbols listed on a symbol's
|
||||||
|
# "select" list, this is done on purpose to help load a set of known required
|
||||||
|
# symbols. Because of this use of select should be used with caution. An
|
||||||
|
# example of this issue is below.
|
||||||
|
#
|
||||||
|
# The option B and C are clearly contradicting with respect to A.
|
||||||
|
# However, when A is set, C can be set as well because Kconfig does not
|
||||||
|
# visit the dependencies of the select target (in this case B). And since
|
||||||
|
# Kconfig does not visit the dependencies, it breaks the dependencies of B
|
||||||
|
# (!A).
|
||||||
|
|
||||||
|
mainmenu "Simple example to demo kconfig select broken dependency issue"
|
||||||
|
|
||||||
|
config A
|
||||||
|
bool "CONFIG A"
|
||||||
|
|
||||||
|
config B
|
||||||
|
bool "CONFIG B"
|
||||||
|
depends on !A
|
||||||
|
|
||||||
|
config C
|
||||||
|
bool "CONFIG C"
|
||||||
|
depends on A
|
||||||
|
select B
|
|
@ -393,3 +393,164 @@ config FOO
|
||||||
depends on BAR && m
|
depends on BAR && m
|
||||||
|
|
||||||
limits FOO to module (=m) or disabled (=n).
|
limits FOO to module (=m) or disabled (=n).
|
||||||
|
|
||||||
|
Kconfig recursive dependency limitations
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
If you've hit the Kconfig error: "recursive dependency detected" you've run
|
||||||
|
into a recursive dependency issue with Kconfig, a recursive dependency can be
|
||||||
|
summarized as a circular dependency. The kconfig tools need to ensure that
|
||||||
|
Kconfig files comply with specified configuration requirements. In order to do
|
||||||
|
that kconfig must determine the values that are possible for all Kconfig
|
||||||
|
symbols, this is currently not possible if there is a circular relation
|
||||||
|
between two or more Kconfig symbols. For more details refer to the "Simple
|
||||||
|
Kconfig recursive issue" subsection below. Kconfig does not do recursive
|
||||||
|
dependency resolution; this has a few implications for Kconfig file writers.
|
||||||
|
We'll first explain why this issues exists and then provide an example
|
||||||
|
technical limitation which this brings upon Kconfig developers. Eager
|
||||||
|
developers wishing to try to address this limitation should read the next
|
||||||
|
subsections.
|
||||||
|
|
||||||
|
Simple Kconfig recursive issue
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Read: Documentation/kbuild/Kconfig.recursion-issue-01
|
||||||
|
|
||||||
|
Test with:
|
||||||
|
|
||||||
|
make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-01 allnoconfig
|
||||||
|
|
||||||
|
Cumulative Kconfig recursive issue
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Read: Documentation/kbuild/Kconfig.recursion-issue-02
|
||||||
|
|
||||||
|
Test with:
|
||||||
|
|
||||||
|
make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-02 allnoconfig
|
||||||
|
|
||||||
|
Practical solutions to kconfig recursive issue
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Developers who run into the recursive Kconfig issue have three options
|
||||||
|
at their disposal. We document them below and also provide a list of
|
||||||
|
historical issues resolved through these different solutions.
|
||||||
|
|
||||||
|
a) Remove any superfluous "select FOO" or "depends on FOO"
|
||||||
|
b) Match dependency semantics:
|
||||||
|
b1) Swap all "select FOO" to "depends on FOO" or,
|
||||||
|
b2) Swap all "depends on FOO" to "select FOO"
|
||||||
|
|
||||||
|
The resolution to a) can be tested with the sample Kconfig file
|
||||||
|
Documentation/kbuild/Kconfig.recursion-issue-01 through the removal
|
||||||
|
of the "select CORE" from CORE_BELL_A_ADVANCED as that is implicit already
|
||||||
|
since CORE_BELL_A depends on CORE. At times it may not be possible to remove
|
||||||
|
some dependency criteria, for such cases you can work with solution b).
|
||||||
|
|
||||||
|
The two different resolutions for b) can be tested in the sample Kconfig file
|
||||||
|
Documentation/kbuild/Kconfig.recursion-issue-02.
|
||||||
|
|
||||||
|
Below is a list of examples of prior fixes for these types of recursive issues;
|
||||||
|
all errors appear to involve one or more select's and one or more "depends on".
|
||||||
|
|
||||||
|
commit fix
|
||||||
|
====== ===
|
||||||
|
06b718c01208 select A -> depends on A
|
||||||
|
c22eacfe82f9 depends on A -> depends on B
|
||||||
|
6a91e854442c select A -> depends on A
|
||||||
|
118c565a8f2e select A -> select B
|
||||||
|
f004e5594705 select A -> depends on A
|
||||||
|
c7861f37b4c6 depends on A -> (null)
|
||||||
|
80c69915e5fb select A -> (null) (1)
|
||||||
|
c2218e26c0d0 select A -> depends on A (1)
|
||||||
|
d6ae99d04e1c select A -> depends on A
|
||||||
|
95ca19cf8cbf select A -> depends on A
|
||||||
|
8f057d7bca54 depends on A -> (null)
|
||||||
|
8f057d7bca54 depends on A -> select A
|
||||||
|
a0701f04846e select A -> depends on A
|
||||||
|
0c8b92f7f259 depends on A -> (null)
|
||||||
|
e4e9e0540928 select A -> depends on A (2)
|
||||||
|
7453ea886e87 depends on A > (null) (1)
|
||||||
|
7b1fff7e4fdf select A -> depends on A
|
||||||
|
86c747d2a4f0 select A -> depends on A
|
||||||
|
d9f9ab51e55e select A -> depends on A
|
||||||
|
0c51a4d8abd6 depends on A -> select A (3)
|
||||||
|
e98062ed6dc4 select A -> depends on A (3)
|
||||||
|
91e5d284a7f1 select A -> (null)
|
||||||
|
|
||||||
|
(1) Partial (or no) quote of error.
|
||||||
|
(2) That seems to be the gist of that fix.
|
||||||
|
(3) Same error.
|
||||||
|
|
||||||
|
Future kconfig work
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Work on kconfig is welcomed on both areas of clarifying semantics and on
|
||||||
|
evaluating the use of a full SAT solver for it. A full SAT solver can be
|
||||||
|
desirable to enable more complex dependency mappings and / or queries,
|
||||||
|
for instance on possible use case for a SAT solver could be that of handling
|
||||||
|
the current known recursive dependency issues. It is not known if this would
|
||||||
|
address such issues but such evaluation is desirable. If support for a full SAT
|
||||||
|
solver proves too complex or that it cannot address recursive dependency issues
|
||||||
|
Kconfig should have at least clear and well defined semantics which also
|
||||||
|
addresses and documents limitations or requirements such as the ones dealing
|
||||||
|
with recursive dependencies.
|
||||||
|
|
||||||
|
Further work on both of these areas is welcomed on Kconfig. We elaborate
|
||||||
|
on both of these in the next two subsections.
|
||||||
|
|
||||||
|
Semantics of Kconfig
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The use of Kconfig is broad, Linux is now only one of Kconfig's users:
|
||||||
|
one study has completed a broad analysis of Kconfig use in 12 projects [0].
|
||||||
|
Despite its widespread use, and although this document does a reasonable job
|
||||||
|
in documenting basic Kconfig syntax a more precise definition of Kconfig
|
||||||
|
semantics is welcomed. One project deduced Kconfig semantics through
|
||||||
|
the use of the xconfig configurator [1]. Work should be done to confirm if
|
||||||
|
the deduced semantics matches our intended Kconfig design goals.
|
||||||
|
|
||||||
|
Having well defined semantics can be useful for tools for practical
|
||||||
|
evaluation of depenencies, for instance one such use known case was work to
|
||||||
|
express in boolean abstraction of the inferred semantics of Kconfig to
|
||||||
|
translate Kconfig logic into boolean formulas and run a SAT solver on this to
|
||||||
|
find dead code / features (always inactive), 114 dead features were found in
|
||||||
|
Linux using this methodology [1] (Section 8: Threats to validity).
|
||||||
|
|
||||||
|
Confirming this could prove useful as Kconfig stands as one of the the leading
|
||||||
|
industrial variability modeling languages [1] [2]. Its study would help
|
||||||
|
evaluate practical uses of such languages, their use was only theoretical
|
||||||
|
and real world requirements were not well understood. As it stands though
|
||||||
|
only reverse engineering techniques have been used to deduce semantics from
|
||||||
|
variability modeling languages such as Kconfig [3].
|
||||||
|
|
||||||
|
[0] http://www.eng.uwaterloo.ca/~shshe/kconfig_semantics.pdf
|
||||||
|
[1] http://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf
|
||||||
|
[2] http://gsd.uwaterloo.ca/sites/default/files/ase241-berger_0.pdf
|
||||||
|
[3] http://gsd.uwaterloo.ca/sites/default/files/icse2011.pdf
|
||||||
|
|
||||||
|
Full SAT solver for Kconfig
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Although SAT solvers [0] haven't yet been used by Kconfig directly, as noted in
|
||||||
|
the previous subsection, work has been done however to express in boolean
|
||||||
|
abstraction the inferred semantics of Kconfig to translate Kconfig logic into
|
||||||
|
boolean formulas and run a SAT solver on it [1]. Another known related project
|
||||||
|
is CADOS [2] (former VAMOS [3]) and the tools, mainly undertaker [4], which has
|
||||||
|
been introduced first with [5]. The basic concept of undertaker is to exract
|
||||||
|
variability models from Kconfig, and put them together with a propositional
|
||||||
|
formula extracted from CPP #ifdefs and build-rules into a SAT solver in order
|
||||||
|
to find dead code, dead files, and dead symbols. If using a SAT solver is
|
||||||
|
desirable on Kconfig one approach would be to evaluate repurposing such efforts
|
||||||
|
somehow on Kconfig. There is enough interest from mentors of existing projects
|
||||||
|
to not only help advise how to integrate this work upstream but also help
|
||||||
|
maintain it long term. Interested developers should visit:
|
||||||
|
|
||||||
|
http://kernelnewbies.org/KernelProjects/kconfig-sat
|
||||||
|
|
||||||
|
[0] http://www.cs.cornell.edu/~sabhar/chapters/SATSolvers-KR-Handbook.pdf
|
||||||
|
[1] http://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf
|
||||||
|
[2] https://cados.cs.fau.de
|
||||||
|
[3] https://vamos.cs.fau.de
|
||||||
|
[4] https://undertaker.cs.fau.de
|
||||||
|
[5] https://www4.cs.fau.de/Publications/2011/tartler_11_eurosys.pdf
|
||||||
|
|
|
@ -229,49 +229,21 @@ $(obj)/.tmp_qtcheck: $(src)/Makefile
|
||||||
|
|
||||||
# Qt needs some extra effort...
|
# Qt needs some extra effort...
|
||||||
$(obj)/.tmp_qtcheck:
|
$(obj)/.tmp_qtcheck:
|
||||||
@set -e; $(kecho) " CHECK qt"; dir=""; pkg=""; \
|
@set -e; $(kecho) " CHECK qt"; \
|
||||||
if ! pkg-config --exists QtCore 2> /dev/null; then \
|
if pkg-config --exists Qt5Core; then \
|
||||||
echo "* Unable to find the Qt4 tool qmake. Trying to use Qt3"; \
|
cflags="-std=c++11 -fPIC `pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets`"; \
|
||||||
pkg-config --exists qt 2> /dev/null && pkg=qt; \
|
libs=`pkg-config --libs Qt5Core Qt5Gui Qt5Widgets`; \
|
||||||
pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \
|
moc=`pkg-config --variable=host_bins Qt5Core`/moc; \
|
||||||
if [ -n "$$pkg" ]; then \
|
elif pkg-config --exists QtCore; then \
|
||||||
cflags="\$$(shell pkg-config $$pkg --cflags)"; \
|
cflags=`pkg-config --cflags QtCore QtGui`; \
|
||||||
libs="\$$(shell pkg-config $$pkg --libs)"; \
|
libs=`pkg-config --libs QtCore QtGui`; \
|
||||||
moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \
|
moc=`pkg-config --variable=moc_location QtCore`; \
|
||||||
dir="$$(pkg-config $$pkg --variable=prefix)"; \
|
|
||||||
else \
|
|
||||||
for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \
|
|
||||||
if [ -f $$d/include/qconfig.h ]; then dir=$$d; break; fi; \
|
|
||||||
done; \
|
|
||||||
if [ -z "$$dir" ]; then \
|
|
||||||
echo >&2 "*"; \
|
|
||||||
echo >&2 "* Unable to find any Qt installation. Please make sure that"; \
|
|
||||||
echo >&2 "* the Qt4 or Qt3 development package is correctly installed and"; \
|
|
||||||
echo >&2 "* either qmake can be found or install pkg-config or set"; \
|
|
||||||
echo >&2 "* the QTDIR environment variable to the correct location."; \
|
|
||||||
echo >&2 "*"; \
|
|
||||||
false; \
|
|
||||||
fi; \
|
|
||||||
libpath=$$dir/lib; lib=qt; osdir=""; \
|
|
||||||
$(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \
|
|
||||||
osdir=x$$($(HOSTCXX) -print-multi-os-directory); \
|
|
||||||
test -d $$libpath/$$osdir && libpath=$$libpath/$$osdir; \
|
|
||||||
test -f $$libpath/libqt-mt.so && lib=qt-mt; \
|
|
||||||
cflags="-I$$dir/include"; \
|
|
||||||
libs="-L$$libpath -Wl,-rpath,$$libpath -l$$lib"; \
|
|
||||||
moc="$$dir/bin/moc"; \
|
|
||||||
fi; \
|
|
||||||
if [ ! -x $$dir/bin/moc -a -x /usr/bin/moc ]; then \
|
|
||||||
echo "*"; \
|
|
||||||
echo "* Unable to find $$dir/bin/moc, using /usr/bin/moc instead."; \
|
|
||||||
echo "*"; \
|
|
||||||
moc="/usr/bin/moc"; \
|
|
||||||
fi; \
|
|
||||||
else \
|
else \
|
||||||
cflags="\$$(shell pkg-config QtCore QtGui Qt3Support --cflags)"; \
|
echo >&2 "*"; \
|
||||||
libs="\$$(shell pkg-config QtCore QtGui Qt3Support --libs)"; \
|
echo >&2 "* Could not find Qt via pkg-config."; \
|
||||||
moc="\$$(shell pkg-config QtCore --variable=moc_location)"; \
|
echo >&2 "* Please install either Qt 4.8 or 5.x. and make sure it's in PKG_CONFIG_PATH"; \
|
||||||
[ -n "$$moc" ] || moc="\$$(shell pkg-config QtCore --variable=prefix)/bin/moc"; \
|
echo >&2 "*"; \
|
||||||
|
exit 1; \
|
||||||
fi; \
|
fi; \
|
||||||
echo "KC_QT_CFLAGS=$$cflags" > $@; \
|
echo "KC_QT_CFLAGS=$$cflags" > $@; \
|
||||||
echo "KC_QT_LIBS=$$libs" >> $@; \
|
echo "KC_QT_LIBS=$$libs" >> $@; \
|
||||||
|
|
|
@ -1113,7 +1113,7 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *
|
||||||
fn(data, e->left.sym, e->left.sym->name);
|
fn(data, e->left.sym, e->left.sym->name);
|
||||||
else
|
else
|
||||||
fn(data, NULL, "<choice>");
|
fn(data, NULL, "<choice>");
|
||||||
fn(data, NULL, e->type == E_LEQ ? ">=" : ">");
|
fn(data, NULL, e->type == E_GEQ ? ">=" : ">");
|
||||||
fn(data, e->right.sym, e->right.sym->name);
|
fn(data, e->right.sym, e->right.sym->name);
|
||||||
break;
|
break;
|
||||||
case E_UNEQUAL:
|
case E_UNEQUAL:
|
||||||
|
|
|
@ -32,7 +32,7 @@ usage() {
|
||||||
echo " -m only merge the fragments, do not execute the make command"
|
echo " -m only merge the fragments, do not execute the make command"
|
||||||
echo " -n use allnoconfig instead of alldefconfig"
|
echo " -n use allnoconfig instead of alldefconfig"
|
||||||
echo " -r list redundant entries when merging fragments"
|
echo " -r list redundant entries when merging fragments"
|
||||||
echo " -O dir to put generated output files"
|
echo " -O dir to put generated output files. Consider setting \$KCONFIG_CONFIG instead."
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNMAKE=true
|
RUNMAKE=true
|
||||||
|
@ -77,11 +77,19 @@ while true; do
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ "$#" -lt 2 ] ; then
|
if [ "$#" -lt 1 ] ; then
|
||||||
usage
|
usage
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -z "$KCONFIG_CONFIG" ]; then
|
||||||
|
if [ "$OUTPUT" != . ]; then
|
||||||
|
KCONFIG_CONFIG=$(readlink -m -- "$OUTPUT/.config")
|
||||||
|
else
|
||||||
|
KCONFIG_CONFIG=.config
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
INITFILE=$1
|
INITFILE=$1
|
||||||
shift;
|
shift;
|
||||||
|
|
||||||
|
@ -124,9 +132,9 @@ for MERGE_FILE in $MERGE_LIST ; do
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ "$RUNMAKE" = "false" ]; then
|
if [ "$RUNMAKE" = "false" ]; then
|
||||||
cp $TMP_FILE $OUTPUT/.config
|
cp -T -- "$TMP_FILE" "$KCONFIG_CONFIG"
|
||||||
echo "#"
|
echo "#"
|
||||||
echo "# merged configuration written to $OUTPUT/.config (needs make)"
|
echo "# merged configuration written to $KCONFIG_CONFIG (needs make)"
|
||||||
echo "#"
|
echo "#"
|
||||||
clean_up
|
clean_up
|
||||||
exit
|
exit
|
||||||
|
@ -150,7 +158,7 @@ make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET
|
||||||
for CFG in $(sed -n "$SED_CONFIG_EXP" $TMP_FILE); do
|
for CFG in $(sed -n "$SED_CONFIG_EXP" $TMP_FILE); do
|
||||||
|
|
||||||
REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE)
|
REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE)
|
||||||
ACTUAL_VAL=$(grep -w -e "$CFG" $OUTPUT/.config)
|
ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG")
|
||||||
if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then
|
if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then
|
||||||
echo "Value requested for $CFG not in final .config"
|
echo "Value requested for $CFG not in final .config"
|
||||||
echo "Requested value: $REQUESTED_VAL"
|
echo "Requested value: $REQUESTED_VAL"
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,26 +3,18 @@
|
||||||
* Released under the terms of the GNU GPL v2.0.
|
* Released under the terms of the GNU GPL v2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if QT_VERSION < 0x040000
|
#include <QTextBrowser>
|
||||||
#include <qlistview.h>
|
#include <QTreeWidget>
|
||||||
#else
|
#include <QMainWindow>
|
||||||
#include <q3listview.h>
|
#include <QHeaderView>
|
||||||
#endif
|
|
||||||
#include <qsettings.h>
|
#include <qsettings.h>
|
||||||
|
#include <QPushButton>
|
||||||
#if QT_VERSION < 0x040000
|
#include <QSettings>
|
||||||
#define Q3ValueList QValueList
|
#include <QLineEdit>
|
||||||
#define Q3PopupMenu QPopupMenu
|
#include <QSplitter>
|
||||||
#define Q3ListView QListView
|
#include <QCheckBox>
|
||||||
#define Q3ListViewItem QListViewItem
|
#include <QDialog>
|
||||||
#define Q3VBox QVBox
|
#include "expr.h"
|
||||||
#define Q3TextBrowser QTextBrowser
|
|
||||||
#define Q3MainWindow QMainWindow
|
|
||||||
#define Q3Action QAction
|
|
||||||
#define Q3ToolBar QToolBar
|
|
||||||
#define Q3ListViewItemIterator QListViewItemIterator
|
|
||||||
#define Q3FileDialog QFileDialog
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class ConfigView;
|
class ConfigView;
|
||||||
class ConfigList;
|
class ConfigList;
|
||||||
|
@ -33,8 +25,8 @@ class ConfigMainWindow;
|
||||||
class ConfigSettings : public QSettings {
|
class ConfigSettings : public QSettings {
|
||||||
public:
|
public:
|
||||||
ConfigSettings();
|
ConfigSettings();
|
||||||
Q3ValueList<int> readSizes(const QString& key, bool *ok);
|
QList<int> readSizes(const QString& key, bool *ok);
|
||||||
bool writeSizes(const QString& key, const Q3ValueList<int>& value);
|
bool writeSizes(const QString& key, const QList<int>& value);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum colIdx {
|
enum colIdx {
|
||||||
|
@ -47,9 +39,9 @@ enum optionMode {
|
||||||
normalOpt = 0, allOpt, promptOpt
|
normalOpt = 0, allOpt, promptOpt
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConfigList : public Q3ListView {
|
class ConfigList : public QTreeWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
typedef class Q3ListView Parent;
|
typedef class QTreeWidget Parent;
|
||||||
public:
|
public:
|
||||||
ConfigList(ConfigView* p, const char *name = 0);
|
ConfigList(ConfigView* p, const char *name = 0);
|
||||||
void reinit(void);
|
void reinit(void);
|
||||||
|
@ -61,10 +53,10 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void keyPressEvent(QKeyEvent *e);
|
void keyPressEvent(QKeyEvent *e);
|
||||||
void contentsMousePressEvent(QMouseEvent *e);
|
void mousePressEvent(QMouseEvent *e);
|
||||||
void contentsMouseReleaseEvent(QMouseEvent *e);
|
void mouseReleaseEvent(QMouseEvent *e);
|
||||||
void contentsMouseMoveEvent(QMouseEvent *e);
|
void mouseMoveEvent(QMouseEvent *e);
|
||||||
void contentsMouseDoubleClickEvent(QMouseEvent *e);
|
void mouseDoubleClickEvent(QMouseEvent *e);
|
||||||
void focusInEvent(QFocusEvent *e);
|
void focusInEvent(QFocusEvent *e);
|
||||||
void contextMenuEvent(QContextMenuEvent *e);
|
void contextMenuEvent(QContextMenuEvent *e);
|
||||||
|
|
||||||
|
@ -95,32 +87,23 @@ public:
|
||||||
}
|
}
|
||||||
ConfigItem* firstChild() const
|
ConfigItem* firstChild() const
|
||||||
{
|
{
|
||||||
return (ConfigItem *)Parent::firstChild();
|
return (ConfigItem *)children().first();
|
||||||
}
|
}
|
||||||
int mapIdx(colIdx idx)
|
void addColumn(colIdx idx)
|
||||||
{
|
{
|
||||||
return colMap[idx];
|
showColumn(idx);
|
||||||
}
|
|
||||||
void addColumn(colIdx idx, const QString& label)
|
|
||||||
{
|
|
||||||
colMap[idx] = Parent::addColumn(label);
|
|
||||||
colRevMap[colMap[idx]] = idx;
|
|
||||||
}
|
}
|
||||||
void removeColumn(colIdx idx)
|
void removeColumn(colIdx idx)
|
||||||
{
|
{
|
||||||
int col = colMap[idx];
|
hideColumn(idx);
|
||||||
if (col >= 0) {
|
|
||||||
Parent::removeColumn(col);
|
|
||||||
colRevMap[col] = colMap[idx] = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void setAllOpen(bool open);
|
void setAllOpen(bool open);
|
||||||
void setParentMenu(void);
|
void setParentMenu(void);
|
||||||
|
|
||||||
bool menuSkip(struct menu *);
|
bool menuSkip(struct menu *);
|
||||||
|
|
||||||
template <class P>
|
void updateMenuList(ConfigItem *parent, struct menu*);
|
||||||
void updateMenuList(P*, struct menu*);
|
void updateMenuList(ConfigList *parent, struct menu*);
|
||||||
|
|
||||||
bool updateAll;
|
bool updateAll;
|
||||||
|
|
||||||
|
@ -132,30 +115,26 @@ public:
|
||||||
enum listMode mode;
|
enum listMode mode;
|
||||||
enum optionMode optMode;
|
enum optionMode optMode;
|
||||||
struct menu *rootEntry;
|
struct menu *rootEntry;
|
||||||
QColorGroup disabledColorGroup;
|
QPalette disabledColorGroup;
|
||||||
QColorGroup inactivedColorGroup;
|
QPalette inactivedColorGroup;
|
||||||
Q3PopupMenu* headerPopup;
|
QMenu* headerPopup;
|
||||||
|
|
||||||
private:
|
|
||||||
int colMap[colNr];
|
|
||||||
int colRevMap[colNr];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConfigItem : public Q3ListViewItem {
|
class ConfigItem : public QTreeWidgetItem {
|
||||||
typedef class Q3ListViewItem Parent;
|
typedef class QTreeWidgetItem Parent;
|
||||||
public:
|
public:
|
||||||
ConfigItem(Q3ListView *parent, ConfigItem *after, struct menu *m, bool v)
|
ConfigItem(ConfigList *parent, ConfigItem *after, struct menu *m, bool v)
|
||||||
: Parent(parent, after), menu(m), visible(v), goParent(false)
|
: Parent(parent, after), nextItem(0), menu(m), visible(v), goParent(false)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v)
|
ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v)
|
||||||
: Parent(parent, after), menu(m), visible(v), goParent(false)
|
: Parent(parent, after), nextItem(0), menu(m), visible(v), goParent(false)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
ConfigItem(Q3ListView *parent, ConfigItem *after, bool v)
|
ConfigItem(ConfigList *parent, ConfigItem *after, bool v)
|
||||||
: Parent(parent, after), menu(0), visible(v), goParent(true)
|
: Parent(parent, after), nextItem(0), menu(0), visible(v), goParent(true)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
@ -166,33 +145,43 @@ public:
|
||||||
void testUpdateMenu(bool v);
|
void testUpdateMenu(bool v);
|
||||||
ConfigList* listView() const
|
ConfigList* listView() const
|
||||||
{
|
{
|
||||||
return (ConfigList*)Parent::listView();
|
return (ConfigList*)Parent::treeWidget();
|
||||||
}
|
}
|
||||||
ConfigItem* firstChild() const
|
ConfigItem* firstChild() const
|
||||||
{
|
{
|
||||||
return (ConfigItem *)Parent::firstChild();
|
return (ConfigItem *)Parent::child(0);
|
||||||
}
|
}
|
||||||
ConfigItem* nextSibling() const
|
ConfigItem* nextSibling()
|
||||||
{
|
{
|
||||||
return (ConfigItem *)Parent::nextSibling();
|
ConfigItem *ret = NULL;
|
||||||
|
ConfigItem *_parent = (ConfigItem *)parent();
|
||||||
|
|
||||||
|
if(_parent) {
|
||||||
|
ret = (ConfigItem *)_parent->child(_parent->indexOfChild(this)+1);
|
||||||
|
} else {
|
||||||
|
QTreeWidget *_treeWidget = treeWidget();
|
||||||
|
ret = (ConfigItem *)_treeWidget->topLevelItem(_treeWidget->indexOfTopLevelItem(this)+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
void setText(colIdx idx, const QString& text)
|
void setText(colIdx idx, const QString& text)
|
||||||
{
|
{
|
||||||
Parent::setText(listView()->mapIdx(idx), text);
|
Parent::setText(idx, text);
|
||||||
}
|
}
|
||||||
QString text(colIdx idx) const
|
QString text(colIdx idx) const
|
||||||
{
|
{
|
||||||
return Parent::text(listView()->mapIdx(idx));
|
return Parent::text(idx);
|
||||||
}
|
}
|
||||||
void setPixmap(colIdx idx, const QPixmap& pm)
|
void setPixmap(colIdx idx, const QIcon &icon)
|
||||||
{
|
{
|
||||||
Parent::setPixmap(listView()->mapIdx(idx), pm);
|
Parent::setIcon(idx, icon);
|
||||||
}
|
}
|
||||||
const QPixmap* pixmap(colIdx idx) const
|
const QIcon pixmap(colIdx idx) const
|
||||||
{
|
{
|
||||||
return Parent::pixmap(listView()->mapIdx(idx));
|
return icon(idx);
|
||||||
}
|
}
|
||||||
void paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align);
|
// TODO: Implement paintCell
|
||||||
|
|
||||||
ConfigItem* nextItem;
|
ConfigItem* nextItem;
|
||||||
struct menu *menu;
|
struct menu *menu;
|
||||||
|
@ -216,9 +205,9 @@ public:
|
||||||
ConfigItem *item;
|
ConfigItem *item;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConfigView : public Q3VBox {
|
class ConfigView : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
typedef class Q3VBox Parent;
|
typedef class QWidget Parent;
|
||||||
public:
|
public:
|
||||||
ConfigView(QWidget* parent, const char *name = 0);
|
ConfigView(QWidget* parent, const char *name = 0);
|
||||||
~ConfigView(void);
|
~ConfigView(void);
|
||||||
|
@ -249,9 +238,9 @@ public:
|
||||||
static QAction *showPromptAction;
|
static QAction *showPromptAction;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConfigInfoView : public Q3TextBrowser {
|
class ConfigInfoView : public QTextBrowser {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
typedef class Q3TextBrowser Parent;
|
typedef class QTextBrowser Parent;
|
||||||
public:
|
public:
|
||||||
ConfigInfoView(QWidget* parent, const char *name = 0);
|
ConfigInfoView(QWidget* parent, const char *name = 0);
|
||||||
bool showDebug(void) const { return _showDebug; }
|
bool showDebug(void) const { return _showDebug; }
|
||||||
|
@ -271,8 +260,8 @@ protected:
|
||||||
QString debug_info(struct symbol *sym);
|
QString debug_info(struct symbol *sym);
|
||||||
static QString print_filter(const QString &str);
|
static QString print_filter(const QString &str);
|
||||||
static void expr_print_help(void *data, struct symbol *sym, const char *str);
|
static void expr_print_help(void *data, struct symbol *sym, const char *str);
|
||||||
Q3PopupMenu* createPopupMenu(const QPoint& pos);
|
QMenu *createStandardContextMenu(const QPoint & pos);
|
||||||
void contentsContextMenuEvent(QContextMenuEvent *e);
|
void contextMenuEvent(QContextMenuEvent *e);
|
||||||
|
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
struct menu *_menu;
|
struct menu *_menu;
|
||||||
|
@ -299,10 +288,10 @@ protected:
|
||||||
struct symbol **result;
|
struct symbol **result;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConfigMainWindow : public Q3MainWindow {
|
class ConfigMainWindow : public QMainWindow {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
static Q3Action *saveAction;
|
static QAction *saveAction;
|
||||||
static void conf_changed(void);
|
static void conf_changed(void);
|
||||||
public:
|
public:
|
||||||
ConfigMainWindow(void);
|
ConfigMainWindow(void);
|
||||||
|
@ -331,8 +320,11 @@ protected:
|
||||||
ConfigView *configView;
|
ConfigView *configView;
|
||||||
ConfigList *configList;
|
ConfigList *configList;
|
||||||
ConfigInfoView *helpText;
|
ConfigInfoView *helpText;
|
||||||
Q3ToolBar *toolBar;
|
QToolBar *toolBar;
|
||||||
Q3Action *backAction;
|
QAction *backAction;
|
||||||
QSplitter* split1;
|
QAction *singleViewAction;
|
||||||
QSplitter* split2;
|
QAction *splitViewAction;
|
||||||
|
QAction *fullViewAction;
|
||||||
|
QSplitter *split1;
|
||||||
|
QSplitter *split2;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1116,6 +1116,8 @@ static void sym_check_print_recursive(struct symbol *last_sym)
|
||||||
if (stack->sym == last_sym)
|
if (stack->sym == last_sym)
|
||||||
fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
|
fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
|
||||||
prop->file->name, prop->lineno);
|
prop->file->name, prop->lineno);
|
||||||
|
fprintf(stderr, "For a resolution refer to Documentation/kbuild/kconfig-language.txt\n");
|
||||||
|
fprintf(stderr, "subsection \"Kconfig recursive dependency limitations\"\n");
|
||||||
if (stack->expr) {
|
if (stack->expr) {
|
||||||
fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
|
fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
|
||||||
prop->file->name, prop->lineno,
|
prop->file->name, prop->lineno,
|
||||||
|
|
Loading…
Add table
Reference in a new issue