diff --git a/Makefile b/Makefile
index a5654dfe2..31986582e 100644
--- a/Makefile
+++ b/Makefile
@@ -26,6 +26,7 @@ LDFLAGS     := -pthread
 INCLUDES    :=
 LIBS	    :=
 OBJS	    :=
+OBJS_TEST :=
 PROF        :=
 
 MODULES     :=
diff --git a/common.rules b/common.rules
index 2838c0e5d..a609da742 100644
--- a/common.rules
+++ b/common.rules
@@ -9,4 +9,4 @@ MODULE_TEST_OBJS-$(MODULE) := $(MODULE_TEST_OBJS)
 # If not building as a plugin, add the object files to the main OBJS list
 #OBJS += $(MODULE_LIB-$(MODULE))
 OBJS += $(MODULE_OBJS)
-OBJS_TEST := $(MODULE_TEST_OBJS)
+OBJS_TEST += $(MODULE_TEST_OBJS)
diff --git a/src/cheat/module.mk b/src/cheat/module.mk
index 2b454e45c..5064f6e65 100644
--- a/src/cheat/module.mk
+++ b/src/cheat/module.mk
@@ -7,8 +7,10 @@ MODULE_OBJS := \
 	src/cheat/BankRomCheat.o \
 	src/cheat/RamCheat.o
 
+MODULE_TEST_OBJS =
+
 MODULE_DIRS += \
 	src/cheat
 
-# Include common rules 
+# Include common rules
 include $(srcdir)/common.rules
diff --git a/src/common/audio/module.mk b/src/common/audio/module.mk
index 91961a13b..d3986e63d 100644
--- a/src/common/audio/module.mk
+++ b/src/common/audio/module.mk
@@ -6,6 +6,8 @@ MODULE_OBJS := \
 	src/common/audio/LanczosResampler.o \
 	src/common/audio/HighPass.o
 
+MODULE_TEST_OBJS =
+
 MODULE_DIRS += \
 	src/emucore/tia \
 	src/emucore/elf
diff --git a/src/common/module.mk b/src/common/module.mk
index 4b29556e8..58bee6d5d 100644
--- a/src/common/module.mk
+++ b/src/common/module.mk
@@ -4,7 +4,7 @@ MODULE_OBJS := \
 	src/common/AudioQueue.o \
 	src/common/AudioSettings.o \
 	src/common/Base.o \
-        src/common/Bezel.o \
+  src/common/Bezel.o \
 	src/common/DevSettingsHandler.o \
 	src/common/EventHandlerSDL2.o \
 	src/common/FBBackendSDL2.o \
@@ -41,6 +41,9 @@ MODULE_OBJS := \
 	src/common/repository/CompositeKVRJsonAdapter.o \
 	src/common/repository/CompositeKeyValueRepository.o
 
+MODULE_TEST_OBJS = \
+	src/common/Logger.o
+
 MODULE_DIRS += \
 	src/common
 
diff --git a/src/common/repository/sqlite/module.mk b/src/common/repository/sqlite/module.mk
index 2bf7f680c..695908839 100644
--- a/src/common/repository/sqlite/module.mk
+++ b/src/common/repository/sqlite/module.mk
@@ -9,6 +9,8 @@ MODULE_OBJS := \
 	src/common/repository/sqlite/SqliteStatement.o \
 	src/common/repository/sqlite/SqliteTransaction.o
 
+MODULE_TEST_OBJS =
+
 MODULE_DIRS += \
 	src/common/repository/sqlite
 
diff --git a/src/common/tv_filters/module.mk b/src/common/tv_filters/module.mk
index 02fedb50b..8f2cc535d 100644
--- a/src/common/tv_filters/module.mk
+++ b/src/common/tv_filters/module.mk
@@ -4,6 +4,8 @@ MODULE_OBJS := \
 	src/common/tv_filters/NTSCFilter.o \
 	src/common/tv_filters/AtariNTSC.o
 
+MODULE_TEST_OBJS =
+
 MODULE_DIRS += \
 	src/common/tv_filters
 
diff --git a/src/debugger/gui/module.mk b/src/debugger/gui/module.mk
index d52f9ecbe..f7fb85c5c 100644
--- a/src/debugger/gui/module.mk
+++ b/src/debugger/gui/module.mk
@@ -90,6 +90,8 @@ MODULE_OBJS := \
         src/debugger/gui/ToggleWidget.o \
         src/debugger/gui/TrakBallWidget.o
 
