Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 166 additions & 24 deletions megacmd/Makefile
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,54 +1,196 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2011-2025 Entware
#
# The newer versions based on cmake+vcpkg build system with online dependencies installation

include $(TOPDIR)/rules.mk

PKG_NAME:=megacmd
PKG_VERSION:=1.7.0
PKG_REV:=bc0e4016eeb561677e8078294422e9b1619515b5
PKG_VERSION:=2.4.0
PKG_RELEASE:=1

PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE_URL:=https://github.com/meganz/MEGAcmd.git
PKG_SOURCE_PROTO:=git
PKG_MIRROR_HASH:=8b47296930c42a61ade9ca6e5e06ce26e9e6189a6d604c1292c2d299f26e6911
PKG_SOURCE_URL:=https://github.com/meganz/MEGAcmd.git
PKG_SOURCE_VERSION:=2.4.0_Linux
PKG_MIRROR_HASH:=skip

PKG_LICENSE:=BSD-2-Clause GPL-3.0-or-later
PKG_LICENSE_FILES:=LICENSE
PKG_MAINTAINER:=Your Name <your.email@example.com>

PKG_FIXUP:=autoreconf
PKG_INSTALL:=1
PKG_BUILD_PARALLEL:=1
PKG_FIXUP:=libtool

CMAKE_BINARY_SUBDIR:=.build

include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk

define Package/megacmd
SECTION:=net
CATEGORY:=Network
SUBMENU:=File Transfer
DEPENDS:=+icu +libcares +libcryptopp +libcurl +libmediainfo \
+libpcre +libreadline +libsodium +libsqlite3 +libuv
+libpcrecpp +libreadline +libsodium +libsqlite3 +libuv \
+libopenssl +libffmpeg-full +libfuse +zlib
TITLE:=Command Line Interactive and Scriptable Application
URL:=https://github.com/meganz/megacmd
MAINTAINER:=Entware team, https://entware.net
endef

define Package/megacmd/description
MEGAcmd provides non UI access to MEGA services. It intends to offer all the
functionality with your MEGA account via commands.
MEGAcmd provides non-UI access to MEGA services. It features a
server-client architecture where the server handles all cloud
operations and multiple clients can send commands to it.

This package includes command-line tools for file transfer,
synchronization, and cloud storage management.

License: BSD-2-Clause AND GPL-3.0-or-later
See /opt/share/doc/megacmd/LICENSE for full license text.
endef

# Check if tests are enabled via environment variable
# Usage: make package/feeds/rtndev/megacmd/compile MEGACMD_ENABLE_TESTS=1
ifeq ($(MEGACMD_ENABLE_TESTS),1)
CMAKE_OPTIONS += \
-DENABLE_MEGACMD_TESTS=ON \
-DFETCHCONTENT_FULLY_DISCONNECTED=OFF \
-DFETCHCONTENT_QUIET=OFF
else
# Default: disable tests for production builds
CMAKE_OPTIONS += \
-DENABLE_MEGACMD_TESTS=OFF
endif

# Disable vcpkg and external package managers
CMAKE_OPTIONS += \
-DUSE_VCPKG=OFF \
-DENABLE_VCPKG=OFF \
-DCMAKE_DISABLE_FIND_PACKAGE_Vcpkg=ON \
-DFULL_REQS=OFF

# Feature selection
CMAKE_OPTIONS += \
-DUSE_PDFIUM=OFF \
-DUSE_FREEIMAGE=OFF \
-DUSE_FFMPEG=ON \
-DUSE_PCRE=ON \
-DENABLE_MEDIA_FILE_METADATA=ON \
-DUSE_READLINE=ON \
-DUSE_LIBUV=ON \
-DUSE_OPENSSL=ON

# Library paths for Entware staging
CMAKE_OPTIONS += \
-DFUSE_INCLUDE_DIR=$(STAGING_DIR)/opt/include/fuse \
-DFUSE_LIBRARY=$(STAGING_DIR)/opt/lib/libfuse.so \
-DCRYPTOPP_INCLUDE_DIR=$(STAGING_DIR)/opt/include \
-DCRYPTOPP_LIBRARY=$(STAGING_DIR)/opt/lib/libcryptopp.so

# Installation configuration
CMAKE_OPTIONS += \
-DCMAKE_INSTALL_PREFIX=/opt \
-DCMAKE_INSTALL_BINDIR=bin \
-DCMAKE_INSTALL_LIBDIR=lib \
-DBUILD_SHARED_LIBS=ON

define Package/megacmd/conffiles
/opt/etc/sysctl.d/99-megacmd-inotify-limit.conf
endef

