Merge pull request #561 from EdgeTX/cpn-build

Windows & Mac OSX companion build
This commit is contained in:
Raphael Coeffic
2021-09-13 12:37:45 +02:00
committed by GitHub
18 changed files with 462 additions and 1176 deletions
+100
View File
@@ -0,0 +1,100 @@
name: MacOSX Companion
on:
push:
branches:
- 'main'
paths:
- '.github/workflow/macosx_cpn.yml'
- 'companion/**'
- 'tools/build-companion-nightly.sh'
pull_request:
branches:
- 'main'
paths:
- '.github/workflow/macosx_cpn.yml'
- 'companion/**'
- 'tools/build-companion-nightly.sh'
workflow_dispatch:
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
QT_VERSION: "5.12.9"
jobs:
build:
# The CMake configure and build commands are platform agnostic and should work equally
# well on Windows or Mac. You can convert this to a matrix build if you need
# cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: macos-latest
steps:
- name: Check out the repo
uses: actions/checkout@v2
with:
submodules: recursive
- name: Create Build Environment
# Some projects don't allow in-source building, so create a separate build directory
# We'll use this as our working directory for all subsequent commands
run: cmake -E make_directory ${{github.workspace}}/build
- name: Install Qt
uses: jurplel/install-qt-action@v2
with:
version: ${{ env.QT_VERSION }}
- name: Install dependencies
run: python -m pip install --upgrade pip Pillow
- name: Install ARM toolchain
uses: fiam/arm-none-eabi-gcc@v1
with:
release: '10-2020-q4'
- name: Install dfu-util
run: wget https://downloads.sourceforge.net/project/dfu-util/dfu-util-0.9.tar.gz &&
tar xfv dfu-util-0.9.tar.gz &&
cd dfu-util-0.9 &&
./configure &&
make install
- name: Install libusb
run: wget https://github.com/libusb/libusb/releases/download/v1.0.20/libusb-1.0.20.tar.bz2 &&
export MACOSX_DEPLOYMENT_TARGET=10.9 &&
tar xfv libusb-1.0.20.tar.bz2 &&
cd libusb-1.0.20 &&
./configure &&
make install &&
cd ..
- name: Install libsdl
run: wget https://www.libsdl.org/release/SDL-1.2.15.tar.gz &&
tar xfv SDL-1.2.15.tar.gz &&
export MACOSX_DEPLOYMENT_TARGET=10.9 &&
cd SDL-1.2.15 &&
wget 'https://bugzilla-attachments.libsdl.org/attachment.cgi?id=1320' -O patch1 &&
wget 'https://bugzilla-attachments.libsdl.org/attachment.cgi?id=1324' -O patch2 &&
wget 'https://hg.libsdl.org/SDL/raw-rev/91ad7b43317a' -O patch3 &&
patch -p1 < patch1 &&
patch -p1 < patch2 &&
patch -p1 < patch3 &&
./configure --without-x &&
make install
- name: Build
working-directory: ${{github.workspace}}
shell: bash
run: |
mkdir output && \
tools/build-companion-nightly.sh $(pwd) $(pwd)/output/
- name: Archive production artifacts
uses: actions/upload-artifact@v2
with:
name: companion-nightly
path: ${{github.workspace}}/output
retention-days: 15
+89
View File
@@ -0,0 +1,89 @@
name: Windows Companion
on:
push:
branches:
- 'main'
paths:
- '.github/workflow/win_cpn.yml'
- 'companion/**'
- 'tools/build-companion-nightly.sh'
pull_request:
branches:
- 'main'
paths:
- '.github/workflow/win_cpn.yml'
- 'companion/**'
- 'tools/build-companion-nightly.sh'
workflow_dispatch:
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
CMAKE_GENERATOR: "MSYS Makefiles"
QT_VERSION: "5.12.9"
MINGW_VERSION: "win64_mingw73"
MINGW_PATH: "mingw73_64"
jobs:
build:
# The CMake configure and build commands are platform agnostic and should work equally
# well on Windows or Mac. You can convert this to a matrix build if you need
# cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: windows-latest
defaults:
run:
shell: msys2 {0}
steps:
- uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
update: true
install: git make mingw-w64-x86_64-toolchain
- name: Install Dependencies
run: |
pacman -S --noconfirm mingw-w64-x86_64-cmake \
mingw-w64-x86_64-python-pip \
mingw-w64-x86_64-arm-none-eabi-gcc \
mingw-w64-x86_64-libjpeg-turbo \
mingw-w64-x86_64-zlib \
mingw-w64-x86_64-libtiff \
mingw-w64-x86_64-freetype \
mingw-w64-x86_64-lcms2 \
mingw-w64-x86_64-libwebp \
mingw-w64-x86_64-openjpeg2 \
mingw-w64-x86_64-libimagequant \
mingw-w64-x86_64-libraqm \
mingw-w64-x86_64-SDL \
mingw-w64-x86_64-nsis
pip install Pillow
- name: Install Qt
uses: jurplel/install-qt-action@v2
with:
version: ${{ env.QT_VERSION }}
arch: ${{ env.MINGW_VERSION }}
- name: Check out the repo
uses: actions/checkout@v2
with:
submodules: recursive
- name: Build
working-directory: ${{github.workspace}}
# Execute the build. You can specify a specific target with "--target <NAME>"
run: |
mkdir output && \
CMAKE_PREFIX_PATH=$RUNNER_WORKSPACE/Qt/$QT_VERSION/$MINGW_PATH \
tools/build-companion-nightly.sh $(pwd) $(pwd)/output/
- name: Archive production artifacts
uses: actions/upload-artifact@v2
with:
name: companion-nightly
path: ${{github.workspace}}/output
retention-days: 15
+11 -9
View File
@@ -202,15 +202,17 @@ if(WIN32)
list(APPEND WIN_INCLUDE_DIRS "${RADIO_SRC_DIR}/thirdparty/windows/dirent")
if(MSVC)
list(APPEND WIN_INCLUDE_DIRS "${RADIO_SRC_DIR}/thirdparty/windows/msinttypes")
set(WIN_PTHREAD_BASE_PATH "${WIN_EXTRA_LIBS_PATH}/pthreads/Pre-built.2" CACHE PATH "Where to find pthreads include and lib folders.")
list(APPEND WIN_INCLUDE_DIRS "${WIN_PTHREAD_BASE_PATH}/include")
find_file(WIN_PTHREAD_LIB pthreadVC2.lib PATHS "${WIN_PTHREAD_BASE_PATH}" PATH_SUFFIXES lib/x86 lib NO_DEFAULT_PATH)
find_file(WIN_PTHREAD_DLL pthreadVC2.dll PATHS "${WIN_PTHREAD_BASE_PATH}" PATH_SUFFIXES lib/x86 lib dll/x86 dll NO_DEFAULT_PATH)
if(WIN_PTHREAD_LIB)
list(APPEND WIN_LINK_LIBRARIES "${WIN_PTHREAD_LIB}")
else()
message(SEND_ERROR "pthreadVC2.lib not found!")
endif()
#set(WIN_PTHREAD_BASE_PATH "${WIN_EXTRA_LIBS_PATH}/pthreads/Pre-built.2" CACHE PATH "Where to find pthreads include and lib folders.")
#list(APPEND WIN_INCLUDE_DIRS "${WIN_PTHREAD_BASE_PATH}/include")
#find_file(WIN_PTHREAD_LIB pthreadVC2.lib PATHS "${WIN_PTHREAD_BASE_PATH}" PATH_SUFFIXES lib/x86 lib NO_DEFAULT_PATH)
#find_file(WIN_PTHREAD_DLL pthreadVC2.dll PATHS "${WIN_PTHREAD_BASE_PATH}" PATH_SUFFIXES lib/x86 lib dll/x86 dll NO_DEFAULT_PATH)
#if(WIN_PTHREAD_LIB)
# list(APPEND WIN_LINK_LIBRARIES "${WIN_PTHREAD_LIB}")
#else()
# message(SEND_ERROR "pthreadVC2.lib not found!")
#endif()
find_package(pthreads)
#target_link_libraries(mytarget pthreads)
else()
set(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES OFF)
set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES OFF)
+37 -79
View File
@@ -60,17 +60,9 @@ endif()
add_definitions(${APP_COMMON_DEFINES}) # set in top-level CMakeLists
if(NOT MSVC)
set(WARNING_FLAGS "${WARNING_FLAGS} -Wall")
if(WARNINGS_AS_ERRORS)
set(WARNING_FLAGS "${WARNING_FLAGS} -Werror")
endif()
else()
# silence lots of warnings regarding "insecure" use of functions (sprintf, strcpy, etc)
set(WARNING_FLAGS "${WARNING_FLAGS} /D_CRT_SECURE_NO_WARNINGS")
if(WARNINGS_AS_ERRORS)
set(WARNING_FLAGS "${WARNING_FLAGS} /WX")
endif()
set(WARNING_FLAGS "${WARNING_FLAGS} -Wall")
if(WARNINGS_AS_ERRORS)
set(WARNING_FLAGS "${WARNING_FLAGS} -Werror")
endif()
if(WIN32)
@@ -78,16 +70,10 @@ if(WIN32)
if(NOT WIN_USE_CONSOLE)
set(WIN_EXECUTABLE_TYPE WIN32) # GUI (WinMain) app
endif()
if(MSVC)
if(NOT CLANG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /LD /MP")
endif()
if(NOT WIN_USE_CONSOLE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS,5.01") # is this even needed?
endif()
elseif(MINGW)
if(MINGW)
get_filename_component(MINGW_DIR ${CMAKE_CXX_COMPILER} DIRECTORY)
# struct packing breaks on MinGW w/out -mno-ms-bitfields: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991 & http://stackoverflow.com/questions/24015852/struct-packing-and-alignment-with-mingw
# struct packing breaks on MinGW w/out -mno-ms-bitfields: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991
# & http://stackoverflow.com/questions/24015852/struct-packing-and-alignment-with-mingw
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mno-ms-bitfields")
endif()
else()
@@ -322,18 +308,12 @@ set(simu_SRCS simulator.cpp )
add_executable(${SIMULATOR_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${simu_SRCS} ${icon_RC})
target_link_libraries(${SIMULATOR_NAME} PRIVATE ${CPN_COMMON_LIB})
if(NOT MSVC)
add_subdirectory(tests)
endif()
add_subdirectory(tests)
############# Install ####################
# Generate list of simulator plugins, used by all platforms
if(WIN32)
file(GLOB simulator_plugins "${CMAKE_BINARY_DIR}/Release/*opentx-*simulator${CMAKE_SHARED_LIBRARY_SUFFIX}")
else()
file(GLOB simulator_plugins "${CMAKE_BINARY_DIR}/*opentx-*simulator${CMAKE_SHARED_LIBRARY_SUFFIX}")
endif()
file(GLOB simulator_plugins "${CMAKE_BINARY_DIR}/*opentx-*simulator${CMAKE_SHARED_LIBRARY_SUFFIX}")
# the current flavour is not automatically added if build in the current cmake iteration, so always
# add its library name to be sure
@@ -394,24 +374,17 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
# Linux specific code
set(OperatingSystem "Linux")
elseif(WIN32)
if(NOT WIN_DO_FULL_INSTALL)
# Just copy supporting DLLs to build folder
set(INSTALL_DESTINATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
message(STATUS "Partial install to " ${INSTALL_DESTINATION})
else()
# Full Windows installation with all supporting files
set(INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}")
message(STATUS "Full install to " ${INSTALL_DESTINATION})
# companion & simulator binaries
install(TARGETS ${COMPANION_NAME} DESTINATION ${INSTALL_DESTINATION})
install(TARGETS ${SIMULATOR_NAME} DESTINATION ${INSTALL_DESTINATION})
install(FILES ${simulator_plugins} DESTINATION "${INSTALL_DESTINATION}")
# supporting utilities
set(INSTALL_TEMP_FILES dfu-util.exe libusb0.dll libusb-1.0.dll license.txt)
foreach(tmpfile ${INSTALL_TEMP_FILES})
install(FILES "${COMPANION_SRC_DIRECTORY}/../targets/windows/${tmpfile}" DESTINATION ${INSTALL_DESTINATION})
endforeach()
endif() # WIN_DO_FULL_INSTALL
set(INSTALL_DESTINATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE}")
message(STATUS "Install to " ${INSTALL_DESTINATION})
# companion & simulator binaries
install(TARGETS ${COMPANION_NAME} DESTINATION ${INSTALL_DESTINATION})
install(TARGETS ${SIMULATOR_NAME} DESTINATION ${INSTALL_DESTINATION})
install(FILES ${simulator_plugins} DESTINATION ${INSTALL_DESTINATION})
# supporting utilities
set(INSTALL_TEMP_FILES dfu-util.exe libusb0.dll libusb-1.0.dll license.txt)
foreach(tmpfile ${INSTALL_TEMP_FILES})
install(FILES "${COMPANION_SRC_DIRECTORY}/../targets/windows/${tmpfile}" DESTINATION ${INSTALL_DESTINATION})
endforeach()
# Qt dlls (using windeployqt)
## Qt translations are already packaged into our custom qrc. Also don't need software rendering engines.
@@ -419,14 +392,11 @@ elseif(WIN32)
if(CMAKE_BUILD_TYPE STREQUAL "Release")
set(wdqtopts ${wdqtopts} --release) # release builds aren't always properly detected with mingw
endif()
if(MSVC)
set(wdqtopts ${wdqtopts} --no-compiler-runtime) # --compiler-runtime includes vcredist_x86, but we just copy the required DLLs manually
endif()
set(wdqtopts ${wdqtopts} -dir "\"${INSTALL_DESTINATION}\"" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release/${COMPANION_NAME}.exe" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release/${SIMULATOR_NAME}.exe")
set(wdqtopts ${wdqtopts} -dir "\"${INSTALL_DESTINATION}\"" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${COMPANION_NAME}.exe" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${SIMULATOR_NAME}.exe")
list(JOIN wdqtopts " " wdqtopts)
# Add installer command to execute windeployqt
message(STATUS "windeployqt command: ${QT_BIN_DIR}/windeployqt.exe ${wdqtopts}")
install(CODE "execute_process(COMMAND \"${QT_BIN_DIR}/windeployqt.exe\" ${wdqtopts})")
# SDL dll
if(SDL_FOUND AND EXISTS "${SDL_LIBRARY_PATH}/SDL.dll")
@@ -437,34 +407,21 @@ elseif(WIN32)
endif()
# libeay (SSL) dlls (used by QtNetwork) -- not strictly required but avoids possible issues with downloads and Qt warnings.
file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" WIN_PROGRAM_FILES)
find_path(EAY_LIB_DIR libeay32.dll HINTS
"${WIN_PROGRAM_FILES}/OpenSSL" "${WIN_PROGRAM_FILES}/OpenSSL-Win32"
"C:/OpenSSL/" "C:/OpenSSL-Win32/"
"${WIN_EXTRA_LIBS_PATH}" "${WIN_EXTRA_LIBS_PATH}/OpenSSL" "${WIN_EXTRA_LIBS_PATH}/OpenSSL-Win32"
"${MINGW_DIR}/../opt/bin"
"${PYTHON_DIRECTORY}/lib/site-packages/PyQt4"
PATH_SUFFIXES bin
DOC "Path to libeay32.dll and ssleay32.dll (OpenSSL)"
)
if (EAY_LIB_DIR)
install(FILES "${EAY_LIB_DIR}/libeay32.dll" "${EAY_LIB_DIR}/ssleay32.dll" DESTINATION ${INSTALL_DESTINATION} OPTIONAL)
else()
message(WARNING "Installer: SSL libs not found, set EAY_LIB_DIR manually.")
endif()
# C++/system dlls, depends on compiler
if(MSVC)
file(TO_CMAKE_PATH "$ENV{windir}/SysWOW64" WIN_SYSDIR) # This would be "system32" for a 64-bit build or on x86... but how to tell?
if (NOT EXISTS "${WIN_SYSDIR}")
file(TO_CMAKE_PATH "$ENV{windir}/system32" WIN_SYSDIR) # Must be 32-bit Windows.
endif()
install(FILES "${WIN_SYSDIR}/msvcp140.dll" "${WIN_SYSDIR}/vcruntime140.dll" DESTINATION ${INSTALL_DESTINATION} OPTIONAL)
if(WIN_PTHREAD_DLL)
install(FILES "${WIN_PTHREAD_DLL}" DESTINATION ${INSTALL_DESTINATION})
endif()
endif()
# file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" WIN_PROGRAM_FILES)
# find_path(EAY_LIB_DIR libeay32.dll HINTS
# "${WIN_PROGRAM_FILES}/OpenSSL" "${WIN_PROGRAM_FILES}/OpenSSL-Win32"
# "C:/OpenSSL/" "C:/OpenSSL-Win32/"
# "${WIN_EXTRA_LIBS_PATH}" "${WIN_EXTRA_LIBS_PATH}/OpenSSL" "${WIN_EXTRA_LIBS_PATH}/OpenSSL-Win32"
# "${MINGW_DIR}/../opt/bin"
# "${PYTHON_DIRECTORY}/lib/site-packages/PyQt4"
# PATH_SUFFIXES bin
# DOC "Path to libeay32.dll and ssleay32.dll (OpenSSL)"
# )
# if (EAY_LIB_DIR)
# install(FILES "${EAY_LIB_DIR}/libeay32.dll" "${EAY_LIB_DIR}/ssleay32.dll" DESTINATION ${INSTALL_DESTINATION} OPTIONAL)
# else()
# message(WARNING "Installer: SSL libs not found, set EAY_LIB_DIR manually.")
# endif()
endif() # WIN32 install
############# Packaging ####################
@@ -486,6 +443,7 @@ if(WIN32)
add_custom_target(installer
# The 'install' target prepares all the distro files, make sure it has been executed first.
COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}" --target install --config Release
COMMAND "${QT_BIN_DIR}/windeployqt.exe" "${wdqtopts}"
COMMAND "${NSIS_EXE}" "${NSI_FILE}"
DEPENDS "${NSI_FILE}"
COMMENT "Building Windows NSIS installer..."
+1
View File
@@ -30,6 +30,7 @@ set(firmwares_SRCS
opentx/opentxeeprom.cpp
opentx/opentxinterface.cpp
datahelpers.cpp
customisation_data.cpp
)
string(REPLACE ".cpp" ".h" firmwares_HDRS "${firmwares_SRCS}")
@@ -0,0 +1,138 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "customisation_data.h"
// cannot use QColor so use formula from libopenui_defines.h
#define RADIO_RGB(r, g, b) \
(uint16_t)((((r)&0xF8) << 8) + (((g)&0xFC) << 3) + (((b)&0xF8) >> 3))
#define WHITE RADIO_RGB(0xFF, 0xFF, 0xFF)
#define RED RADIO_RGB(229, 32, 30)
inline void setZoneOptionValue(ZoneOptionValue& zov, bool value)
{
zov.boolValue = value;
}
inline void setZoneOptionValue(ZoneOptionValue& zov, int value)
{
zov.signedValue = value;
}
inline void setZoneOptionValue(ZoneOptionValue& zov, char value)
{
memset(&zov.stringValue, value, LEN_ZONE_OPTION_STRING);
}
inline void setZoneOptionValue(ZoneOptionValue& zov, unsigned int value)
{
zov.unsignedValue = value;
}
inline ZoneOptionValueEnum zoneValueEnumFromType(ZoneOption::Type type)
{
switch(type) {
case ZoneOption::File:
case ZoneOption::String:
return ZOV_String;
case ZoneOption::Integer:
return ZOV_Signed;
case ZoneOption::Bool:
return ZOV_Bool;
case ZoneOption::Color:
case ZoneOption::Timer:
case ZoneOption::Switch:
case ZoneOption::Source:
case ZoneOption::TextSize:
default:
return ZOV_Unsigned;
}
}
inline const char * zoneOptionValueEnumToString(ZoneOptionValueEnum zovenum) {
switch (zovenum) {
case ZOV_Unsigned:
return "unsigned";
case ZOV_Signed:
return "signed";
case ZOV_Bool:
return "bool";
case ZOV_String:
return "string";
default:
return "unknown";
}
}
void RadioTheme::init(const char* themeName, ThemeData& themeData)
{
memset(&themeData, 0, sizeof(ThemeData));
memcpy(&themeData.themeName, themeName, THEME_NAME_LEN);
PersistentData& persistentData = themeData.themePersistentData;
persistentData.options[0].type =
zoneValueEnumFromType(ZoneOption::Type::Color);
setZoneOptionValue(persistentData.options[0].value, (unsigned int)WHITE);
persistentData.options[1].type =
zoneValueEnumFromType(ZoneOption::Type::Color);
setZoneOptionValue(persistentData.options[1].value, (unsigned int)RED);
}
void RadioLayout::init(const char* layoutId, CustomScreens& customScreens)
{
memset(&customScreens, 0, sizeof(CustomScreens));
for (int i = 0; i < MAX_CUSTOM_SCREENS; i++) {
if (i == 0)
memcpy(&customScreens.customScreenData[i].layoutId, layoutId,
LAYOUT_ID_LEN);
LayoutPersistentData& persistentData =
customScreens.customScreenData[i].layoutPersistentData;
int j = 0;
persistentData.options[j].type =
zoneValueEnumFromType(ZoneOption::Type::Bool);
setZoneOptionValue(persistentData.options[j++].value, (bool)true);
persistentData.options[j].type =
zoneValueEnumFromType(ZoneOption::Type::Bool);
setZoneOptionValue(persistentData.options[j++].value, (bool)true);
persistentData.options[j].type =
zoneValueEnumFromType(ZoneOption::Type::Bool);
setZoneOptionValue(persistentData.options[j++].value, (bool)true);
persistentData.options[j].type =
zoneValueEnumFromType(ZoneOption::Type::Bool);
setZoneOptionValue(persistentData.options[j++].value, (bool)true);
persistentData.options[j].type =
zoneValueEnumFromType(ZoneOption::Type::Bool);
setZoneOptionValue(persistentData.options[j++].value, (bool)false);
}
}
+6 -91
View File
@@ -68,21 +68,6 @@ enum ZoneOptionValueEnum {
ZOV_LAST = ZOV_String
};
inline const char * zoneOptionValueEnumToString(ZoneOptionValueEnum zovenum) {
switch (zovenum) {
case ZOV_Unsigned:
return "unsigned";
case ZOV_Signed:
return "signed";
case ZOV_Bool:
return "bool";
case ZOV_String:
return "string";
default:
return "unknown";
}
}
struct ZoneOption
{
enum Type {
@@ -110,29 +95,6 @@ struct ZoneOptionValueTyped
ZoneOptionValue value;
};
inline ZoneOptionValueEnum zoneValueEnumFromType(ZoneOption::Type type)
{
switch(type) {
case ZoneOption::File:
case ZoneOption::String:
return ZOV_String;
case ZoneOption::Integer:
return ZOV_Signed;
case ZoneOption::Bool:
return ZOV_Bool;
case ZoneOption::Color:
case ZoneOption::Timer:
case ZoneOption::Switch:
case ZoneOption::Source:
case ZoneOption::TextSize:
default:
return ZOV_Unsigned;
}
}
struct WidgetPersistentData {
ZoneOptionValueTyped options[MAX_WIDGET_OPTIONS];
};
@@ -148,19 +110,11 @@ struct WidgetsContainerPersistentData {
ZoneOptionValueTyped options[O];
};
typedef WidgetsContainerPersistentData<MAX_LAYOUT_ZONES, MAX_LAYOUT_OPTIONS> LayoutPersistentData;
typedef WidgetsContainerPersistentData<MAX_LAYOUT_ZONES, MAX_LAYOUT_OPTIONS>
LayoutPersistentData;
typedef WidgetsContainerPersistentData<MAX_TOPBAR_ZONES, MAX_TOPBAR_OPTIONS> TopBarPersistentData;
inline void setZoneOptionValue(ZoneOptionValue & zov, bool value) { zov.boolValue = value; }
inline void setZoneOptionValue(ZoneOptionValue & zov, int value) { zov.signedValue = value; }
inline void setZoneOptionValue(ZoneOptionValue & zov, char value) { memset(&zov.stringValue, value, LEN_ZONE_OPTION_STRING); }
inline void setZoneOptionValue(ZoneOptionValue & zov, unsigned int value) { zov.unsignedValue = value; }
// cannot use QColor so use formula from libopenui_defines.h
#define RGB(r, g, b) (uint16_t)((((r) & 0xF8) << 8) + (((g) & 0xFC) << 3) + (((b) & 0xF8) >> 3))
#define WHITE RGB(0xFF, 0xFF, 0xFF)
#define RED RGB(229, 32, 30)
typedef WidgetsContainerPersistentData<MAX_TOPBAR_ZONES, MAX_TOPBAR_OPTIONS>
TopBarPersistentData;
class RadioTheme
{
@@ -176,20 +130,7 @@ class RadioTheme
PersistentData themePersistentData;
};
static void init(const char * themeName, ThemeData & themeData)
{
memset(&themeData, 0, sizeof(ThemeData));
memcpy(&themeData.themeName, themeName, THEME_NAME_LEN);
PersistentData & persistentData = themeData.themePersistentData;
persistentData.options[0].type = zoneValueEnumFromType(ZoneOption::Type::Color);
setZoneOptionValue(persistentData.options[0].value, (unsigned int)WHITE);
persistentData.options[1].type = zoneValueEnumFromType(ZoneOption::Type::Color);
setZoneOptionValue(persistentData.options[1].value, (unsigned int)RED);
}
static void init(const char * themeName, ThemeData & themeData);
};
class RadioLayout
@@ -206,31 +147,5 @@ class RadioLayout
CustomScreenData customScreenData[MAX_CUSTOM_SCREENS];
};
static void init(const char * layoutId, CustomScreens & customScreens)
{
memset(&customScreens, 0, sizeof(CustomScreens));
for (int i = 0; i < MAX_CUSTOM_SCREENS; i++) {
if (i == 0)
memcpy(&customScreens.customScreenData[i].layoutId, layoutId, LAYOUT_ID_LEN);
LayoutPersistentData & persistentData = customScreens.customScreenData[i].layoutPersistentData;
int j = 0;
persistentData.options[j].type = zoneValueEnumFromType(ZoneOption::Type::Bool);
setZoneOptionValue(persistentData.options[j++].value, (bool)true);
persistentData.options[j].type = zoneValueEnumFromType(ZoneOption::Type::Bool);
setZoneOptionValue(persistentData.options[j++].value, (bool)true);
persistentData.options[j].type = zoneValueEnumFromType(ZoneOption::Type::Bool);
setZoneOptionValue(persistentData.options[j++].value, (bool)true);
persistentData.options[j].type = zoneValueEnumFromType(ZoneOption::Type::Bool);
setZoneOptionValue(persistentData.options[j++].value, (bool)true);
persistentData.options[j].type = zoneValueEnumFromType(ZoneOption::Type::Bool);
setZoneOptionValue(persistentData.options[j++].value, (bool)false);
}
}
static void init(const char * layoutId, CustomScreens & customScreens);
};
+21 -20
View File
@@ -13,14 +13,14 @@
;General
;Name and file
Name "OpenTX Companion @VERSION_FAMILY@"
Name "EdgeTX Companion @VERSION_FAMILY@"
OutFile "companion-windows-@VERSION@.exe"
;Default installation folder
InstallDir "$PROGRAMFILES\OpenTX\Companion @VERSION_FAMILY@"
InstallDir "$PROGRAMFILES\EdgeTX\Companion @VERSION_FAMILY@"
;Get installation folder from registry if available
InstallDirRegKey HKCU "Software\OpenTX\Companion @VERSION_FAMILY@" ""
InstallDirRegKey HKCU "Software\EdgeTX\Companion @VERSION_FAMILY@" ""
;Compressor options
SetCompressor /FINAL /SOLID lzma
@@ -71,7 +71,7 @@
;Start Menu Folder Page Configuration
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU"
!define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\OpenTX\Companion @VERSION_FAMILY@"
!define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\EdgeTX\Companion @VERSION_FAMILY@"
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
!insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder
@@ -102,7 +102,7 @@
;--------------------------------
;Installer Sections
Section "OpenTX Companion @VERSION_FAMILY@" SecDummy
Section "EdgeTX Companion @VERSION_FAMILY@" SecDummy
Delete "$INSTDIR\opentx-*-simulator.dll"
RMDir /r "$INSTDIR\lang"
@@ -114,22 +114,22 @@ Section "OpenTX Companion @VERSION_FAMILY@" SecDummy
File /r "@NSIS_DISTRO@\*"
;Store installation folder
WriteRegStr HKCU "Software\OpenTX\Companion @VERSION_FAMILY@" "" $INSTDIR
WriteRegStr HKCU "Software\EdgeTX\Companion @VERSION_FAMILY@" "" $INSTDIR
;Associate with extentions .otx
${registerExtension} "$INSTDIR\companion.exe" ".otx" "OpenTX Settings File"
${registerExtension} "$INSTDIR\companion.exe" ".otx" "EdgeTX Settings File"
;Create uninstaller
WriteUninstaller "$INSTDIR\Uninstall.exe"
;Registry information for add/remove programs
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX Companion @VERSION_FAMILY@" "DisplayName" "OpenTX Companion @VERSION_FAMILY@"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX Companion @VERSION_FAMILY@" "DisplayVersion" "@VERSION@"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX Companion @VERSION_FAMILY@" "UninstallString" "$\"$INSTDIR\Uninstall.exe$\""
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX Companion @VERSION_FAMILY@" "DisplayIcon" "$\"$INSTDIR\companion.exe$\""
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX Companion @VERSION_FAMILY@" "Publisher" "OpenTX"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX Companion @VERSION_FAMILY@" "URLInfoAbout" "https://www.open-tx.org"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX Companion @VERSION_FAMILY@" "QuietUninstallString" "$\"$INSTDIR\Uninstall.exe$\" /S"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\EdgeTX Companion @VERSION_FAMILY@" "DisplayName" "EdgeTX Companion @VERSION_FAMILY@"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\EdgeTX Companion @VERSION_FAMILY@" "DisplayVersion" "@VERSION@"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\EdgeTX Companion @VERSION_FAMILY@" "UninstallString" "$\"$INSTDIR\Uninstall.exe$\""
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\EdgeTX Companion @VERSION_FAMILY@" "DisplayIcon" "$\"$INSTDIR\companion.exe$\""
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\EdgeTX Companion @VERSION_FAMILY@" "Publisher" "EdgeTX"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\EdgeTX Companion @VERSION_FAMILY@" "URLInfoAbout" "https://www.open-tx.org"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\EdgeTX Companion @VERSION_FAMILY@" "QuietUninstallString" "$\"$INSTDIR\Uninstall.exe$\" /S"
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
@@ -151,8 +151,8 @@ SectionEnd
;Descriptions
;Language strings
LangString DESC_SecDummy ${LANG_ENGLISH} "Models and settings editor for OpenTX"
LangString DESC_SecDummy ${LANG_FRENCH} "Editeur de r�glages et mod�les pour OpenTX"
LangString DESC_SecDummy ${LANG_ENGLISH} "Models and settings editor for EdgeTX"
LangString DESC_SecDummy ${LANG_FRENCH} "Editeur de r�glages et mod�les pour EdgeTX"
LangString SML_SubTitle ${LANG_ENGLISH} "Choose a location for the Start Menu shortcuts"
LangString SML_SubTitle ${LANG_FRENCH} "Choisissez un emplacement pour les raccourcis de l'application"
LangString SML_MainLabel ${LANG_ENGLISH} "Create start menu shortcuts for:"
@@ -170,7 +170,7 @@ SectionEnd
;--------------------------------
;Uninstaller Section
Section "un.OpenTX Companion @VERSION_FAMILY@"
Section "un.EdgeTX Companion @VERSION_FAMILY@"
SectionIn RO ; Not deselectable
@@ -199,6 +199,7 @@ Section "un.OpenTX Companion @VERSION_FAMILY@"
Delete "$INSTDIR\ssleay32.dll"
; MinGW libs
Delete "$INSTDIR\libgcc_s_dw2-1.dll"
Delete "$INSTDIR\libgcc_s_seh-1.dll"
Delete "$INSTDIR\libstdc++-6.dll"
Delete "$INSTDIR\libwinpthread-1.dll"
@@ -219,7 +220,7 @@ Section "un.OpenTX Companion @VERSION_FAMILY@"
${unregisterExtension} ".bin" "BIN File"
${unregisterExtension} ".hex" "HEX File"
${unregisterExtension} ".eepm" "EEPE File"
${unregisterExtension} ".otx" "OpenTX Settings File"
${unregisterExtension} ".otx" "EdgeTX Settings File"
!insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder
@@ -235,11 +236,11 @@ Section "un.OpenTX Companion @VERSION_FAMILY@"
Delete "$SMPROGRAMS\$StartMenuFolder\Uninstall Companion @VERSION_FAMILY@.lnk"
RMDir "$SMPROGRAMS\$StartMenuFolder"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX Companion @VERSION_FAMILY@"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\EdgeTX Companion @VERSION_FAMILY@"
SectionEnd
Section /o "un.Settings"
DeleteRegKey HKCU "Software\OpenTX\Companion @VERSION_FAMILY@"
DeleteRegKey HKCU "Software\EdgeTX\Companion @VERSION_FAMILY@"
SectionEnd
Function LaunchLink
+5 -2
View File
@@ -1,6 +1,9 @@
Copyright © 2011-2019 OpenTX team
Copyright © 2021 EdgeTX team
OpenTX Companion is based on code named eePe by author - Erez Raviv <erezraviv@gmail.com>
EdgeTX Companion is based on code:
- named eePe by author - Erez Raviv <erezraviv@gmail.com>
- named OpenTX Companion - https://github.com/opentx/opentx
This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
@@ -9,4 +12,4 @@ Permission is granted to anyone to use this software for any purpose, including
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any distribution.
3. This notice may not be removed or altered from any distribution.
+2
View File
@@ -94,10 +94,12 @@
#endif
#if defined(__cplusplus)
#undef EXTERN_C
#define EXTERN_C(__Declaration__) extern "C" { __Declaration__ ; }
#define EXTERN_C_START extern "C" {
#define EXTERN_C_END }
#else
#undef EXTERN_C
#define EXTERN_C(__Declaration__) __Declaration__
#define EXTERN_C_START
#define EXTERN_C_END
+5 -5
View File
@@ -325,9 +325,9 @@ set(STM32LIB_SRC
MACRO(GET_GCC_INCLUDE_PATH gcc_include_path)
if (WIN32)
execute_process(COMMAND arm-none-eabi-gcc -v -x c -E NUL ERROR_VARIABLE _gcc_output OUTPUT_QUIET)
execute_process(COMMAND ${CMAKE_C_COMPILER} -v -x c -E NUL ERROR_VARIABLE _gcc_output OUTPUT_QUIET)
else()
execute_process(COMMAND arm-none-eabi-gcc -v -x c -E - INPUT_FILE /dev/null ERROR_VARIABLE _gcc_output OUTPUT_QUIET)
execute_process(COMMAND ${CMAKE_C_COMPILER} -v -x c -E - INPUT_FILE /dev/null ERROR_VARIABLE _gcc_output OUTPUT_QUIET)
endif()
# Build an array of string from the GCC output
@@ -346,7 +346,7 @@ MACRO(GET_GCC_INCLUDE_PATH gcc_include_path)
# Remove the leading and trailing empty characters
string(REPLACE "\r" "" _line ${_line})
string(SUBSTRING "${_line}" 1 -1 _line)
set(_include_path "${_include_path}" "-I${_line}")
set(_include_path "${_include_path}" "-I\"${_line}\"")
endif()
if(${_line} STREQUAL "#include <...> search starts here:")
@@ -357,12 +357,12 @@ MACRO(GET_GCC_INCLUDE_PATH gcc_include_path)
ENDMACRO()
if(PYTHONINTERP_FOUND)
GET_GCC_INCLUDE_PATH(arm_gcc_include_path)
GET_GCC_INCLUDE_PATH(gcc_include_path)
add_custom_command(
OUTPUT ${PROJECT_BINARY_DIR}/radio/src/datacopy.cpp
WORKING_DIRECTORY ${RADIO_DIRECTORY}/src
COMMAND ${PYTHON_EXECUTABLE} ${RADIO_DIRECTORY}/util/generate_datacopy.py datastructs.h -DPCBHORUS -DPCBX10 -DCPUARM -DSTM32F4 -DSTM32F429_439xx -DCOLORLCD -DBACKUP -DSIMU -I. -Igui/colorlcd -Itargets/horus -Itargets/common/arm/stm32 -I${THIRDPARTY_DIR} -I${THIRDPARTY_DIR}/libopenui/src -I${THIRDPARTY_DIR}/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0/Libraries/STM32F4xx_StdPeriph_Driver/inc -I${THIRDPARTY_DIR}/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0/Libraries/CMSIS/Device/ST/STM32F4xx/Include -I${THIRDPARTY_DIR}/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0/Libraries/CMSIS/Include ${arm_gcc_include_path} -Wno-pragma-once-outside-header > ${PROJECT_BINARY_DIR}/radio/src/datacopy.cpp
COMMAND ${PYTHON_EXECUTABLE} ${RADIO_DIRECTORY}/util/generate_datacopy.py datastructs.h -DPCBHORUS -DPCBX10 -DCPUARM -DSTM32F4 -DSTM32F429_439xx -DCOLORLCD -DBACKUP -DSIMU -I. -Igui/colorlcd -Itargets/horus -Itargets/common/arm/stm32 -I${THIRDPARTY_DIR} -I${THIRDPARTY_DIR}/libopenui/src -I${THIRDPARTY_DIR}/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0/Libraries/STM32F4xx_StdPeriph_Driver/inc -I${THIRDPARTY_DIR}/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0/Libraries/CMSIS/Device/ST/STM32F4xx/Include -I${THIRDPARTY_DIR}/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0/Libraries/CMSIS/Include ${gcc_include_path} -Wno-pragma-once-outside-header > ${PROJECT_BINARY_DIR}/radio/src/datacopy.cpp
DEPENDS ${RADIO_DIRECTORY}/src/datastructs.h ${RADIO_DIRECTORY}/util/generate_datacopy.py
)
+13 -1
View File
@@ -44,12 +44,24 @@ if(Qt5Widgets_FOUND)
add_dependencies(${SIMULATOR_TARGET} ${RADIO_DEPENDENCIES})
target_compile_definitions(${SIMULATOR_TARGET} PUBLIC ${APP_COMMON_DEFINES}) # set in top-level CMakeLists
target_link_libraries(${SIMULATOR_TARGET} ${SDL_LIBRARY} Qt5::Core)
# Remove debug symbols on release builds
if(NOT CLANG)
if(${CMAKE_BUILD_TYPE} STREQUAL "Release")
add_custom_command(TARGET ${SIMULATOR_TARGET} POST_BUILD
COMMAND ${CMAKE_STRIP} $<TARGET_FILE:${SIMULATOR_TARGET}>)
endif()
endif()
# Introduced at 2.5 - TODO replace with a code change
# When compiled shared simulators using libopenui and Companion have classes named MainWindow
# When the simulator is launched from Companion the runtime dynamic linking can result in Companion overiding the simulator
# and crashing the simulator under some OSes
# The flag forces the runtime linker to always look for references in the simulator first
target_link_options(${SIMULATOR_TARGET} PRIVATE "LINKER:-Bsymbolic")
if (NOT CLANG)
target_link_options(${SIMULATOR_TARGET} PRIVATE "LINKER:-Bsymbolic")
endif()
#
add_custom_target(libsimulator DEPENDS ${SIMULATOR_TARGET})
+21 -21
View File
@@ -208,24 +208,24 @@ void splitPath(const std::string & path, std::string & dir, std::string & name)
#if !MSVC_BUILD
bool isFile(const std::string & fullName, unsigned int d_type)
bool isFile(const std::string & fullName)
{
#if defined(WIN32) || defined(__APPLE__) || defined(__FreeBSD__)
#define REGULAR_FILE DT_REG
#define SYMBOLIC_LINK DT_LNK
#else
#define REGULAR_FILE simu::DT_REG
#define SYMBOLIC_LINK simu::DT_LNK
#endif
//#if defined(WIN32) || defined(__APPLE__) || defined(__FreeBSD__)
// #define REGULAR_FILE DT_REG
// #define SYMBOLIC_LINK DT_LNK
//#else
// #define REGULAR_FILE simu::DT_REG
// #define SYMBOLIC_LINK simu::DT_LNK
//#endif
if (d_type == REGULAR_FILE) return true;
if (d_type == SYMBOLIC_LINK) {
//if (d_type == REGULAR_FILE) return true;
//if (d_type == SYMBOLIC_LINK) {
struct stat tmp;
if (stat(fullName.c_str(), &tmp) == 0) {
// TRACE_SIMPGMSPACE("\tsymlik: %s is %s", fullName.c_str(), (tmp.st_mode & S_IFREG) ? "file" : "other");
if (tmp.st_mode & S_IFREG) return true;
}
}
//}
return false;
}
#endif
@@ -255,7 +255,7 @@ std::vector<std::string> listDirectoryFiles(const std::string & dirName)
struct simu::dirent * res;
while ((res = simu::readdir(dir)) != 0) {
std::string fullName = dirName + "/" + std::string(res->d_name);
if (isFile(fullName, res->d_type)) {
if (isFile(fullName)) {
// TRACE_SIMPGMSPACE("listDirectoryFiles(): %s", fullName.c_str());
result.push_back(fullName);
}
@@ -452,20 +452,20 @@ FRESULT f_readdir (DIR * rep, FILINFO * fil)
if (strcmp(ent->d_name, ".") && strcmp(ent->d_name, "..") ) break;
}
#if defined(WIN32) || !defined(__GNUC__) || defined(__APPLE__) || defined(__FreeBSD__)
fil->fattrib = (ent->d_type == DT_DIR ? AM_DIR : 0);
#else
if (ent->d_type == simu::DT_UNKNOWN || ent->d_type == simu::DT_LNK) {
//#if defined(WIN32) || !defined(__GNUC__) || defined(__APPLE__) || defined(__FreeBSD__)
// fil->fattrib = (ent->d_type == DT_DIR ? AM_DIR : 0);
//#else
// if (ent->d_type == simu::DT_UNKNOWN || ent->d_type == simu::DT_LNK) {
fil->fattrib = 0;
struct stat buf;
if (stat(ent->d_name, &buf) == 0) {
fil->fattrib = (S_ISDIR(buf.st_mode) ? AM_DIR : 0);
}
}
else {
fil->fattrib = (ent->d_type == simu::DT_DIR ? AM_DIR : 0);
}
#endif
//}
//else {
// fil->fattrib = (ent->d_type == simu::DT_DIR ? AM_DIR : 0);
//}
//#endif
memset(fil->fname, 0, FF_MAX_LFN);
strcpy(fil->fname, ent->d_name);
+1 -5
View File
@@ -35,11 +35,7 @@ extern "C" {
/* Integer types used for FatFs API */
#if defined(_WIN32) /* Main development platform */
#define FF_INTDEF 2
#include <windows.h>
typedef unsigned __int64 QWORD;
#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */
#define FF_INTDEF 2
#include <stdint.h>
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
+1 -1
View File
@@ -13,7 +13,7 @@
** if needed, includes windows header before everything else
*/
#if defined(_WIN32)
#include <windows.h>
//#include <windows.h>
#endif
-917
View File
@@ -1,917 +0,0 @@
/*
* Dirent interface for Microsoft Visual Studio
* Version 1.21
*
* Copyright (C) 2006-2012 Toni Ronkko
* This file is part of dirent. Dirent may be freely distributed
* under the MIT license. For all details and documentation, see
* https://github.com/tronkko/dirent
*/
#ifndef DIRENT_H
#define DIRENT_H
/*
* Define architecture flags so we don't need to include windows.h.
* Avoiding windows.h makes it simpler to use windows sockets in conjunction
* with dirent.h.
*/
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86)
# define _X86_
#endif
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_AMD64)
#define _AMD64_
#endif
#include <stdio.h>
#include <stdarg.h>
#include <windef.h>
#include <winbase.h>
#include <wchar.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
/* Indicates that d_type field is available in dirent structure */
#define _DIRENT_HAVE_D_TYPE
/* Indicates that d_namlen field is available in dirent structure */
#define _DIRENT_HAVE_D_NAMLEN
/* Entries missing from MSVC 6.0 */
#if !defined(FILE_ATTRIBUTE_DEVICE)
# define FILE_ATTRIBUTE_DEVICE 0x40
#endif
/* File type and permission flags for stat(), general mask */
#if !defined(S_IFMT)
# define S_IFMT _S_IFMT
#endif
/* Directory bit */
#if !defined(S_IFDIR)
# define S_IFDIR _S_IFDIR
#endif
/* Character device bit */
#if !defined(S_IFCHR)
# define S_IFCHR _S_IFCHR
#endif
/* Pipe bit */
#if !defined(S_IFFIFO)
# define S_IFFIFO _S_IFFIFO
#endif
/* Regular file bit */
#if !defined(S_IFREG)
# define S_IFREG _S_IFREG
#endif
/* Read permission */
#if !defined(S_IREAD)
# define S_IREAD _S_IREAD
#endif
/* Write permission */
#if !defined(S_IWRITE)
# define S_IWRITE _S_IWRITE
#endif
/* Execute permission */
#if !defined(S_IEXEC)
# define S_IEXEC _S_IEXEC
#endif
/* Pipe */
#if !defined(S_IFIFO)
# define S_IFIFO _S_IFIFO
#endif
/* Block device */
#if !defined(S_IFBLK)
# define S_IFBLK 0
#endif
/* Link */
#if !defined(S_IFLNK)
# define S_IFLNK 0
#endif
/* Socket */
#if !defined(S_IFSOCK)
# define S_IFSOCK 0
#endif
/* Read user permission */
#if !defined(S_IRUSR)
# define S_IRUSR S_IREAD
#endif
/* Write user permission */
#if !defined(S_IWUSR)
# define S_IWUSR S_IWRITE
#endif
/* Execute user permission */
#if !defined(S_IXUSR)
# define S_IXUSR 0
#endif
/* Read group permission */
#if !defined(S_IRGRP)
# define S_IRGRP 0
#endif
/* Write group permission */
#if !defined(S_IWGRP)
# define S_IWGRP 0
#endif
/* Execute group permission */
#if !defined(S_IXGRP)
# define S_IXGRP 0
#endif
/* Read others permission */
#if !defined(S_IROTH)
# define S_IROTH 0
#endif
/* Write others permission */
#if !defined(S_IWOTH)
# define S_IWOTH 0
#endif
/* Execute others permission */
#if !defined(S_IXOTH)
# define S_IXOTH 0
#endif
/* Maximum length of file name */
#if !defined(PATH_MAX)
# define PATH_MAX MAX_PATH
#endif
#if !defined(FILENAME_MAX)
# define FILENAME_MAX MAX_PATH
#endif
#if !defined(NAME_MAX)
# define NAME_MAX FILENAME_MAX
#endif
/* File type flags for d_type */
#define DT_UNKNOWN 0
#define DT_REG S_IFREG
#define DT_DIR S_IFDIR
#define DT_FIFO S_IFIFO
#define DT_SOCK S_IFSOCK
#define DT_CHR S_IFCHR
#define DT_BLK S_IFBLK
#define DT_LNK S_IFLNK
/* Macros for converting between st_mode and d_type */
#define IFTODT(mode) ((mode) & S_IFMT)
#define DTTOIF(type) (type)
/*
* File type macros. Note that block devices, sockets and links cannot be
* distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
* only defined for compatibility. These macros should always return false
* on Windows.
*/
#if !defined(S_ISFIFO)
# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
#endif
#if !defined(S_ISDIR)
# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif
#if !defined(S_ISREG)
# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
#endif
#if !defined(S_ISLNK)
# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
#endif
#if !defined(S_ISSOCK)
# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
#endif
#if !defined(S_ISCHR)
# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
#endif
#if !defined(S_ISBLK)
# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
#endif
/* Return the exact length of d_namlen without zero terminator */
#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
/* Return number of bytes needed to store d_namlen */
#define _D_ALLOC_NAMLEN(p) (PATH_MAX)
#ifdef __cplusplus
extern "C" {
#endif
/* Wide-character version */
struct _wdirent {
/* Always zero */
long d_ino;
/* Structure size */
unsigned short d_reclen;
/* Length of name without \0 */
size_t d_namlen;
/* File type */
int d_type;
/* File name */
wchar_t d_name[PATH_MAX];
};
typedef struct _wdirent _wdirent;
struct _WDIR {
/* Current directory entry */
struct _wdirent ent;
/* Private file data */
WIN32_FIND_DATAW data;
/* True if data is valid */
int cached;
/* Win32 search handle */
HANDLE handle;
/* Initial directory name */
wchar_t *patt;
};
typedef struct _WDIR _WDIR;
static _WDIR *_wopendir (const wchar_t *dirname);
static struct _wdirent *_wreaddir (_WDIR *dirp);
static int _wclosedir (_WDIR *dirp);
static void _wrewinddir (_WDIR* dirp);
/* For compatibility with Symbian */
#define wdirent _wdirent
#define WDIR _WDIR
#define wopendir _wopendir
#define wreaddir _wreaddir
#define wclosedir _wclosedir
#define wrewinddir _wrewinddir
/* Multi-byte character versions */
struct dirent {
/* Always zero */
long d_ino;
/* Structure size */
unsigned short d_reclen;
/* Length of name without \0 */
size_t d_namlen;
/* File type */
int d_type;
/* File name */
char d_name[PATH_MAX];
};
typedef struct dirent dirent;
struct DIR {
struct dirent ent;
struct _WDIR *wdirp;
};
typedef struct DIR DIR;
static DIR *opendir (const char *dirname);
static struct dirent *readdir (DIR *dirp);
static int closedir (DIR *dirp);
static void rewinddir (DIR* dirp);
/* Internal utility functions */
static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
static int dirent_mbstowcs_s(
size_t *pReturnValue,
wchar_t *wcstr,
size_t sizeInWords,
const char *mbstr,
size_t count);
static int dirent_wcstombs_s(
size_t *pReturnValue,
char *mbstr,
size_t sizeInBytes,
const wchar_t *wcstr,
size_t count);
static void dirent_set_errno (int error);
/*
* Open directory stream DIRNAME for read and return a pointer to the
* internal working area that is used to retrieve individual directory
* entries.
*/
static _WDIR*
_wopendir(
const wchar_t *dirname)
{
_WDIR *dirp = NULL;
int error;
/* Must have directory name */
if (dirname == NULL || dirname[0] == '\0') {
dirent_set_errno (ENOENT);
return NULL;
}
/* Allocate new _WDIR structure */
dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
if (dirp != NULL) {
DWORD n;
/* Reset _WDIR structure */
dirp->handle = INVALID_HANDLE_VALUE;
dirp->patt = NULL;
dirp->cached = 0;
/* Compute the length of full path plus zero terminator */
n = GetFullPathNameW (dirname, 0, NULL, NULL);
/* Allocate room for absolute directory name and search pattern */
dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
if (dirp->patt) {
/*
* Convert relative directory name to an absolute one. This
* allows rewinddir() to function correctly even when current
* working directory is changed between opendir() and rewinddir().
*/
n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
if (n > 0) {
wchar_t *p;
/* Append search pattern \* to the directory name */
p = dirp->patt + n;
if (dirp->patt < p) {
switch (p[-1]) {
case '\\':
case '/':
case ':':
/* Directory ends in path separator, e.g. c:\temp\ */
/*NOP*/;
break;
default:
/* Directory name doesn't end in path separator */
*p++ = '\\';
}
}
*p++ = '*';
*p = '\0';
/* Open directory stream and retrieve the first entry */
if (dirent_first (dirp)) {
/* Directory stream opened successfully */
error = 0;
} else {
/* Cannot retrieve first entry */
error = 1;
dirent_set_errno (ENOENT);
}
} else {
/* Cannot retrieve full path name */
dirent_set_errno (ENOENT);
error = 1;
}
} else {
/* Cannot allocate memory for search pattern */
error = 1;
}
} else {
/* Cannot allocate _WDIR structure */
error = 1;
}
/* Clean up in case of error */
if (error && dirp) {
_wclosedir (dirp);
dirp = NULL;
}
return dirp;
}
/*
* Read next directory entry. The directory entry is returned in dirent
* structure in the d_name field. Individual directory entries returned by
* this function include regular files, sub-directories, pseudo-directories
* "." and ".." as well as volume labels, hidden files and system files.
*/
static struct _wdirent*
_wreaddir(
_WDIR *dirp)
{
WIN32_FIND_DATAW *datap;
struct _wdirent *entp;
/* Read next directory entry */
datap = dirent_next (dirp);
if (datap) {
size_t n;
DWORD attr;
/* Pointer to directory entry to return */
entp = &dirp->ent;
/*
* Copy file name as wide-character string. If the file name is too
* long to fit in to the destination buffer, then truncate file name
* to PATH_MAX characters and zero-terminate the buffer.
*/
n = 0;
while (n + 1 < PATH_MAX && datap->cFileName[n] != 0) {
entp->d_name[n] = datap->cFileName[n];
n++;
}
dirp->ent.d_name[n] = 0;
/* Length of file name excluding zero terminator */
entp->d_namlen = n;
/* File type */
attr = datap->dwFileAttributes;
if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
entp->d_type = DT_CHR;
} else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
entp->d_type = DT_DIR;
} else {
entp->d_type = DT_REG;
}
/* Reset dummy fields */
entp->d_ino = 0;
entp->d_reclen = sizeof (struct _wdirent);
} else {
/* Last directory entry read */
entp = NULL;
}
return entp;
}
/*
* Close directory stream opened by opendir() function. This invalidates the
* DIR structure as well as any directory entry read previously by
* _wreaddir().
*/
static int
_wclosedir(
_WDIR *dirp)
{
int ok;
if (dirp) {
/* Release search handle */
if (dirp->handle != INVALID_HANDLE_VALUE) {
FindClose (dirp->handle);
dirp->handle = INVALID_HANDLE_VALUE;
}
/* Release search pattern */
if (dirp->patt) {
free (dirp->patt);
dirp->patt = NULL;
}
/* Release directory structure */
free (dirp);
ok = /*success*/0;
} else {
/* Invalid directory stream */
dirent_set_errno (EBADF);
ok = /*failure*/-1;
}
return ok;
}
/*
* Rewind directory stream such that _wreaddir() returns the very first
* file name again.
*/
static void
_wrewinddir(
_WDIR* dirp)
{
if (dirp) {
/* Release existing search handle */
if (dirp->handle != INVALID_HANDLE_VALUE) {
FindClose (dirp->handle);
}
/* Open new search handle */
dirent_first (dirp);
}
}
/* Get first directory entry (internal) */
static WIN32_FIND_DATAW*
dirent_first(
_WDIR *dirp)
{
WIN32_FIND_DATAW *datap;
/* Open directory and retrieve the first entry */
dirp->handle = FindFirstFileW (dirp->patt, &dirp->data);
if (dirp->handle != INVALID_HANDLE_VALUE) {
/* a directory entry is now waiting in memory */
datap = &dirp->data;
dirp->cached = 1;
} else {
/* Failed to re-open directory: no directory entry in memory */
dirp->cached = 0;
datap = NULL;
}
return datap;
}
/* Get next directory entry (internal) */
static WIN32_FIND_DATAW*
dirent_next(
_WDIR *dirp)
{
WIN32_FIND_DATAW *p;
/* Get next directory entry */
if (dirp->cached != 0) {
/* A valid directory entry already in memory */
p = &dirp->data;
dirp->cached = 0;
} else if (dirp->handle != INVALID_HANDLE_VALUE) {
/* Get the next directory entry from stream */
if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {
/* Got a file */
p = &dirp->data;
} else {
/* The very last entry has been processed or an error occured */
FindClose (dirp->handle);
dirp->handle = INVALID_HANDLE_VALUE;
p = NULL;
}
} else {
/* End of directory stream reached */
p = NULL;
}
return p;
}
/*
* Open directory stream using plain old C-string.
*/
static DIR*
opendir(
const char *dirname)
{
struct DIR *dirp;
int error;
/* Must have directory name */
if (dirname == NULL || dirname[0] == '\0') {
dirent_set_errno (ENOENT);
return NULL;
}
/* Allocate memory for DIR structure */
dirp = (DIR*) malloc (sizeof (struct DIR));
if (dirp) {
wchar_t wname[PATH_MAX];
size_t n;
/* Convert directory name to wide-character string */
error = dirent_mbstowcs_s (&n, wname, PATH_MAX, dirname, PATH_MAX);
if (!error) {
/* Open directory stream using wide-character name */
dirp->wdirp = _wopendir (wname);
if (dirp->wdirp) {
/* Directory stream opened */
error = 0;
} else {
/* Failed to open directory stream */
error = 1;
}
} else {
/*
* Cannot convert file name to wide-character string. This
* occurs if the string contains invalid multi-byte sequences or
* the output buffer is too small to contain the resulting
* string.
*/
error = 1;
}
} else {
/* Cannot allocate DIR structure */
error = 1;
}
/* Clean up in case of error */
if (error && dirp) {
free (dirp);
dirp = NULL;
}
return dirp;
}
/*
* Read next directory entry.
*
* When working with text consoles, please note that file names returned by
* readdir() are represented in the default ANSI code page while any output to
* console is typically formatted on another code page. Thus, non-ASCII
* characters in file names will not usually display correctly on console. The
* problem can be fixed in two ways: (1) change the character set of console
* to 1252 using chcp utility and use Lucida Console font, or (2) use
* _cprintf function when writing to console. The _cprinf() will re-encode
* ANSI strings to the console code page so many non-ASCII characters will
* display correcly.
*/
static struct dirent*
readdir(
DIR *dirp)
{
WIN32_FIND_DATAW *datap;
struct dirent *entp;
/* Read next directory entry */
datap = dirent_next (dirp->wdirp);
if (datap) {
size_t n;
int error;
/* Attempt to convert file name to multi-byte string */
error = dirent_wcstombs_s(
&n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX);
/*
* If the file name cannot be represented by a multi-byte string,
* then attempt to use old 8+3 file name. This allows traditional
* Unix-code to access some file names despite of unicode
* characters, although file names may seem unfamiliar to the user.
*
* Be ware that the code below cannot come up with a short file
* name unless the file system provides one. At least
* VirtualBox shared folders fail to do this.
*/
if (error && datap->cAlternateFileName[0] != '\0') {
error = dirent_wcstombs_s(
&n, dirp->ent.d_name, PATH_MAX,
datap->cAlternateFileName, PATH_MAX);
}
if (!error) {
DWORD attr;
/* Initialize directory entry for return */
entp = &dirp->ent;
/* Length of file name excluding zero terminator */
entp->d_namlen = n - 1;
/* File attributes */
attr = datap->dwFileAttributes;
if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
entp->d_type = DT_CHR;
} else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
entp->d_type = DT_DIR;
} else {
entp->d_type = DT_REG;
}
/* Reset dummy fields */
entp->d_ino = 0;
entp->d_reclen = sizeof (struct dirent);
} else {
/*
* Cannot convert file name to multi-byte string so construct
* an errornous directory entry and return that. Note that
* we cannot return NULL as that would stop the processing
* of directory entries completely.
*/
entp = &dirp->ent;
entp->d_name[0] = '?';
entp->d_name[1] = '\0';
entp->d_namlen = 1;
entp->d_type = DT_UNKNOWN;
entp->d_ino = 0;
entp->d_reclen = 0;
}
} else {
/* No more directory entries */
entp = NULL;
}
return entp;
}
/*
* Close directory stream.
*/
static int
closedir(
DIR *dirp)
{
int ok;
if (dirp) {
/* Close wide-character directory stream */
ok = _wclosedir (dirp->wdirp);
dirp->wdirp = NULL;
/* Release multi-byte character version */
free (dirp);
} else {
/* Invalid directory stream */
dirent_set_errno (EBADF);
ok = /*failure*/-1;
}
return ok;
}
/*
* Rewind directory stream to beginning.
*/
static void
rewinddir(
DIR* dirp)
{
/* Rewind wide-character string directory stream */
_wrewinddir (dirp->wdirp);
}
/* Convert multi-byte string to wide character string */
static int
dirent_mbstowcs_s(
size_t *pReturnValue,
wchar_t *wcstr,
size_t sizeInWords,
const char *mbstr,
size_t count)
{
int error;
#if defined(_MSC_VER) && _MSC_VER >= 1400
/* Microsoft Visual Studio 2005 or later */
error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
#else
/* Older Visual Studio or non-Microsoft compiler */
size_t n;
/* Convert to wide-character string (or count characters) */
n = mbstowcs (wcstr, mbstr, sizeInWords);
if (!wcstr || n < count) {
/* Zero-terminate output buffer */
if (wcstr && sizeInWords) {
if (n >= sizeInWords) {
n = sizeInWords - 1;
}
wcstr[n] = 0;
}
/* Length of resuting multi-byte string WITH zero terminator */
if (pReturnValue) {
*pReturnValue = n + 1;
}
/* Success */
error = 0;
} else {
/* Could not convert string */
error = 1;
}
#endif
return error;
}
/* Convert wide-character string to multi-byte string */
static int
dirent_wcstombs_s(
size_t *pReturnValue,
char *mbstr,
size_t sizeInBytes, /* max size of mbstr */
const wchar_t *wcstr,
size_t count)
{
int error;
#if defined(_MSC_VER) && _MSC_VER >= 1400
/* Microsoft Visual Studio 2005 or later */
error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
#else
/* Older Visual Studio or non-Microsoft compiler */
size_t n;
/* Convert to multi-byte string (or count the number of bytes needed) */
n = wcstombs (mbstr, wcstr, sizeInBytes);
if (!mbstr || n < count) {
/* Zero-terminate output buffer */
if (mbstr && sizeInBytes) {
if (n >= sizeInBytes) {
n = sizeInBytes - 1;
}
mbstr[n] = '\0';
}
/* Lenght of resulting multi-bytes string WITH zero-terminator */
if (pReturnValue) {
*pReturnValue = n + 1;
}
/* Success */
error = 0;
} else {
/* Cannot convert string */
error = 1;
}
#endif
return error;
}
/* Set errno variable */
static void
dirent_set_errno(
int error)
{
#if defined(_MSC_VER) && _MSC_VER >= 1400
/* Microsoft Visual Studio 2005 and later */
_set_errno (error);
#else
/* Non-Microsoft compiler or older Microsoft compiler */
errno = error;
#endif
}
#ifdef __cplusplus
}
#endif
#endif /*DIRENT_H*/
+10 -24
View File
@@ -30,38 +30,21 @@ done
SRCDIR=$1
OUTDIR=$2
COMMON_OPTIONS="-DALLOW_NIGHTLY_BUILDS=YES -DTEST_BUILD_WARNING=YES -DGVARS=YES -DHELI=YES -DLUA=YES -DMULTIMODULE=YES -DTELEMETRY=FRSKY -DPPM_LIMITS_SYMETRICAL=YES -DVARIO=YES -DAUTOSWITCH=YES -DAUTOSOURCE=YES -DAUDIO=YES -DGPS=YES -DPPM_CENTER_ADJUSTABLE=YES -DFLIGHT_MODES=YES -DOVERRIDE_CHANNEL_FUNCTION=YES -DFRSKY_STICKS=YES"
COMMON_OPTIONS="-DGVARS=YES -DHELI=YES -DLUA=YES -Wno-dev -DCMAKE_BUILD_TYPE=Release"
if [ "$(uname)" = "Darwin" ]; then
COMMON_OPTIONS="${COMMON_OPTIONS} -DCMAKE_PREFIX_PATH=~/Qt/5.7/clang_64/ -DCMAKE_OSX_DEPLOYMENT_TARGET='10.9'"
COMMON_OPTIONS="${COMMON_OPTIONS} -DCMAKE_OSX_DEPLOYMENT_TARGET='10.9'"
elif [ "$(uname)" != "Linux" ]; then
COMMON_OPTIONS="${COMMON_OPTIONS} -DSDL_LIBRARY_PATH=/mingw64/bin/"
fi
if [ "$3" != "" ]; then
COMMON_OPTIONS="${COMMON_OPTIONS} -DVERSION_SUFFIX=$3"
else
wget https://downloads.open-tx.org/2.3/nightlies/companion/companion-linux.stamp
version=$(cut -d'N' -f 3 < companion-linux.stamp)
version=$(echo $version | tr -cd '[[:digit:]]')
version=$((version+1))
nightly=N"$version"
COMMON_OPTIONS="${COMMON_OPTIONS} -DVERSION_SUFFIX=$nightly"
fi
rm -rf build
mkdir build
cd build
cmake ${COMMON_OPTIONS} -DPCB=AR9X ${SRCDIR}
make -j${JOBS} libsimulator
rm CMakeCache.txt
cmake ${COMMON_OPTIONS} -DPCB=SKY9X ${SRCDIR}
make -j${JOBS} libsimulator
rm CMakeCache.txt
cmake ${COMMON_OPTIONS} -DPCB=9XRPRO ${SRCDIR}
make -j${JOBS} libsimulator
rm CMakeCache.txt
cmake ${COMMON_OPTIONS} -DPCB=X9LITE ${SRCDIR}
make -j${JOBS} libsimulator
rm CMakeCache.txt
@@ -141,10 +124,13 @@ rm CMakeCache.txt
cmake ${COMMON_OPTIONS} -DPCB=X12S ${SRCDIR}
make -j${JOBS} libsimulator
make -j${JOBS} package
if [ "$(uname)" = "Darwin" ]; then
make -j${JOBS} package
cp *.dmg ${OUTDIR}
else
elif [ "$(uname)" = "Linux" ]; then
make -j${JOBS} package
cp *.deb ${OUTDIR}
else
make installer
cp companion/*.exe ${OUTDIR}
fi