+MODULE_TEST_OBJS =
+
 MODULE_DIRS += \
         src/debugger/gui
 
diff --git a/src/debugger/module.mk b/src/debugger/module.mk
index 6356aad6a..5999938b1 100644
--- a/src/debugger/module.mk
+++ b/src/debugger/module.mk
@@ -11,6 +11,8 @@ MODULE_OBJS := \
         src/debugger/TIADebug.o \
         src/debugger/TimerMap.o
 
+MODULE_TEST_OBJS =
+
 MODULE_DIRS += \
         src/debugger
 
diff --git a/src/debugger/yacc/module.mk b/src/debugger/yacc/module.mk
index 9f51bb344..38e523dc7 100644
--- a/src/debugger/yacc/module.mk
+++ b/src/debugger/yacc/module.mk
@@ -3,6 +3,8 @@ MODULE := src/debugger/yacc
 MODULE_OBJS := \
 	src/debugger/yacc/YaccParser.o
 
+MODULE_TEST_OBJS =
+
 MODULE_DIRS += \
 	src/debugger/yacc
 
diff --git a/src/emucore/elf/ElfParser.cxx b/src/emucore/elf/ElfParser.cxx
index 0d46e36e2..06bc3edf9 100644
--- a/src/emucore/elf/ElfParser.cxx
+++ b/src/emucore/elf/ElfParser.cxx
@@ -129,7 +129,7 @@ const vector<ElfParser::Symbol>& ElfParser::getSymbols() const
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 const optional<vector<ElfParser::Relocation>> ElfParser::getRelocations(size_t section) const
 {
-  return myRelocations.contains(section) ? myRelocations.at(section) : optional<vector<ElfParser::Relocation>>();
+  return myRelocations.contains(section) ? myRelocations.at(section) : optional<vector<Relocation>>();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/emucore/elf/LinkerTest.cxx b/src/emucore/elf/LinkerTest.cxx
new file mode 100644
index 000000000..5095930cb
--- /dev/null
+++ b/src/emucore/elf/LinkerTest.cxx
@@ -0,0 +1,244 @@
+//============================================================================
+//
+//   SSSS    tt          lll  lll
+//  SS  SS   tt           ll   ll
+//  SS     tttttt  eeee   ll   ll   aaaa
+//   SSSS    tt   ee  ee  ll   ll      aa
+//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
+//  SS  SS   tt   ee      ll   ll  aa  aa
+//   SSSS     ttt  eeeee llll llll  aaaaa
+//
+// Copyright (c) 1995-2024 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+#include <gtest/gtest.h>
+#include <unordered_map>
+
+#include "bspf.hxx"
+#include "ElfFile.hxx"
+#include "ElfLinker.hxx"
+
+namespace {
+
+  class ElfFixture: public ElfFile {
+    public:
+      explicit ElfFixture(size_t size) : mySize(size) {
+        myData = make_unique<uInt8[]>(mySize);
+      }
+
+      const uInt8 *getData() const override {
+        return myData.get();
+      }
+
+      size_t getSize() const override {
+        return mySize;
+      }
+
+      const vector<Section>& getSections() const override {
+        return mySections;
+      }
+
+      const vector<Symbol>& getSymbols() const override {
+        return mySymbols;
+      }
+
+      const optional<vector<Relocation>> getRelocations(size_t section) const override {
+        return myRelocations.contains(section) ? myRelocations.at(section) : optional<vector<Relocation>>();
+      }
+
+      ElfFixture& addSection(string_view name, uInt32 type, uInt32 offset, uInt32 size, uInt32 align = 4) {
+        mySections.push_back({
+          .nameOffset = 0,
+          .name = string(name),
+          .type = type,
+          .flags = 0,
+          .virtualAddress = 0,
+          .offset = offset,
+          .size = size,
+          .info = 0,
+          .align = align
+        });
+
+        return *this;
+      }
+
+      ElfFixture& write8(size_t address, uInt8 value) {
+        myData[address] = value;
+
+        return *this;
+      }
+
+    public:
+      size_t mySize;
+      unique_ptr<uInt8[]> myData;
+
+      vector<Section> mySections;
+      vector<Symbol> mySymbols;
+      std::unordered_map<size_t, vector<Relocation>> myRelocations;
+  };
+
+  TEST(ElfLinker, HasEmptySegmentsForAnEmptyELF) {
+    ElfFixture fixture(0);
+    ElfLinker linker(0x00100000, 0x00200000, 0x00300000, fixture);
+
+    linker.link({});
+
+    EXPECT_EQ(linker.getSegmentSize(ElfLinker::SegmentType::text), static_cast<uInt32>(0));
+    EXPECT_EQ(linker.getSegmentSize(ElfLinker::SegmentType::data), static_cast<uInt32>(0));
+    EXPECT_EQ(linker.getSegmentSize(ElfLinker::SegmentType::rodata), static_cast<uInt32>(0));
+  }
+
+  TEST(ElfLinker, TextSegmentsGoToText) {
+    ElfFixture fixture(1000);
+    ElfLinker linker(0x00100000, 0x00200000, 0x00300000, fixture);
+
+    fixture
+      .addSection(".text.1", ElfFile::SHT_PROGBITS, 0, 10, 4)
+      .write8(0, 0x01)
+      .addSection(".text.2", ElfFile::SHT_PROGBITS, 10, 21, 4)
+      .write8(10, 0x02)
+      .addSection(".text.3", ElfFile::SHT_PROGBITS, 31, 33, 2)
+      .write8(31, 0x03)
+      .addSection(".text.4", ElfFile::SHT_PROGBITS, 64, 11, 1)
+      .write8(64, 0x04);
+
+    linker.link({});
+
+    EXPECT_EQ(linker.getSegmentSize(ElfLinker::SegmentType::text), static_cast<uInt32>(78));
+    EXPECT_EQ(linker.getSegmentSize(ElfLinker::SegmentType::data), static_cast<uInt32>(0));
+    EXPECT_EQ(linker.getSegmentSize(ElfLinker::SegmentType::rodata), static_cast<uInt32>(0));
+
+    EXPECT_EQ(linker.getRelocatedSections()[0]->offset, static_cast<uInt32>(0));
+    EXPECT_EQ(linker.getRelocatedSections()[0]->segment, ElfLinker::SegmentType::text);
+
+    EXPECT_EQ(linker.getRelocatedSections()[1]->offset, static_cast<uInt32>(12));
+    EXPECT_EQ(linker.getRelocatedSections()[1]->segment, ElfLinker::SegmentType::text);
+
+    EXPECT_EQ(linker.getRelocatedSections()[2]->offset, static_cast<uInt32>(34));
+    EXPECT_EQ(linker.getRelocatedSections()[2]->segment, ElfLinker::SegmentType::text);
+
+    EXPECT_EQ(linker.getRelocatedSections()[3]->offset, static_cast<uInt32>(67));
+    EXPECT_EQ(linker.getRelocatedSections()[3]->segment, ElfLinker::SegmentType::text);
+
+    EXPECT_EQ(linker.getSegmentData(ElfLinker::SegmentType::text)[0], 0x01);
+    EXPECT_EQ(linker.getSegmentData(ElfLinker::SegmentType::text)[12], 0x02);
+    EXPECT_EQ(linker.getSegmentData(ElfLinker::SegmentType::text)[34], 0x03);
+    EXPECT_EQ(linker.getSegmentData(ElfLinker::SegmentType::text)[67], 0x04);
+  }
+
+  TEST(ElfLinker, DataSegmentsGoToData) {
+    ElfFixture fixture(1000);
+    ElfLinker linker(0x00100000, 0x00200000, 0x00300000, fixture);
+
+    fixture
+      .addSection(".data.1", ElfFile::SHT_PROGBITS, 0, 10, 4)
+      .write8(0, 0x01)
+      .addSection(".data.2", ElfFile::SHT_PROGBITS, 10, 21, 4)
+      .write8(10, 0x02)
+      .addSection(".data.3", ElfFile::SHT_PROGBITS, 31, 33, 2)
+      .write8(31, 0x03)
+      .addSection(".data.4", ElfFile::SHT_PROGBITS, 64, 11, 1)
+      .write8(64, 0x04);
+
+    linker.link({});
+
+    EXPECT_EQ(linker.getSegmentSize(ElfLinker::SegmentType::text), static_cast<uInt32>(0));
+    EXPECT_EQ(linker.getSegmentSize(ElfLinker::SegmentType::data), static_cast<uInt32>(78));
+    EXPECT_EQ(linker.getSegmentSize(ElfLinker::SegmentType::rodata), static_cast<uInt32>(0));
+
+    EXPECT_EQ(linker.getRelocatedSections()[0]->offset, static_cast<uInt32>(0));
+    EXPECT_EQ(linker.getRelocatedSections()[0]->segment, ElfLinker::SegmentType::data);
+
+    EXPECT_EQ(linker.getRelocatedSections()[1]->offset, static_cast<uInt32>(12));
+    EXPECT_EQ(linker.getRelocatedSections()[1]->segment, ElfLinker::SegmentType::data);
+
+    EXPECT_EQ(linker.getRelocatedSections()[2]->offset, static_cast<uInt32>(34));
+    EXPECT_EQ(linker.getRelocatedSections()[2]->segment, ElfLinker::SegmentType::data);
+
+    EXPECT_EQ(linker.getRelocatedSections()[3]->offset, static_cast<uInt32>(67));
+    EXPECT_EQ(linker.getRelocatedSections()[3]->segment, ElfLinker::SegmentType::data);
+
+    EXPECT_EQ(linker.getSegmentData(ElfLinker::SegmentType::data)[0], 0x01);
+    EXPECT_EQ(linker.getSegmentData(ElfLinker::SegmentType::data)[12], 0x02);
+    EXPECT_EQ(linker.getSegmentData(ElfLinker::SegmentType::data)[34], 0x03);
+    EXPECT_EQ(linker.getSegmentData(ElfLinker::SegmentType::data)[67], 0x04);
+  }
+
+TEST(ElfLinker, RodataSegmentsGoToRodata) {
+    ElfFixture fixture(1000);
+    ElfLinker linker(0x00100000, 0x00200000, 0x00300000, fixture);
+
+    fixture
+      .addSection(".rodata.1", ElfFile::SHT_PROGBITS, 0, 10, 4)
+      .write8(0, 0x01)
+      .addSection(".rodata.2", ElfFile::SHT_PROGBITS, 10, 21, 4)
+      .write8(10, 0x02)
+      .addSection(".rodata.3", ElfFile::SHT_PROGBITS, 31, 33, 2)
+      .write8(31, 0x03)
+      .addSection(".rodata.4", ElfFile::SHT_PROGBITS, 64, 11, 1)
+      .write8(64, 0x04);
+
+    linker.link({});
+
+    EXPECT_EQ(linker.getSegmentSize(ElfLinker::SegmentType::text), static_cast<uInt32>(0));
+    EXPECT_EQ(linker.getSegmentSize(ElfLinker::SegmentType::data), static_cast<uInt32>(0));
+    EXPECT_EQ(linker.getSegmentSize(ElfLinker::SegmentType::rodata), static_cast<uInt32>(78));
+
+    EXPECT_EQ(linker.getRelocatedSections()[0]->offset, static_cast<uInt32>(0));
+    EXPECT_EQ(linker.getRelocatedSections()[0]->segment, ElfLinker::SegmentType::rodata);
+
+    EXPECT_EQ(linker.getRelocatedSections()[1]->offset, static_cast<uInt32>(12));
+    EXPECT_EQ(linker.getRelocatedSections()[1]->segment, ElfLinker::SegmentType::rodata);
+
+    EXPECT_EQ(linker.getRelocatedSections()[2]->offset, static_cast<uInt32>(34));
+    EXPECT_EQ(linker.getRelocatedSections()[2]->segment, ElfLinker::SegmentType::rodata);
+
+    EXPECT_EQ(linker.getRelocatedSections()[3]->offset, static_cast<uInt32>(67));
+    EXPECT_EQ(linker.getRelocatedSections()[3]->segment, ElfLinker::SegmentType::rodata);
+
+    EXPECT_EQ(linker.getSegmentData(ElfLinker::SegmentType::rodata)[0], 0x01);
+    EXPECT_EQ(linker.getSegmentData(ElfLinker::SegmentType::rodata)[12], 0x02);
+    EXPECT_EQ(linker.getSegmentData(ElfLinker::SegmentType::rodata)[34], 0x03);
+    EXPECT_EQ(linker.getSegmentData(ElfLinker::SegmentType::rodata)[67], 0x04);
+  }
+
+  TEST(ElfLinker, BssSectionsGoToTheEndOfData) {
+    ElfFixture fixture(1000);
+    ElfLinker linker(0x00100000, 0x00200000, 0x00300000, fixture);
+
+    fixture
+      .addSection(".data.1", ElfFile::SHT_PROGBITS, 0, 10, 4)
+      .write8(0, 0x01)
+      .addSection(".bss", ElfFile::SHT_NOBITS, 0, 21, 4)
+      .addSection(".data.2", ElfFile::SHT_PROGBITS, 10, 33, 2)
+      .write8(10, 0x02)
+      .addSection(".noinit", ElfFile::SHT_NOBITS, 0, 11, 1);
+
+    linker.link({});
+
+    EXPECT_EQ(linker.getSegmentSize(ElfLinker::SegmentType::text), static_cast<uInt32>(0));
+    EXPECT_EQ(linker.getSegmentSize(ElfLinker::SegmentType::data), static_cast<uInt32>(76));
+    EXPECT_EQ(linker.getSegmentSize(ElfLinker::SegmentType::rodata), static_cast<uInt32>(0));
+
+    EXPECT_EQ(linker.getRelocatedSections()[0]->offset, static_cast<uInt32>(0));
+    EXPECT_EQ(linker.getRelocatedSections()[0]->segment, ElfLinker::SegmentType::data);
+
+    EXPECT_EQ(linker.getRelocatedSections()[1]->offset, static_cast<uInt32>(44));
+    EXPECT_EQ(linker.getRelocatedSections()[1]->segment, ElfLinker::SegmentType::data);
+
+    EXPECT_EQ(linker.getRelocatedSections()[2]->offset, static_cast<uInt32>(10));
+    EXPECT_EQ(linker.getRelocatedSections()[2]->segment, ElfLinker::SegmentType::data);
+
+    EXPECT_EQ(linker.getRelocatedSections()[3]->offset, static_cast<uInt32>(65));
+    EXPECT_EQ(linker.getRelocatedSections()[3]->segment, ElfLinker::SegmentType::data);
+
+    EXPECT_EQ(linker.getSegmentData(ElfLinker::SegmentType::data)[0], 0x01);
+    EXPECT_EQ(linker.getSegmentData(ElfLinker::SegmentType::data)[10], 0x02);
+    EXPECT_EQ(linker.getSegmentData(ElfLinker::SegmentType::data)[44], 0);
+    EXPECT_EQ(linker.getSegmentData(ElfLinker::SegmentType::data)[65], 0);
+  }
+}
diff --git a/src/emucore/elf/module.mk b/src/emucore/elf/module.mk
index 1fe5fd51f..21dfc746b 100644
--- a/src/emucore/elf/module.mk
+++ b/src/emucore/elf/module.mk
@@ -8,10 +8,12 @@ MODULE_OBJS = \
 
 MODULE_TEST_OBJS = \
 	src/emucore/elf/ElfUtil.o \
-	src/emucore/elf/EncodingTest.o
+	src/emucore/elf/ElfLinker.o \
+	src/emucore/elf/EncodingTest.o \
+	src/emucore/elf/LinkerTest.o
 
 MODULE_DIRS += \
-	src/emucore/elf/EncodingTest.o
+	src/emucore/elf
 
 # Include common rules
 include $(srcdir)/common.rules
diff --git a/src/emucore/module.mk b/src/emucore/module.mk
index b9e542dbd..d356d09e1 100644
--- a/src/emucore/module.mk
+++ b/src/emucore/module.mk
@@ -99,6 +99,8 @@ MODULE_OBJS := \
 	src/emucore/TIASurface.o \
 	src/emucore/Thumbulator.o
 
+MODULE_TEST_OBJS =
+
 MODULE_DIRS += \
 	src/emucore
 
diff --git a/src/emucore/tia/frame-manager/module.mk b/src/emucore/tia/frame-manager/module.mk
index b4f8fdcdb..53ef04139 100644
--- a/src/emucore/tia/frame-manager/module.mk
+++ b/src/emucore/tia/frame-manager/module.mk
@@ -6,6 +6,8 @@ MODULE_OBJS := \
 	src/emucore/tia/frame-manager/FrameLayoutDetector.o \
 	src/emucore/tia/frame-manager/JitterEmulation.o
 
+MODULE_TEST_OBJS =
+
 MODULE_DIRS += \
 	src/emucore/tia/frame-manager
 
diff --git a/src/emucore/tia/module.mk b/src/emucore/tia/module.mk
index 3b88dce3a..f136b5480 100644
--- a/src/emucore/tia/module.mk
+++ b/src/emucore/tia/module.mk
@@ -13,6 +13,8 @@ MODULE_OBJS := \
 	src/emucore/tia/Audio.o \
 	src/emucore/tia/AudioChannel.o
 
+MODULE_TEST_OBJS =
+
 MODULE_DIRS += \
 	src/emucore/tia
 
diff --git a/src/gui/module.mk b/src/gui/module.mk
index 0e693ecbc..91c48d171 100644
--- a/src/gui/module.mk
+++ b/src/gui/module.mk
@@ -64,6 +64,8 @@ MODULE_OBJS := \
         src/gui/WhatsNewDialog.o \
         src/gui/Widget.o
 
+MODULE_TEST_OBJS =
+
 MODULE_DIRS += \
         src/gui
 
diff --git a/src/lib/libpng/module.mk b/src/lib/libpng/module.mk
index d450711b5..73e222c15 100644
--- a/src/lib/libpng/module.mk
+++ b/src/lib/libpng/module.mk
@@ -17,6 +17,8 @@ MODULE_OBJS := \
 	src/lib/libpng/pngwtran.o \
 	src/lib/libpng/pngwutil.o
 
+MODULE_TEST_OBJS =
+
 MODULE_DIRS += \
 	src/lib/libpng
 
diff --git a/src/lib/sqlite/module.mk b/src/lib/sqlite/module.mk
index bfb143ca9..92c28e2d4 100644
--- a/src/lib/sqlite/module.mk
+++ b/src/lib/sqlite/module.mk
@@ -3,6 +3,8 @@ MODULE := src/lib/sqlite
 MODULE_OBJS := \
 	src/lib/sqlite/sqlite3.o
 
+MODULE_TEST_OBJS =
+
 MODULE_DIRS += \
 	src/lib/sqlite
 
diff --git a/src/lib/tinyexif/module.mk b/src/lib/tinyexif/module.mk
index 1d59efe84..8b044479a 100644
--- a/src/lib/tinyexif/module.mk
+++ b/src/lib/tinyexif/module.mk
@@ -3,6 +3,8 @@ MODULE := src/lib/tinyexif
 MODULE_OBJS := \
 	src/lib/tinyexif/tinyexif.o
 
+MODULE_TEST_OBJS =
+
 MODULE_DIRS += \
 	src/lib/tinyexif
 
diff --git a/src/lib/zlib/module.mk b/src/lib/zlib/module.mk
index f536747ab..0adf9d2f2 100644
--- a/src/lib/zlib/module.mk
+++ b/src/lib/zlib/module.mk
@@ -17,6 +17,8 @@ MODULE_OBJS := \
 	src/lib/zlib/inftrees.o \
 	src/lib/zlib/inffast.o
 
+MODULE_TEST_OBJS =
+
 MODULE_DIRS += \
 	src/lib/zlib
 
diff --git a/src/os/unix/module.mk b/src/os/unix/module.mk
index 782d3e98a..a6eb05c16 100644
--- a/src/os/unix/module.mk
+++ b/src/os/unix/module.mk
@@ -5,6 +5,8 @@ MODULE_OBJS := \
 	src/os/unix/OSystemUNIX.o \
 	src/os/unix/SerialPortUNIX.o
 
+MODULE_TEST_OBJS =
+
 MODULE_DIRS += \
 	src/os/unix
 
diff --git a/src/os/unix/r77/module.mk b/src/os/unix/r77/module.mk
index 95463ddbc..5c6763cc7 100644
--- a/src/os/unix/r77/module.mk
+++ b/src/os/unix/r77/module.mk
@@ -4,6 +4,8 @@ MODULE_OBJS := \
 	src/os/unix/r77/OSystemR77.o \
 	src/os/unix/r77/SettingsR77.o
 
+MODULE_TEST_OBJS =
+
 MODULE_DIRS += \
 	src/os/unix/r77
 
diff --git a/src/os/windows/module.mk b/src/os/windows/module.mk
index a4745ed0b..b2a767cb0 100644
--- a/src/os/windows/module.mk
+++ b/src/os/windows/module.mk
@@ -7,6 +7,8 @@ MODULE_OBJS := \
 	src/os/windows/SettingsWINDOWS.o \
 	src/os/windows/stella_icon.o
 
+MODULE_TEST_OBJS =
+
 MODULE_DIRS += \
 	src/os/windows