From bfde35b0997e8d38bf8b3cd59d20f303559a7c30 Mon Sep 17 00:00:00 2001 From: Morgan Caron Date: Thu, 14 Aug 2025 20:48:50 +0200 Subject: [PATCH] CI MacOS --- .github/workflows/ci-cpp-linux.yml | 12 ++++++-- .github/workflows/ci-cpp-macos.yml | 21 ++++++++------ modules/FileSystem/Watcher.mpp | 3 +- modules/Network/Client.mpp | 2 +- modules/Network/Server.mpp | 2 +- modules/Network/Socket.mpp | 46 +++++++++++++++--------------- modules/Terminal/Cursor.mpp | 4 +-- modules/Terminal/RawTerminal.mpp | 4 +-- modules/Terminal/Size.mpp | 12 ++++---- modules/Terminal/Title.mpp | 4 +-- tests/FileSystem/Watcher.mpp | 32 +++------------------ 11 files changed, 64 insertions(+), 78 deletions(-) diff --git a/.github/workflows/ci-cpp-linux.yml b/.github/workflows/ci-cpp-linux.yml index 5509986f..029f491a 100644 --- a/.github/workflows/ci-cpp-linux.yml +++ b/.github/workflows/ci-cpp-linux.yml @@ -49,10 +49,16 @@ jobs: if: ${{ matrix.compiler.name == 'Latest Clang' }} uses: MorganCaron/latest-clang-action@master - - name: Compile + - name: Update xmake repository + run: xmake repo --update + + - name: Configure & Install dependencies + run: | + xmake f ${{ matrix.compiler.xmake-toolchain }} --runtimes="c++_shared" --enable_tests=y -v --yes + + - name: Build run: | - xmake f ${{ matrix.compiler.xmake-toolchain }} --runtimes="c++_shared" --enable_tests=y --yes - xmake build -vD + xmake build -v - name: Run tests run: | diff --git a/.github/workflows/ci-cpp-macos.yml b/.github/workflows/ci-cpp-macos.yml index 805a1e7f..7f66a74e 100644 --- a/.github/workflows/ci-cpp-macos.yml +++ b/.github/workflows/ci-cpp-macos.yml @@ -17,22 +17,25 @@ jobs: } steps: - uses: actions/checkout@v4 + + - uses: tecolicom/actions-use-homebrew-tools@v1 + with: + tools: llvm ninja cmake + - uses: xmake-io/github-action-setup-xmake@v1 with: xmake-version: branch@master - - name: Install LLVM - if: ${{ matrix.compiler.name == 'Clang' }} + - name: Update xmake repository + run: xmake repo --update + + - name: Configure & Install dependencies run: | - brew install llvm + xmake f --toolchain=llvm --sdk="$(brew --prefix)/opt/llvm/" --runtimes="c++_shared" --enable_tests=y -v --yes - - name: Compile - env: - CC: ${{ matrix.compiler.cc }} - CXX: ${{ matrix.compiler.cxx }} + - name: Build run: | - xmake f --enable_tests=y --yes - xmake build -vD + xmake build -v - name: Run tests run: | diff --git a/modules/FileSystem/Watcher.mpp b/modules/FileSystem/Watcher.mpp index e6e533fe..9eefe4a4 100644 --- a/modules/FileSystem/Watcher.mpp +++ b/modules/FileSystem/Watcher.mpp @@ -10,6 +10,7 @@ module; # include #elif defined(OS_MACOS) # include +# include #endif export module CppUtils.FileSystem.Watcher; @@ -259,7 +260,7 @@ export namespace CppUtils::FileSystem Container::BidirectionalMap m_watchDescriptors; std::vector> m_subscribedFunctions; #elif defined(OS_MACOS) - FSEventStreamRef m_filesystemEventStream; + [[maybe_unused]] FSEventStreamRef m_filesystemEventStream; #endif }; } diff --git a/modules/Network/Client.mpp b/modules/Network/Client.mpp index 39328387..182e6e89 100644 --- a/modules/Network/Client.mpp +++ b/modules/Network/Client.mpp @@ -4,7 +4,7 @@ module; #if defined(OS_WINDOWS) # include -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) or defined(OS_MACOS) # include #endif diff --git a/modules/Network/Server.mpp b/modules/Network/Server.mpp index 92198092..841656a7 100644 --- a/modules/Network/Server.mpp +++ b/modules/Network/Server.mpp @@ -5,7 +5,7 @@ module; #if defined(OS_WINDOWS) # include # pragma comment(lib, "ws2_32.lib") -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) or defined(OS_MACOS) # include # include #endif diff --git a/modules/Network/Socket.mpp b/modules/Network/Socket.mpp index ccca1601..d54d58c5 100644 --- a/modules/Network/Socket.mpp +++ b/modules/Network/Socket.mpp @@ -5,7 +5,7 @@ module; #if defined(OS_WINDOWS) # include # include // for socklen_t -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) or defined(OS_MACOS) # include # include # include @@ -63,7 +63,7 @@ export namespace CppUtils::Network #if defined(OS_WINDOWS) inline constexpr auto throwErrno = std::addressof(WindowsSocketApi::throwErrno); -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) or defined(OS_MACOS) inline constexpr auto throwErrno = std::addressof(System::throwErrno); #endif @@ -72,7 +72,7 @@ export namespace CppUtils::Network public: #if defined(OS_WINDOWS) using NativeSocket = SOCKET; -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) or defined(OS_MACOS) using NativeSocket = int; #endif @@ -80,7 +80,7 @@ export namespace CppUtils::Network { IPV4 = AF_INET, IPV6 = AF_INET6, -#if defined(OS_LINUX) +#if defined(OS_LINUX) or defined(OS_MACOS) Local = AF_UNIX #endif }; @@ -101,7 +101,7 @@ export namespace CppUtils::Network m_socket = ::socket(static_cast(domain), static_cast(type), 0); if (m_socket == INVALID_SOCKET) throw std::runtime_error{"Socket creation failed"}; -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) or defined(OS_MACOS) m_socket = ::socket(static_cast(domain), static_cast(type), 0); if (m_socket < 0) throw std::runtime_error{"Socket creation failed"}; @@ -112,7 +112,7 @@ export namespace CppUtils::Network explicit inline Socket(SOCKET socket) noexcept: m_socket{socket} {} -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) or defined(OS_MACOS) explicit inline Socket(int socket) noexcept: m_socket{socket} {} @@ -127,7 +127,7 @@ export namespace CppUtils::Network { #if defined(OS_WINDOWS) other.m_socket = INVALID_SOCKET; -#else +#elif defined(OS_LINUX) or defined(OS_MACOS) other.m_socket = -1; #endif } @@ -141,7 +141,7 @@ export namespace CppUtils::Network #if defined(OS_WINDOWS) if (m_socket != INVALID_SOCKET) ::closesocket(m_socket); -#else +#elif defined(OS_LINUX) or defined(OS_MACOS) if (m_socket != -1) ::close(m_socket); #endif @@ -150,7 +150,7 @@ export namespace CppUtils::Network m_socket = other.m_socket; #if defined(OS_WINDOWS) other.m_socket = INVALID_SOCKET; -#else +#elif defined(OS_LINUX) or defined(OS_MACOS) other.m_socket = -1; #endif } @@ -162,7 +162,7 @@ export namespace CppUtils::Network #if defined(OS_WINDOWS) if (m_socket != INVALID_SOCKET) ::closesocket(m_socket); -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) or defined(OS_MACOS) if (m_socket != -1) ::close(m_socket); #endif @@ -195,7 +195,7 @@ export namespace CppUtils::Network auto mode = enable ? u_long{0} : u_long{1}; if (::ioctlsocket(m_socket, static_cast(FIONBIO), std::addressof(mode)) != 0) throw std::runtime_error{"CppUtils::Network::Socket::setBlocking: Failed to set blocking mode"}; -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) or defined(OS_MACOS) auto flags = ::fcntl(m_socket, F_GETFL); if (flags == -1) throw std::runtime_error{"CppUtils::Network::Socket::setBlocking: Failed to get socket flags"}; @@ -214,7 +214,7 @@ export namespace CppUtils::Network auto mode = u_long{}; ::ioctlsocket(m_socket, static_cast(FIONBIO), std::addressof(mode)); return mode == 0; -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) or defined(OS_MACOS) int flags = ::fcntl(m_socket, F_GETFL, 0); if (flags == -1) throw std::runtime_error{"CppUtils::Network::Socket::isBlocking: Failed to get socket flags"}; @@ -237,7 +237,7 @@ export namespace CppUtils::Network // TODO make implementation for windows // @see https://stackoverflow.com/questions/72759272/how-to-deal-with-socket-in-select-method auto result = -1; -#else +#elif defined(OS_LINUX) or defined(OS_MACOS) auto result = select(m_socket + 1, std::addressof(readSet), nullptr, nullptr, std::addressof(timeValue)); #endif if (result < 0) @@ -250,7 +250,7 @@ export namespace CppUtils::Network { #if defined(OS_WINDOWS) return not ::setsockopt(socket, level, option, reinterpret_cast(value), static_cast(valueSize)); -#else +#elif defined(OS_LINUX) or defined(OS_MACOS) return not ::setsockopt(socket, level, option, value, static_cast(valueSize)); #endif } @@ -306,7 +306,7 @@ export namespace CppUtils::Network { #ifdef OS_WINDOWS if (::send(m_socket, std::bit_cast(std::addressof(data)), sizeof(decltype(data)), 0) < 0) -#else +#elif defined(OS_LINUX) or defined(OS_MACOS) if (::send(m_socket, std::bit_cast(std::addressof(data)), sizeof(decltype(data)), 0) < 0) #endif throw std::runtime_error{"CppUtils::Network::Socket::send: Send failed"}; @@ -317,14 +317,14 @@ export namespace CppUtils::Network for (auto totalSent = 0uz; totalSent < std::size(data);) #ifdef OS_WINDOWS if (auto bytesSent = ::send(m_socket, std::bit_cast(std::data(data)) + totalSent, static_cast(std::size(data) - totalSent), 0); -#else +#elif defined(OS_LINUX) or defined(OS_MACOS) if (auto bytesSent = ::send(m_socket, std::data(data) + totalSent, std::size(data) - totalSent, 0); #endif bytesSent < 0) { #if defined(OS_WINDOWS) if (::WSAGetLastError() == WSAEWOULDBLOCK) -#else +#elif defined(OS_LINUX) or defined(OS_MACOS) if (errno == EAGAIN or errno == EWOULDBLOCK) #endif continue; @@ -338,7 +338,7 @@ export namespace CppUtils::Network { #if defined(OS_WINDOWS) if (::send(m_socket, std::data(string), static_cast(std::size(string)), 0) < 0) -#else +#elif defined(OS_LINUX) or defined(OS_MACOS) if (::send(m_socket, std::data(string), std::size(string), 0) < 0) #endif @@ -350,7 +350,7 @@ export namespace CppUtils::Network { #if defined(OS_WINDOWS) if (::WSAGetLastError() == WSAEWOULDBLOCK) -#else +#elif defined(OS_LINUX) or defined(OS_MACOS) if (errno == EWOULDBLOCK) #endif return std::runtime_error{"Socket is non-blocking and no data is available"}; @@ -367,7 +367,7 @@ export namespace CppUtils::Network { #if defined(OS_WINDOWS) const auto size = static_cast(sizeof(T) - totalBytesReceived); -#else +#elif defined(OS_LINUX) or defined(OS_MACOS) const auto size = sizeof(T) - totalBytesReceived; #endif auto bytesReceived = ::recv(m_socket, reinterpret_cast(std::addressof(data)) + totalBytesReceived, size, 0); @@ -375,7 +375,7 @@ export namespace CppUtils::Network { #if defined(OS_WINDOWS) if (WSAGetLastError() == WSAEWOULDBLOCK) -#else +#elif defined(OS_LINUX) or defined(OS_MACOS) if (errno == EAGAIN) continue; if (errno == EWOULDBLOCK) @@ -399,14 +399,14 @@ export namespace CppUtils::Network { #if defined(OS_WINDOWS) auto bytesReceived = ::recv(m_socket, std::bit_cast(std::data(buffer)) + totalBytesReceived, static_cast(bufferSize - totalBytesReceived), 0); -#else +#elif defined(OS_LINUX) or defined(OS_MACOS) auto bytesReceived = ::recv(m_socket, std::data(buffer) + totalBytesReceived, bufferSize - totalBytesReceived, 0); #endif if (bytesReceived < 0) { #if defined(OS_WINDOWS) if (WSAGetLastError() == WSAEWOULDBLOCK) -#else +#elif defined(OS_LINUX) or defined(OS_MACOS) if (errno == EAGAIN or errno == EWOULDBLOCK) #endif continue; diff --git a/modules/Terminal/Cursor.mpp b/modules/Terminal/Cursor.mpp index 235f0212..9be18440 100644 --- a/modules/Terminal/Cursor.mpp +++ b/modules/Terminal/Cursor.mpp @@ -21,7 +21,7 @@ export namespace CppUtils::Terminal consoleScreenBufferInfo.srWindow.Left, consoleScreenBufferInfo.srWindow.Top}; } -#elif defined(OS_MAC) or defined(OS_LINUX) +#elif defined(OS_LINUX) or defined(OS_MACOS) [[nodiscard]] inline auto getCursorPosition() -> std::expected { using namespace std::literals; @@ -43,7 +43,7 @@ export namespace CppUtils::Terminal { SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), COORD{static_cast(position.x()), static_cast(position.y())}); } -#elif defined(OS_MAC) or defined(OS_LINUX) +#elif defined(OS_LINUX) or defined(OS_MACOS) inline auto setCursorPosition([[maybe_unused]] Container::Size2 position) -> void { std::print("\x1b[{};{}H", position.y() + 1, position.x() + 1); diff --git a/modules/Terminal/RawTerminal.mpp b/modules/Terminal/RawTerminal.mpp index 5ef2296c..57c9a276 100644 --- a/modules/Terminal/RawTerminal.mpp +++ b/modules/Terminal/RawTerminal.mpp @@ -2,7 +2,7 @@ module; #include -#if defined(OS_MAC) or defined(OS_LINUX) +#if defined(OS_LINUX) or defined(OS_MACOS) # include # include #endif @@ -13,7 +13,7 @@ import std; export namespace CppUtils::Terminal { -#if defined(OS_MAC) or defined(OS_LINUX) +#if defined(OS_LINUX) or defined(OS_MACOS) class RawTerminal final { public: diff --git a/modules/Terminal/Size.mpp b/modules/Terminal/Size.mpp index a34f61b5..183dfa99 100644 --- a/modules/Terminal/Size.mpp +++ b/modules/Terminal/Size.mpp @@ -2,7 +2,7 @@ module; #include -#if defined(OS_MAC) or defined(OS_LINUX) +#if defined(OS_LINUX) or defined(OS_MACOS) # include # include #endif @@ -18,19 +18,19 @@ export namespace CppUtils::Terminal [[nodiscard]] inline auto getTerminalSize() -> Container::Size2 { auto consoleScreenBufferInfo = CONSOLE_SCREEN_BUFFER_INFO{}; - GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleScreenBufferInfo); + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), std::addressof(consoleScreenBufferInfo)); return Container::Size2{ static_cast(consoleScreenBufferInfo.srWindow.Right - consoleScreenBufferInfo.srWindow.Left + 1), static_cast(consoleScreenBufferInfo.srWindow.Bottom - consoleScreenBufferInfo.srWindow.Top + 1)}; } -#elif defined(OS_MAC) or defined(OS_LINUX) +#elif defined(OS_LINUX) or defined(OS_MACOS) [[nodiscard]] inline auto getTerminalSize() -> Container::Size2 { auto windowsSize = winsize{}; - ioctl(STDOUT_FILENO, TIOCGWINSZ, &windowsSize); + ioctl(STDOUT_FILENO, TIOCGWINSZ, std::addressof(windowsSize)); return Container::Size2{ - windowsSize.ws_col, - windowsSize.ws_row}; + static_cast(windowsSize.ws_col), + static_cast(windowsSize.ws_row)}; } #endif } diff --git a/modules/Terminal/Title.mpp b/modules/Terminal/Title.mpp index 4465cab0..3dd467d9 100644 --- a/modules/Terminal/Title.mpp +++ b/modules/Terminal/Title.mpp @@ -21,7 +21,7 @@ export namespace CppUtils::Terminal title.resize(size); ::GetConsoleTitleW(std::data(title), size); return title; -#elif defined(OS_MAC) or defined(OS_LINUX) +#elif defined(OS_LINUX) or defined(OS_MACOS) /* using namespace std::literals; @@ -41,7 +41,7 @@ export namespace CppUtils::Terminal { #if defined(OS_WINDOWS) ::SetConsoleTitleW(std::data(title)); -#elif defined(OS_MAC) or defined(OS_LINUX) +#elif defined(OS_LINUX) or defined(OS_MACOS) std::print("\x1B]0;{}\a", title); std::fflush(stdout); #endif diff --git a/tests/FileSystem/Watcher.mpp b/tests/FileSystem/Watcher.mpp index 50a4676a..0898bee5 100644 --- a/tests/FileSystem/Watcher.mpp +++ b/tests/FileSystem/Watcher.mpp @@ -9,30 +9,24 @@ import CppUtils; export namespace CppUtils::UnitTest::FileSystem::Watcher { +#if defined(OS_LINUX) inline auto _ = TestSuite{ "FileSystem/Watcher", {"Logger", "FileSystem/Directory", "FileSystem/File"}, [](auto& suite) { using namespace std::chrono_literals; -#if defined(OS_LINUX) using Logger = CppUtils::Logger<"CppUtils">; -#endif suite.addTest("No file", [&] { CppUtils::FileSystem::TemporaryDirectory{[&suite](const auto& directory) -> void { auto watcher = CppUtils::FileSystem::Watcher{}; watcher.watch(directory / "test.tmp"); -#if defined(OS_LINUX) watcher.onEvent( [&suite]( [[maybe_unused]] CppUtils::FileSystem::Event event, [[maybe_unused]] const std::filesystem::path& filePath) -> void { suite.expect(false); }); -#else - auto& _ = suite; -# warning "TODO onEvent not implemented for this platform" -#endif std::this_thread::sleep_for(10ms); }}; }); @@ -44,17 +38,12 @@ export namespace CppUtils::UnitTest::FileSystem::Watcher auto watcher = CppUtils::FileSystem::Watcher{}; watcher.watch(filePath); -#if defined(OS_LINUX) watcher.onEvent( [&suite]( [[maybe_unused]] CppUtils::FileSystem::Event event, [[maybe_unused]] const std::filesystem::path& filePath) -> void { suite.expect(false); }); -#else - auto& _ = suite; -# warning "TODO onEvent not implemented for this platform" -#endif std::this_thread::sleep_for(10ms); }}; }); @@ -75,7 +64,6 @@ export namespace CppUtils::UnitTest::FileSystem::Watcher auto watcher = CppUtils::FileSystem::Watcher{}; watcher.watch(directory); -#if defined(OS_LINUX) watcher.onEvent( [](CppUtils::FileSystem::Event event, const std::filesystem::path& filePath) -> void { @@ -97,9 +85,6 @@ export namespace CppUtils::UnitTest::FileSystem::Watcher suite.expectEqual(eventFilePath, filePath); expectCloseFile = true; }); -#else -# warning "TODO onEvent not implemented for this platform" -#endif CppUtils::FileSystem::String::write(directory / "test.tmp", "Hello World!"); std::this_thread::sleep_for(100ms); @@ -116,7 +101,6 @@ export namespace CppUtils::UnitTest::FileSystem::Watcher auto watcher = CppUtils::FileSystem::Watcher{}; watcher.watch(filePath); -#if defined(OS_LINUX) watcher.onEvent( [](CppUtils::FileSystem::Event event, const std::filesystem::path& filePath) -> void { @@ -130,9 +114,6 @@ export namespace CppUtils::UnitTest::FileSystem::Watcher suite.expectEqual(eventFilePath, filePath); expectModifyFile = true; }); -#else -# warning "TODO onEvent not implemented for this platform" -#endif CppUtils::FileSystem::String::write(filePath, "Bar"); std::this_thread::sleep_for(100ms); @@ -148,7 +129,6 @@ export namespace CppUtils::UnitTest::FileSystem::Watcher auto watcher = CppUtils::FileSystem::Watcher{}; watcher.watch(directory); -#if defined(OS_LINUX) watcher.onEvent( [](CppUtils::FileSystem::Event event, const std::filesystem::path& filePath) -> void { @@ -162,9 +142,6 @@ export namespace CppUtils::UnitTest::FileSystem::Watcher suite.expectEqual(eventFilePath, filePath); expectModifyFile = true; }); -#else -# warning "TODO onEvent not implemented for this platform" -#endif CppUtils::FileSystem::String::write(filePath, "Bar"); std::this_thread::sleep_for(100ms); @@ -180,7 +157,6 @@ export namespace CppUtils::UnitTest::FileSystem::Watcher auto watcher = CppUtils::FileSystem::Watcher{}; watcher.watch(directory); -#if defined(OS_LINUX) watcher.onEvent( [](CppUtils::FileSystem::Event event, const std::filesystem::path& filePath) -> void { @@ -194,9 +170,6 @@ export namespace CppUtils::UnitTest::FileSystem::Watcher suite.expectEqual(eventFilePath, filePath); expectDeleteFile = true; }); -#else -# warning "TODO onEvent not implemented for this platform" -#endif std::filesystem::remove(filePath); std::this_thread::sleep_for(100ms); @@ -204,4 +177,7 @@ export namespace CppUtils::UnitTest::FileSystem::Watcher }}; }); }}; +#else +# warning "TODO onEvent not implemented for this platform" +#endif }