Compare commits

...

14 Commits

51 changed files with 1351 additions and 1032 deletions

View File

@ -13,6 +13,7 @@ portability-*,
-cppcoreguidelines-owning-memory,
-cppcoreguidelines-avoid-magic-numbers,
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
-llvm-header-guard,
-readability-magic-numbers,
-readability-else-after-return,
-modernize-use-trailing-return-type,
@ -88,9 +89,9 @@ CheckOptions:
- key: readability-identifier-naming.ConstexprMethodSuffix
value: ''
- key: readability-identifier-naming.ConstexprVariableCase
value: lower_case
value: CamelCase
- key: readability-identifier-naming.ConstexprVariablePrefix
value: ''
value: 'k_'
- key: readability-identifier-naming.ConstexprVariableSuffix
value: ''
- key: readability-identifier-naming.EnumCase
@ -102,7 +103,7 @@ CheckOptions:
- key: readability-identifier-naming.EnumConstantCase
value: CamelCase
- key: readability-identifier-naming.EnumConstantPrefix
value: 'k_'
value: 'k'
- key: readability-identifier-naming.EnumConstantSuffix
value: ''
- key: readability-identifier-naming.FunctionCase
@ -114,7 +115,7 @@ CheckOptions:
- key: readability-identifier-naming.GlobalConstantCase
value: CamelCase
- key: readability-identifier-naming.GlobalConstantPrefix
value: 'k_'
value: ''
- key: readability-identifier-naming.GlobalConstantSuffix
value: ''
- key: readability-identifier-naming.GlobalConstantPointerCase

View File

@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.3)
cmake_policy(VERSION 3.0.2..3.7)
# Название проекта
project(myx VERSION 0.3.0 LANGUAGES C CXX)
project(myx VERSION 0.4.0 LANGUAGES C CXX)
# В каталоге cmake/lib находятся файлы с библиотечными функциями
if(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/cmake/cmlib)
@ -13,54 +13,44 @@ else()
endif()
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/find)
if(NOT DEFINED MYXLIB_MASTER_PROJECT)
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(MYXLIB_MASTER_PROJECT ON)
else()
set(MYXLIB_MASTER_PROJECT OFF)
endif()
endif()
include(CMLibCommon)
option(BUILD_EXAMPLES "Build examples" OFF)
option(MYXLIB_BUILD_LIBRARIES "Build libraries" OFF)
if(MYXLIB_BUILD_LIBRARIES)
option(MYXLIB_BUILD_EXAMPLES "Build examples" OFF)
endif()
option(MYXLIB_BUILD_EXAMPLES_HO "Build examples using header only version" OFF)
# Поиск библиотек с помощью pkgconfig
find_package(PkgConfig)
find_package(PkgConfig REQUIRED)
# Потоки
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
# Qt5
find_package(
Qt5
COMPONENTS
Core
Network
Gui
Widgets
DBus
Concurrent
Sql
REQUIRED)
# Автоматически генерируемый заголовочный файл
cmlib_config_hpp_generate()
configure_file(${CMAKE_SOURCE_DIR}/src/myx/base/config_flags.hpp.in
${CMAKE_BINARY_DIR}/include/config_flags.hpp)
# Подключение внешних проектов
include(ExternalProject)
find_package(Qt5 COMPONENTS Core Network REQUIRED)
# Библиотеки
add_subdirectory(src/myx/base)
add_subdirectory(src/myx/filesystem)
add_subdirectory(src/myx/qt)
add_subdirectory(src/myx/math)
add_subdirectory(src/myx/redis)
# add_subdirectory(src/myx/redis)
# Примеры
if(BUILD_EXAMPLES)
if(MYXLIB_BUILD_EXAMPLES OR MYXLIB_BUILD_EXAMPLES_HO)
add_subdirectory(examples/filesystem)
add_subdirectory(examples/qt)
add_dependencies(example-filesystem-minimal create_auxilary_symlinks)
endif()
# Документация
add_subdirectory(cmake/doc)

View File

@ -10,19 +10,5 @@ set(CPACK_COMPONENTS_ALL EXAMPLES)
set(CPACK_GENERATOR "TXZ;DEB")
set(CPACK_PACKAGE_CONTACT "Andrei Astafev <dev@246060.ru>")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Mixed functions")
set(CPACK_DEBIAN_PACKAGE_SECTION "misc")
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
set(CPACK_SOURCE_IGNORE_FILES
.git/
obj.*/
build
files/var
debian/tmp/
debian/files
debian/.*\\\\.log$
debian/.*.substvars
debian/stamp.*
CMakeLists.txt.user
cmake/lib/.git$
~$
\\\\..*\\\\.swp$)
set(CMLIB_GENERATED_HEADERS_PATH ${CMAKE_BINARY_DIR}/include/myx/base)

View File

