We have developed a bunch of controllers and APIs, we need to delete some controllers but we are unable to find a way to delete the API and controllers.
We looked at the available options but no flag to delete the apis.
operator-sdk --help
CLI tool for building Kubernetes extensions and tools.
Usage:
operator-sdk [flags]
operator-sdk [command]
Examples:
The first step is to initialize your project:
operator-sdk init [--plugins=<PLUGIN KEYS> [--project-version=<PROJECT VERSION>]]
<PLUGIN KEYS> is a comma-separated list of plugin keys from the following table
and <PROJECT VERSION> a supported project version for these plugins.
Plugin keys | Supported project versions
-------------------------------------+----------------------------
ansible.sdk.operatorframework.io/v1 | 3
declarative.go.kubebuilder.io/v1 | 2, 3
go.kubebuilder.io/v2 | 2, 3
go.kubebuilder.io/v3 | 3
helm.sdk.operatorframework.io/v1 | 3
kustomize.common.kubebuilder.io/v1 | 3
quarkus.javaoperatorsdk.io/v1-alpha | 3
For more specific help for the init command of a certain plugins and project version
configuration please run:
operator-sdk init --help --plugins=<PLUGIN KEYS> [--project-version=<PROJECT VERSION>]
Default plugin keys: "go.kubebuilder.io/v3"
Default project version: "3"
Available Commands:
alpha Alpha-stage subcommands
bundle Manage operator bundle metadata
cleanup Clean up an Operator deployed with the 'run' subcommand
completion Load completions for the specified shell
create Scaffold a Kubernetes API or webhook
edit Update the project configuration
generate Invokes a specific generator
help Help about any command
init Initialize a new project
olm Manage the Operator Lifecycle Manager installation in your cluster
pkgman-to-bundle Migrates packagemanifests to bundles
run Run an Operator in a variety of environments
scorecard Runs scorecard
version Print the operator-sdk version
Flags:
-h, --help help for operator-sdk
--plugins strings plugin keys to be used for this subcommand execution
--project-version string project version (default "3")
--verbose Enable verbose logging
There is not an automated way to remove APIs via the operator-sdk.
There are a couple ways to do it. If you're operator is fairly simple, you could just scaffold a new operator and copy the code you want into it.
Otherwise, you'll have to remove it by hand. I created a dummy operator, commited it, and then added a new API to get this diff which can be used to see what you'll need to delete. (This is using the master branch, it may be different depending on the version you are using.)
diff --git a/PROJECT b/PROJECT
index ca36be5..0bb71be 100644
--- a/PROJECT
+++ b/PROJECT
## -16,4 +16,13 ## resources:
kind: Memcached
path: github.com/example/memcached-operator/api/v1alpha1
version: v1alpha1
+- api:
+ crdVersion: v1
+ namespaced: true
+ controller: true
+ domain: example.com
+ group: cache
+ kind: Memcached2
+ path: github.com/example/memcached-operator/api/v1alpha1
+ version: v1alpha1
version: "3"
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 7730cf5..8211ded 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
## -51,6 +51,95 ## func (in *Memcached) DeepCopyObject() runtime.Object {
return nil
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Memcached2) DeepCopyInto(out *Memcached2) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ out.Spec = in.Spec
+ out.Status = in.Status
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Memcached2.
+func (in *Memcached2) DeepCopy() *Memcached2 {
+ if in == nil {
+ return nil
+ }
+ out := new(Memcached2)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *Memcached2) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Memcached2List) DeepCopyInto(out *Memcached2List) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]Memcached2, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Memcached2List.
+func (in *Memcached2List) DeepCopy() *Memcached2List {
+ if in == nil {
+ return nil
+ }
+ out := new(Memcached2List)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *Memcached2List) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Memcached2Spec) DeepCopyInto(out *Memcached2Spec) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Memcached2Spec.
+func (in *Memcached2Spec) DeepCopy() *Memcached2Spec {
+ if in == nil {
+ return nil
+ }
+ out := new(Memcached2Spec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Memcached2Status) DeepCopyInto(out *Memcached2Status) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Memcached2Status.
+func (in *Memcached2Status) DeepCopy() *Memcached2Status {
+ if in == nil {
+ return nil
+ }
+ out := new(Memcached2Status)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *MemcachedList) DeepCopyInto(out *MemcachedList) {
*out = *in
diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml
index 8b7bb5b..5d83219 100644
--- a/config/crd/kustomization.yaml
+++ b/config/crd/kustomization.yaml
## -3,17 +3,20 ##
# It should be run by config/default
resources:
- bases/cache.example.com_memcacheds.yaml
+- bases/cache.example.com_memcached2s.yaml
#+kubebuilder:scaffold:crdkustomizeresource
patchesStrategicMerge:
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix.
# patches here are for enabling the conversion webhook for each CRD
#- patches/webhook_in_memcacheds.yaml
+#- patches/webhook_in_memcached2s.yaml
#+kubebuilder:scaffold:crdkustomizewebhookpatch
# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
# patches here are for enabling the CA injection for each CRD
#- patches/cainjection_in_memcacheds.yaml
+#- patches/cainjection_in_memcached2s.yaml
#+kubebuilder:scaffold:crdkustomizecainjectionpatch
# the following config is for teaching kustomize how to do kustomization for CRDs.
diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml
index 42654aa..9c62d32 100644
--- a/config/samples/kustomization.yaml
+++ b/config/samples/kustomization.yaml
## -1,4 +1,5 ##
## Append samples you want in your CSV to this file as resources ##
resources:
- cache_v1alpha1_memcached.yaml
+- cache_v1alpha1_memcached2.yaml
#+kubebuilder:scaffold:manifestskustomizesamples
diff --git a/controllers/suite_test.go b/controllers/suite_test.go
index 97d4bfb..ffce919 100644
--- a/controllers/suite_test.go
+++ b/controllers/suite_test.go
## -65,6 +65,9 ## var _ = BeforeSuite(func() {
err = cachev1alpha1.AddToScheme(scheme.Scheme)
Expect(err).NotTo(HaveOccurred())
+ err = cachev1alpha1.AddToScheme(scheme.Scheme)
+ Expect(err).NotTo(HaveOccurred())
+
//+kubebuilder:scaffold:scheme
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
diff --git a/main.go b/main.go
index b2bedfd..443397e 100644
--- a/main.go
+++ b/main.go
## -85,6 +85,13 ## func main() {
setupLog.Error(err, "unable to create controller", "controller", "Memcached")
os.Exit(1)
}
+ if err = (&controllers.Memcached2Reconciler{
+ Client: mgr.GetClient(),
+ Scheme: mgr.GetScheme(),
+ }).SetupWithManager(mgr); err != nil {
+ setupLog.Error(err, "unable to create controller", "controller", "Memcached2")
+ os.Exit(1)
+ }
//+kubebuilder:scaffold:builder
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
I'm not sure if this is something that we could add to the operator-sdk right now, but it would be worth filing an issue, which we will discuss at our triage meeting. https://github.com/operator-framework/operator-sdk/issues/new?assignees=&labels=&template=feature-request.md&title=
I am new for yocto ,now I use a MTK-demo-board to build a linux-distro base on Yocto. I want to realize OTA by mender followed this tutorial:https://docs.mender.io/1.0/Devices/Integrating-with-U-Boot.
but Mender support u-boot as bootloader by default, the MTK use lk bootloader,Then how to realize this function?
The AP which I used is MT8183,The steps I have done list below:
1. /meta/meta-mediatek/recipes-bsp/lk/lk_2.0.0.0.bb . add follow code:
require recipes-bsp/u-boot/u-boot-mender.inc
PROVIDES += "u-boot"
RPROVIDES_{PN} += "u-boot"
2.cp lk_2.0.0.0 lk-fw-utils_2.0.0.0,and changed the file as behind:
a. delete do_genkey{} function;
b. add EXTRA_OEMAKE_class-target = 'CROSS_COMPILE=${TARGET_PREFIX} CC="${CC} ${CFLAGS} ${LDFLAGS}" V=1'
c. add "oe_runmake env" in function do_compile()
d. add PROVIDES_${PN} = "lk-fw-utils"
RPROVIDES_${PN} = "lk-fw-utils"
DEPENDS += "mtd-utils"
3./build/local.conf,add these code
MENDER_ARTIFACT_NAME = "release-1"
INHERIT += "mender-full"
MACHINE = "aiv8183m1v2"
PREFERRED_VERSION_pn-mender = "1.0.%"
PREFERRED_VERSION_pn-mender-artifact = "1.0.%"
PREFERRED_VERSION_pn-mender-artifact-native = "1.0.%"
DISTRO_FEATURES_append = "systemd"
VIRTUAL-RUNTIME_init_manager = "systemed"
DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
VIRTUAL-RUNTIME_initscripts = ""
IMAGE_FSTYPES = "ext4"
4.execute bitbake-layers add-layer /meta/meta-mender/meta-mender-core
5.bitbake-layers create-layer meta-mylayer,in this layer,I mkdir -p /recipes-mender/mender/files, in directory mender,I touch mender_%.bbappend file as bellow:
FILESEXTARPATHS_prepend := "${THISDIR}/file:"
SRC_URI_append = "file://server.crt"
and put servert.crt in the the file directory.
6.in the mancine.conf(aiv8183m1v2.conf),I have added
PREFERRED_PROVIDER_u-boot-fw-utils = "lk-fw-utils"
PREFERRED_PROVIDER_u-boot = "lk"
IMAGE_INSTALL_append = "kernel-modules"
MENDER_STORAGE_DEVICE = "/dev/mmcblk0"
7./meta-mender/meta-mender-core/classes/mender-full.bbclass
MENDER_FEATURES_ENABLE_append_arm = ""
MENDER_FEATURES_ENABLE_append_aarch64 = ""
the result I expected is the linux can OTA over mender.
But,actual results is the project can't cross build.the log says:
DEBUG: Executing shell function soft_link_to_rootfs
| ln: target ‘mender.bmap’ is not a directory
| WARNING: /home/yewkui/yocto-linux/build/tmp/work/aiv8183m1v2-poky-linux/mtk-image-openmm-aiv/1.0-r0/temp/run.soft_link_to_rootfs.1347217:1 exit 1 from 'ln -nfs mtk-image-openmm-aiv-aiv8183m1v2-20181224064735.rootfs.ext4 mender mender.bmap /home/yewkui/yocto-linux/build/tmp/deploy/images/aiv8183m1v2/rootfs.ext4 mender mender.bmap'
| DEBUG: Python function do_rootfs finished
| ERROR: Function failed: soft_link_to_rootfs (log file is located at /home/yewkui/yocto-linux/build/tmp/work/aiv8183m1v2-poky-linux/mtk-image-openmm-aiv/1.0-r0/temp/log.do_rootfs.1347217)
ERROR: Task (/home/yewkui/yocto-linux/meta/poky/../meta-mediatek-mt8183/recipes-aiv/images/mtk-image-openmm-aiv.bb:do_rootfs) failed with exit code '1'
NOTE: Tasks Summary: Attempted 2392 tasks of which 2391 didn't need to be rerun and 1 failed.
NOTE: Writing buildhistory
Maybe I am wrong at first step,but how to realize the OTA by yocto base on MTK lk-bootloader,please help! thanks a lot!
this question is about cross compilation.
What kind of different targets are available using the -target or -target-cpu option of the swift compiler?
Where can I find an overview?
Is it only there to create iOS/watchOS apps or can I use it to create linux programs (regular x86-64 processor) on macOS?
I tried searching the github repository and found 'x86_64-unknown-linux-gnu' as a target. However when I try to compile a simple "hello world" program (swiftc -target x86_64-unknown-linux-gnu test.swift) I get this error:
<unknown>:0: error: unable to load standard library for target 'x86_64-unknown-linux-gnu'
Edit:
I agree with CristiFati. The last part of this question is rather about how to properly include/reference the glibc (?!?).
If you look at Swift repository on Github (Exact location: swift/utils/swift_build_support/swift_build_support/targets.py) You will see all host targets at line 149-192 in target.py.
Supports:
def host_target():
"""
Return the host target for the build machine, if it is one of
the recognized targets. Otherwise, throw a NotImplementedError.
"""
system = platform.system()
machine = platform.machine()
if system == 'Linux':
if machine == 'x86_64':
return StdlibDeploymentTarget.Linux.x86_64
elif machine.startswith('armv7'):
# linux-armv7* is canonicalized to 'linux-armv7'
return StdlibDeploymentTarget.Linux.armv7
elif machine.startswith('armv6'):
# linux-armv6* is canonicalized to 'linux-armv6'
return StdlibDeploymentTarget.Linux.armv6
elif machine == 'aarch64':
return StdlibDeploymentTarget.Linux.aarch64
elif machine == 'ppc64':
return StdlibDeploymentTarget.Linux.powerpc64
elif machine == 'ppc64le':
return StdlibDeploymentTarget.Linux.powerpc64le
elif machine == 's390x':
return StdlibDeploymentTarget.Linux.s390x
elif system == 'Darwin':
if machine == 'x86_64':
return StdlibDeploymentTarget.OSX.x86_64
elif system == 'FreeBSD':
if machine == 'amd64':
return StdlibDeploymentTarget.FreeBSD.x86_64
elif system == 'CYGWIN_NT-10.0':
if machine == 'x86_64':
return StdlibDeploymentTarget.Cygwin.x86_64
elif system == 'Windows':
if machine == "AMD64":
return StdlibDeploymentTarget.Windows.x86_64
raise NotImplementedError('System "%s" with architecture "%s" is not '
'supported' % (system, machine))
The Qt page does not list pre-compiled Qt 5 packages for Solaris. Searching around, it does not seem to be included in the popular package repository OpenCSW, either. Some google hits suggest that building Qt 5 under Solaris involves some work under Solaris 10.
Thus my question: How to build Qt 5.2 under Solaris 10?
Basically it is:
cd qt-everywhere-opensource-src-5.2.0
./configure -prefix $MY_PREFIX -opensource -confirm-license -nomake tests \
-R /opt/csw/lib/64 -R /opt/csw/X11/lib/64 -qt-xcb -platform solaris-g++-64 \
-verbose
gmake -j16
gmake -j16 install
plus some adjustments because Qt 5 does not seem to be used on
Solaris much, yet.
Adjustments
Obtain the source
wget http://download.qt-project.org/official_releases/qt/5.2/5.2.0/single/qt-everywhere-opensource-src-5.2.0.tar.gz
md5sum qt-everywhere-opensource-src-5.2.0.tar.gz
228b6384dfd7272de00fd8b2c144fecd qt-everywhere-opensource-src-5.2.0.tar.gz
If the system does not habe md5sum you can use openssl md5 filename instead.
Install dependencies
I recommend to use OpenCSW because we need some dependencies to build Qt. The most important ones are:
CSWlibxcbdevel
CSWlibicu-dev # soft-dependency
CSWgcc4g++
CSWgmake
I suggest to use GCC to compile Qt. I am not aware of any advantages using the C++ compiler from Solaris Studio. On the contrary, the level of C++/STL support of this compiler may be not sufficient for a lot of use cases.
Setup environment
Make sure that you environment is clean. That means that /opt/csw/bin comes first and no LD_LIBRAYR_PATH* variables are set.
To simplify things it is probably a good idea that some directories are removed from PATH. For example such that no cc, CC commands from a Solaris Studio installation are accidentally picked up (e.g. during the compile of a bundled 3rd party component.
Adjust the specs
The software under /usr/sfw is just too outdated. /opt/csw from OpenCSW is a better replacement. Then the X-Open version is not sufficient for some used system functions.
--- a/qtbase/mkspecs/solaris-g++-64/qmake.conf
+++ b/qtbase/mkspecs/solaris-g++-64/qmake.conf
## -35,7 +35,7 ## QMAKE_LEX = flex
QMAKE_LEXFLAGS =
QMAKE_YACC = yacc
QMAKE_YACCFLAGS = -d
-QMAKE_CFLAGS = -m64 -D_XOPEN_SOURCE=500 -D__EXTENSIONS__
+QMAKE_CFLAGS = -m64 -D_XOPEN_SOURCE=600 -D__EXTENSIONS__
QMAKE_CFLAGS_DEPS = -M
QMAKE_CFLAGS_WARN_ON = -Wall -W
QMAKE_CFLAGS_WARN_OFF = -w
## -58,8 +58,8 ## QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
-QMAKE_INCDIR = /usr/sfw/include
-QMAKE_LIBDIR = /usr/sfw/lib/64
+QMAKE_INCDIR = /opt/csw/include /opt/csw/X11/include
+QMAKE_LIBDIR = /opt/csw/lib/64 /opt/csw/X11/lib/64
QMAKE_INCDIR_X11 = /usr/openwin/include
QMAKE_LIBDIR_X11 = /usr/openwin/lib/64
QMAKE_INCDIR_OPENGL = /usr/openwin/include
Fix the shell
Solaris comes with a /bin/sh that violates POSIX to an extend such
that Qt's configure scripts and even shell-code in qmake-generated
code fails.
POSIX does not specify that /bin/sh has to be conforming it just specifies that the system must have a conforming shell available 'somewhere'. On Solaris it is e.g. under /usr/xpg4/bin/sh. The portable way to get a conforming shell is to search for it in the directories returned by getconf CS_PATH ...
Anyways, my choice for Solaris is to just use /usr/bin/bash:
Anyways, my choice for Solaris is to just use /usr/bin/bash:
--- a/configure
+++ b/configure
## -1,4 +1,4 ##
-#! /bin/sh
+#!/usr/bin/bash
#############################################################################
##
## Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
--- a/qtbase/configure
+++ b/qtbase/configure
## -1,4 +1,4 ##
-#!/bin/sh
+#!/usr/bin/bash
#############################################################################
##
## Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
## -6892,7 +6892,7 ## fi'`
echo "$CONFIG_STATUS" | grep '\-confirm\-license' >/dev/null 2>&1 || CONFIG_STATUS="$CONFIG_STATUS -confirm-license"
[ -f "$outpath/config.status" ] && rm -f "$outpath/config.status"
- echo "#!/bin/sh" > "$outpath/config.status"
+ echo "#!/usr/bin/bash" > "$outpath/config.status"
[ -n "$PKG_CONFIG_SYSROOT_DIR" ] && \
echo "export PKG_CONFIG_SYSROOT_DIR=$PKG_CONFIG_SYSROOT_DIR" >> "$outpath/config.status"
[ -n "$PKG_CONFIG_LIBDIR" ] && \
--- a/qtbase/qmake/generators/makefile.cpp
+++ b/qtbase/qmake/generators/makefile.cpp
## -2306,6 +2306,10 ## MakefileGenerator::writeHeader(QTextStream &t)
if (ofile.lastIndexOf(Option::dir_sep) != -1)
ofile.remove(0, ofile.lastIndexOf(Option::dir_sep) +1);
t << "MAKEFILE = " << ofile << endl << endl;
+
+ t << "# custom mod because Solaris /bin/sh is such a standard-violating choice\n"
+ << "# - gs, 2013-12-23" << endl;
+ t << "SHELL = /usr/bin/bash" << endl << endl;
}
QList<MakefileGenerator::SubTarget*>
Fix the ICU test
Solaris 10 comes with an outdated libicu - which is missing features Qt 5 needs. Thus, we simply extend the icu-test. Then either no ICU-support is build or proper one in case we install a recent libicu e.g. via OpenCSW.
--- a/qtbase/config.tests/unix/icu/icu.cpp
+++ b/qtbase/config.tests/unix/icu/icu.cpp
## -43,6 +43,16 ##
#include <unicode/ucol.h>
#include <unicode/ustring.h>
+// for testing if ucal_clone is there (i.e. if we have libicu >= 4.0)
+#include <unicode/ucal.h>
+
+static UCalendar *ucp(UCalendar *i)
+{
+ UErrorCode status = U_ZERO_ERROR;
+ UCalendar *r = ucal_clone(i, &status);
+ return r;
+}
+
int main(int, char **)
{
UErrorCode status = U_ZERO_ERROR;
## -50,5 +60,10 ## int main(int, char **)
if (U_FAILURE(status))
return 0;
ucol_close(collator);
+
+ UCalendar *cal = ucal_open(0, -1, "C", UCAL_GREGORIAN, &status);
+ UCalendar *x = ucp(cal);
+ ucal_close(x);
+
return 0;
}
Fix bundled pcre
Perhaps alternatively one can install a libpcre via OpenCSW.
--- a/qtbase/src/3rdparty/pcre/pcre_compile.c
+++ b/qtbase/src/3rdparty/pcre/pcre_compile.c
## -66,6 +66,8 ## COMPILE_PCREx macro will already be appropriately set. */
#endif
+#include <stdint.h>
+
/* Macro for setting individual bits in class bitmaps. */
#define SETBIT(a,b) a[(b)/8] |= (1 << ((b)&7))
Fix sha3
At least on Solaris 10/Sparc the functions fromBytesToWord and fromWordtoBytes are used by the code, thus:
--- a/qtbase/src/3rdparty/sha3/KeccakF-1600-opt64.c
+++ b/qtbase/src/3rdparty/sha3/KeccakF-1600-opt64.c
## -324,7 +324,7 ## static void KeccakPermutation(unsigned char *state)
KeccakPermutationOnWords((UINT64*)state);
}
-#if 0 // Unused in the Qt configuration
+#if 1 // Unused in the Qt configuration
static void fromBytesToWord(UINT64 *word, const UINT8 *bytes)
{
unsigned int i;
## -445,7 +445,7 ## static void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsign
#endif
}
-#if 0 // Unused in the Qt configuration
+#if 1 // Unused in the Qt configuration
static void fromWordToBytes(UINT8 *bytes, const UINT64 word)
{
unsigned int i;
Include/type/usage fixes
The uname() function is activated via a CPP construct on Solaris
and is declared in that header:
--- a/qtbase/src/corelib/io/qfileselector.cpp
+++ b/qtbase/src/corelib/io/qfileselector.cpp
## -51,6 +51,8 ##
#include <QtCore/QLocale>
#include <QtCore/QDebug>
+#include <sys/utsname.h>
+
QT_BEGIN_NAMESPACE
//Environment variable to allow tooling full control of file selectors
Under Solaris parent is unused in that code-path and the code gets compiled with -Werror ...
--- a/qtbase/src/corelib/io/qfilesystemwatcher.cpp
+++ b/qtbase/src/corelib/io/qfilesystemwatcher.cpp
## -77,6 +77,7 ## QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine(QObject
#elif defined(Q_OS_FREEBSD) || defined(Q_OS_MAC)
return QKqueueFileSystemWatcherEngine::create(parent);
#else
+ (void)parent;
return 0;
#endif
}
Under Solaris uid_t has an 'unexpected' sign (-> Werror). Casting it to ssize_t should be a portable and safe choice:
--- a/qtbase/src/corelib/io/qstandardpaths_unix.cpp
+++ b/qtbase/src/corelib/io/qstandardpaths_unix.cpp
## -132,7 +132,7 ## QString QStandardPaths::writableLocation(StandardLocation type)
}
// "The directory MUST be owned by the user"
QFileInfo fileInfo(xdgRuntimeDir);
- if (fileInfo.ownerId() != myUid) {
+ if (fileInfo.ownerId() != ssize_t(myUid)) {
qWarning("QStandardPaths: wrong ownership on runtime directory %s, %d instead of %d", qPrintable(xdgRuntimeDir),
fileInfo.ownerId(), myUid);
return QString();
Similar issue with threading code (Werror because of sign-mismatch in pointer cast). Casting to size_t should be a portable safe choice:
--- a/qtbase/src/corelib/thread/qthread_unix.cpp
+++ b/qtbase/src/corelib/thread/qthread_unix.cpp
## -231,7 +231,7 ## QThreadData *QThreadData::current()
}
data->deref();
data->isAdopted = true;
- data->threadId = (Qt::HANDLE)pthread_self();
+ data->threadId = (Qt::HANDLE)((size_t)pthread_self());
if (!QCoreApplicationPrivate::theMainThread)
QCoreApplicationPrivate::theMainThread = data->thread;
}
## -314,7 +314,7 ## void *QThreadPrivate::start(void *arg)
thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag));
}
- data->threadId = (Qt::HANDLE)pthread_self();
+ data->threadId = (Qt::HANDLE)((size_t)pthread_self());
set_thread_data(data);
data->ref();
## -393,7 +393,7 ## void QThreadPrivate::finish(void *arg)
Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW
{
// requires a C cast here otherwise we run into trouble on AIX
- return (Qt::HANDLE)pthread_self();
+ return (Qt::HANDLE)((size_t)pthread_self());
}
#if defined(QT_LINUXBASE) && !defined(_SC_NPROCESSORS_ONLN)
The struct in_addr has a struct as first attribute on Solaris, thus gives a warning with GCC when initializing with {0} - thus, yields an error during Qt-compile:
--- a/qtbase/src/network/socket/qnativesocketengine_unix.cpp
+++ b/qtbase/src/network/socket/qnativesocketengine_unix.cpp
## -63,6 +63,7 ##
#endif
#include <netinet/tcp.h>
+#include <string.h>
QT_BEGIN_NAMESPACE
## -737,7 +738,8 ## QNetworkInterface QNativeSocketEnginePrivate::nativeMulticastInterface() const
return QNetworkInterface::interfaceFromIndex(v);
}
- struct in_addr v = { 0 };
+ struct in_addr v;
+ memset(&v, 0, sizeof(struct in_addr));
QT_SOCKOPTLEN_T sizeofv = sizeof(v);
if (::getsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, &v, &sizeofv) == -1)
return QNetworkInterface();
The header comment of X11/Xutil.h lists X11/Xutil.h as dependency, and indeed, without that include some declarations are missing under Solaris.
--- a/qtbase/src/plugins/platforms/xcb/qxcbmime.cpp
+++ b/qtbase/src/plugins/platforms/xcb/qxcbmime.cpp
## -46,6 +46,7 ##
#include <QtCore/QBuffer>
#include <qdebug.h>
+#include <X11/Xlib.h>
#include <X11/Xutil.h>
#undef XCB_ATOM_STRING
The X11/extensions/XIproto.h is not C++-safe under Solaris. That means it contains struct members names class. Fortunately, the header does not seem to be used in that code.
--- a/qtbase/src/plugins/platforms/xcb/qxcbxsettings.cpp
+++ b/qtbase/src/plugins/platforms/xcb/qxcbxsettings.cpp
## -43,7 +43,7 ##
#include <QtCore/QByteArray>
-#include <X11/extensions/XIproto.h>
+//#include <X11/extensions/XIproto.h>
QT_BEGIN_NAMESPACE
/* Implementation of http://standards.freedesktop.org/xsettings-spec/xsettings-0.5.html */
The pow() function has some overloads as specified in the C++ standard which introduce ambiguities under Solaris. Fixing the types like this should be portable and safe:
--- a/qtdeclarative/src/qml/jsruntime/qv4globalobject.cpp
+++ b/qtdeclarative/src/qml/jsruntime/qv4globalobject.cpp
## -534,7 +534,7 ## ReturnedValue GlobalFunctions::method_parseInt(CallContext *ctx)
}
if (overflow) {
- double result = (double) v_overflow * pow(R, overflow_digit_count);
+ double result = (double) v_overflow * pow(double(R), int(overflow_digit_count));
result += v;
return Encode(sign * result);
} else {
Under Solaris, alloca needs another header:
--- a/qtdeclarative/src/qml/jsruntime/qv4stringobject.cpp
+++ b/qtdeclarative/src/qml/jsruntime/qv4stringobject.cpp
## -73,6 +73,11 ##
# include <windows.h>
#endif
+
+#if OS(SOLARIS)
+#include <alloca.h>
+#endif
+
using namespace QV4;
DEFINE_MANAGED_VTABLE(StringObject);
Fix deep mkdir
Qt does a 'deep' mkdir() (e.g. something like mkdir -p for e.g. creating a directory hierarchy, e.g. ~/.config/company/product. The Qt 5.2 algorithm may abort too soon on Solaris if an existing directory is located inside a non-writable NFS mounted parent - because in that case Solaris returns EACCESS instead of EEXIST.
--- a/qtbase/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/qtbase/src/corelib/io/qfilesystemengine_unix.cpp
## -579,6 +579,11 ## bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool crea
// on the QNet mountpoint returns successfully and reports S_IFDIR.
|| errno == ENOENT
#endif
+#if defined(Q_OS_SOLARIS)
+ // On Solaris 10, mkdir returns EACCESS on a directory which exists
+ // inside an NFS mount ...
+ || errno == EACCES
+#endif
) {
QT_STATBUF st;
if (QT_STAT(chunk.constData(), &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR)
Temporary files
Solaris also does not have mkdtemp():
--- a/qtbase/src/corelib/io/qtemporarydir.cpp
+++ b/qtbase/src/corelib/io/qtemporarydir.cpp
## -52,7 +52,7 ##
#endif
#include <stdlib.h> // mkdtemp
-#if defined(Q_OS_QNX) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID)
+#if defined(Q_OS_QNX) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID) || defined(Q_OS_SOLARIS)
#include <private/qfilesystemengine_p.h>
#endif
## -96,7 +96,7 ## static QString defaultTemplateName()
static char *q_mkdtemp(char *templateName)
{
-#if defined(Q_OS_QNX ) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID)
+#if defined(Q_OS_QNX ) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID) || defined(Q_OS_SOLARIS)
static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
const size_t length = strlen(templateName);
Pthreads
Solaris does not have pthread_get_stacksize_np (the _np suffix stands for non-portable).
Solaris has another function for getting stack-address/size values. My attempt:
--- a/qtdeclarative/src/qml/jsruntime/qv4engine.cpp
+++ b/qtdeclarative/src/qml/jsruntime/qv4engine.cpp
## -73,6 +73,11 ##
#include "qv4isel_moth_p.h"
#if USE(PTHREADS)
+
+#if OS(SOLARIS)
+#include <thread.h>
+#endif
+
# include <pthread.h>
#endif
## -103,6 +108,11 ## quintptr getStackLimit()
} else
size = pthread_get_stacksize_np(thread_self);
stackLimit -= size;
+# elif OS(SOLARIS)
+ stack_t ss;
+ int r = thr_stksegment(&ss);
+ (void)r;
+ stackLimit = reinterpret_cast<quintptr>(ss.ss_sp);
# else
void* stackBottom = 0;
pthread_attr_t attr;
--- a/qtdeclarative/src/qml/jsruntime/qv4mm.cpp
+++ b/qtdeclarative/src/qml/jsruntime/qv4mm.cpp
## -67,6 +67,11 ##
#include <sys/storage.h> // __tls()
#endif
+#if OS(SOLARIS)
+#include <thread.h>
+#include <pthread.h>
+#endif
+
QT_BEGIN_NAMESPACE
using namespace QV4;
## -218,6 +223,11 ## MemoryManager::MemoryManager()
# if OS(DARWIN)
void *st = pthread_get_stackaddr_np(pthread_self());
m_d->stackTop = static_cast<quintptr *>(st);
+# elif OS(SOLARIS)
+ stack_t ss;
+ int r = thr_stksegment(&ss);
+ (void)r;
+ m_d->stackTop = static_cast<quintptr *>(ss.ss_sp) + ss.ss_size/sizeof(quintptr);
# else
void* stackBottom = 0;
pthread_attr_t attr;
I recommend a careful review of that code because my Qt-code does not use that Qt-module, thus, I did not test it much.
XKB extension
Qt 5 seems to heavily rely on the XKB extension. It seems that you can't build Qt 5 without XKB support. It comes bundled with xkbcommon.
First, make sure that it finds the right XKB database. Otherwise keyboard input does not work at all in your Qt programs!
Solaris does not have the default value /usr/share/X11/xkb. It has instead:
/usr/X11/lib/X11/xkb
/usr/openwin/lib/X11/xkb
But I havn't had luck with those - xkbcommon simply could not find any components with those.
I ended up with copying /usr/share/X11/xkb from a cygwin distribution to a custom path and configuring that as XKB database.
Whatever XKB you choose you have to configure it:
--- a/qtbase/src/3rdparty/xkbcommon.pri
+++ b/qtbase/src/3rdparty/xkbcommon.pri
## -1,7 +1,12 ##
QMAKE_CFLAGS += -std=gnu99 -w
INCLUDEPATH += $$PWD/xkbcommon $$PWD/xkbcommon/src $$PWD/xkbcommon/src/xkbcomp
+solaris-g++-64 {
+DEFINES += DFLT_XKB_CONFIG_ROOT='\\"/MY/XKB/CHOICE\\"'
+} else {
DEFINES += DFLT_XKB_CONFIG_ROOT='\\"/usr/share/X11/xkb\\"'
+}
### RMLVO names can be overwritten with environmental variables (See libxkbcommon documentation)
DEFINES += DEFAULT_XKB_RULES='\\"evdev\\"'
For testing it also make sense to check for NULL values in error message parameters:
--- a/qtbase/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c
+++ b/qtbase/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c
## -68,8 +68,11 ## text_v1_keymap_new_from_names(struct xkb_keymap *keymap,
log_err(keymap->ctx,
"Couldn't look up rules '%s', model '%s', layout '%s', "
"variant '%s', options '%s'\n",
- rmlvo->rules, rmlvo->model, rmlvo->layout, rmlvo->variant,
- rmlvo->options);
+ rmlvo->rules, rmlvo->model,
+ rmlvo->layout ? rmlvo->layout : "(NULL)",
+ rmlvo->variant ? rmlvo->variant : "(NULL)",
+ rmlvo->options ? rmlvo->options : "(NULL)"
+ );
return false;
}
There is also the possibility that your XServer does not even support the XKB extension. Again, I don't know if Qt 5 can be configured with disabled-XKB-support under X.
You can check your X-server like this:
xprop -root | grep xkb
Or call a random xkb-program, e.g.:
xkbvleds
Such call should not result in an error like:
Fatal Error: Server doesn't support a compatible XKB
In case your XServer does not have XKB - Qt programs are likely to segfault. Qt does not seem to really check for XKB support. It does not seem to have a fallback mechanism when XKB is not usable.
Examples
Some examples fail because of module quick not being found:
--- a/qtconnectivity/examples/bluetooth/scanner/scanner.pro
+++ b/qtconnectivity/examples/bluetooth/scanner/scanner.pro
## -1,4 +1,4 ##
-QT = core bluetooth quick
+QT = core bluetooth # quick
SOURCES += qmlscanner.cpp
TARGET = qml_scanner
diff --git a/qtconnectivity/examples/nfc/poster/poster.pro b/qtconnectivity/examples/nfc/poster/poster.pro
index d108b2a..d0d0659 100644
--- a/qtconnectivity/examples/nfc/poster/poster.pro
+++ b/qtconnectivity/examples/nfc/poster/poster.pro
## -1,4 +1,4 ##
-QT += qml quick network nfc widgets
+QT += qml network nfc widgets # quick
SOURCES += \
qmlposter.cpp
They are also built without.
make install
A gmake install surprisingly triggers the compilation of several modules not yet compiled. Thus it make sense to execute it in parallel:
$ gmake -j16 install
(assuming that your system has a sufficient number of cores)
QtHelp
The bundled QtHelp module is not build/installed with the main compile/install steps.
To fix that:
cd qttools
PATH=$MY_PREFIX/bin:$PATH qmake
gmake
gmake install
Open issues
when using a remote Cygwin-X connection some colors are weird - e.g. the standard widget-gray is some light-light-blue - any ideas where to start to look for that?
QtSVG is successfully built but displaying a small SVG (e.g. inside a QLabel) hangs the dialog - a truss -u : shows function calls inside libm/QtWidget - perhaps the system is just way too slow and/or some code-path is not optimized on Solaris/in combination with a X-forwarding over ssh
a Qt-Program prints on startup: Qt Warning: Could not find a location of the system's Compose files. Consider setting the QTCOMPOSE environment variable. - no idea what feature this is about
Conclusion
With those adjustments 'normal' Qt programs (without QtSvg) compile
and run fine under Solaris 10.