From 99f14e5e6a58dc555b6154ad12a81c64998597b4 Mon Sep 17 00:00:00 2001 From: Benjamin Bannier Date: Mon, 2 Sep 2024 10:53:45 +0200 Subject: [PATCH 1/4] Add header file for GNUmakeTokenPoolPosix This allows actually using this implementation. --- cc/src/tokenpool-gnu-make-posix.cc | 34 +-------------------- cc/src/tokenpool-gnu-make-posix.h | 48 ++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 33 deletions(-) create mode 100644 cc/src/tokenpool-gnu-make-posix.h diff --git a/cc/src/tokenpool-gnu-make-posix.cc b/cc/src/tokenpool-gnu-make-posix.cc index a8b0f76..ca0aacd 100644 --- a/cc/src/tokenpool-gnu-make-posix.cc +++ b/cc/src/tokenpool-gnu-make-posix.cc @@ -12,49 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "tokenpool-gnu-make.h" +#include "tokenpool-gnu-make-posix.h" #include #include #include #include -#include #include #include #include #include -// TokenPool implementation for GNU make jobserver - POSIX implementation -// (http://make.mad-scientist.net/papers/jobserver-implementation/) -struct GNUmakeTokenPoolPosix : public GNUmakeTokenPool { - GNUmakeTokenPoolPosix(); - virtual ~GNUmakeTokenPoolPosix(); - - virtual int GetMonitorFd(); - - virtual const char* GetEnv(const char* name) { return getenv(name); } - virtual bool SetEnv(const char* name, const char* value) { - return setenv(name, value, 1) == 0; - } - virtual bool ParseAuth(const char* jobserver); - virtual bool CreatePool(int parallelism, std::string* auth); - virtual int AcquireToken(); - virtual bool ReleaseToken(int token); - - private: - int rfd_; - int wfd_; - - struct sigaction old_act_; - bool restore_; - - static int dup_rfd_; - static void CloseDupRfd(int signum); - - bool CheckFd(int fd); - bool SetAlarmHandler(); -}; - GNUmakeTokenPoolPosix::GNUmakeTokenPoolPosix() : rfd_(-1), wfd_(-1), restore_(false) { } diff --git a/cc/src/tokenpool-gnu-make-posix.h b/cc/src/tokenpool-gnu-make-posix.h new file mode 100644 index 0000000..237cc22 --- /dev/null +++ b/cc/src/tokenpool-gnu-make-posix.h @@ -0,0 +1,48 @@ +// Copyright 2016-2018 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "tokenpool-gnu-make.h" + +#include + +// TokenPool implementation for GNU make jobserver - POSIX implementation +// (http://make.mad-scientist.net/papers/jobserver-implementation/) +struct GNUmakeTokenPoolPosix : public GNUmakeTokenPool { + GNUmakeTokenPoolPosix(); + virtual ~GNUmakeTokenPoolPosix(); + + virtual int GetMonitorFd(); + + virtual const char* GetEnv(const char* name) { return getenv(name); } + virtual bool SetEnv(const char* name, const char* value) { + return setenv(name, value, 1) == 0; + } + virtual bool ParseAuth(const char* jobserver); + virtual bool CreatePool(int parallelism, std::string* auth); + virtual int AcquireToken(); + virtual bool ReleaseToken(int token); + + private: + int rfd_; + int wfd_; + + struct sigaction old_act_; + bool restore_; + + static int dup_rfd_; + static void CloseDupRfd(int signum); + + bool CheckFd(int fd); + bool SetAlarmHandler(); +}; From f4acaf424bceb8b2b38bed792e4e79d6ceb8dc32 Mon Sep 17 00:00:00 2001 From: Benjamin Bannier Date: Mon, 2 Sep 2024 10:45:52 +0200 Subject: [PATCH 2/4] Fix comparisons between pointers and integers in test Some compilers like Apple clang-15 reject constructs like this outright, so replace them with checks for "truthiness". --- cc/src/tokenpool_test.cc | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/cc/src/tokenpool_test.cc b/cc/src/tokenpool_test.cc index 86dab99..42b2ef3 100644 --- a/cc/src/tokenpool_test.cc +++ b/cc/src/tokenpool_test.cc @@ -172,7 +172,7 @@ TEST_F(TokenPoolTest, SuccessfulOldSetup) { // GNUmake <= 4.1 CreatePool(AUTH_FORMAT("--jobserver-fds")); - EXPECT_NE(NULL, tokens_); + EXPECT_TRUE(tokens_); EXPECT_EQ(kLoadAverageDefault, load_avg_); } @@ -180,7 +180,7 @@ TEST_F(TokenPoolTest, SuccessfulNewSetup) { // GNUmake => 4.2 CreateDefaultPool(); - EXPECT_NE(NULL, tokens_); + EXPECT_TRUE(tokens_); EXPECT_EQ(kLoadAverageDefault, load_avg_); } @@ -194,7 +194,7 @@ TEST_F(TokenPoolTest, IgnoreWithJN) { TEST_F(TokenPoolTest, HonorLN) { CreatePool(AUTH_FORMAT("-l9 --jobserver-auth")); - EXPECT_NE(NULL, tokens_); + EXPECT_TRUE(tokens_); EXPECT_EQ(9.0, load_avg_); } @@ -203,14 +203,14 @@ TEST_F(TokenPoolTest, SemaphoreNotFound) { semaphore_name_ = SEMAPHORE_NAME "_foobar"; CreateDefaultPool(); - EXPECT_EQ(NULL, tokens_); + EXPECT_TRUE(tokens_); EXPECT_EQ(kLoadAverageDefault, load_avg_); } TEST_F(TokenPoolTest, TokenIsAvailable) { CreateDefaultPool(); - ASSERT_NE(NULL, tokens_); + ASSERT_TRUE(tokens_); EXPECT_EQ(kLoadAverageDefault, load_avg_); EXPECT_TRUE(tokens_->TokenIsAvailable((ULONG_PTR)tokens_)); @@ -219,7 +219,7 @@ TEST_F(TokenPoolTest, TokenIsAvailable) { TEST_F(TokenPoolTest, MonitorFD) { CreateDefaultPool(); - ASSERT_NE(NULL, tokens_); + ASSERT_TRUE(tokens_); EXPECT_EQ(kLoadAverageDefault, load_avg_); EXPECT_EQ(fds_[0], tokens_->GetMonitorFd()); @@ -229,7 +229,7 @@ TEST_F(TokenPoolTest, MonitorFD) { TEST_F(TokenPoolTest, ImplicitToken) { CreateDefaultPool(); - ASSERT_NE(NULL, tokens_); + ASSERT_TRUE(tokens_); EXPECT_EQ(kLoadAverageDefault, load_avg_); EXPECT_TRUE(tokens_->Acquire()); @@ -242,7 +242,7 @@ TEST_F(TokenPoolTest, ImplicitToken) { TEST_F(TokenPoolTest, TwoTokens) { CreateDefaultPool(); - ASSERT_NE(NULL, tokens_); + ASSERT_TRUE(tokens_); EXPECT_EQ(kLoadAverageDefault, load_avg_); // implicit token @@ -286,7 +286,7 @@ TEST_F(TokenPoolTest, TwoTokens) { TEST_F(TokenPoolTest, Clear) { CreateDefaultPool(); - ASSERT_NE(NULL, tokens_); + ASSERT_TRUE(tokens_); EXPECT_EQ(kLoadAverageDefault, load_avg_); // implicit token @@ -328,17 +328,17 @@ TEST_F(TokenPoolTest, Clear) { TEST_F(TokenPoolTest, NoPoolForSerialBuild) { CreateMaster(1); - EXPECT_EQ(NULL, tokens_); + EXPECT_FALSE(tokens_); } TEST_F(TokenPoolTest, MasterNoLoadAvg) { // kLoadAverageDefault <= 0.0f -> no load averaging CreateMaster(2); - ASSERT_NE(NULL, tokens_); + ASSERT_TRUE(tokens_); const char *env = ENVIRONMENT_GET(); - ASSERT_NE(NULL, env); + ASSERT_TRUE(env); EXPECT_EQ(env, strstr(env, "--jobserver-auth=")); EXPECT_EQ(NULL, strstr(env, " -l")); @@ -350,13 +350,13 @@ TEST_F(TokenPoolTest, MasterWithLoadAvg) { load_avg_ = 3.1415f; CreateMaster(3); - ASSERT_NE(NULL, tokens_); + ASSERT_TRUE(tokens_); const char *env = ENVIRONMENT_GET(); - ASSERT_NE(NULL, env); + ASSERT_TRUE(env); EXPECT_EQ(env, strstr(env, "--jobserver-auth=")); - EXPECT_NE(NULL, strstr(env, " -l3.1415")); + EXPECT_TRUE(strstr(env, " -l3.1415")); CheckTokens(env, 3); } From e62fc377a4dc5c51168bc4a5622a47a64795ed62 Mon Sep 17 00:00:00 2001 From: Benjamin Bannier Date: Mon, 2 Sep 2024 10:33:28 +0200 Subject: [PATCH 3/4] Add proper CMake setup This adds a CMake library and a test for it. We now explicitly pull in a specific version of GTest for testing. --- cc/src/CMakeLists.txt | 33 +++++++++++++++++++++++++++++++++ cc/src/tokenpool_test.cc | 2 +- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 cc/src/CMakeLists.txt diff --git a/cc/src/CMakeLists.txt b/cc/src/CMakeLists.txt new file mode 100644 index 0000000..665ae2c --- /dev/null +++ b/cc/src/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.14) +project(gnumake-tokenpool LANGUAGES CXX) + +add_library( + gnumake-tokenpool + tokenpool-gnu-make-posix.cc + # tokenpool-gnu-make-win32.cc # TODO: Add this file iff building on win32. + tokenpool-gnu-make.cc) +target_include_directories(gnumake-tokenpool PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +option(GNUMAKE_TOKENPOOL_BUILD_TESTS "build gnumake-tokenpool tests" ON) + +if (GNUMAKE_TOKENPOOL_BUILD_TESTS) + # GoogleTest requires at least C++14 + set(CMAKE_CXX_STANDARD 14) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + + include(FetchContent) + FetchContent_Declare( + googletest + URL https://github.com/google/googletest/releases/download/v1.15.2/googletest-1.15.2.tar.gz) + # For Windows: Prevent overriding the parent project's compiler/linker settings + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + FetchContent_MakeAvailable(googletest) + + add_executable(gnumake-tokenpool-test tokenpool_test.cc) + target_link_libraries(gnumake-tokenpool-test gnumake-tokenpool gtest_main) + + enable_testing() + + include(GoogleTest) + gtest_discover_tests(gnumake-tokenpool-test) +endif () diff --git a/cc/src/tokenpool_test.cc b/cc/src/tokenpool_test.cc index 42b2ef3..c73ecaa 100644 --- a/cc/src/tokenpool_test.cc +++ b/cc/src/tokenpool_test.cc @@ -14,7 +14,7 @@ #include "tokenpool.h" -#include "test.h" +#include "gtest/gtest.h" #ifdef _WIN32 #include From 11ecae4ea78491824f929c35ec778a671715306c Mon Sep 17 00:00:00 2001 From: Benjamin Bannier Date: Mon, 2 Sep 2024 11:34:42 +0200 Subject: [PATCH 4/4] Add GH action for CC library --- .github/workflows/cc-test.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/cc-test.yml diff --git a/.github/workflows/cc-test.yml b/.github/workflows/cc-test.yml new file mode 100644 index 0000000..f242a95 --- /dev/null +++ b/.github/workflows/cc-test.yml @@ -0,0 +1,19 @@ +name: Test CC library + +on: + push: + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install LLVM and Clang + uses: KyleMayes/install-llvm-action@v2 + with: + version: "18" + - run: cmake cc/src -B build + - run: cmake --build build + - run: ctest --test-dir build/ +