# Custom test hook - runs after Build/Compile if tests are enabled
define Build/RunTests
echo ""; \
echo "========================================"; \
echo "Running MEGAcmd Tests"; \
echo "========================================"; \
echo ""; \
echo "Note: Tests require Google Test which will be downloaded during build"; \
echo ""; \
cd $(PKG_BUILD_DIR)/$(CMAKE_BINARY_SUBDIR) && \
export MEGACMD_TEST_USER=$(MEGACMD_TEST_USER) MEGACMD_TEST_PASS=$(MEGACMD_TEST_PASS) && export LD_LIBRARY_PATH=$(PKG_BUILD_DIR)/$(CMAKE_BINARY_SUBDIR)/sdk:$(PKG_BUILD_DIR)/$(CMAKE_BINARY_SUBDIR)/lib:$(STAGING_DIR)/opt/lib:$(TOOLCHAIN_DIR)/lib:$$$$$$$$LD_LIBRARY_PATH && \
if [ -f mega-cmd-tests-unit ]; then \
echo "Running unit tests..."; \
if [ -x "$(TOOLCHAIN_DIR)/lib/ld-linux-x86-64.so.2" ]; then \
$(TOOLCHAIN_DIR)/lib/ld-linux-x86-64.so.2 ./mega-cmd-tests-unit --gtest_brief=1 || { echo "Unit tests failed!"; exit 1; }; \
else \
./mega-cmd-tests-unit --gtest_brief=1 || { echo "Unit tests failed!"; exit 1; }; \
fi; \
echo ""; \
else \
echo "Warning: Unit test binary not found"; \
fi; \
if [ -f mega-cmd-tests-integration ]; then \
echo "Running integration tests..."; \
echo "Note: Integration tests may require network access and MEGA credentials"; \
if [ -x "$(TOOLCHAIN_DIR)/lib/ld-linux-x86-64.so.2" ]; then \
$(TOOLCHAIN_DIR)/lib/ld-linux-x86-64.so.2 ./mega-cmd-tests-integration --gtest_brief=1 || { echo "Integration tests failed (may be expected without credentials)"; }; \
else \
./mega-cmd-tests-integration --gtest_brief=1 || { echo "Integration tests failed (may be expected without credentials)"; }; \
fi; \
echo ""; \
else \
echo "Warning: Integration test binary not found"; \
fi; \
echo "========================================"; \
echo "Test execution completed"; \
echo "========================================"; \
echo "";
endef

CONFIGURE_ARGS += \
--disable-doxygen-doc \
--without-freeimage \
--without-ffmpeg
# Hook the test execution after compilation
ifeq ($(MEGACMD_ENABLE_TESTS),1)
Hooks/Compile/Post += Build/RunTests
endif

define Package/megacmd/install
# Install binaries
$(INSTALL_DIR) $(1)/opt/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/opt/bin/mega-* $(1)/opt/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/opt/bin/mega-* $(1)/opt/bin/
rm -f $(1)/opt/bin/mega-cmd-tests-*