@ -4,9 +4,9 @@ set(TRGT example-filesystem-minimal)
# Список файлов исходных текстов
set(TRGT_cpp ${CMAKE_CURRENT_SOURCE_DIR}/minimal.cpp)
if(MYXLIB_BUILD_EXAMPLES)
# Путь поиска библиотек внутри проекта
link_directories(${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
link_directories(${CMAKE_BINARY_DIR}/src/myx/filesystem/lib)
# Цель для создания исполняемого файла
add_executable(${TRGT} ${TRGT_cpp} ${TRGT_qrc})
@ -27,19 +27,18 @@ add_pvs_check(${TRGT})
# Создание цели для автоматического форматирования кода
add_format_sources(${TRGT} ${TRGT_cpp})
add_dependencies(${TRGT} base_static)
add_dependencies(${TRGT} filesystem_static)
target_include_directories(${TRGT} PRIVATE ${CMAKE_SOURCE_DIR}/src)
target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
target_compile_definitions(${TRGT} PUBLIC MYXLIB_BUILD_LIBRARIES)
add_dependencies(${TRGT} base_static filesystem_static)
target_link_libraries(${TRGT} myx-filesystem)
target_link_libraries(${TRGT} Qt5::Core)
target_link_libraries(${TRGT} Threads::Threads)
# Имя выходного файла для цели
set_target_properties(${TRGT} PROPERTIES OUTPUT_NAME filesystem-minimal
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})
set_target_properties(${TRGT} PROPERTIES OUTPUT_NAME filesystem-minimal)
add_sanitizers(${TRGT})
@ -48,4 +47,30 @@ cotire(${TRGT})
add_dependencies(${TRGT} create_auxilary_symlinks)
# Правила для установки
install(TARGETS ${TRGT} COMPONENT EXAMPLES RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(TARGETS ${TRGT} COMPONENT examples RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
if(MYXLIB_BUILD_EXAMPLES_HO)
# Цель для создания исполняемого файла
add_executable(${TRGT}-ho ${TRGT_cpp} ${TRGT_qrc})
common_target_properties(${TRGT}-ho)
target_include_directories(${TRGT}-ho PRIVATE ${CMAKE_SOURCE_DIR}/src)
target_include_directories(${TRGT}-ho SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
add_dependencies(${TRGT}-ho base-header-only filesystem-header-only)
target_link_libraries(${TRGT}-ho Qt5::Core)
target_link_libraries(${TRGT}-ho Threads::Threads)
# Имя выходного файла для цели
set_target_properties(${TRGT}-ho PROPERTIES OUTPUT_NAME filesystem-minimal-ho)
add_sanitizers(${TRGT}-ho)
cotire(${TRGT}-ho)
add_dependencies(${TRGT}-ho create_auxilary_symlinks)
# Правила для установки
install(TARGETS ${TRGT}-ho COMPONENT examples RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()

View File

@ -1,5 +1,3 @@
#include "cmlib_private_config.hpp"
#include <myx/base/config.hpp>
#include <myx/filesystem/paths.hpp>
@ -8,12 +6,15 @@
#include <QCoreApplication>
#include <QDebug>
#define CMLIB_PROJECT_NAME "myxlib"
namespace MF = myx::filesystem;
// Переменные для защиты экземпляра класса MF::PathsMT
std::atomic< MF::PathsMT* > MF::PathsMT::mInstance;
std::mutex MF::PathsMT::mMutex;
int main( int argc, char** argv )
{
(void)argc;

View File

@ -10,9 +10,10 @@ qt5_translation(
BASE_NAME ${TRGT}
LANGUAGES ru_RU)
if(MYXLIB_BUILD_EXAMPLES)
# Путь поиска библиотек внутри проекта
link_directories(${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
link_directories(${CMAKE_BINARY_DIR}/src/myx/qt/lib)
# Цель для создания исполняемого файла
add_executable(${TRGT} ${TRGT_cpp} ${TRGT_qrc})
@ -33,19 +34,18 @@ add_pvs_check(${TRGT})
# Создание цели для автоматического форматирования кода
add_format_sources(${TRGT} ${TRGT_cpp})
add_dependencies(${TRGT} base_static)
add_dependencies(${TRGT} qt_static)
# Qt5
target_include_directories(${TRGT} PRIVATE ${CMAKE_SOURCE_DIR}/src)
target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
target_link_libraries(${TRGT} myx-qt)
target_compile_definitions(${TRGT} PUBLIC MYXLIB_HEADER_ONLY)
target_include_directories(${TRGT} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src)
add_dependencies(${TRGT} base qt)
target_link_libraries(${TRGT} Qt5::Core)
# Имя выходного файла для цели
set_target_properties(${TRGT} PROPERTIES OUTPUT_NAME qt-translators
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})
set_target_properties(${TRGT} PROPERTIES OUTPUT_NAME qt-translators)
add_sanitizers(${TRGT})
@ -54,4 +54,30 @@ cotire(${TRGT})
add_dependencies(${TRGT} create_auxilary_symlinks)
# Правила для установки
install(TARGETS ${TRGT} COMPONENT EXAMPLES RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(TARGETS ${TRGT} COMPONENT examples RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
if(MYXLIB_BUILD_EXAMPLES_HO)
# Цель для создания исполняемого файла
add_executable(${TRGT}-ho ${TRGT_cpp} ${TRGT_qrc})
common_target_properties(${TRGT}-ho)
target_include_directories(${TRGT}-ho PRIVATE ${CMAKE_SOURCE_DIR}/src)
target_include_directories(${TRGT}-ho SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
add_dependencies(${TRGT}-ho base-header-only qt-header-only)
target_link_libraries(${TRGT}-ho Qt5::Core)
target_link_libraries(${TRGT}-ho Threads::Threads)
# Имя выходного файла для цели
set_target_properties(${TRGT}-ho PROPERTIES OUTPUT_NAME qt-translators-ho)
add_sanitizers(${TRGT}-ho)
cotire(${TRGT}-ho)
add_dependencies(${TRGT}-ho create_auxilary_symlinks)
# Правила для установки
install(TARGETS ${TRGT}-ho COMPONENT examples RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()

View File

@ -3,47 +3,57 @@ set(TRGT base)
# cmake-format: off
# Список файлов исходных текстов
set(TRGT_sources
set(TRGT_cpp
${CMAKE_CURRENT_SOURCE_DIR}/config.cpp)
# Список заголовочных файлов
set(TRGT_headers
set(TRGT_hpp
${CMAKE_CURRENT_SOURCE_DIR}/config.hpp
${CMAKE_CURRENT_SOURCE_DIR}/config-inl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/limits.hpp
${CMAKE_CURRENT_SOURCE_DIR}/enum_bitmask_operations.hpp)
set(TRGT_headers ${TRGT_hpp})
# cmake-format: on
add_common_library(${TRGT} OUTPUT_NAME myx-${TRGT} SOURCES ${TRGT_sources} ${TRGT_headers})
add_library(${TRGT}-header-only INTERFACE)
target_include_directories(
${TRGT}-header-only SYSTEM INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
if(MYXLIB_BUILD_LIBRARIES)
add_common_library(${TRGT} OUTPUT_NAME myx-${TRGT} SOURCES ${TRGT_cpp} ${TRGT_headers})
common_target_properties(${TRGT})
# Создание цели для проверки утилитой clang-tidy
add_clang_tidy_check(${TRGT} ${TRGT_sources})
add_clang_tidy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
# Создание цели для проверки утилитой clang-analyze
add_clang_analyze_check(${TRGT} ${TRGT_sources})
add_clang_analyze_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
# Создание цели для проверки утилитой clazy
add_clazy_check(${TRGT} ${TRGT_sources})
add_clazy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
# Создание цели для проверки утилитой pvs-studio
add_pvs_check(${TRGT})
# Создание цели для автоматического форматирования кода
add_format_sources(${TRGT} ${TRGT_sources} ${TRGT_headers})
add_format_sources(${TRGT} ${TRGT_cpp} ${TRGT_headers})
target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
target_compile_definitions(${TRGT} PUBLIC MYXLIB_BUILD_LIBRARIES)
target_include_directories(${TRGT} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src)
cotire(${TRGT})
install(TARGETS ${TRGT}_static COMPONENT libs-dev ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(BUILD_SHARED_LIBS)
install(TARGETS ${TRGT}_shared COMPONENT main LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
endif()
install(FILES ${TRGT_headers} ${CMAKE_BINARY_DIR}/include/myx/base/compiler_features.hpp COMPONENT headers
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
install(FILES ${CMAKE_BINARY_DIR}/${TRGT}.pc COMPONENT headers DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
add_custom_target(${TRGT}-install-headers COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=DEV -P
add_custom_target(${TRGT}-install-headers COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=headers -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
# Правила для установки
install(TARGETS ${TRGT}_static COMPONENT DEV ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(BUILD_SHARED_LIBS)
install(TARGETS ${TRGT}_shared COMPONENT DEV LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
install(FILES ${CMAKE_BINARY_DIR}/include/config_flags.hpp ${TRGT_headers} COMPONENT DEV
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
install(FILES ${CMAKE_BINARY_DIR}/${TRGT}.pc COMPONENT DEV DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)

View File

@ -0,0 +1,10 @@
#ifndef MYX_BASE_CONFIG_INL_HPP_
#define MYX_BASE_CONFIG_INL_HPP_
#pragma once
#ifndef MYXLIB_HEADER_ONLY
#include <myx/base/config.hpp>
#endif
#endif // MYX_BASE_CONFIG_INL_HPP_

View File

@ -1 +1,5 @@
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#endif
#include "config.hpp"

View File

@ -1,6 +1,18 @@
#ifndef MYX_BASE_CONFIG_HPP_
#define MYX_BASE_CONFIG_HPP_
#include "config_flags.hpp"
#pragma once
#ifdef MYXLIB_BUILD_LIBRARIES
#undef MYXLIB_HEADER_ONLY
#define MYXLIB_INLINE inline
#else
#define MYXLIB_HEADER_ONLY
#define MYXLIB_INLINE inline
#endif
#ifdef MYXLIB_HEADER_ONLY
#include "config-inl.hpp"
#endif
#endif // MYX_BASE_CONFIG_HPP_

View File

@ -1,7 +1,6 @@
#ifndef MYX_BASE_ENUM_BITWISE_OPERATIONS_HPP_
#define MYX_BASE_ENUM_BITWISE_OPERATIONS_HPP_
#pragma once
#include <type_traits>
@ -13,17 +12,17 @@ namespace base {
template< typename Enum >
struct EnableBitMaskOperators
{
static const bool enable = false;
static const bool k_Enable = false;
};
template< typename Enum >
typename std::enable_if< EnableBitMaskOperators< Enum >::enable, Enum >::type
typename std::enable_if< EnableBitMaskOperators< Enum >::k_Enable, Enum >::type
operator |( Enum lhs, Enum rhs )
{
using underlying = typename std::underlying_type< Enum >::type;
using Underlying = typename std::underlying_type< Enum >::type;
return( static_cast< Enum >(
static_cast< underlying >( lhs ) |
static_cast< underlying >( rhs )
static_cast< Underlying >( lhs ) |
static_cast< Underlying >( rhs )
) );
}
@ -52,7 +51,7 @@ operator |( Enum lhs, Enum rhs )
template<> \
struct myx::base::EnableBitMaskOperators< x > \
{ \
static const bool enable = true; \
static const bool k_Enable = true; \
};
#endif // ifndef MYX_BASE_ENUM_BITWISE_OPERATIONS_HPP_

View File

@ -3,50 +3,62 @@ set(TRGT filesystem)
# cmake-format: off
# Список файлов исходных текстов
set(TRGT_sources
set(TRGT_cpp
${CMAKE_CURRENT_SOURCE_DIR}/current_executable.cpp
${CMAKE_CURRENT_SOURCE_DIR}/paths.cpp
${CMAKE_CURRENT_SOURCE_DIR}/paths_mt.cpp)
# Список заголовочных файлов
set(TRGT_headers
set(TRGT_hpp
${CMAKE_CURRENT_SOURCE_DIR}/current_executable.hpp
${CMAKE_CURRENT_SOURCE_DIR}/paths.hpp
${CMAKE_CURRENT_SOURCE_DIR}/paths_mt.hpp)
${CMAKE_CURRENT_SOURCE_DIR}/paths_mt.hpp
${CMAKE_CURRENT_SOURCE_DIR}/current_executable-inl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/paths-inl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/paths_mt-inl.hpp)
set(TRGT_headers ${TRGT_hpp})
# cmake-format: on
add_common_library(${TRGT} OUTPUT_NAME myx-${TRGT} SOURCES ${TRGT_sources})
add_library(${TRGT}-header-only INTERFACE)
target_include_directories(
${TRGT}-header-only SYSTEM INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
if(MYXLIB_BUILD_LIBRARIES)
add_common_library(${TRGT} OUTPUT_NAME myx-${TRGT} SOURCES ${TRGT_cpp} ${TRGT_headers})
common_target_properties(${TRGT})
# Создание цели для проверки утилитой clang-tidy
add_clang_tidy_check(${TRGT} ${TRGT_sources})
add_clang_tidy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
# Создание цели для проверки утилитой clang-analyze
add_clang_analyze_check(${TRGT} ${TRGT_sources})
add_clang_analyze_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
# Создание цели для проверки утилитой clazy
add_clazy_check(${TRGT} ${TRGT_sources})
add_clazy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
# Создание цели для проверки утилитой pvs-studio
add_pvs_check(${TRGT})
# Создание цели для автоматического форматирования кода
add_format_sources(${TRGT} ${TRGT_sources} ${TRGT_headers})
add_format_sources(${TRGT} ${TRGT_cpp} ${TRGT_headers})
target_compile_definitions(${TRGT} PUBLIC MYXLIB_BUILD_LIBRARIES)
target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
target_include_directories(${TRGT} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src)
target_include_directories(${TRGT} PRIVATE ${CMAKE_BINARY_DIR}/include)
cotire(${TRGT})
install(TARGETS ${TRGT}_static COMPONENT libs-dev ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(BUILD_SHARED_LIBS)
install(TARGETS ${TRGT}_shared COMPONENT main LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
endif()
install(FILES ${TRGT_headers} COMPONENT DEV DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
install(FILES ${CMAKE_BINARY_DIR}/${TRGT}.pc COMPONENT DEV DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
add_custom_target(${TRGT}-install-headers COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=DEV -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
# Правила для установки
install(TARGETS ${TRGT}_static COMPONENT DEV ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(BUILD_SHARED_LIBS)
install(TARGETS ${TRGT}_shared COMPONENT DEV LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
install(FILES ${TRGT_headers} COMPONENT DEV DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
install(FILES ${CMAKE_BINARY_DIR}/${TRGT}.pc COMPONENT DEV DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)

View File

@ -0,0 +1,41 @@
#ifndef MYX_BASE_CURRENT_EXECUTABLE_INL_HPP_
#define MYX_BASE_CURRENT_EXECUTABLE_INL_HPP_
#pragma once
#ifndef MYXLIB_HEADER_ONLY
#include <myx/filesystem/current_executable.hpp>
#endif
#include <myx/base/config.hpp>
#include <paths.h>
#include <QCoreApplication>
#include <QString>
namespace myx {
namespace filesystem {
#if !defined ( __linux__ )
error "Class CurrentExecutable is supported only in Linux"
#endif
MYXLIB_INLINE CurrentExecutable::CurrentExecutable() :
m_procFilePath( QStringLiteral( "/proc/self/exe" ) )
{
m_canonicalFilePath = m_procFilePath.canonicalFilePath();
}
MYXLIB_INLINE const QFileInfo& CurrentExecutable::canonicalFilePath() const
{
return( m_canonicalFilePath );
}
} // namespace filesystem
} // namespace myx
#endif // MYX_BASE_CURRENT_EXECUTABLE_INL_HPP_

View File

@ -1,31 +1,5 @@
#include <myx/base/config.hpp>
#include <myx/filesystem/current_executable.hpp>
#include <paths.h>
#include <QCoreApplication>
#include <QString>
namespace myx {
namespace filesystem {
#if !defined ( __linux__ )
error "Class CurrentExecutable is supported only in Linux"
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#endif
CurrentExecutable::CurrentExecutable() :
m_procFilePath( QStringLiteral( "/proc/self/exe" ) )
{
m_canonicalFilePath = m_procFilePath.canonicalFilePath();
}
const QFileInfo& CurrentExecutable::canonicalFilePath() const
{
return( m_canonicalFilePath );
}
} // namespace filesystem
} // namespace myx
#include <myx/filesystem/current_executable-inl.hpp>

View File

@ -8,9 +8,11 @@
#pragma once
#include <QString>
#include <myx/base/config.hpp>
#include <QDir>
#include <QFileInfo>
#include <QString>
namespace myx {
@ -42,4 +44,8 @@ public:
} // namespace myx
#ifdef MYXLIB_HEADER_ONLY
#include "current_executable-inl.hpp"
#endif
#endif // MYX_FILESYSTEM_CURRENT_EXECUTABLE_HPP_

View File

@ -0,0 +1,359 @@
#ifndef MYX_BASE_PATHS_INL_HPP_
#define MYX_BASE_PATHS_INL_HPP_
#pragma once
#ifndef MYXLIB_HEADER_ONLY
#include <myx/filesystem/paths.hpp>
#endif
#include <myx/base/config.hpp>
#include <myx/filesystem/current_executable.hpp>
#include <paths.h>
#include <QCoreApplication>
#include <QString>
namespace myx {
namespace filesystem {
MYXLIB_INLINE Paths::Paths() = default;
MYXLIB_INLINE Paths::HierarchyType Paths::getHierarchyType()
{
QRegExp binUnityRegexp( "/s*bin/unity$" );
QRegExp binRegexp( "/s*bin$" );
auto binaryDir = m_currentExecutable.m_canonicalFilePath.canonicalPath();
if ( binUnityRegexp.indexIn( binaryDir ) >= 0 )
{
binaryDir.remove( binUnityRegexp );
QFileInfo etcDirInfo { binaryDir + "/etc" };
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo constDataDirInfo { binaryDir + "/files/data" };
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo varDataDirInfo { binaryDir + "/files/lib" };
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
QFileInfo logDirInfo { binaryDir + "/files/log" };
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
m_systemLogDirectory = logDirInfo.canonicalFilePath();
return ( HierarchyType::kDevelopment );
}
if ( binRegexp.indexIn( binaryDir ) == -1 )
{
return ( HierarchyType::kFlat );
}
QRegExp optRegexp( "^/opt(/|/.+/)" + m_projectName + "/" );
if ( optRegexp.indexIn( binaryDir ) >= 0 )
{
binaryDir.remove( binRegexp );
QFileInfo etcDirInfo { binaryDir + "/etc" };
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo constDataDirInfo { binaryDir + "/files/data" };
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo varDataDirInfo { binaryDir + "/files/lib" };
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
QFileInfo logDirInfo { binaryDir + "/files/log" };
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
m_systemLogDirectory = logDirInfo.canonicalFilePath();
return ( HierarchyType::kOpt );
}
if ( binaryDir.startsWith( QStringLiteral( "/usr/local" ) ) )
{
QFileInfo etcDirInfo { "/usr/local/etc/" + m_projectName };
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo constDataDirInfo { "/usr/local/share/" + m_projectName };
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo varDataDirInfo { "/var/lib/" + m_projectName };
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
QFileInfo logDirInfo { "/var/log/" + m_projectName };
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
m_systemLogDirectory = logDirInfo.canonicalFilePath();
return ( HierarchyType::kUsr );
}
if ( binaryDir.startsWith( QStringLiteral( "/usr" ) ) )
{
QFileInfo etcDirInfo { "/etc/" + m_projectName };
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo constDataDirInfo { "/usr/share/" + m_projectName };
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo varDataDirInfo { "/var/lib/" + m_projectName };
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
QFileInfo logDirInfo { "/var/log/" + m_projectName };
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
m_systemLogDirectory = logDirInfo.canonicalFilePath();
return ( HierarchyType::kUsr );
}
if ( binaryDir.startsWith( m_homeDirectory.canonicalPath() + "/.local/bin" ) ||
binaryDir.startsWith( m_homeDirectory.canonicalPath() + "/bin" ) )
{
QFileInfo etcDirInfo { m_userConfigDirectory.canonicalPath() };
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo constDataDirInfo { m_userConstDataDirectory.canonicalPath() };
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo varDataDirInfo { m_userVarDataDirectory.canonicalPath() };
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
QFileInfo logDirInfo { m_userLogDirectory.canonicalPath() };
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
m_systemLogDirectory = logDirInfo.canonicalFilePath();
return( HierarchyType::kHome );
}
binaryDir.remove( binRegexp );
QFileInfo etcDirInfo { binaryDir + "/etc" };
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo constDataDirInfo { binaryDir + "/files/data" };
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo varDataDirInfo { binaryDir + "/files/lib" };
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
QFileInfo logDirInfo { binaryDir + "/files/log" };
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
m_systemLogDirectory = logDirInfo.canonicalFilePath();
return ( HierarchyType::kDevelopment );
} // Paths::getHierarchyType
MYXLIB_INLINE bool Paths::init( const QString& projectDir, const QString& configFileExtension )
{
m_projectName = projectDir.isEmpty() ? m_currentExecutable.m_canonicalFilePath.fileName()
: projectDir;
m_configFileExtension = configFileExtension.isEmpty() ? QStringLiteral( "conf" )
: configFileExtension;
m_configFileName = m_projectName + "." + m_configFileExtension;
m_homeDirectory = QDir::homePath();
m_tempDirectory = QDir::tempPath();
auto configHome = QString::fromLocal8Bit( qgetenv( "XDG_CONFIG_HOME" ) );
if ( configHome.isEmpty() )
{
configHome = m_homeDirectory.canonicalPath() + "/.config";
}
m_userConfigDirectory = configHome + "/" + m_projectName;
auto dataHome = QString::fromLocal8Bit( qgetenv( "XDG_DATA_HOME" ) );
if ( dataHome.isEmpty() )
{
dataHome = m_homeDirectory.canonicalPath() + "/.local/share";
}
dataHome += "/" + m_projectName;
m_userConstDataDirectory = dataHome + "/data";
m_userVarDataDirectory = dataHome + "/lib";
m_userLogDirectory = dataHome + "/log";
m_hierarchyType = getHierarchyType();
if ( m_hierarchyType == HierarchyType::kFlat )
{
m_systemConstDataDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
m_systemVarDataDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
m_systemConfigDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
m_systemLogDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
}
m_configFilePath = m_systemConfigDirectory.canonicalPath() + "/" + m_configFileName;
return( true );
} // Paths::updatePaths
MYXLIB_INLINE bool Paths::makeDefaultDirectories()
{
bool status = true;
if ( !m_userConfigDirectory.mkpath( m_userConfigDirectory.absolutePath() ) ) { status = false; }
if ( !m_userVarDataDirectory.mkpath( m_userVarDataDirectory.absolutePath() ) ) { status = false; }
if ( !m_userConstDataDirectory.mkpath( m_userConstDataDirectory.absolutePath() ) ) { status = false; }
if ( !m_userLogDirectory.mkpath( m_userLogDirectory.absolutePath() ) ) { status = false; }
return( status );
}
MYXLIB_INLINE QString Paths::findConfigFile( const QString& defaultConfigFile )
{
if ( !defaultConfigFile.isEmpty() && QFileInfo( defaultConfigFile ).isReadable() )
{
m_configFilePath = defaultConfigFile;
return( defaultConfigFile );
}
auto fileName = QString::fromLocal8Bit( qgetenv( QCoreApplication::applicationName()
.toUpper().toUtf8() + "_CONFIG" ) );
if ( QFileInfo( fileName ).isReadable() )
{
m_configFilePath = fileName;
return( fileName );
}
if ( QFileInfo( m_configFilePath ).isReadable() )
{
return( m_configFilePath.absoluteFilePath() );
}
return( QString() );
} // Paths::findConfigFile
MYXLIB_INLINE QDir Paths::executableFileDirectory() const
{
return( m_currentExecutable.m_canonicalFilePath.dir() );
}
MYXLIB_INLINE const QDir& Paths::userConfigDirectory() const
{
return( m_userConfigDirectory );
}
MYXLIB_INLINE const QDir& Paths::systemConfigDirectory() const
{
return( m_systemConfigDirectory );
}
MYXLIB_INLINE const QFileInfo& Paths::configFilePath() const
{
return( m_configFilePath );
}
MYXLIB_INLINE const QString& Paths::configFileName() const
{
return( m_configFileName );
}
MYXLIB_INLINE const QString& Paths::configFileExtension() const
{
return( m_configFileExtension );
}
MYXLIB_INLINE const QDir& Paths::userVarDataDirectory() const
{
return( m_userVarDataDirectory );
}
MYXLIB_INLINE const QDir& Paths::systemVarDataDirectory() const
{
return( m_systemVarDataDirectory );
}
MYXLIB_INLINE const QDir& Paths::userConstDataDirectory() const
{
return( m_userConstDataDirectory );
}
MYXLIB_INLINE const QDir& Paths::systemConstDataDirectory() const
{
return( m_systemConstDataDirectory );
}
MYXLIB_INLINE const QDir& Paths::userLogDirectory() const
{
return( m_userLogDirectory );
}
MYXLIB_INLINE const QDir& Paths::systemLogDirectory() const
{
return( m_systemLogDirectory );
}
MYXLIB_INLINE const QDir& Paths::tempDirectory() const
{
return( m_tempDirectory );
}
MYXLIB_INLINE const QDir& Paths::homeDirectory() const
{
return( m_homeDirectory );
}
MYXLIB_INLINE const QString& Paths::projectName() const
{
return( m_projectName );
}
MYXLIB_INLINE QString Paths::executableFileName() const
{
return( m_currentExecutable.m_canonicalFilePath.fileName() );
}
MYXLIB_INLINE const QFileInfo& Paths::executableFilePath() const
{
return( m_currentExecutable.m_canonicalFilePath );
}
} // namespace filesystem
} // namespace myx
#endif // MYX_BASE_PATHS_INL_HPP_

View File

@ -1,349 +1,5 @@
#include <myx/base/config.hpp>
#include <myx/filesystem/current_executable.hpp>
#include <myx/filesystem/paths.hpp>
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#endif
#include <paths.h>
#include <QCoreApplication>
#include <QString>
namespace myx {
namespace filesystem {
Paths::Paths() = default;
Paths::HierarchyType Paths::getHierarchyType()
{
QRegExp binUnityRegexp( "/s*bin/unity$" );
QRegExp binRegexp( "/s*bin$" );
auto binaryDir = m_currentExecutable.m_canonicalFilePath.canonicalPath();
if ( binUnityRegexp.indexIn( binaryDir ) >= 0 )
{
binaryDir.remove( binUnityRegexp );
QFileInfo etcDirInfo { binaryDir + "/etc" };
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo constDataDirInfo { binaryDir + "/files/data" };
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo varDataDirInfo { binaryDir + "/files/lib" };
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
QFileInfo logDirInfo { binaryDir + "/files/log" };
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
m_systemLogDirectory = logDirInfo.canonicalFilePath();
return ( HierarchyType::kDevelopment );
}
if ( binRegexp.indexIn( binaryDir ) == -1 )
{
return ( HierarchyType::kFlat );
}
QRegExp optRegexp( "^/opt(/|/.+/)" + m_projectName + "/" );
if ( optRegexp.indexIn( binaryDir ) >= 0 )
{
binaryDir.remove( binRegexp );
QFileInfo etcDirInfo { binaryDir + "/etc" };
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo constDataDirInfo { binaryDir + "/files/data" };
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo varDataDirInfo { binaryDir + "/files/lib" };
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
QFileInfo logDirInfo { binaryDir + "/files/log" };
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
m_systemLogDirectory = logDirInfo.canonicalFilePath();
return ( HierarchyType::kOpt );
}
if ( binaryDir.startsWith( QStringLiteral( "/usr/local" ) ) )
{
QFileInfo etcDirInfo { "/usr/local/etc/" + m_projectName };
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo constDataDirInfo { "/usr/local/share/" + m_projectName };
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo varDataDirInfo { "/var/lib/" + m_projectName };
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
QFileInfo logDirInfo { "/var/log/" + m_projectName };
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
m_systemLogDirectory = logDirInfo.canonicalFilePath();
return ( HierarchyType::kUsr );
}
if ( binaryDir.startsWith( QStringLiteral( "/usr" ) ) )
{
QFileInfo etcDirInfo { "/etc/" + m_projectName };
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo constDataDirInfo { "/usr/share/" + m_projectName };
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo varDataDirInfo { "/var/lib/" + m_projectName };
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
QFileInfo logDirInfo { "/var/log/" + m_projectName };
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
m_systemLogDirectory = logDirInfo.canonicalFilePath();
return ( HierarchyType::kUsr );
}
if ( binaryDir.startsWith( m_homeDirectory.canonicalPath() + "/.local/bin" ) ||
binaryDir.startsWith( m_homeDirectory.canonicalPath() + "/bin" ) )
{
QFileInfo etcDirInfo { m_userConfigDirectory.canonicalPath() };
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo constDataDirInfo { m_userConstDataDirectory.canonicalPath() };
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo varDataDirInfo { m_userVarDataDirectory.canonicalPath() };
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
QFileInfo logDirInfo { m_userLogDirectory.canonicalPath() };
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
m_systemLogDirectory = logDirInfo.canonicalFilePath();
return( HierarchyType::kHome );
}
binaryDir.remove( binRegexp );
QFileInfo etcDirInfo { binaryDir + "/etc" };
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo constDataDirInfo { binaryDir + "/files/data" };
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
QFileInfo varDataDirInfo { binaryDir + "/files/lib" };
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
QFileInfo logDirInfo { binaryDir + "/files/log" };
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
m_systemLogDirectory = logDirInfo.canonicalFilePath();
return ( HierarchyType::kDevelopment );
} // Paths::getHierarchyType
bool Paths::init( const QString& projectDir, const QString& configFileExtension )
{
m_projectName = projectDir.isEmpty() ? m_currentExecutable.m_canonicalFilePath.fileName()
: projectDir;
m_configFileExtension = configFileExtension.isEmpty() ? QStringLiteral( "conf" )
: configFileExtension;
m_configFileName = m_projectName + "." + m_configFileExtension;
m_homeDirectory = QDir::homePath();
m_tempDirectory = QDir::tempPath();
auto configHome = QString::fromLocal8Bit( qgetenv( "XDG_CONFIG_HOME" ) );
if ( configHome.isEmpty() )
{
configHome = m_homeDirectory.canonicalPath() + "/.config";
}
m_userConfigDirectory = configHome + "/" + m_projectName;
auto dataHome = QString::fromLocal8Bit( qgetenv( "XDG_DATA_HOME" ) );
if ( dataHome.isEmpty() )
{
dataHome = m_homeDirectory.canonicalPath() + "/.local/share";
}
dataHome += "/" + m_projectName;
m_userConstDataDirectory = dataHome + "/data";
m_userVarDataDirectory = dataHome + "/lib";
m_userLogDirectory = dataHome + "/log";
m_hierarchyType = getHierarchyType();
if ( m_hierarchyType == HierarchyType::kFlat )
{
m_systemConstDataDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
m_systemVarDataDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
m_systemConfigDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
m_systemLogDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
}
m_configFilePath = m_systemConfigDirectory.canonicalPath() + "/" + m_configFileName;
return( true );
} // Paths::updatePaths
bool Paths::makeDefaultDirectories()
{
bool status = true;
if ( !m_userConfigDirectory.mkpath( m_userConfigDirectory.absolutePath() ) ) { status = false; }
if ( !m_userVarDataDirectory.mkpath( m_userVarDataDirectory.absolutePath() ) ) { status = false; }
if ( !m_userConstDataDirectory.mkpath( m_userConstDataDirectory.absolutePath() ) ) { status = false; }
if ( !m_userLogDirectory.mkpath( m_userLogDirectory.absolutePath() ) ) { status = false; }
return( status );
}
QString Paths::findConfigFile( const QString& defaultConfigFile )
{
if ( !defaultConfigFile.isEmpty() && QFileInfo( defaultConfigFile ).isReadable() )
{
m_configFilePath = defaultConfigFile;
return( defaultConfigFile );
}
auto fileName = QString::fromLocal8Bit( qgetenv( QCoreApplication::applicationName()
.toUpper().toUtf8() + "_CONFIG" ) );
if ( QFileInfo( fileName ).isReadable() )
{
m_configFilePath = fileName;
return( fileName );
}
if ( QFileInfo( m_configFilePath ).isReadable() )
{
return( m_configFilePath.absoluteFilePath() );
}
return( QString() );
} // Paths::findConfigFile
QDir Paths::executableFileDirectory() const
{
return( m_currentExecutable.m_canonicalFilePath.dir() );
}
const QDir& Paths::userConfigDirectory() const
{
return( m_userConfigDirectory );
}
const QDir& Paths::systemConfigDirectory() const
{
return( m_systemConfigDirectory );
}
const QFileInfo& Paths::configFilePath() const
{
return( m_configFilePath );
}
const QString& Paths::configFileName() const
{
return( m_configFileName );
}
const QString& Paths::configFileExtension() const
{
return( m_configFileExtension );
}
const QDir& Paths::userVarDataDirectory() const
{
return( m_userVarDataDirectory );
}
const QDir& Paths::systemVarDataDirectory() const
{
return( m_systemVarDataDirectory );
}
const QDir& Paths::userConstDataDirectory() const
{
return( m_userConstDataDirectory );
}
const QDir& Paths::systemConstDataDirectory() const
{
return( m_systemConstDataDirectory );
}
const QDir& Paths::userLogDirectory() const
{
return( m_userLogDirectory );
}
const QDir& Paths::systemLogDirectory() const
{
return( m_systemLogDirectory );
}
const QDir& Paths::tempDirectory() const
{
return( m_tempDirectory );
}
const QDir& Paths::homeDirectory() const
{
return( m_homeDirectory );
}
const QString& Paths::projectName() const
{
return( m_projectName );
}
QString Paths::executableFileName() const
{
return( m_currentExecutable.m_canonicalFilePath.fileName() );
}
const QFileInfo& Paths::executableFilePath() const
{
return( m_currentExecutable.m_canonicalFilePath );
}
} // namespace filesystem
} // namespace myx
#include <myx/filesystem/paths-inl.hpp>

View File

@ -8,11 +8,12 @@
#pragma once
#include <myx/base/config.hpp>
#include <myx/filesystem/current_executable.hpp>
#include <QString>
#include <QDir>
#include <QFileInfo>
#include <QString>
namespace myx {
@ -88,8 +89,8 @@ class Paths
protected:
Paths();
~Paths() = default;
Paths( const Paths& ) = delete;
Paths& operator=( const Paths& ) = delete;
Paths( const Paths& ) = delete; // NOLINT
Paths& operator=( const Paths& ) = delete; // NOLINT
public:
/**
@ -218,4 +219,8 @@ public:
} // namespace myx
#ifdef MYXLIB_HEADER_ONLY
#include "paths-inl.hpp"
#endif
#endif // MYX_FILESYSTEM_PATHS_HPP_

View File

@ -0,0 +1,44 @@
#ifndef MYX_BASE_PATHS_MT_INL_HPP_
#define MYX_BASE_PATHS_MT_INL_HPP_
#pragma once
#ifndef MYXLIB_HEADER_ONLY
#include <myx/filesystem/paths_mt.hpp>
#endif
#include <myx/base/config.hpp>
#include <myx/filesystem/current_executable.hpp>
#include <paths.h>
#include <QCoreApplication>
#include <QString>
namespace myx {
namespace filesystem {
MYXLIB_INLINE PathsMT::PathsMT() = default;
MYXLIB_INLINE PathsMT& PathsMT::instance()
{
volatile PathsMT* localInstance = mInstance.load( std::memory_order_acquire );
if ( localInstance == nullptr )
{
std::lock_guard< std::mutex > myLock( mMutex );
localInstance = mInstance.load( std::memory_order_relaxed );
if ( localInstance == nullptr ) // -V1036
{
localInstance = new PathsMT();
mInstance.store( const_cast< PathsMT* >( localInstance ), std::memory_order_release ); // NOLINT
}
}
return( const_cast< PathsMT& >( *localInstance ) ); // NOLINT
}
} // namespace filesystem
} // namespace myx
#endif // MYX_BASE_PATHS_MT_INL_HPP_

View File

@ -1,34 +1,5 @@
#include <myx/base/config.hpp>
#include <myx/filesystem/current_executable.hpp>
#include <myx/filesystem/paths_mt.hpp>
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#endif
#include <paths.h>
#include <QCoreApplication>
#include <QString>
namespace myx {
namespace filesystem {
PathsMT::PathsMT() = default;
PathsMT& PathsMT::instance()
{
volatile PathsMT* localInstance = mInstance.load( std::memory_order_acquire );
if ( localInstance == nullptr )
{
std::lock_guard< std::mutex > myLock( mMutex );
localInstance = mInstance.load( std::memory_order_relaxed );
if ( localInstance == nullptr ) // -V1036
{
localInstance = new PathsMT();
mInstance.store( const_cast< PathsMT* >( localInstance ), std::memory_order_release ); // NOLINT
}
}
return( const_cast< PathsMT& >( *localInstance ) ); // NOLINT
}
} // namespace filesystem
} // namespace myx
#include <myx/filesystem/paths_mt-inl.hpp>

View File

@ -8,12 +8,13 @@
#pragma once
#include <myx/filesystem/paths.hpp>
#include <myx/base/config.hpp>
#include <myx/filesystem/current_executable.hpp>
#include <myx/filesystem/paths.hpp>
#include <QString>
#include <QDir>
#include <QFileInfo>
#include <QString>
#include <atomic>
#include <future>
@ -29,8 +30,8 @@ class PathsMT : public Paths
{
PathsMT();
~PathsMT() = default;
PathsMT( const PathsMT& ) = delete;
PathsMT& operator=( const PathsMT& ) = delete;
PathsMT( const PathsMT& ) = delete; // NOLINT
PathsMT& operator=( const PathsMT& ) = delete; // NOLINT
static std::atomic< PathsMT* > mInstance;
static std::mutex mMutex;
@ -47,4 +48,8 @@ public:
} // namespace myx
#ifdef MYXLIB_HEADER_ONLY
#include "paths_mt-inl.hpp"
#endif
#endif // MYX_FILESYSTEM_PATHS_MT_HPP_

View File

@ -3,7 +3,7 @@ set(TRGT math)
# cmake-format: off
# Список файлов исходных текстов
set(TRGT_sources
set(TRGT_cpp
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_relative.cpp
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_relative_and_abs.cpp
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_ulps.cpp
@ -11,30 +11,45 @@ set(TRGT_sources
${CMAKE_CURRENT_SOURCE_DIR}/constants.cpp)
# Список заголовочных файлов
set(TRGT_headers
set(TRGT_hpp
${CMAKE_CURRENT_SOURCE_DIR}/all.hpp
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_relative.hpp
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_relative-inl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_relative_and_abs.hpp
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_relative_and_abs-inl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_ulps.hpp
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_ulps-inl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_ulps_and_abs.hpp
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_ulps_and_abs-inl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/constants.hpp
${CMAKE_CURRENT_SOURCE_DIR}/constants-inl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/float_cmp_types.hpp
${CMAKE_CURRENT_SOURCE_DIR}/functions.hpp
${CMAKE_CURRENT_SOURCE_DIR}/radar.hpp
${CMAKE_CURRENT_SOURCE_DIR}/units.hpp)
set(TRGT_headers ${TRGT_hpp})
# cmake-format: on
add_common_library(${TRGT} OUTPUT_NAME myx-${TRGT} SOURCES ${TRGT_sources})
add_library(${TRGT}-header-only INTERFACE)
target_sources(${TRGT}-header-only INTERFACE ${TRGT_headers})
target_include_directories(
${TRGT}-header-only SYSTEM INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
if(MYXLIB_BUILD_LIBRARIES)
add_common_library(${TRGT} OUTPUT_NAME myx-${TRGT} SOURCES ${TRGT_cpp} ${TRGT_headers})
common_target_properties(${TRGT})
# Создание цели для проверки утилитой clang-tidy
add_clang_tidy_check(${TRGT} ${TRGT_sources})
add_clang_tidy_check(${TRGT} ${TRGT_sources} ${TRGT_headers})
# Создание цели для проверки утилитой clang-analyze
add_clang_analyze_check(${TRGT} ${TRGT_sources})
add_clang_analyze_check(${TRGT} ${TRGT_sources} ${TRGT_headers})
# Создание цели для проверки утилитой clazy
add_clazy_check(${TRGT} ${TRGT_sources})
add_clazy_check(${TRGT} ${TRGT_sources} ${TRGT_headers})
# Создание цели для проверки утилитой pvs-studio
add_pvs_check(${TRGT})
@ -42,20 +57,19 @@ add_pvs_check(${TRGT})
# Создание цели для автоматического форматирования кода
add_format_sources(${TRGT} ${TRGT_sources} ${TRGT_headers})
target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
target_compile_definitions(${TRGT} PUBLIC MYXLIB_BUILD_LIBRARIES)
target_include_directories(${TRGT} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src)
target_include_directories(${TRGT} PRIVATE ${CMAKE_BINARY_DIR}/include)
cotire(${TRGT})
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
add_custom_target(${TRGT}-install-headers COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=DEV -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
# Правила для установки
install(TARGETS ${TRGT}_static COMPONENT DEV ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(BUILD_SHARED_LIBS)
install(TARGETS ${TRGT}_shared COMPONENT DEV LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
endif()
install(FILES ${TRGT_headers} COMPONENT DEV DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
install(FILES ${CMAKE_BINARY_DIR}/${TRGT}.pc COMPONENT DEV DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
add_custom_target(${TRGT}-install-headers COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=DEV -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")

View File

@ -1,8 +1,15 @@
#ifndef MYX_MATH_ALL_HPP_
#define MYX_MATH_ALL_HPP_
#pragma once
#include <myx/math/almost_equal_relative.hpp>
#include <myx/math/almost_equal_relative_and_abs.hpp>
#include <myx/math/almost_equal_ulps.hpp>
#include <myx/math/almost_equal_ulps_and_abs.hpp>
#include <myx/math/constants.hpp>
#include <myx/math/functions.hpp>
#include <myx/math/units.hpp>
#include <myx/math/radar.hpp>
#include <myx/math/almost_equal_relative_and_abs.hpp>
#include <myx/math/almost_equal_relative.hpp>
#include <myx/math/almost_equal_ulps_and_abs.hpp>
#include <myx/math/almost_equal_ulps.hpp>
#include <myx/math/units.hpp>
#endif

View File

@ -0,0 +1,51 @@
#ifndef MYX_MATH_ALMOST_EQUAL_RELATIVE_INL_HPP_
#define MYX_MATH_ALMOST_EQUAL_RELATIVE_INL_HPP_
#pragma once
#ifndef MYXLIB_HEADER_ONLY
#include <myx/math/almost_equal_relative.hpp>
#endif
#include <cmath>
namespace myx {
namespace math {
MYXLIB_INLINE bool almost_equal_relative( const float a, const float b,
const float maxRelDiff )
{
float diff = fabsf( a - b );
float aN = fabsf( a );
float bN = fabsf( b );
float largest = ( bN > aN ) ? bN : aN;
if ( diff <= largest * maxRelDiff )
{
return( true );
}
return( false );
}
MYXLIB_INLINE bool almost_equal_relative( const double a, const double b,
const double maxRelDiff )
{
double diff = fabs( a - b );
double aN = fabs( a );
double bN = fabs( b );
double largest = ( bN > aN ) ? bN : aN;
if ( diff <= largest * maxRelDiff )
{
return( true );
}
return( false );
}
} // namespace math
} // namespace myx
#endif

View File

@ -1,42 +1,5 @@
#include <myx/math/almost_equal_relative.hpp>
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#endif
#include <cmath>
namespace myx {
namespace math {
bool almost_equal_relative( const float a, const float b,
const float maxRelDiff )
{
float diff = fabsf( a - b );
float aN = fabsf( a );
float bN = fabsf( b );
float largest = ( bN > aN ) ? bN : aN;
if ( diff <= largest * maxRelDiff )
{
return( true );
}
return( false );
}
bool almost_equal_relative( const double a, const double b,
const double maxRelDiff )
{
double diff = fabs( a - b );
double aN = fabs( a );
double bN = fabs( b );
double largest = ( bN > aN ) ? bN : aN;
if ( diff <= largest * maxRelDiff )
{
return( true );
}
return( false );
}
} // namespace math
} // namespace myx
#include <myx/math/almost_equal_relative-inl.hpp>

View File

@ -1,6 +1,10 @@
#ifndef MYX_MATH_ALMOST_EQUAL_RELATIVE_HPP_
#define MYX_MATH_ALMOST_EQUAL_RELATIVE_HPP_
#pragma once
#include <myx/base/config.hpp>
#include <cfloat>
// https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
@ -14,18 +18,22 @@ namespace math {
* Параметр maxRelDiff определяет максимальную относительную допустимую разницу,
* при которой аргументы считаются равными.
*/
bool almost_equal_relative( const float a, const float b,
const float maxRelDiff = FLT_EPSILON );
bool almost_equal_relative( float a, float b,
float maxRelDiff = FLT_EPSILON );
/**
* @brief Проверка на равенство двух аргументов типа double.
* Параметр maxRelDiff определяет максимальную относительную допустимую разницу,
* при которой аргументы считаются равными.
*/
bool almost_equal_relative( const double a, const double b,
const double maxRelDiff = DBL_EPSILON );
bool almost_equal_relative( double a, double b,
double maxRelDiff = DBL_EPSILON );
} // namespace math
} // namespace myx
#ifdef MYXLIB_HEADER_ONLY
#include "almost_equal_relative-inl.hpp"
#endif
#endif // MYX_MATH_ALMOST_EQUAL_RELATIVE_HPP_

View File

@ -0,0 +1,65 @@
#ifndef MYX_MATH_ALMOST_EQUAL_RELATIVE_AND_ABS_INL_HPP_
#define MYX_MATH_ALMOST_EQUAL_RELATIVE_AND_ABS_INL_HPP_
#pragma once
#ifndef MYXLIB_HEADER_ONLY
#include <myx/math/almost_equal_relative_and_abs.hpp>
#endif
#include <cmath>
namespace myx {
namespace math {
MYXLIB_INLINE bool almost_equal_relative_and_abs( const float a, const float b,
const float maxAbsDiff, const float maxRelDiff )
{
// Check if the numbers are really close -- needed
// when comparing numbers near zero.
float diff = fabsf( a - b );
if ( diff <= maxAbsDiff )
{
return( true );
}
float aN = fabsf( a );
float bN = fabsf( b );
float largest = ( bN > aN ) ? bN : aN;
if ( diff <= largest * maxRelDiff )
{
return( true );
}
return( false );
}
MYXLIB_INLINE bool almost_equal_relative_and_abs( const double a, const double b,
const double maxAbsDiff, const double maxRelDiff )
{
// Check if the numbers are really close -- needed
// when comparing numbers near zero.
double diff = fabs( a - b );
if ( diff <= maxAbsDiff )
{
return( true );
}
double aN = fabs( a );
double bN = fabs( b );
double largest = ( bN > aN ) ? bN : aN;
if ( diff <= largest * maxRelDiff )
{
return( true );
}
return( false );
}
} // namespace math
} // namespace myx
#endif

View File

@ -1,56 +1,5 @@
#include <myx/math/almost_equal_relative_and_abs.hpp>
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#endif
#include <cmath>
namespace myx {
namespace math {
bool almost_equal_relative_and_abs( const float a, const float b,
const float maxAbsDiff, const float maxRelDiff )
{
// Check if the numbers are really close -- needed
// when comparing numbers near zero.
float diff = fabsf( a - b );
if ( diff <= maxAbsDiff )
{
return( true );
}
float aN = fabsf( a );
float bN = fabsf( b );
float largest = ( bN > aN ) ? bN : aN;
if ( diff <= largest * maxRelDiff )
{
return( true );
}
return( false );
}
bool almost_equal_relative_and_abs( const double a, const double b,
const double maxAbsDiff, const double maxRelDiff )
{
// Check if the numbers are really close -- needed
// when comparing numbers near zero.
double diff = fabs( a - b );
if ( diff <= maxAbsDiff )
{
return( true );
}
double aN = fabs( a );
double bN = fabs( b );
double largest = ( bN > aN ) ? bN : aN;
if ( diff <= largest * maxRelDiff )
{
return( true );
}
return( false );
}
} // namespace math
} // namespace myx
#include <myx/math/almost_equal_relative_and_abs-inl.hpp>

View File

@ -1,6 +1,10 @@
#ifndef MYX_MATH_ALMOST_EQUAL_RELATIVE_AND_ABS_HPP_
#define MYX_MATH_ALMOST_EQUAL_RELATIVE_AND_ABS_HPP_
#pragma once
#include <myx/base/config.hpp>
#include <cfloat>
namespace myx {
@ -13,19 +17,23 @@ namespace math {
* Параметр maxRelDiff определяет максимальную относительную допустимую разницу,
* при которой аргументы считаются равными.
*/
bool almost_equal_relative_and_abs( const float a, const float b,
const float maxAbsDiff, const float maxRelDiff = FLT_EPSILON );
bool almost_equal_relative_and_abs( float a, float b,
float maxAbsDiff, float maxRelDiff = FLT_EPSILON );
/**
* @brief Проверка на равенство двух аргументов типа double.
* Параметр maxAbsDiff определяет максимальную абсолютную допустимую разницу.
* Параметр maxRelDiff определяет максимальную относительную допустимую разницу,
* при которой аргументы считаются равными.
*/
bool almost_equal_relative_and_abs( const double a, const double b,
const double maxAbsDiff, const double maxRelDiff = DBL_EPSILON );
bool almost_equal_relative_and_abs( double a, double b,
double maxAbsDiff, double maxRelDiff = DBL_EPSILON );
} // namespace math
} // namespace myx
#ifdef MYXLIB_HEADER_ONLY
#include "almost_equal_relative_and_abs-inl.hpp"
#endif
#endif // MYX_MATH_ALMOST_EQUAL_RELATIVE_AND_ABS_HPP_

View File

@ -0,0 +1,93 @@
#ifndef MYX_MATH_ALMOST_EQUAL_ULPS_INL_HPP_
#define MYX_MATH_ALMOST_EQUAL_ULPS_INL_HPP_
#pragma once
#ifndef MYXLIB_HEADER_ONLY
#include <myx/math/almost_equal_ulps.hpp>
#endif
#include <myx/math/float_cmp_types.hpp>
#include <cmath>
namespace myx {
namespace math {
MYXLIB_INLINE bool almost_equal_ulps( const float a, const float b,
const int maxUlpsDiff )
{
FloatCmp uA( a );
FloatCmp uB( b );
// Если знаки разные, то числа не равны.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
if ( uA.negative() != uB.negative() )
{
// Кроме случая, когда +0==-0
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
if ( a == b ) // -V550
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
{
return( true );
}
return( false );
}
// Разница в младших битах.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
auto ulpsDiff = std::abs( uA.i - uB.i );
if ( ulpsDiff <= maxUlpsDiff )
{
return( true );
}
return( false );
} // almost_equal_ulps
MYXLIB_INLINE bool almost_equal_ulps( const double a, const double b,
const int maxUlpsDiff )
{
DoubleCmp uA( a );
DoubleCmp uB( b );
// Если знаки разные, то числа не равны.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
if ( uA.negative() != uB.negative() )
{
// Кроме случая, когда +0==-0
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
if ( a == b ) // -V550
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
{
return( true );
}
return( false );
}
// Разница в младших битах.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
auto ulpsDiff = std::abs( uA.i - uB.i );
if ( ulpsDiff <= maxUlpsDiff )
{
return( true );
}
return( false );
} // almost_equal_ulps
} // namespace math
} // namespace myx
#endif

View File

@ -1,83 +1,5 @@
#include <myx/math/almost_equal_ulps.hpp>
#include <myx/math/float_cmp_types.hpp>
#include <cmath>
namespace myx {
namespace math {
bool almost_equal_ulps( const float a, const float b,
const int maxUlpsDiff )
{
float_cmp_t uA( a );
float_cmp_t uB( b );
// Если знаки разные, то числа не равны.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
if ( uA.negative() != uB.negative() )
{
// Кроме случая, когда +0==-0
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#endif
if ( a == b ) // -V550
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
{
return( true );
}
return( false );
}
// Разница в младших битах.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
auto ulpsDiff = std::abs( uA.i - uB.i );
if ( ulpsDiff <= maxUlpsDiff )
{
return( true );
}
return( false );
} // almost_equal_ulps
bool almost_equal_ulps( const double a, const double b,
const int maxUlpsDiff )
{
double_cmp_t uA( a );
double_cmp_t uB( b );
// Если знаки разные, то числа не равны.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
if ( uA.negative() != uB.negative() )
{
// Кроме случая, когда +0==-0
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
if ( a == b ) // -V550
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
{
return( true );
}
return( false );
}
// Разница в младших битах.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
auto ulpsDiff = std::abs( uA.i - uB.i );
if ( ulpsDiff <= maxUlpsDiff )
{
return( true );
}
return( false );
} // almost_equal_ulps
} // namespace math
} // namespace myx
#include <myx/math/almost_equal_ulps-inl.hpp>

View File

@ -1,6 +1,9 @@
#ifndef MYX_MATH_ALMOST_EQUAL_ULPS_HPP_
#define MYX_MATH_ALMOST_EQUAL_ULPS_HPP_
#pragma once
#include <myx/base/config.hpp>
#include <myx/math/float_cmp_types.hpp>
#include <cmath>
@ -14,18 +17,22 @@ namespace math {
* Параметр maxUlpsDiff определяет максимальную разницу между аргументами,
* при которой они считаются равными.
*/
bool almost_equal_ulps( const float a, const float b,
const int maxUlpsDiff );
bool almost_equal_ulps( float a, float b,
int maxUlpsDiff );
/**
* @brief Проверка на равенство двух аргументов типа double.
* Параметр maxUlpsDiff определяет максимальную разницу между аргументами,
* при которой они считаются равными.
*/
bool almost_equal_ulps( const double a, const double b,
const int maxUlpsDiff );
bool almost_equal_ulps( double a, double b,
int maxUlpsDiff );
} // namespace math
} // namespace myx
#ifdef MYXLIB_HEADER_ONLY
#include "almost_equal_ulps-inl.hpp"
#endif
#endif // MYX_MATH_ALMOST_EQUAL_ULPS_HPP_

View File

@ -0,0 +1,87 @@
#ifndef MYX_MATH_ALMOST_EQUAL_ULPS_INL_HPP_
#define MYX_MATH_ALMOST_EQUAL_ULPS_INL_HPP_
#pragma once
#ifndef MYXLIB_HEADER_ONLY
#include <myx/math/almost_equal_ulps_and_abs.hpp>
#endif
#include <myx/math/float_cmp_types.hpp>
#include <cmath>
namespace myx {
namespace math {
MYXLIB_INLINE bool almost_equal_ulps_and_abs( const float a, const float b,
const float maxAbsDiff, const int maxUlpsDiff )
{
// Check if the numbers are really close -- needed
// when comparing numbers near zero.
float absDiff = fabsf( a - b );
if ( absDiff <= maxAbsDiff )
{
return( true );
}
FloatCmp uA( a );
FloatCmp uB( b );
// Different signs means they do not match.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
if ( uA.negative() != uB.negative() )
{
return( false );
}
// Find the difference in ULPs.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
int ulpsDiff = std::abs( uA.i - uB.i );
if ( ulpsDiff <= maxUlpsDiff )
{
return( true );
}
return( false );
} // almost_equal_ulps_and_abs
MYXLIB_INLINE bool almost_equal_ulps_and_abs( const double a, const double b,
const double maxAbsDiff, const int maxUlpsDiff )
{
// Check if the numbers are really close -- needed
// when comparing numbers near zero.
double absDiff = fabs( a - b );
if ( absDiff <= maxAbsDiff )
{
return( true );
}
DoubleCmp uA( a );
DoubleCmp uB( b );
// Different signs means they do not match.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
if ( uA.negative() != uB.negative() )
{
return( false );
}
// Find the difference in ULPs.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
auto ulpsDiff = std::abs( uA.i - uB.i );
if ( ulpsDiff <= maxUlpsDiff )
{
return( true );
}
return( false );
} // almost_equal_ulps_and_abs
} // namespace math
} // namespace myx
#endif

View File

@ -1,77 +1,5 @@
#include <myx/math/almost_equal_ulps_and_abs.hpp>
#include <myx/math/float_cmp_types.hpp>
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#endif
#include <cmath>
namespace myx {
namespace math {
bool almost_equal_ulps_and_abs( const float a, const float b,
const float maxAbsDiff, const int maxUlpsDiff )
{
// Check if the numbers are really close -- needed
// when comparing numbers near zero.
float absDiff = fabsf( a - b );
if ( absDiff <= maxAbsDiff )
{
return( true );
}
float_cmp_t uA( a );
float_cmp_t uB( b );
// Different signs means they do not match.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
if ( uA.negative() != uB.negative() )
{
return( false );
}
// Find the difference in ULPs.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
int ulpsDiff = std::abs( uA.i - uB.i );
if ( ulpsDiff <= maxUlpsDiff )
{
return( true );
}
return( false );
} // almost_equal_ulps_and_abs
bool almost_equal_ulps_and_abs( const double a, const double b,
const double maxAbsDiff, const int maxUlpsDiff )
{
// Check if the numbers are really close -- needed
// when comparing numbers near zero.
double absDiff = fabs( a - b );
if ( absDiff <= maxAbsDiff )
{
return( true );
}
double_cmp_t uA( a );
double_cmp_t uB( b );
// Different signs means they do not match.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
if ( uA.negative() != uB.negative() )
{
return( false );
}
// Find the difference in ULPs.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
auto ulpsDiff = std::abs( uA.i - uB.i );
if ( ulpsDiff <= maxUlpsDiff )
{
return( true );
}
return( false );
} // almost_equal_ulps_and_abs
} // namespace math
} // namespace myx
#include <myx/math/almost_equal_ulps_and_abs-inl.hpp>

View File

@ -1,6 +1,10 @@
#ifndef MYX_MATH_ALMOST_EQUAL_ULPS_HPP_
#define MYX_MATH_ALMOST_EQUAL_ULPS_HPP_
#pragma once
#include <myx/base/config.hpp>
namespace myx {
namespace math {
@ -11,19 +15,23 @@ namespace math {
* Параметр maxUlpsDiff определяет максимальную разницу между аргументами,
* при которой они считаются равными.
*/
bool almost_equal_ulps_and_abs( const float a, const float b,
const float maxAbsDiff, const int maxUlpsDiff );
bool almost_equal_ulps_and_abs( float a, float b,
float maxAbsDiff, int maxUlpsDiff );
/**
* @brief Проверка на равенство двух аргументов типа double.
* Параметр maxAbsDiff определяет максимальную абсолютную допустимую разницу.
* Параметр maxUlpsDiff определяет максимальную разницу между аргументами,
* при которой они считаются равными.
*/
bool almost_equal_ulps_and_abs( const double a, const double b,
const double maxAbsDiff, const int maxUlpsDiff );
bool almost_equal_ulps_and_abs( double a, double b,
double maxAbsDiff, int maxUlpsDiff );
} // namespace math
} // namespace myx
#ifdef MYXLIB_HEADER_ONLY
#include "almost_equal_ulps_and_abs-inl.hpp"
#endif
#endif // MYX_MATH_ALMOST_EQUAL_ULPS_HPP_

View File

@ -0,0 +1,18 @@
#ifndef MYX_MATH_CONSTANTS_INL_HPP_
#define MYX_MATH_CONSTANTS_INL_HPP_
#pragma once
#ifndef MYXLIB_HEADER_ONLY
#include <myx/math/constants.hpp>
#endif
namespace myx {
namespace math {
} // namespace math
} // namespace myx
#endif

View File

@ -1,9 +1,5 @@
#include <myx/math/constants.hpp>
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#endif
namespace myx {
namespace math {
} // namespace math
} // namespace myx
#include <myx/math/constants-inl.hpp>

View File

@ -1,18 +1,25 @@
#ifndef MYX_MATH_CONSTANTS_HPP_
#define MYX_MATH_CONSTANTS_HPP_
#include <type_traits>
#pragma once
#include <myx/base/config.hpp>
#include <cmath>
#include <type_traits>
namespace myx {
namespace math {
const auto ImpedanceOfFreeSpace = 376.7303136675757;
const auto ImpedanceOfFreeSpace = (M_PI * 119.9169832);
} // namespace math
} // namespace myx
#ifdef MYXLIB_HEADER_ONLY
#include "constants-inl.hpp"
#endif
#endif // MYX_MATH_CONSTANTS_HPP_

View File

@ -1,12 +1,14 @@
#ifndef MYX_MATH_FLOAT_CMP_TYPES_HPP_
#define MYX_MATH_FLOAT_CMP_TYPES_HPP_
#pragma once
#include <cstdint>
/**
* @brief Объединение для получения знака аргумента типа float.
*/
union float_cmp_t
union FloatCmp
{
int32_t i;
float f;
@ -14,7 +16,7 @@ union float_cmp_t
/**
* @brief Инициализация.
*/
float_cmp_t( float num = 0.0f ) : f( num )
explicit FloatCmp( float num = 0.0F ) : f( num )
{
}
@ -30,7 +32,7 @@ union float_cmp_t
/**
* @brief Объединение для получения знака аргумента типа double.
*/
union double_cmp_t
union DoubleCmp
{
int64_t i;
double d;
@ -38,7 +40,7 @@ union double_cmp_t
/**
* @brief Инициализация.
*/
double_cmp_t( double num = 0.0l ) : d( num )
explicit DoubleCmp( double num = 0.0L ) : d( num )
{
}

View File

@ -1,9 +1,11 @@
#ifndef MYX_MATH_FUNCTIONS_HPP_
#define MYX_MATH_FUNCTIONS_HPP_
#include <type_traits>
#include <cmath>
#pragma once
#include <boost/math/special_functions/pow.hpp>
#include <cmath>
#include <type_traits>
namespace myx {

View File

@ -1,8 +1,10 @@
#ifndef MYX_MATH_RADAR_HPP_
#define MYX_MATH_RADAR_HPP_
#include <type_traits>
#pragma once
#include <cmath>
#include <type_traits>
namespace myx {

View File

@ -1,8 +1,10 @@
#ifndef MYX_MATH_UNITS_HPP_
#define MYX_MATH_UNITS_HPP_
#include <type_traits>
#pragma once
#include <cmath>
#include <type_traits>
namespace myx {
@ -14,7 +16,7 @@ namespace math {
* \return Значение в градусах
*/
template < typename T >
T radians_to_degrees( const T& radians, typename std::enable_if< std::is_floating_point< T >::value >::type* = 0 )
T radians_to_degrees( const T& radians, typename std::enable_if< std::is_floating_point< T >::value >::type* /*unused*/ = 0 )
{
static_assert( std::is_arithmetic< T >::value, "Arithmetic type is required." );
return( radians * M_1_PI * 180.0 );
@ -27,7 +29,7 @@ T radians_to_degrees( const T& radians, typename std::enable_if< std::is_floatin
* \return Значение в радианах
*/
template < typename T >
T degrees_to_radians( const T& degrees, typename std::enable_if< std::is_floating_point< T >::value >::type* = 0 )
T degrees_to_radians( const T& degrees, typename std::enable_if< std::is_floating_point< T >::value >::type* /*unused*/ = 0 )
{
static_assert( std::is_arithmetic< T >::value, "Arithmetic type is required." );
return( degrees * M_PI / 180.0 );
@ -88,5 +90,4 @@ T magnitude_to_decibel( T const& magnitude )
} // namespace myx
#endif // MYX_MATH_UNITS_HPP_

View File

@ -3,46 +3,59 @@ set(TRGT qt)
# cmake-format: off
# Список файлов исходных текстов
set(TRGT_sources
if(NOT MYXLIB_HEADER_ONLY)
set(TRGT_cpp
${CMAKE_CURRENT_SOURCE_DIR}/translators.cpp)
endif()
# Список заголовочных файлов (используется для установки)
set(TRGT_headers
set(TRGT_hpp
${CMAKE_CURRENT_SOURCE_DIR}/backports.hpp
${CMAKE_CURRENT_SOURCE_DIR}/translators.hpp)
${CMAKE_CURRENT_SOURCE_DIR}/translators.hpp
${CMAKE_CURRENT_SOURCE_DIR}/translators-inl.hpp)
set(TRGT_headers ${TRGT_hpp})
# cmake-format: on
add_common_library(${TRGT} OUTPUT_NAME myx-${TRGT} SOURCES ${TRGT_sources})
add_library(${TRGT}-header-only INTERFACE)
target_include_directories(
${TRGT}-header-only SYSTEM INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
if(MYXLIB_BUILD_LIBRARIES)
add_common_library(${TRGT} OUTPUT_NAME myx-${TRGT} SOURCES ${TRGT_cpp} ${TRGT_headers})
common_target_properties(${TRGT})
# Создание цели для проверки утилитой clang-tidy
add_clang_tidy_check(${TRGT} ${TRGT_sources})
add_clang_tidy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
# Создание цели для проверки утилитой clang-analyze
add_clang_analyze_check(${TRGT} ${TRGT_sources})
add_clang_analyze_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
# Создание цели для проверки утилитой clazy
add_clazy_check(${TRGT} ${TRGT_sources})
add_clazy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
# Создание цели для проверки утилитой pvs-studio
add_pvs_check(${TRGT})
# Создание цели для автоматического форматирования кода
add_format_sources(${TRGT} ${TRGT_sources} ${TRGT_headers})
add_format_sources(${TRGT} ${TRGT_cpp} ${TRGT_headers})
target_compile_definitions(${TRGT} PUBLIC MYXLIB_BUILD_LIBRARIES)
target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
target_include_directories(${TRGT} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src)
cotire(${TRGT})
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
add_custom_target(${TRGT}-install-headers COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=DEV -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
# Правила для установки
install(TARGETS ${TRGT}_static COMPONENT DEV ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(TARGETS ${TRGT}_static COMPONENT libs-dev ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(BUILD_SHARED_LIBS)
install(TARGETS ${TRGT}_shared COMPONENT DEV LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(TARGETS ${TRGT}_shared COMPONENT main LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
install(FILES ${TRGT_headers} COMPONENT DEV DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
install(FILES ${CMAKE_BINARY_DIR}/${TRGT}.pc COMPONENT DEV DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
endif()
install(FILES ${TRGT_headers} COMPONENT headers
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
install(FILES ${CMAKE_BINARY_DIR}/${TRGT}.pc COMPONENT headers DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
add_custom_target(${TRGT}-install-headers COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=headers -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")

View File

@ -1,6 +1,8 @@
#ifndef MYX_QT_BACKPORTS_HPP_
#define MYX_QT_BACKPORTS_HPP_
#pragma once
#if ( defined ( TARGET_LSB_ID_AstraLinuxSE ) && defined ( TARGET_LSB_CODENAME_smolensk ) )
#define override

View File

@ -0,0 +1,67 @@
#ifndef MYX_QT_TRANSLATORS_INL_HPP_
#define MYX_QT_TRANSLATORS_INL_HPP_
#pragma once
#ifndef MYXLIB_HEADER_ONLY
#include <myx/qt/translators.hpp>
#endif
#include <myx/base/config.hpp>
#include <QCoreApplication>
#include <QLibraryInfo>
#include <QLocale>
namespace myx {
namespace qt {
MYXLIB_INLINE void append_translators( QTranslatorsList& translators, const QString& appName )
{
auto* translator = new QTranslator( qApp );
if ( translator->load( QLocale(),
appName, QStringLiteral( "_" ), QStringLiteral( ":/qm" ) ) )
{
translators.append( translator );
}
else
{
translator->deleteLater();
}
translator = new QTranslator( qApp );
if ( translator->load( QLocale::system(),
QStringLiteral( "qt" ), QStringLiteral( "_" ),
QLibraryInfo::location( QLibraryInfo::TranslationsPath ) ) )
{
translators.append( translator );
}
else
{
translator->deleteLater();
}
translator = new QTranslator( qApp );
if ( translator->load( "qtbase_" + QLocale::system().name(),
QLibraryInfo::location( QLibraryInfo::TranslationsPath ) ) )
{
translators.append( translator );
}
else
{
translator->deleteLater();
}
for ( auto* i : qAsConst( translators ) )
{
qApp->installTranslator( i );
}
} // append_translators
} // namespace qt
} // namespace myx
#endif // MYX_QT_TRANSLATORS_INL_HPP_

View File

@ -1,58 +1,5 @@
#include "translators.hpp"
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#endif
#include <myx/base/config.hpp>
#include <QCoreApplication>
#include <QLibraryInfo>
#include <QLocale>
namespace myx {
namespace qt {
void append_translators( QTranslatorsList& translators, const QString& appName )
{
auto* translator = new QTranslator( qApp );
if ( translator->load( QLocale(),
appName, QStringLiteral( "_" ), QStringLiteral( ":/qm" ) ) )
{
translators.append( translator );
}
else
{
translator->deleteLater();
}
translator = new QTranslator( qApp );
if ( translator->load( QLocale::system(),
QStringLiteral( "qt" ), QStringLiteral( "_" ),
QLibraryInfo::location( QLibraryInfo::TranslationsPath ) ) )
{
translators.append( translator );
}
else
{
translator->deleteLater();
}
translator = new QTranslator( qApp );
if ( translator->load( QStringLiteral( "qtbase_" ) + QLocale::system().name(),
QLibraryInfo::location( QLibraryInfo::TranslationsPath ) ) )
{
translators.append( translator );
}
else
{
translator->deleteLater();
}
for ( auto* i : qAsConst( translators ) )
{
qApp->installTranslator( i );
}
} // append_translators
} // namespace qt
} // namespace myx
#include <myx/qt/translators.hpp>

View File

@ -1,6 +1,9 @@
#ifndef MYX_LOG_QT_TRANSLATORS_HPP_
#define MYX_LOG_QT_TRANSLATORS_HPP_
#ifndef MYX_QT_TRANSLATORS_HPP_
#define MYX_QT_TRANSLATORS_HPP_
#pragma once
#include <myx/base/config.hpp>
#include <myx/qt/backports.hpp>
#include <QTranslator>
@ -9,12 +12,16 @@ namespace myx {
namespace qt {
typedef QList< QTranslator* > QTranslatorsList;
using QTranslatorsList = QList< QTranslator* >;
void append_translators( QTranslatorsList& translators, const QString& appName );
void append_translators( QTranslatorsList& translators, const QString& appName ); // NOLINT
} // namespace qt
} // namespace myx
#endif // ifndef MYX_LOG_QT_TRANSLATORS_HPP_
#ifdef MYXLIB_HEADER_ONLY
#include "translators-inl.hpp"
#endif
#endif // ifndef MYX_QT_TRANSLATORS_HPP_

View File

@ -3,7 +3,7 @@ set(TRGT redis)
# cmake-format: off
# Список файлов исходных текстов
set(TRGT_sources
set(TRGT_cpp
${CMAKE_CURRENT_SOURCE_DIR}/client.cpp
${CMAKE_CURRENT_SOURCE_DIR}/config.cpp
${CMAKE_CURRENT_SOURCE_DIR}/lexer.cpp
@ -11,48 +11,56 @@ set(TRGT_sources
${CMAKE_CURRENT_SOURCE_DIR}/request.cpp)
# Список заголовочных файлов (используется для установки)
set(TRGT_headers
set(TRGT_moc_hpp
${CMAKE_CURRENT_SOURCE_DIR}/client.hpp
${CMAKE_CURRENT_SOURCE_DIR}/config.hpp
${CMAKE_CURRENT_SOURCE_DIR}/lexer.hpp
${CMAKE_CURRENT_SOURCE_DIR}/parser.hpp
${CMAKE_CURRENT_SOURCE_DIR}/reply.hpp
${CMAKE_CURRENT_SOURCE_DIR}/request.hpp)
set(TRGT_headers ${TRGT_hpp})
# cmake-format: on
add_common_library(${TRGT} OUTPUT_NAME myx-${TRGT} SOURCES ${TRGT_sources})
add_library(${TRGT}-header-only INTERFACE)
target_include_directories(
${TRGT}-header-only SYSTEM INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
if(MYXLIB_BUILD_LIBRARIES)
add_common_library(${TRGT} OUTPUT_NAME myx-${TRGT} SOURCES ${TRGT_cpp} ${TRGT_headers})
common_target_properties(${TRGT})
# Создание цели для проверки утилитой clang-tidy
add_clang_tidy_check(${TRGT} ${TRGT_sources})
add_clang_tidy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
# Создание цели для проверки утилитой clang-analyze
add_clang_analyze_check(${TRGT} ${TRGT_sources})
add_clang_analyze_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
# Создание цели для проверки утилитой clazy
add_clazy_check(${TRGT} ${TRGT_sources})
add_clazy_check(${TRGT} ${TRGT_cpp} ${TRGT_headers})
# Создание цели для проверки утилитой pvs-studio
add_pvs_check(${TRGT})
# Создание цели для автоматического форматирования кода
add_format_sources(${TRGT} ${TRGT_sources} ${TRGT_headers})
add_format_sources(${TRGT} ${TRGT_cpp} ${TRGT_headers})
target_compile_definitions(${TRGT} PUBLIC MYXLIB_BUILD_LIBRARIES)
target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Network_INCLUDE_DIRS})
target_include_directories(${TRGT} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src)
target_include_directories(${TRGT} PRIVATE ${CMAKE_BINARY_DIR}/include)
cotire(${TRGT})
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
add_custom_target(${TRGT}-install-headers COMMAND ${CMAKE_COMMAND} -DCMAKE_INSTALL_COMPONENT=DEV -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
# Правила для установки
install(TARGETS ${TRGT}_static COMPONENT DEV ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(BUILD_SHARED_LIBS)
install(TARGETS ${TRGT}_shared COMPONENT DEV LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
endif()
install(FILES ${TRGT_headers} COMPONENT DEV DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
install(FILES ${CMAKE_BINARY_DIR}/${TRGT}.pc COMPONENT DEV DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
add_custom_target(${TRGT}-install-headers COMMAND ${CMAKE_COMMAND} -DCMAKE_INSTALL_COMPONENT=DEV -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")

View File

@ -9,6 +9,6 @@
// #define MYX_REDIS_EXPORT Q_DECL_IMPORT
// #endif
#include "config_flags.hpp"
// #include <myx/base/config_flags.hpp>
#endif // MYX_REDIS_CONFIG_HPP_