pax_global_header 0000666 0000000 0000000 00000000064 14742171435 0014522 g ustar 00root root 0000000 0000000 52 comment=ad7344c45a86a4f66cbafc4b081b5f7b876cb0b7
qtkeychain-0.15.0/ 0000775 0000000 0000000 00000000000 14742171435 0013745 5 ustar 00root root 0000000 0000000 qtkeychain-0.15.0/.gitignore 0000664 0000000 0000000 00000002674 14742171435 0015746 0 ustar 00root root 0000000 0000000 # This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash
# qtcreator generated files
*.pro.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
*.dll
*.exe
#CMake files
CMakeCache.txt
CMakeFiles
CMakeScripts
cmake_install.cmake
#Keychain temporary files
Qt5KeychainBuildTreeSettings.cmake
Qt5KeychainConfig.cmake
Qt5KeychainConfigVersion.cmake
QtKeychainBuildTreeSettings.cmake
QtKeychainConfig.cmake
QtKeychainConfigVersion.cmake
kwallet_interface.cpp
kwallet_interface.h
kwallet_interface.moc
moc_keychain.*
moc_keychain_p.*
moc_gnomekeyring_p.*
qkeychain_export.h
qt_Qt5Keychain.pri
#Qt files
*_parameters
*.qm
#General build files
Debug
Release
Makefile
#Linux build files
libqt5keychain.*
testclient
#Windows build files
install_manifest.txt
*.manifest
*.lib
#Mac build files
qtkeychain.xcodeproj
qtkeychain.build
#Temporary files
*.sw?
/build-*/
/compile_commands.json
qtkeychain-0.15.0/CMakeLists.txt 0000664 0000000 0000000 00000017437 14742171435 0016521 0 ustar 00root root 0000000 0000000 cmake_minimum_required(VERSION 3.16)
set(QTKEYCHAIN_VERSION 0.15.0)
set(QTKEYCHAIN_SOVERSION 1)
project(qtkeychain VERSION ${QTKEYCHAIN_VERSION} LANGUAGES CXX)
# Enable C++11
SET(CMAKE_CXX_STANDARD 11)
include(FindPkgConfig)
###
# write binaries and libraries into a shared folder, this simplifies the execution of tests on Windows
# see https://github.com/KDE/extra-cmake-modules/blob/b3a13868f7f54ab0b7ac19fd26b6dfead8907d25/kde-modules/KDECMakeSettings.cmake#L256C1-L258C69
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/Modules")
include(GNUInstallDirs)
include(GenerateExportHeader)
include(CMakePackageConfigHelpers)
include(ECMSetupVersion)
include(ECMGeneratePriFile)
include(CMakeDependentOption)
option(BUILD_WITH_QT6 "Build qtkeychain with Qt 6" OFF)
option(BUILD_TEST_APPLICATION "Build test application" OFF)
option(BUILD_TRANSLATIONS "Build translations" ON)
option(BUILD_SHARED_LIBS "Build dynamic library" ON)
if(QTKEYCHAIN_STATIC)
set(BUILD_SHARED_LIBS OFF)
message(WARNING "QTKEYCHAIN_STATIC is deprecated. Use BUILD_SHARED_LIBS=OFF instead.")
endif()
CMAKE_DEPENDENT_OPTION(BUILD_TRANSLATIONS_AS_RESOURCES "Bundle translations with the library" OFF
"BUILD_TRANSLATIONS" OFF)
if(CMAKE_SYSTEM_NAME STREQUAL Android)
set(ANDROID 1)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL Haiku)
set(HAIKU 1)
endif()
if (WIN32)
option(USE_CREDENTIAL_STORE "Build with windows CredentialStore support" ON)
if (USE_CREDENTIAL_STORE)
add_definitions(-DUSE_CREDENTIAL_STORE=1)
endif()
endif()
if( NOT BUILD_WITH_QT6 )
find_package(Qt5 COMPONENTS Core REQUIRED)
endif()
if (Qt5Core_FOUND AND NOT BUILD_WITH_QT6)
set(QTKEYCHAIN_VERSION_INFIX 5)
if(ANDROID)
if(Qt5Core_VERSION VERSION_LESS 5.7)
find_package(Qt5 COMPONENTS Core REQUIRED Private)
include_directories(${Qt5Core_PRIVATE_INCLUDE_DIRS})
endif()
find_package(Qt5 COMPONENTS AndroidExtras REQUIRED)
include_directories(${Qt5AndroidExtras_INCLUDE_DIRS})
set(QTANDROIDEXTRAS_LIBRARIES ${Qt5AndroidExtras_LIBRARIES})
endif()
if(UNIX AND NOT APPLE AND NOT ANDROID AND NOT HAIKU)
find_package(Qt5 COMPONENTS DBus REQUIRED)
include_directories(${Qt5DBus_INCLUDE_DIRS})
set(QTDBUS_LIBRARIES ${Qt5DBus_LIBRARIES})
macro(qt_add_dbus_interface)
qt5_add_dbus_interface(${ARGN})
endmacro()
endif()
if(BUILD_TRANSLATIONS)
find_package(Qt5 COMPONENTS LinguistTools REQUIRED)
macro(qt_add_translation)
qt5_add_translation(${ARGN})
endmacro(qt_add_translation)
macro(qt_create_translation)
qt5_create_translation(${ARGN})
endmacro(qt_create_translation)
endif()
macro(qt_wrap_cpp)
qt5_wrap_cpp(${ARGN})
endmacro()
set(QTCORE_LIBRARIES ${Qt5Core_LIBRARIES})
include_directories(${Qt5Core_INCLUDE_DIRS})
else()
find_package(Qt6 COMPONENTS Core REQUIRED)
set(QTKEYCHAIN_VERSION_INFIX 6)
if(UNIX AND NOT APPLE AND NOT ANDROID AND NOT HAIKU)
find_package(Qt6 COMPONENTS DBus REQUIRED)
include_directories(${Qt6DBus_INCLUDE_DIRS})
set(QTDBUS_LIBRARIES ${Qt6DBus_LIBRARIES})
macro(qt_add_dbus_interface)
qt6_add_dbus_interface(${ARGN})
endmacro()
endif()
if(BUILD_TRANSLATIONS)
find_package(Qt6 COMPONENTS LinguistTools REQUIRED)
macro(qt_add_translation)
qt6_add_translation(${ARGN})
endmacro(qt_add_translation)
macro(qt_create_translation)
qt6_create_translation(${ARGN})
endmacro(qt_create_translation)
endif()
macro(qt_wrap_cpp)
qt6_wrap_cpp(${ARGN})
endmacro()
set(QTCORE_LIBRARIES ${Qt6Core_LIBRARIES})
endif()
set(QTKEYCHAIN_TARGET_NAME qt${QTKEYCHAIN_VERSION_INFIX}keychain)
add_subdirectory(qtkeychain)
###
### Translations
###
set(qtkeychain_TR_FILES
translations/qtkeychain_de.ts
translations/qtkeychain_fr.ts
translations/qtkeychain_ro.ts
translations/qtkeychain_ru.ts
translations/qtkeychain_zh.ts
)
file(GLOB qtkeychain_TR_SOURCES qtkeychain/*.cpp qtkeychain/*.h qtkeychain/*.ui)
if ( BUILD_TRANSLATIONS )
qt_create_translation(qtkeychain_MESSAGES ${qtkeychain_TR_SOURCES} ${qtkeychain_TR_FILES})
qt_add_translation(qtkeychain_QM_FILES ${qtkeychain_TR_FILES})
add_custom_target(messages DEPENDS ${qtkeychain_MESSAGES})
add_custom_target(translations DEPENDS ${qtkeychain_QM_FILES} messages)
# https://github.com/frankosterfeld/qtkeychain/issues/185
add_dependencies(${QTKEYCHAIN_TARGET_NAME} translations)
if (BUILD_TRANSLATIONS_AS_RESOURCES)
set(QM_FILE_LIST "")
foreach(FILE ${qtkeychain_QM_FILES})
list(APPEND QM_FILE_LIST "${FILE}")
endforeach()
string(REPLACE ";" "" QM_FILE_LIST ${QM_FILE_LIST})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/translations/translations.qrc.in ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc)
target_sources(${QTKEYCHAIN_TARGET_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc)
else()
if(QTKEYCHAIN_VERSION_INFIX EQUAL 5 AND QT_TRANSLATIONS_DIR AND NOT QTKEYCHAIN_TRANSLATIONS_DIR)
# Back compatibility with pre-0.11 versions
message (WARNING "QT_TRANSLATIONS_DIR is deprecated, use QTKEYCHAIN_TRANSLATIONS_DIR instead")
set(QTKEYCHAIN_TRANSLATIONS_DIR ${QT_TRANSLATIONS_DIR}
CACHE PATH "The location of the QtKeychain translations" FORCE)
else()
set(QTKEYCHAIN_TRANSLATIONS_DIR
${CMAKE_INSTALL_DATADIR}/qt${QTKEYCHAIN_VERSION_INFIX}keychain/translations
CACHE PATH "The location of the QtKeychain translations" )
endif()
install(FILES ${qtkeychain_QM_FILES} DESTINATION ${QTKEYCHAIN_TRANSLATIONS_DIR})
endif()
endif( BUILD_TRANSLATIONS )
###
### Test application ("testclient")
###
if(BUILD_TEST_APPLICATION)
set( testclient_LIBRARIES ${QTKEYCHAIN_TARGET_NAME} )
if(APPLE)
list(APPEND testclient_LIBRARIES "-framework Cocoa")
if (BUILD_WITH_QT6)
find_package(Qt6 COMPONENTS Gui REQUIRED)
list(APPEND testclient_LIBRARIES Qt6::Gui)
else()
find_package(Qt5 COMPONENTS Gui REQUIRED)
list(APPEND testclient_LIBRARIES Qt5::Gui)
endif()
endif()
add_executable( testclient testclient.cpp )
target_link_libraries( testclient ${testclient_LIBRARIES})
endif()
include(CTest)
if(BUILD_TESTING)
add_subdirectory(autotest)
endif()
###
### CMake config file
###
configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/QtKeychainConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/Qt${QTKEYCHAIN_VERSION_INFIX}KeychainConfig.cmake"
INSTALL_DESTINATION Qt${QTKEYCHAIN_VERSION_INFIX}Keychain)
ecm_setup_version("${QTKEYCHAIN_VERSION}" VARIABLE_PREFIX SNORE
PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/Qt${QTKEYCHAIN_VERSION_INFIX}KeychainConfigVersion.cmake"
SOVERSION ${QTKEYCHAIN_VERSION})
if(UNIX AND NOT APPLE AND NOT ANDROID AND NOT HAIKU)
set(PRI_EXTRA_DEPS "dbus")
endif()
ecm_generate_pri_file(BASE_NAME Qt${QTKEYCHAIN_VERSION_INFIX}Keychain
LIB_NAME ${QTKEYCHAIN_TARGET_NAME}
DEPS "core ${PRI_EXTRA_DEPS}"
INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}
FILENAME_VAR pri_filename)
install(FILES ${pri_filename} DESTINATION ${ECM_MKSPECS_INSTALL_DIR})
install(EXPORT Qt${QTKEYCHAIN_VERSION_INFIX}KeychainLibraryDepends
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Qt${QTKEYCHAIN_VERSION_INFIX}Keychain"
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Qt${QTKEYCHAIN_VERSION_INFIX}KeychainConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/Qt${QTKEYCHAIN_VERSION_INFIX}KeychainConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Qt${QTKEYCHAIN_VERSION_INFIX}Keychain
)
qtkeychain-0.15.0/COPYING 0000664 0000000 0000000 00000002475 14742171435 0015010 0 ustar 00root root 0000000 0000000 Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
qtkeychain-0.15.0/ChangeLog 0000664 0000000 0000000 00000012120 14742171435 0015513 0 ustar 00root root 0000000 0000000 ChangeLog
=========
version 0.15.0 (release 2025-01-16)
- Windows: Increase size of possible payloads (Hannah von Reth )
- KWallet: Increase timeout when opening wallet (David Faure )
- Haiku: Fix reading passwords (Joshua Goins )
- Add unit tests (Hannah von Reth )
- Windows build fixes (Nerixyz )
- Fix translation creation (Christophe Marin )
version 0.14.3 (release 2024-05-03)
- Fix Android build for Qt 6.7 (Volker Krause )
version 0.14.2 (release 2023-12-17)
- Add support for KWallet 6 (Volker Krause )
version 0.14.1 (release 2023-06-01)
- Export QKeychain::isAvailable() to make it usable in a shared build (Volker Krause )
- Protect against creating the QtKeychain::QtKeychain alias target twice (Volker Krause )
version 0.14.0 (release 2023-05-12)
- Add Qt 6 Android support (Igor Bugaev )
- Add QtQuick client example ((Igor Bugaev )
- Added Dutch translation (Heimen Stoffels )
- Fix potential freezing with Apple keychain (Claudio Cambra )
- Add API to check whether a secure backend is available at all (Volker Krause )
version 0.13.2 (release 2021-11-18)
- CMake: Deprecate QTKEYCHAIN_STATIC in favor of BUILD_SHARED_LIBS (be@mixxx.org)
version 0.13.1 (release 2021-11-08)
- KWallet: Fix deletion of entries (Issue #199)
version 0.13.0 (release 2021-11-07)
- Linux: Require libsecret if not explicitly disabled
- Unify implementations for macOS and iOS
- CMake: lots of fixes
version 0.12.0 (release 2020-12-16)
* Add Qt 6 support, drop Qt 4 support
* Require C++11
* Add Android support (Mathias Hasselmann)
version 0.11.1 (release 2020-09-08)
* Build system fixes
version 0.11.0 (release 2020-09-08)
* Important: Debug builds on Windows now get the "d" suffix
* Various build system fixes
* Add Haiku support (François Revol )
* Translation: Russian (Alexander Gorishnyak )
* Translation: Update French (David Geiger )
version 0.10.0 (release 2019-12-17)
* Detect XFCE desktop correctly. (Sandro Knauß )
* Windows Use CRED_PERSIST_ENTERPRISE (Olivier Goffart )
* Windows: Improve CredWrite() error handling (Christian Kamm )
* Fix build with Qt 5.12.x (Sergey Ilinykh )
* Fix Qt 4 build (Robert-André Mauchin )
* Translation: Mandarin (Taiwan) (Poren Chiang )
* Translation: French (François Revol )
version 0.9.1 (release 2018-08-20)
* Windows Credential Store: Use CRED_PERSIST_ENTERPRISE (Olivier Goffart )
* Secret: Don't match the schema name #114 (Christian Kamm )
* Fix qmake build on Windows (Alexander Gorishnyak )
version 0.9.0 (release 2018-07-13)
* Fall back on libsecret if kwallet is not available (Christian Kamm )
* Only require QtLinguist if building translations (Victor Kropp )
* Fix building on Windows without credential store (Dmitry Ivanov )
* Fix Qt 4 build (Sandro Knauß )
* Make build of test application optional (Boris Pek )
version 0.8.0 (release 2017-04-19)
* Buildsystem improvements (Kristofer Tingdahl , Hannah von Reth , Giuseppe D'Angelo )
* Enable C++11 support for Qt >= 5.7 (Dmitry Ivanov )
* Doxygen documentation ( Elvis Angelaccio )
* Libsecret support (Armin Novak )
* iOS support (Mathias Hasselmann )
version 0.7.0 (release 2016-05-23)
* Bump SO version due to 0.6 being binary-incompatible to previous releases
version 0.6.2 (release 2016-04-04)
* KWallet: Fixes a crash when storing passwords, seen on Debian/KDE4
version 0.6.1 (release 2016-03-31)
* Fix KWallet not working (regressions in 0.6.0)
version 0.6.0 (release 2016-03-18)
* Added support for the Windows Credential Store
version 0.5.0 (release 2015-05-04)
* Added support for KWallet5 (KDE5/KF)
version 0.4.0 (release 2014-09-01)
* KWallet: Handle case where no wallet exists yet (Liviu Cristian Mirea Ghiban )
* Improved desktop environment detection at runtime (Daniel Molkentin )
version 0.3.0 (release 2014-03-13)
* Gnome Keyring supported added (Francois Ferrand )
* Improved Qt 5 support
* KWallet: Distinguish empty passwords from non-existing entries
* KWallet: Do not use hardcoded wallet name
* German translation (Daniel Molkentin )
* Romanian translation (Arthur Țițeică )
version 0.2.0: no official release
version 0.1.0 (release 2013-01-16)
* Initial release
qtkeychain-0.15.0/QtKeychainConfig.cmake.in 0000664 0000000 0000000 00000002151 14742171435 0020541 0 ustar 00root root 0000000 0000000 # - Config file for the QtKeychain package
# It defines the following variables
# QTKEYCHAIN_INCLUDE_DIRS - include directories for QtKeychain
# QTKEYCHAIN_LIBRARIES - libraries to link against
# as well as the following imported targets
# qt5keychain / qt6keychain
# Qt5Keychain::Qt5Keychain / Qt6Keychain::Qt6Keychain
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/Qt@QTKEYCHAIN_VERSION_INFIX@KeychainLibraryDepends.cmake")
include(CMakeFindDependencyMacro)
find_dependency(Qt@QTKEYCHAIN_VERSION_INFIX@Core)
if(UNIX AND NOT APPLE AND NOT ANDROID)
find_dependency(Qt@QTKEYCHAIN_VERSION_INFIX@DBus)
endif()
set(QTKEYCHAIN_LIBRARIES "@QTKEYCHAIN_TARGET_NAME@")
get_target_property(QTKEYCHAIN_INCLUDE_DIRS "@QTKEYCHAIN_TARGET_NAME@" INTERFACE_INCLUDE_DIRECTORIES)
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.18.0 AND NOT TARGET Qt@QTKEYCHAIN_VERSION_INFIX@Keychain::Qt@QTKEYCHAIN_VERSION_INFIX@Keychain)
add_library(Qt@QTKEYCHAIN_VERSION_INFIX@Keychain::Qt@QTKEYCHAIN_VERSION_INFIX@Keychain ALIAS qt@QTKEYCHAIN_VERSION_INFIX@keychain)
endif()
check_required_components(Qt@QTKEYCHAIN_VERSION_INFIX@Keychain)
qtkeychain-0.15.0/ReadMe.md 0000664 0000000 0000000 00000002657 14742171435 0015436 0 ustar 00root root 0000000 0000000 QtKeychain
==========
QtKeychain is a Qt API to store passwords and other secret data securely. How the data is stored depends on the platform:
* **macOS:** Passwords are stored in the macOS Keychain.
* **Linux/Unix:** If running, GNOME Keyring is used, otherwise QtKeychain tries to use KWallet (via D-Bus), if available. Libsecret (common API for desktop-specific solutions)
is also supported.
* **Windows:** By default, the Windows Credential Store is used (requires Windows 7 or newer).
Pass `-DUSE_CREDENTIAL_STORE=OFF` to cmake to disable it. If disabled, QtKeychain uses the Windows API function
[CryptProtectData](http://msdn.microsoft.com/en-us/library/windows/desktop/aa380261%28v=vs.85%29.aspx "CryptProtectData function")
to encrypt the password with the user's logon credentials. The encrypted data is then persisted via QSettings.
* **Android and iOS:** Passwords are stored in the Android keystore system and iOS keychain, respectively.
In unsupported environments QtKeychain will report an error. It will not store any data unencrypted unless explicitly requested (`setInsecureFallback( true )`).
Requirements
------------
QtKeychain 0.12 and newer supports Qt 5 and Qt 6 and requires a compiler with C++11 support. Older versions support Qt 4 and Qt 5.
License
-------
QtKeychain is available under the [Modified BSD License](http://www.gnu.org/licenses/license-list.html#ModifiedBSD). See the file COPYING for details.
qtkeychain-0.15.0/TestAppExample/ 0000775 0000000 0000000 00000000000 14742171435 0016641 5 ustar 00root root 0000000 0000000 qtkeychain-0.15.0/TestAppExample/.gitignore 0000664 0000000 0000000 00000001345 14742171435 0020634 0 ustar 00root root 0000000 0000000 # This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash
# qtcreator generated files
*.pro.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
*.dll
*.exe
qtkeychain-0.15.0/TestAppExample/TestAppExample.pro 0000664 0000000 0000000 00000001405 14742171435 0022257 0 ustar 00root root 0000000 0000000 QT += quick
CONFIG += c++11
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
include(../qtkeychain.pri)
SOURCES += \
keychainclass.cpp \
main.cpp
RESOURCES += qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
HEADERS += \
keychainclass.h
qtkeychain-0.15.0/TestAppExample/keychainclass.cpp 0000664 0000000 0000000 00000003534 14742171435 0022173 0 ustar 00root root 0000000 0000000 #include
#include "keychainclass.h"
KeyChainClass::KeyChainClass(QObject* parent) :
QObject(parent),
m_readCredentialJob(QLatin1String("keychain.example.project.app")),
m_writeCredentialJob(QLatin1String("keychain.example.project.app")),
m_deleteCredentialJob(QLatin1String("keychain.example.project.app"))
{
m_readCredentialJob.setAutoDelete(false);
m_writeCredentialJob.setAutoDelete(false);
m_deleteCredentialJob.setAutoDelete(false);
}
void KeyChainClass::readKey(const QString &key)
{
m_readCredentialJob.setKey(key);
QObject::connect(&m_readCredentialJob, &QKeychain::ReadPasswordJob::finished, [=](){
if (m_readCredentialJob.error()) {
emit error(tr("Read key failed: %1").arg(qPrintable(m_readCredentialJob.errorString())));
return;
}
emit keyRestored(key, m_readCredentialJob.textData());
});
m_readCredentialJob.start();
}
void KeyChainClass::writeKey(const QString &key, const QString &value)
{
m_writeCredentialJob.setKey(key);
QObject::connect(&m_writeCredentialJob, &QKeychain::WritePasswordJob::finished, [=](){
if (m_writeCredentialJob.error()) {
emit error(tr("Write key failed: %1").arg(qPrintable(m_writeCredentialJob.errorString())));
return;
}
emit keyStored(key);
});
m_writeCredentialJob.setTextData(value);
m_writeCredentialJob.start();
}
void KeyChainClass::deleteKey(const QString &key)
{
m_deleteCredentialJob.setKey(key);
QObject::connect(&m_deleteCredentialJob, &QKeychain::DeletePasswordJob::finished, [=](){
if (m_deleteCredentialJob.error()) {
emit error(tr("Delete key failed: %1").arg(qPrintable(m_deleteCredentialJob.errorString())));
return;
}
emit keyDeleted(key);
});
m_deleteCredentialJob.start();
}
qtkeychain-0.15.0/TestAppExample/keychainclass.h 0000664 0000000 0000000 00000001411 14742171435 0021630 0 ustar 00root root 0000000 0000000 #ifndef KEYCHAINCLASS_H
#define KEYCHAINCLASS_H
#include
#include
class KeyChainClass: public QObject
{
Q_OBJECT
public:
KeyChainClass(QObject* parent = nullptr);
Q_INVOKABLE void readKey(const QString& key);
Q_INVOKABLE void writeKey(const QString& key, const QString& value);
Q_INVOKABLE void deleteKey(const QString& key);
Q_SIGNALS:
void keyStored(const QString& key);
void keyRestored(const QString& key, const QString& value);
void keyDeleted(const QString& key);
void error(const QString& errorText);
private:
QKeychain::ReadPasswordJob m_readCredentialJob;
QKeychain::WritePasswordJob m_writeCredentialJob;
QKeychain::DeletePasswordJob m_deleteCredentialJob;
};
#endif // KEYCHAINCLASS_H
qtkeychain-0.15.0/TestAppExample/main.cpp 0000664 0000000 0000000 00000001424 14742171435 0020272 0 ustar 00root root 0000000 0000000 #include
#include
#include
#include "keychainclass.h"
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
KeyChainClass keyChainClass;
engine.rootContext()->setContextProperty("KeyChain", &keyChainClass);
engine.load(url);
return app.exec();
}
qtkeychain-0.15.0/TestAppExample/main.qml 0000664 0000000 0000000 00000007023 14742171435 0020302 0 ustar 00root root 0000000 0000000 import QtQuick 2.13
import QtQuick.Window 2.13
import QtQuick.Controls 2.12
Window {
id: root
width: 640
height: 480
visible: true
Column {
anchors {
fill: parent
margins: 50
}
spacing: 20
Label {
text: 'Key name:'
font.pixelSize: 20
}
TextField {
id: keyNameTextField
width: parent.width
height: 50
text: 'default key name'
}
Label {
text: 'Key value:'
font.pixelSize: 20
}
TextField {
id: keyValueTextField
width: parent.width
height: 50
text: 'some value'
}
Label {
id: infoLabel
width: parent.width
wrapMode: Text.Wrap
visible: false
onVisibleChanged: if (visible) hideAnimation.start();
SequentialAnimation {
id: hideAnimation
PauseAnimation {
duration: 10000
}
ScriptAction {
script: infoLabel.visible = false
}
}
Component.onCompleted: {
KeyChain.keyStored.connect((key) => {
infoLabel.text = String("Key '%1' successfully stored").arg(key)
infoLabel.color = 'green'
infoLabel.visible = true
})
KeyChain.keyRestored.connect((key, value) => {
infoLabel.text = String("Key '%1' successfully restored with data '%2'").arg(key).arg(value)
infoLabel.color = 'green'
infoLabel.visible = true
})
KeyChain.keyDeleted.connect((key) => {
infoLabel.text = String("Key '%1' successfully deleted").arg(key)
infoLabel.color = 'green'
infoLabel.visible = true
})
KeyChain.error.connect((errorText) => {
infoLabel.text = errorText
infoLabel.color = 'red'
infoLabel.visible = true
})
}
}
Row {
width: parent.width
height: 50
spacing: 20
Button {
width: 80
height: parent.height
text: 'Store'
onClicked: {
KeyChain.writeKey(keyNameTextField.text.trim(), keyValueTextField.text.trim())
}
}
Button {
width: 80
height: parent.height
text: 'Restore'
onClicked: {
KeyChain.readKey(keyNameTextField.text.trim())
}
}
Button {
width: 80
height: parent.height
text: 'Delete'
onClicked: {
KeyChain.deleteKey(keyNameTextField.text.trim())
}
}
}
}
}
qtkeychain-0.15.0/TestAppExample/qml.qrc 0000664 0000000 0000000 00000000127 14742171435 0020141 0 ustar 00root root 0000000 0000000 main.qml
qtkeychain-0.15.0/appveyor.yml 0000664 0000000 0000000 00000001454 14742171435 0016341 0 ustar 00root root 0000000 0000000 version: '{build}'
build_script:
- ps: |
$ErrorActionPreference="Stop"
Import-Module $env:APPVEYOR_BUILD_FOLDER\appveyorHelp.psm1
Init @("ninja")
mkdir -Force $env:APPVEYOR_BUILD_FOLDER\work\build\$env:APPVEYOR_PROJECT_NAME
cd $env:APPVEYOR_BUILD_FOLDER\work\build\$env:APPVEYOR_PROJECT_NAME
LogExec cmake -G"Ninja" $env:APPVEYOR_BUILD_FOLDER -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$CMAKE_INSTALL_ROOT"
CmakeImageInstall
test: off
cache:
- work\install -> appveyor.yml
- C:\ProgramData\chocolatey\bin -> appveyor.yml
- C:\ProgramData\chocolatey\lib -> appveyor.yml
environment:
QT_VER: 5.7
matrix:
- COMPILER: msvc2015
- COMPILER: msvc2015_64
- COMPILER: mingw53_32
qtkeychain-0.15.0/appveyorHelp.psm1 0000664 0000000 0000000 00000026465 14742171435 0017242 0 ustar 00root root 0000000 0000000 Write-Host "Appveyor Helper scrips https://github.com/TheOneRing/appVeyorHelp"
$ErrorActionPreference="Stop"
$script:INSTALL_DIR="$env:APPVEYOR_BUILD_FOLDER\work\install"
$CMAKE_INSTALL_ROOT="`"$INSTALL_DIR`"" -replace "\\", "/"
$env:PATH="$env:PATH;$script:INSTALL_DIR"
if(!$env:CI -eq "true")
{
function Push-AppveyorArtifact()
{
Write-Host "Push-AppveyorArtifact $ARGS"
}
function Start-FileDownload([string] $url, [string] $out)
{
if(!$out)
{
$out = $url.SubString($url.LastIndexOf("/"))
}
wget $url -Outfile $out
}
}
function LogExec()
{
$OldErrorActionPreference=$ErrorActionPreference
$ErrorActionPreference="Continue"
$LastExitCode = 0
Write-Host $Args[0], $Args[1..(($Args.Count)-1)]
& $Args[0] $Args[1..(($Args.Count)-1)]
if(!$LastExitCode -eq 0)
{
exit $LastExitCode
}
$ErrorActionPreference=$OldErrorActionPreference
}
#Set environment variables for Visual Studio Command Prompt
#http://stackoverflow.com/questions/2124753/how-i-can-use-powershell-with-the-visual-studio-command-prompt
function BAT-CALL([string] $path, [string] $arg)
{
Write-Host "Calling `"$path`" `"$arg`""
cmd /c "$path" "$arg" `&`& set `|`| exit 1|
foreach {
if ($_ -match "=") {
$v = $_.split("=")
#Write-Host "ENV:\$($v[0])=$($v[1])"
set-item -force -path "ENV:\$($v[0])" -value "$($v[1])"
}
}
if($LastExitCode -eq 1) {
Write-Error "$path not found."
}
}
function Get-QtDir()
{
$ver = 5.5
if($env:QT_VER)
{
$ver = $env:QT_VER
}
return "C:\Qt\$ver\$env:COMPILER\"
}
function SETUP-QT()
{
[string] $compiler=$env:COMPILER
$qtDir = Get-QtDir
$script:QT_BINARY_DIRS = @($qtDir)
BAT-CALL "$qtDir\bin\qtenv2.bat"
if ($compiler.StartsWith("mingw49"))
{
#remove sh.exe from path
$env:PATH=$env:PATH -replace "C:\\Program Files \(x86\)\\Git\\bin", ""
$script:MAKE="mingw32-make"
$script:CMAKE_GENERATOR="MinGW Makefiles"
$script:STRIP=@("strip", "-s")
$script:QT_BINARY_DIRS += (Resolve-Path "$qtDir\..\..\Tools\mingw492_32\opt\")
}
elseif ($compiler.StartsWith("msvc"))
{
$arch = "x86"
if($compiler.EndsWith("64"))
{
$arch = "amd64"
}
$compilerDirs = @{
"msvc2010" = "VS100COMNTOOLS";
"msvc2012" = "VS110COMNTOOLS";
"msvc2013" = "VS120COMNTOOLS";
"msvc2015" = "VS140COMNTOOLS"
}
$compilerVar = $compilerDirs[$compiler.Split("_")[0]]
$compilerDir = (get-item -path "env:\$($compilerVar)").Value
BAT-CALL "$compilerDir\..\..\VC\vcvarsall.bat" $arch
$script:MAKE="nmake"
$script:CMAKE_GENERATOR="NMake Makefiles"
if($arch -eq "x86")
{
$script:QT_BINARY_DIRS += ("C:\OpenSSL-Win32")
}
else
{
$script:QT_BINARY_DIRS += ("C:\OpenSSL-Win64")
}
}
}
function Install-ChocolatelyModule([string] $module, [string[]] $myargs)
{
Write-Host "Install chocolately package $module"
LogExec cinst $module @myargs -y
}
function Install-CmakeGitModule([string] $url, [hashtable] $arguments)
{
$module = $url.SubString($url.LastIndexOf("/")+1)
$module = $module.Substring(0,$module.Length - 4)
if(!$arguments.Contains("branch"))
{
$arguments["branch"] = "master"
}
if(!$arguments.Contains("buildType"))
{
$arguments["buildType"] = "Release"
}
mkdir -Force $env:APPVEYOR_BUILD_FOLDER\work\build\$module
pushd $env:APPVEYOR_BUILD_FOLDER\work\git
LogExec git clone -q --depth 1 --branch ([string]$arguments["branch"]) $url $module
popd
pushd $env:APPVEYOR_BUILD_FOLDER\work\build\$module
LogExec cmake -G $script:CMAKE_GENERATOR ("-DCMAKE_BUILD_TYPE=`"{0}`"" -f [string]$arguments["buildType"]) $env:APPVEYOR_BUILD_FOLDER\work\git\$module -DCMAKE_INSTALL_PREFIX="$CMAKE_INSTALL_ROOT" $arguments["options"]
LogExec $script:MAKE install
popd
}
function Init([string[]] $chocoDeps, [System.Collections.Specialized.OrderedDictionary] $cmakeModules)
{
$script:MAKE=""
$script:CMAKE_GENERATOR=""
$script:STRIP=$null
mkdir -Force $env:APPVEYOR_BUILD_FOLDER\work\image | Out-Null
mkdir -Force $env:APPVEYOR_BUILD_FOLDER\work\build | Out-Null
SETUP-QT
if($chocoDeps -contains "ninja") {
$script:CMAKE_GENERATOR="Ninja"
$script:MAKE="ninja"
}
if ( !(Test-Path "$env:APPVEYOR_BUILD_FOLDER\work\install" ) )
{
mkdir -Force $env:APPVEYOR_BUILD_FOLDER\work\install | Out-Null
mkdir -Force $env:APPVEYOR_BUILD_FOLDER\work\git | Out-Null
foreach($module in $chocoDeps) {
if($module -eq "nsis")
{
Install-ChocolatelyModule "nsis.portable" @("-pre")
continue
}
Install-ChocolatelyModule $module
}
foreach($key in $cmakeModules.Keys) {
Install-CmakeGitModule $key $cmakeModules[$key]
}
[string] $compiler=$env:COMPILER
if($compiler.StartsWith("msvc"))
{
Write-Host "Downloading vcredist.exe"
if ($compiler.StartsWith("msvc2015"))
{
if($compiler.EndsWith("64"))
{
Start-FileDownload https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x64.exe $env:APPVEYOR_BUILD_FOLDER\work\install\vcredist.exe
}
else
{
Start-FileDownload https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x86.exe $env:APPVEYOR_BUILD_FOLDER\work\install\vcredist.exe
}
}
else
{
if($compiler.EndsWith("64"))
{
Start-FileDownload http://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x64.exe $env:APPVEYOR_BUILD_FOLDER\work\install\vcredist.exe
}
else
{
Start-FileDownload http://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x86.exe $env:APPVEYOR_BUILD_FOLDER\work\install\vcredist.exe
}
}
}
}
}
function relativePath([string] $root, [string] $path)
{
pushd $root
$out = Resolve-Path -Relative $path
popd
return $out
}
function StripFile([string] $name)
{
if($script:STRIP) {
if( $name.EndsWith(".dll") -or $name.EndsWith(".exe"))
{
Write-Host "strip file $name"
LogExec @script:STRIP $name
}
}
}
function Get-DeployImageName()
{
$version = Get-Version
if($env:APPVEYOR_REPO_TAG -eq "true") {
return "$env:APPVEYOR_PROJECT_NAME`_$version`_Qt$env:QT_VER`_$env:COMPILER"
}else{
return "$env:APPVEYOR_PROJECT_NAME`_$env:APPVEYOR_REPO_BRANCH`_$version`_Qt$env:QT_VER`_$env:COMPILER"
}
}
function Get-Version()
{
if($env:APPVEYOR_REPO_TAG -eq "true") {
return $env:APPVEYOR_REPO_TAG_NAME
}else{
$commit = ([string]$env:APPVEYOR_REPO_COMMIT).SubString(0,6)
return $commit
}
}
function CmakeImageInstall()
{
$imageName = Get-DeployImageName
$destDir = "$env:APPVEYOR_BUILD_FOLDER\work\cmakeDeployImage\$imageName"
$env:DESTDIR = $destDir
LogExec $script:MAKE install
$env:DESTDIR = $null
if(!$LastExitCode -eq 0)
{
Write-Error "Build Failed"
}
$env:DESTDIR=$null
$prefix=$script:INSTALL_DIR
if( $prefix.substring(1,1) -eq ":")
{
$prefix=$prefix.substring(3)
}
Write-Host "move $destDir\$prefix to $destDir"
mv -Force "$destDir\$prefix\*" "$destDir"
$rootLeftOver = $prefix.substring(0, $prefix.indexOf("\"))
rm -Recurse "$destDir\$rootLeftOver"
}
function CreateDeployImage([string[]] $whiteList, [string[]] $blackList)
{
$imageName = Get-DeployImageName
$deployPath = "$env:APPVEYOR_BUILD_FOLDER\work\deployImage\$imageName"
function copyWithWhitelist([string] $root)
{
$files = ls $root -Recurse
foreach($fileName in $files.FullName)
{
$relPath = (relativePath $root $fileName).SubString(2)
if($whiteList | Where {$relPath -match $_})
{
if($blackList | Where {$relPath -match $_})
{
continue
}
if(!(Test-Path $deployPath\$relPath))
{
Write-Host "copy $fileName to $deployPath\$relPath"
mkdir -Force (Split-Path -Parent $deployPath\$relPath) | Out-Null
cp -Force $fileName $deployPath\$relPath
StripFile $deployPath\$relPath
}
}
}
}
Write-Host "CreateDeployImage $imageName"
mkdir $deployPath | Out-Null
copyWithWhitelist "$env:APPVEYOR_BUILD_FOLDER\work\cmakeDeployImage\$imageName"
copyWithWhitelist "$env:APPVEYOR_BUILD_FOLDER\work\install\"
foreach($folder in $script:QT_BINARY_DIRS)
{
copyWithWhitelist $folder
}
Write-Host "Deploy path $deployPath"
return $deployPath
}
function 7ZipDeployImage()
{
$imageName = Get-DeployImageName
LogExec 7za a "$env:APPVEYOR_BUILD_FOLDER\work\deployImage\$imageName.7z" "$env:APPVEYOR_BUILD_FOLDER\work\deployImage\$imageName"
Push-AppveyorArtifact "$env:APPVEYOR_BUILD_FOLDER\work\deployImage\$imageName.7z"
}
function NsisDeployImage([string] $scriptName)
{
$imageName = Get-DeployImageName
$installerName = "$env:APPVEYOR_BUILD_FOLDER\work\deployImage\$imageName.exe"
$version = Get-Version
if(([string]$env:COMPILER).StartsWith("msvc"))
{
$redist = "$env:APPVEYOR_BUILD_FOLDER\work\install\vcredist.exe"
}else{
$redist = "none"
}
if($env:COMPILER.EndsWith("64"))
{
$defaultinstdir = "`$PROGRAMFILES64"
}else{
$defaultinstdir = "`$PROGRAMFILES"
}
LogExec makensis.exe /DgitDir=$env:APPVEYOR_BUILD_FOLDER /Dsetupname=$installerName /Dcaption=$imageName /Dversion=$version /Dcompiler=$env:COMPILER /Dvcredist=$redist /Ddefaultinstdir=$defaultinstdir /Dsrcdir=$env:APPVEYOR_BUILD_FOLDER\work\deployImage\$imageName $scriptName
Push-AppveyorArtifact $installerName
}
# based on http://thesurlyadmin.com/2013/01/07/remove-empty-directories-recursively/
function DeleteEmptyFodlers([string] $root)
{
$Folders = @()
foreach($Folder in (Get-ChildItem -Path $root -Recurse -Directory))
{
$Folders += New-Object PSObject -Property @{
Object = $Folder
Depth = ($Folder.FullName.Split("\")).Count
}
}
$Folders = $Folders | Sort Depth -Descending
foreach($Folder in $Folders)
{
If ($Folder.Object.GetFileSystemInfos().Count -eq 0)
{
Write-Host "Delete empty dir:" $Folder.Object.FullName
Remove-Item -Path $Folder.Object.FullName -Force
}
}
}
Write-Host "CMAKE_INSTALL_ROOT: $CMAKE_INSTALL_ROOT"
Write-Host "Image-Name: ", (Get-DeployImageName)
Export-ModuleMember -Function @("Init","CmakeImageInstall", "CreateDeployImage", "LogExec", "7ZipDeployImage", "NsisDeployImage", "DeleteEmptyFodlers") -Variable @("CMAKE_INSTALL_ROOT")
qtkeychain-0.15.0/autotest/ 0000775 0000000 0000000 00000000000 14742171435 0015615 5 ustar 00root root 0000000 0000000 qtkeychain-0.15.0/autotest/CMakeLists.txt 0000664 0000000 0000000 00000000341 14742171435 0020353 0 ustar 00root root 0000000 0000000 include(ECMAddTests)
find_package(Qt${QT_MAJOR_VERSION} COMPONENTS Test REQUIRED)
ecm_add_tests(basic.cpp LINK_LIBRARIES ${QTKEYCHAIN_TARGET_NAME} Qt${QT_MAJOR_VERSION}::Test)
set_property(TARGET basic PROPERTY AUTOMOC ON)
qtkeychain-0.15.0/autotest/basic.cpp 0000664 0000000 0000000 00000004662 14742171435 0017412 0 ustar 00root root 0000000 0000000 #include
#include "qtkeychain/keychain.h"
namespace
{
QByteArray generateRandomString(qsizetype size)
{
std::vector buffer(size, 0);
QRandomGenerator::global()->fillRange(buffer.data(), size);
return QByteArray(reinterpret_cast(buffer.data()), static_cast(size * sizeof(quint32))).toBase64(QByteArray::Base64UrlEncoding).mid(0, size);
}
}
class BasicTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void test_data()
{
QTest::addColumn("password");
QTest::newRow("normal password") << QByteArrayLiteral("this is a password");
QTest::newRow("1000") << generateRandomString(1000);
QTest::newRow("2000") << generateRandomString(2000);
QTest::newRow("3000") << generateRandomString(3000);
QTest::newRow("10000") << generateRandomString(10000);
QTest::newRow("18944") << generateRandomString(18944);
}
void test()
{
#ifdef Q_OS_MACOS
QSKIP("This test case has no access to the keychain");
#endif
const QString serviceKey = QStringLiteral("QtKeychainTest-%1").arg(QTest::currentDataTag());
QFETCH(QByteArray, password);
{
QKeychain::WritePasswordJob writeJob(serviceKey);
writeJob.setKey(serviceKey);
writeJob.setBinaryData(password);
QSignalSpy writeSpy(&writeJob, &QKeychain::WritePasswordJob::finished);
writeJob.start();
writeSpy.wait();
#ifdef Q_OS_WIN
QEXPECT_FAIL("18944", "Maximum for Windows is exceeded", Abort);
#endif
qDebug() << writeJob.errorString();
QCOMPARE(writeJob.error(), QKeychain::NoError);
}
{
QKeychain::ReadPasswordJob readJob(serviceKey);
readJob.setKey(serviceKey);
QSignalSpy readSpy(&readJob, &QKeychain::ReadPasswordJob::finished);
readJob.start();
readSpy.wait();
QCOMPARE(readJob.error(), QKeychain::NoError);
QCOMPARE(readJob.binaryData(), password);
}
{
QKeychain::DeletePasswordJob deleteJob(serviceKey);
deleteJob.setKey(serviceKey);
QSignalSpy deleteSpy(&deleteJob, &QKeychain::DeletePasswordJob::finished);
deleteJob.start();
deleteSpy.wait();
QCOMPARE(deleteJob.error(), QKeychain::NoError);
}
}
};
QTEST_MAIN(BasicTest)
#include "basic.moc"
qtkeychain-0.15.0/cmake/ 0000775 0000000 0000000 00000000000 14742171435 0015025 5 ustar 00root root 0000000 0000000 qtkeychain-0.15.0/cmake/Modules/ 0000775 0000000 0000000 00000000000 14742171435 0016435 5 ustar 00root root 0000000 0000000 qtkeychain-0.15.0/cmake/Modules/ECMAddTests.cmake 0000664 0000000 0000000 00000015320 14742171435 0021500 0 ustar 00root root 0000000 0000000 # SPDX-FileCopyrightText: 2013 Alexander Richardson
# SPDX-FileCopyrightText: 2015 Alex Merry
#
# SPDX-License-Identifier: BSD-3-Clause
#[=======================================================================[.rst:
ECMAddTests
-----------
Convenience functions for adding tests.
::
ecm_add_tests(
LINK_LIBRARIES [ [...]]
[NAME_PREFIX ]
[GUI]
[TARGET_NAMES_VAR ]
[TEST_NAMES_VAR ]
[WORKING_DIRECTORY ] # Since 5.111
)
A convenience function for adding multiple tests, each consisting of a
single source file. For each file in , an executable target will be
created (the name of which will be the basename of the source file). This
will be linked against the libraries given with ``LINK_LIBRARIES``. Each
executable will be added as a test with the same name.
If ``NAME_PREFIX`` is given, this prefix will be prepended to the test names, but
not the target names. As a result, it will not prevent clashes between tests
with the same name in different parts of the project, but it can be used to
give an indication of where to look for a failing test.
If the flag ``GUI`` is passed the test binaries will be GUI executables, otherwise
the resulting binaries will be console applications (regardless of the value
of ``CMAKE_WIN32_EXECUTABLE`` or ``CMAKE_MACOSX_BUNDLE``). Be aware that this changes
the executable entry point on Windows (although some frameworks, such as Qt,
abstract this difference away).
The tests will be build with ``-DQT_FORCE_ASSERTS`` to enable assertions in the
test executable even for release builds.
The ``TARGET_NAMES_VAR`` and ``TEST_NAMES_VAR`` arguments, if given, should specify a
variable name to receive the list of generated target and test names,
respectively. This makes it convenient to apply properties to them as a
whole, for example, using ``set_target_properties()`` or ``set_tests_properties()``.
The generated target executables will have the effects of ``ecm_mark_as_test()``
(from the :module:`ECMMarkAsTest` module) applied to it.
``WORKING_DIRECTORY`` sets the test property `WORKING_DIRECTORY
`_
in which to execute the test. By default the test will be run in
``${CMAKE_CURRENT_BINARY_DIR}``. The working directory can be specified using
generator expressions. Since 5.111.
::
ecm_add_test(
LINK_LIBRARIES [ [...]]
[TEST_NAME ]
[NAME_PREFIX ]
[GUI]
[WORKING_DIRECTORY ] # Since 5.111
)
This is a single-test form of ``ecm_add_tests`` that allows multiple source files
to be used for a single test. If using multiple source files, ``TEST_NAME`` must
be given; this will be used for both the target and test names (and, as with
``ecm_add_tests()``, the ``NAME_PREFIX`` argument will be prepended to the test name).
``WORKING_DIRECTORY`` sets the test property `WORKING_DIRECTORY
`_
in which to execute the test. By default the test will be run in
``${CMAKE_CURRENT_BINARY_DIR}``. The working directory can be specified using
generator expressions. Since 5.111.
Since pre-1.0.0.
#]=======================================================================]
include(ECMMarkAsTest)
include(ECMMarkNonGuiExecutable)
function(ecm_add_test)
set(options GUI)
# TARGET_NAME_VAR and TEST_NAME_VAR are undocumented args used by
# ecm_add_tests
set(oneValueArgs TEST_NAME NAME_PREFIX TARGET_NAME_VAR TEST_NAME_VAR WORKING_DIRECTORY)
set(multiValueArgs LINK_LIBRARIES)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
set(_sources ${ARG_UNPARSED_ARGUMENTS})
list(LENGTH _sources _sourceCount)
if(ARG_TEST_NAME)
set(_targetname ${ARG_TEST_NAME})
elseif(${_sourceCount} EQUAL "1")
#use the source file name without extension as the testname
get_filename_component(_targetname ${_sources} NAME_WE)
else()
#more than one source file passed, but no test name given -> error
message(FATAL_ERROR "ecm_add_test() called with multiple source files but without setting \"TEST_NAME\"")
endif()
set(_testname ${ARG_NAME_PREFIX}${_targetname})
set(gui_args)
if(ARG_GUI)
set(gui_args WIN32 MACOSX_BUNDLE)
endif()
add_executable(${_targetname} ${gui_args} ${_sources})
if(NOT ARG_GUI)
ecm_mark_nongui_executable(${_targetname})
endif()
set(test_args)
if(DEFINED ARG_WORKING_DIRECTORY)
list(APPEND test_args WORKING_DIRECTORY ${ARG_WORKING_DIRECTORY})
endif()
add_test(NAME ${_testname} COMMAND ${_targetname} ${test_args})
target_link_libraries(${_targetname} ${ARG_LINK_LIBRARIES})
target_compile_definitions(${_targetname} PRIVATE -DQT_FORCE_ASSERTS)
ecm_mark_as_test(${_targetname})
if (CMAKE_LIBRARY_OUTPUT_DIRECTORY)
set(_plugin_path ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
if (DEFINED ENV{QT_PLUGIN_PATH})
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
# https://stackoverflow.com/questions/59862894/how-do-i-make-a-list-in-cmake-with-the-semicolon-value
set(PATHSEP "\\\;") # Don't want cmake to treat it like a list
else() # e.g. Linux
set(PATHSEP ":")
endif()
set(_plugin_path "${_plugin_path}${PATHSEP}$ENV{QT_PLUGIN_PATH}")
endif()
set_property(TEST ${_testname} PROPERTY ENVIRONMENT "QT_PLUGIN_PATH=${_plugin_path}")
endif()
if (ARG_TARGET_NAME_VAR)
set(${ARG_TARGET_NAME_VAR} "${_targetname}" PARENT_SCOPE)
endif()
if (ARG_TEST_NAME_VAR)
set(${ARG_TEST_NAME_VAR} "${_testname}" PARENT_SCOPE)
endif()
endfunction()
function(ecm_add_tests)
set(options GUI)
set(oneValueArgs NAME_PREFIX TARGET_NAMES_VAR TEST_NAMES_VAR WORKING_DIRECTORY)
set(multiValueArgs LINK_LIBRARIES)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if(ARG_GUI)
set(_exe_type GUI)
else()
set(_exe_type "")
endif()
set(test_args)
if(DEFINED ARG_WORKING_DIRECTORY)
list(APPEND test_args WORKING_DIRECTORY ${ARG_WORKING_DIRECTORY})
endif()
set(test_names)
set(target_names)
foreach(_test_source ${ARG_UNPARSED_ARGUMENTS})
ecm_add_test(${_test_source}
NAME_PREFIX ${ARG_NAME_PREFIX}
LINK_LIBRARIES ${ARG_LINK_LIBRARIES}
TARGET_NAME_VAR target_name
TEST_NAME_VAR test_name
${_exe_type}
${test_args}
)
list(APPEND _test_names "${test_name}")
list(APPEND _target_names "${target_name}")
endforeach()
if (ARG_TARGET_NAMES_VAR)
set(${ARG_TARGET_NAMES_VAR} "${_target_names}" PARENT_SCOPE)
endif()
if (ARG_TEST_NAMES_VAR)
set(${ARG_TEST_NAMES_VAR} "${_test_names}" PARENT_SCOPE)
endif()
endfunction()
qtkeychain-0.15.0/cmake/Modules/ECMGeneratePriFile.cmake 0000664 0000000 0000000 00000025317 14742171435 0023001 0 ustar 00root root 0000000 0000000 # SPDX-FileCopyrightText: 2014 David Faure
#
# SPDX-License-Identifier: BSD-3-Clause
#[=======================================================================[.rst:
ECMGeneratePriFile
------------------
Generate a ``.pri`` file for the benefit of qmake-based projects.
As well as the function below, this module creates the cache variable
``ECM_MKSPECS_INSTALL_DIR`` and sets the default value to ``mkspecs/modules``.
This assumes Qt and the current project are both installed to the same
non-system prefix. Packagers who use ``-DCMAKE_INSTALL_PREFIX=/usr`` will
certainly want to set ``ECM_MKSPECS_INSTALL_DIR`` to something like
``share/qt5/mkspecs/modules``.
The main thing is that this should be the ``modules`` subdirectory of either
the default qmake ``mkspecs`` directory or of a directory that will be in the
``$QMAKEPATH`` environment variable when qmake is run.
::
ecm_generate_pri_file(BASE_NAME
LIB_NAME
[VERSION ] # since 5.83
[DEPS " [ [...]]"]
[FILENAME_VAR ]
[INCLUDE_INSTALL_DIRS [ [...]]] # since 5.92
[INCLUDE_INSTALL_DIR ] # deprecated since 5.92
[LIB_INSTALL_DIR ])
If your CMake project produces a Qt-based library, you may expect there to be
applications that wish to use it that use a qmake-based build system, rather
than a CMake-based one. Creating a ``.pri`` file will make use of your
library convenient for them, in much the same way that CMake config files make
things convenient for CMake-based applications. ``ecm_generate_pri_file()``
generates just such a file.
``VERSION`` specifies the version of the library the ``.pri`` file describes. If
not set, the value is taken from the context variable ``PROJECT_VERSION``.
This variable is usually set by the ``project(... VERSION ...)`` command or,
if CMake policy CMP0048 is not ``NEW``, by :module:`ECMSetupVersion`.
For backward-compatibility with older ECM versions the
``PROJECT_VERSION_STRING`` variable as set by :module:`ECMSetupVersion`
will be preferred over ``PROJECT_VERSION`` if set, unless the minimum
required version of ECM is 5.83 and newer. Since 5.83.
``BASE_NAME`` specifies the name qmake project (.pro) files should use to refer to
the library (eg: KArchive). ``LIB_NAME`` is the name of the actual library to
link to (ie: the first argument to add_library()). ``DEPS`` is a space-separated
list of the base names of other libraries (for Qt libraries, use the same
names you use with the ``QT`` variable in a qmake project file, such as "core"
for QtCore). ``FILENAME_VAR`` specifies the name of a variable to store the path
to the generated file in.
``INCLUDE_INSTALL_DIRS`` are the paths (relative to ``CMAKE_INSTALL_PREFIX``) that
include files will be installed to. It defaults to
``${INCLUDE_INSTALL_DIR}/`` if the ``INCLUDE_INSTALL_DIR`` variable
is set. If that variable is not set, the ``CMAKE_INSTALL_INCLUDEDIR`` variable
is used instead, and if neither are set ``include`` is used. ``LIB_INSTALL_DIR``
operates similarly for the installation location for libraries; it defaults to
``${LIB_INSTALL_DIR}``, ``${CMAKE_INSTALL_LIBDIR}`` or ``lib``, in that order.
``INCLUDE_INSTALL_DIR`` is the old variant of ``INCLUDE_INSTALL_DIRS``, taking only one
directory.
Example usage:
.. code-block:: cmake
ecm_generate_pri_file(
BASE_NAME KArchive
LIB_NAME KF5KArchive
DEPS "core"
FILENAME_VAR pri_filename
VERSION 4.2.0
)
install(FILES ${pri_filename} DESTINATION ${ECM_MKSPECS_INSTALL_DIR})
A qmake-based project that wished to use this would then do::
QT += KArchive
in their ``.pro`` file.
Since pre-1.0.0.
#]=======================================================================]
# Replicate the logic from KDEInstallDirs.cmake as we can't depend on it
# Ask qmake if we're using the same prefix as Qt
set(_should_query_qt OFF)
if(NOT DEFINED KDE_INSTALL_USE_QT_SYS_PATHS)
include(ECMQueryQt)
ecm_query_qt(qt_install_prefix_dir QT_INSTALL_PREFIX TRY)
if(qt_install_prefix_dir STREQUAL "${CMAKE_INSTALL_PREFIX}")
set(_should_query_qt ON)
endif()
endif()
if(KDE_INSTALL_USE_QT_SYS_PATHS OR _should_query_qt)
include(ECMQueryQt)
ecm_query_qt(qt_install_prefix_dir QT_INSTALL_PREFIX)
ecm_query_qt(qt_host_data_dir QT_HOST_DATA)
if(qt_install_prefix_dir STREQUAL "${CMAKE_INSTALL_PREFIX}")
file(RELATIVE_PATH qt_host_data_dir ${qt_install_prefix_dir} ${qt_host_data_dir})
endif()
if(qt_host_data_dir STREQUAL "")
set(mkspecs_install_dir mkspecs/modules)
else()
set(mkspecs_install_dir ${qt_host_data_dir}/mkspecs/modules)
endif()
set(ECM_MKSPECS_INSTALL_DIR ${mkspecs_install_dir} CACHE PATH "The directory where mkspecs will be installed to.")
else()
set(ECM_MKSPECS_INSTALL_DIR mkspecs/modules CACHE PATH "The directory where mkspecs will be installed to.")
endif()
function(ECM_GENERATE_PRI_FILE)
set(options )
set(oneValueArgs BASE_NAME LIB_NAME DEPS FILENAME_VAR INCLUDE_INSTALL_DIR LIB_INSTALL_DIR VERSION)
set(multiValueArgs INCLUDE_INSTALL_DIRS)
cmake_parse_arguments(EGPF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if(EGPF_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Unknown keywords given to ECM_GENERATE_PRI_FILE(): \"${EGPF_UNPARSED_ARGUMENTS}\"")
endif()
if(ECM_GLOBAL_FIND_VERSION VERSION_LESS 5.83.0)
set(_support_backward_compat_version_string_var TRUE)
else()
set(_support_backward_compat_version_string_var FALSE)
endif()
if(NOT EGPF_BASE_NAME)
message(FATAL_ERROR "Required argument BASE_NAME missing in ECM_GENERATE_PRI_FILE() call")
endif()
if(NOT EGPF_LIB_NAME)
message(FATAL_ERROR "Required argument LIB_NAME missing in ECM_GENERATE_PRI_FILE() call")
endif()
if(NOT EGPF_VERSION)
if(_support_backward_compat_version_string_var)
if(NOT PROJECT_VERSION_STRING AND NOT PROJECT_VERSION)
message(FATAL_ERROR "Required variable PROJECT_VERSION_STRING or PROJECT_VERSION not set before ECM_GENERATE_PRI_FILE() call. Missing call of ecm_setup_version() or project(VERSION)?")
endif()
else()
if(NOT PROJECT_VERSION)
message(FATAL_ERROR "Required variable PROJECT_VERSION not set before ECM_GENERATE_PRI_FILE() call. Missing call of ecm_setup_version() or project(VERSION)?")
endif()
endif()
endif()
if(EGPF_INCLUDE_INSTALL_DIR)
if(EGPF_INCLUDE_INSTALL_DIRS)
message(FATAL_ERROR "Only one argument of INCLUDE_INSTALL_DIR & INCLUDE_INSTALL_DIRS can be used in ECM_GENERATE_PRI_FILE() call")
endif()
set(EGPF_INCLUDE_INSTALL_DIRS ${EGPF_INCLUDE_INSTALL_DIR})
endif()
if(NOT EGPF_INCLUDE_INSTALL_DIRS)
if(INCLUDE_INSTALL_DIR)
set(EGPF_INCLUDE_INSTALL_DIRS "${INCLUDE_INSTALL_DIR}/${EGPF_BASE_NAME}")
elseif(CMAKE_INSTALL_INCLUDEDIR)
set(EGPF_INCLUDE_INSTALL_DIRS "${CMAKE_INSTALL_INCLUDEDIR}/${EGPF_BASE_NAME}")
else()
set(EGPF_INCLUDE_INSTALL_DIRS "include/${EGPF_BASE_NAME}")
endif()
endif()
if(NOT EGPF_LIB_INSTALL_DIR)
if(LIB_INSTALL_DIR)
set(EGPF_LIB_INSTALL_DIR "${LIB_INSTALL_DIR}")
elseif(CMAKE_INSTALL_LIBDIR)
set(EGPF_LIB_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}")
else()
set(EGPF_LIB_INSTALL_DIR "lib")
endif()
endif()
if(EGPF_VERSION)
set(PRI_VERSION "${EGPF_VERSION}")
else()
if(_support_backward_compat_version_string_var AND PROJECT_VERSION_STRING)
set(PRI_VERSION "${PROJECT_VERSION_STRING}")
if(NOT PROJECT_VERSION_STRING STREQUAL PROJECT_VERSION)
message(DEPRECATION "ECM_GENERATE_PRI_FILE() will no longer support PROJECT_VERSION_STRING when the required minimum version of ECM is 5.83 or newer. Set VERSION parameter or use PROJECT_VERSION instead.")
endif()
else()
set(PRI_VERSION "${PROJECT_VERSION}")
endif()
endif()
string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" PRI_VERSION_MAJOR "${PRI_VERSION}")
string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" PRI_VERSION_MINOR "${PRI_VERSION}")
string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" PRI_VERSION_PATCH "${PRI_VERSION}")
# Prepare the right number of "../.." to go from ECM_MKSPECS_INSTALL_DIR to the install prefix
# This allows to make the generated pri files relocatable (no absolute paths)
if (IS_ABSOLUTE ${ECM_MKSPECS_INSTALL_DIR})
set(BASEPATH ${CMAKE_INSTALL_PREFIX})
else()
string(REGEX REPLACE "[^/]+" ".." PRI_ROOT_RELATIVE_TO_MKSPECS ${ECM_MKSPECS_INSTALL_DIR})
set(BASEPATH "$$PWD/${PRI_ROOT_RELATIVE_TO_MKSPECS}")
endif()
set(PRI_TARGET_BASENAME ${EGPF_BASE_NAME})
set(PRI_TARGET_LIBNAME ${EGPF_LIB_NAME})
set(PRI_TARGET_QTDEPS ${EGPF_DEPS})
set(PRI_TARGET_INCLUDES)
foreach(_dir ${EGPF_INCLUDE_INSTALL_DIRS})
# separate list entries with space
if(IS_ABSOLUTE "${_dir}")
string(APPEND PRI_TARGET_INCLUDES " ${_dir}")
else()
string(APPEND PRI_TARGET_INCLUDES " ${BASEPATH}/${_dir}")
endif()
endforeach()
if(IS_ABSOLUTE "${EGPF_LIB_INSTALL_DIR}")
set(PRI_TARGET_LIBS "${EGPF_LIB_INSTALL_DIR}")
else()
set(PRI_TARGET_LIBS "${BASEPATH}/${EGPF_LIB_INSTALL_DIR}")
endif()
set(PRI_TARGET_DEFINES "")
set(PRI_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/qt_${PRI_TARGET_BASENAME}.pri)
if (EGPF_FILENAME_VAR)
set(${EGPF_FILENAME_VAR} ${PRI_FILENAME} PARENT_SCOPE)
endif()
set(PRI_TARGET_MODULE_CONFIG "")
# backward compat: it was not obvious LIB_NAME needs to be a target name,
# and some projects where the target name was not the actual library output name
# passed the output name for LIB_NAME, so .name & .module prperties are correctly set.
# TODO: improve API dox, allow control over module name if target name != output name
if(TARGET ${EGPF_LIB_NAME})
get_target_property(target_type ${EGPF_LIB_NAME} TYPE)
if (target_type STREQUAL "STATIC_LIBRARY")
set(PRI_TARGET_MODULE_CONFIG "staticlib")
endif()
endif()
file(GENERATE
OUTPUT ${PRI_FILENAME}
CONTENT
"QT.${PRI_TARGET_BASENAME}.VERSION = ${PRI_VERSION}
QT.${PRI_TARGET_BASENAME}.MAJOR_VERSION = ${PRI_VERSION_MAJOR}
QT.${PRI_TARGET_BASENAME}.MINOR_VERSION = ${PRI_VERSION_MINOR}
QT.${PRI_TARGET_BASENAME}.PATCH_VERSION = ${PRI_VERSION_PATCH}
QT.${PRI_TARGET_BASENAME}.name = ${PRI_TARGET_LIBNAME}
QT.${PRI_TARGET_BASENAME}.module = ${PRI_TARGET_LIBNAME}
QT.${PRI_TARGET_BASENAME}.defines = ${PRI_TARGET_DEFINES}
QT.${PRI_TARGET_BASENAME}.includes = ${PRI_TARGET_INCLUDES}
QT.${PRI_TARGET_BASENAME}.private_includes =
QT.${PRI_TARGET_BASENAME}.libs = ${PRI_TARGET_LIBS}
QT.${PRI_TARGET_BASENAME}.depends = ${PRI_TARGET_QTDEPS}
QT.${PRI_TARGET_BASENAME}.module_config = ${PRI_TARGET_MODULE_CONFIG}
"
)
endfunction()
qtkeychain-0.15.0/cmake/Modules/ECMMarkAsTest.cmake 0000664 0000000 0000000 00000002236 14742171435 0022005 0 ustar 00root root 0000000 0000000 # SPDX-FileCopyrightText: 2012 Stephen Kelly
# SPDX-FileCopyrightText: 2012 Alex Neundorf
#
# SPDX-License-Identifier: BSD-3-Clause
#[=======================================================================[.rst:
ECMMarkAsTest
-------------
Marks a target as only being required for tests.
::
ecm_mark_as_test( [ [...]])
This will cause the specified targets to not be built unless either
``BUILD_TESTING`` is set to ``ON`` or the user invokes the ``buildtests`` target.
``BUILD_TESTING`` is created as a cache variable by the CTest module and by the
:kde-module:`KDECMakeSettings` module.
Since pre-1.0.0.
#]=======================================================================]
if (NOT BUILD_TESTING)
if(NOT TARGET buildtests)
add_custom_target(buildtests)
endif()
endif()
function(ecm_mark_as_test)
if (NOT BUILD_TESTING)
foreach(_target ${ARGN})
set_target_properties(${_target}
PROPERTIES
EXCLUDE_FROM_ALL TRUE
)
add_dependencies(buildtests ${_target})
endforeach()
endif()
endfunction()
qtkeychain-0.15.0/cmake/Modules/ECMMarkNonGuiExecutable.cmake 0000664 0000000 0000000 00000001674 14742171435 0024010 0 ustar 00root root 0000000 0000000 # SPDX-FileCopyrightText: 2012 Stephen Kelly
#
# SPDX-License-Identifier: BSD-3-Clause
#[=======================================================================[.rst:
ECMMarkNonGuiExecutable
-----------------------
Marks an executable target as not being a GUI application.
::
ecm_mark_nongui_executable( [ [...]])
This will indicate to CMake that the specified targets should not be included
in a MACOSX_BUNDLE and should not be WIN32_EXECUTABLEs. On platforms other
than MacOS X or Windows, this will have no effect.
Since pre-1.0.0.
#]=======================================================================]
function(ecm_mark_nongui_executable)
foreach(_target ${ARGN})
set_target_properties(${_target}
PROPERTIES
WIN32_EXECUTABLE FALSE
MACOSX_BUNDLE FALSE
)
endforeach()
endfunction()
qtkeychain-0.15.0/cmake/Modules/ECMPackageConfigHelpers.cmake 0000664 0000000 0000000 00000015666 14742171435 0024006 0 ustar 00root root 0000000 0000000 #.rst:
# ECMPackageConfigHelpers
# -----------------------
#
# Helper macros for generating CMake package config files.
#
# ``write_basic_package_version_file()`` is the same as the one provided by the
# `CMakePackageConfigHelpers
# `_
# module in CMake; see that module's documentation for
# more information.
#
# ::
#
# ecm_configure_package_config_file(