# Install shared library
$(INSTALL_DIR) $(1)/opt/lib
$(CP) $(PKG_INSTALL_DIR)/opt/lib/libmega.so* $(1)/opt/lib
$(SED) 's,^#!.*bash,#!/opt/bin/sh,' $(1)/opt/bin/*
$(CP) $(PKG_INSTALL_DIR)/opt/lib/libmega.so* $(1)/opt/lib/
$(CP) $(PKG_INSTALL_DIR)/opt/lib/libg{test,mock}*.so* $(1)/opt/lib/

# Install bash completion
$(INSTALL_DIR) $(1)/opt/etc/bash_completion.d
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/opt/etc/bash_completion.d/megacmd_completion.sh \
$(1)/opt/etc/bash_completion.d/

# Install sysctl configuration for inotify limits
$(INSTALL_DIR) $(1)/opt/etc/sysctl.d
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/opt/etc/sysctl.d/99-megacmd-inotify-limit.conf \
$(1)/opt/etc/sysctl.d/

# Install license documentation (BSD-2-Clause compliance)
$(INSTALL_DIR) $(1)/opt/share/doc/megacmd
$(INSTALL_DATA) $(PKG_BUILD_DIR)/LICENSE $(1)/opt/share/doc/megacmd/

# Install README if present
[ ! -f $(PKG_BUILD_DIR)/README.md ] || \
$(INSTALL_DATA) $(PKG_BUILD_DIR)/README.md $(1)/opt/share/doc/megacmd/
endef

define Package/megacmd/postinst
#!/bin/sh
# Apply sysctl settings if system supports it
if [ -f /opt/etc/sysctl.d/99-megacmd-inotify-limit.conf ] && [ -x /opt/sbin/sysctl ]; then
/opt/sbin/sysctl -p /opt/etc/sysctl.d/99-megacmd-inotify-limit.conf 2>/dev/null || true
fi

echo ""
echo "MEGAcmd installed successfully."
echo "Run 'mega-help' to get started or 'mega-cmd-server' to start the server."
echo ""
echo "License: BSD-2-Clause AND GPL-3.0-or-later"
echo "See /opt/share/doc/megacmd/LICENSE for full license text."
echo ""
exit 0
endef

define Package/megacmd/prerm
#!/bin/sh
# Kill running mega-cmd-server instances
killall mega-cmd-server 2>/dev/null || true
exit 0
endef

$(eval $(call BuildPackage,megacmd))
19 changes: 19 additions & 0 deletions megacmd/patches/001-fix-cryptopp-path.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
--- a/sdk/cmake/modules/sdklib_libraries.cmake
+++ b/sdk/cmake/modules/sdklib_libraries.cmake
@@ -49,8 +49,14 @@ macro(load_sdklib_libraries)

find_package(PkgConfig REQUIRED) # For libraries loaded using pkg-config

- pkg_check_modules(cryptopp REQUIRED IMPORTED_TARGET libcrypto++)
- target_link_libraries(SDKlib PUBLIC PkgConfig::cryptopp) # TODO: Private for SDK core
+ if(CRYPTOPP_LIBRARY)
+ include_directories(${CRYPTOPP_INCLUDE_DIR})
+ target_link_libraries(SDKlib PUBLIC ${CRYPTOPP_LIBRARY})
+ message(STATUS "Using provided CRYPTOPP_LIBRARY: ${CRYPTOPP_LIBRARY}")
+ else()
+ pkg_check_modules(cryptopp REQUIRED IMPORTED_TARGET libcrypto++)
+ target_link_libraries(SDKlib PUBLIC PkgConfig::cryptopp) # TODO: Private for SDK core
+ endif()

pkg_check_modules(sodium REQUIRED IMPORTED_TARGET libsodium)
target_link_libraries(SDKlib PRIVATE PkgConfig::sodium)
29 changes: 29 additions & 0 deletions megacmd/patches/002-cryptopp.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -23,7 +23,7 @@
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/build/cmake/modules) # Modules from MEGAcmd
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/sdk/cmake/modules) # Modules from MEGAsdk

-set(VCPKG_ROOT "${CMAKE_CURRENT_LIST_DIR}/../vcpkg" CACHE PATH "If set, it will build and use the VCPKG packages defined in the manifest file")
+set(VCPKG_ROOT "" CACHE PATH "Disabled in Entware build")

include(detect_host_architecture)

@@ -44,7 +44,7 @@
)
endif()

-if((NOT WIN32 OR BASH_VERSION_RESULT EQUAL 0) AND NOT EXISTS ${VCPKG_ROOT})
+if(FALSE)
message(STATUS "vcpkg will be cloned into ${VCPKG_ROOT}")
execute_process(
#TODO: have the same for windows ... or at least check if bash is available
@@ -82,7 +82,7 @@
message(STATUS "Using VCPKG_ROOT = ${VCPKG_ROOT}")

-if(VCPKG_ROOT)
+if(FALSE)
if (ENABLE_MEGACMD_TESTS)
list(APPEND VCPKG_MANIFEST_FEATURES "megacmd-enable-tests")
endif()

11 changes: 11 additions & 0 deletions megacmd/patches/003-fix-cloudraid-pimpl.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
--- a/sdk/include/mega/raid.h
+++ b/sdk/include/mega/raid.h
@@ -281,7 +281,7 @@
const CloudRaidImpl* mPimpl() const { return m_pImpl.get(); }
CloudRaidImpl* mPimpl() { return m_pImpl.get(); }

- std::unique_ptr<CloudRaidImpl> m_pImpl{};
+ std::unique_ptr<CloudRaidImpl> m_pImpl;
bool mShown{};

public:
20 changes: 20 additions & 0 deletions megacmd/patches/004-fix-hashcash.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--- a/sdk/src/hashcash.cpp
+++ b/sdk/src/hashcash.cpp
@@ -82,7 +82,7 @@
h.Update(data, static_cast<unsigned>(len));

uint32_t word{};
- h.TruncatedFinal(reinterpret_cast<CryptoPP::byte*>(&word), 4);
+ h.TruncatedFinal(reinterpret_cast<unsigned char*>(&word), 4);
return word;
}

@@ -220,7 +220,7 @@
}

uint32_t firstWord{};
- hasher.TruncatedFinal(reinterpret_cast<CryptoPP::byte*>(&firstWord), sizeof(uint32_t));
+ hasher.TruncatedFinal(reinterpret_cast<unsigned char*>(&firstWord), sizeof(uint32_t));

if (htonl(firstWord) <= thresholdNetOrder)
{
27 changes: 27 additions & 0 deletions megacmd/patches/005-fix-sqlite-transform-reduce.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
--- a/sdk/src/db/sqlite.cpp
+++ b/sdk/src/db/sqlite.cpp
@@ -535,16 +535,15 @@

std::vector<std::unique_ptr<MigrateType>> migrateElement;
migrateElement.reserve(cols.size());
- bool hasValues = std::transform_reduce(
- cols.begin(),
- cols.end(),
- false,
- std::logical_or{},
- [&migrateElement, &nd](const NewColumn& c) -> bool
+ bool hasValues = false;
+ for (const auto& c : cols)
+ {
+ assert(c.migrateOperation);
+ if (c.migrateOperation(nd, migrateElement))
{
- assert(c.migrateOperation);
- return c.migrateOperation(nd, migrateElement);
- });
+ hasValues = true;
+ }
+ }


++numRows;
Loading