diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b79b213eb5..e472541ce3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -213,7 +213,7 @@ jobs: #load: true linux-build-test: - name: Ubuntu ${{ matrix.UbuntuVersion }} ${{ matrix.configuration }} build/test C++/C# + name: Ubuntu ${{ matrix.UbuntuVersion }} ${{ matrix.configuration }} ${{ matrix.cxx }} build/test C++/C# runs-on: ubuntu-latest needs: [prep-vars, docker-image-cached-build] timeout-minutes: 30 @@ -221,6 +221,12 @@ jobs: matrix: UbuntuVersion: ${{ fromJson(needs.prep-vars.outputs.UbuntuVersionMatrix) }} configuration: [Debug, Release] + cxx: [clang++-10, g++] + include: + - cxx: clang++-10 + cc: clang-10 + - cxx: g++ + cc: gcc steps: - name: Checkout uses: actions/checkout@v2 @@ -258,8 +264,8 @@ jobs: - name: Start ${{ matrix.configuration }} docker instance for Ubuntu ${{ matrix.UbuntuVersion }} shell: bash run: | - echo $UID docker run -it -d -v $PWD:/src/MLOS -u $UID --env CONFIGURATION=${{ matrix.configuration }} \ + --env CC=${{ matrix.cc }} --env CXX=${{ matrix.cxx }} \ --name mlos-${{ matrix.Configuration }}-build-ubuntu-${{ matrix.UbuntuVersion }} \ mlos-build-ubuntu-${{ matrix.UbuntuVersion }}:${{ github.sha }} - name: Setup local user in docker Container @@ -279,7 +285,7 @@ jobs: run: | docker exec mlos-${{ matrix.configuration }}-build-ubuntu-${{ matrix.UbuntuVersion }} \ make dotnet-test - - name: Run ${{ matrix.configuration }} cmake build + - name: Run ${{ matrix.configuration }} cmake build (CXX=${{ matrix.cxx }}) timeout-minutes: 5 shell: bash run: | diff --git a/build.linux.sh b/build.linux.sh index d1998d45f8..b975931723 100755 --- a/build.linux.sh +++ b/build.linux.sh @@ -55,13 +55,20 @@ if [ "$CAKE_VERSION" != "$CAKE_INSTALLED_VERSION" ]; then dotnet tool install Cake.Tool --tool-path "$TOOLS_DIR" --version $CAKE_VERSION if [ $? -ne 0 ]; then - echo "An error occured while installing Cake." + echo "An error occurred while installing Cake." exit 1 fi fi -export CC=/usr/bin/clang-$CLANG_VERSION -export CXX=/usr/bin/clang++-$CLANG_VERSION +if [ "$CC" == '' ] || [ "$CXX" == '' ]; then + echo "Defaulting to CXX=clang++-$CLANG_VERSION" + export CC=/usr/bin/clang-$CLANG_VERSION + export CXX=/usr/bin/clang++-$CLANG_VERSION +fi + +if [ -z "$(which "$CXX" || true)" ]; then + echo "WARNING: CXX=$CXX not found." >&2 +fi $CXX --version diff --git a/build/Common.mk b/build/Common.mk index 01c0eaa037..e041ed2825 100644 --- a/build/Common.mk +++ b/build/Common.mk @@ -19,8 +19,13 @@ MKDIR := mkdir -p # We currently depend on clang due to use of __declspec(selectany) and other # attributes in the codegen output. -CC := clang-10 -CXX := clang++-10 +# gcc is now in part supported, but we still prefer clang if available +ifeq ($(origin CC),default) + CC := clang-10 +endif +ifeq ($(origin CXX),default) + CXX := clang++-10 +endif export CC export CXX diff --git a/build/Mlos.Cpp.cmake b/build/Mlos.Cpp.cmake index 38caf03293..819524eaf9 100644 --- a/build/Mlos.Cpp.cmake +++ b/build/Mlos.Cpp.cmake @@ -18,12 +18,6 @@ set(CMAKE_CXX_STANDARD_REQUIRED True) add_compile_options(-Wall -Wextra -Wpedantic -Werror) add_link_options(-Wall -Wextra -Wpedantic -Werror) -# The codegen output currently relies on __declspec(selectany) attributes to -# instruct the linker to ignore extra definitions resulting from including the -# same header in multiple places. -# NOTE: This option is only available with clang, not gcc. -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdeclspec") - # When compiling for Debug build, make sure that DEBUG is defined for the compiler. # This is to mimic MSVC behavior so that our #ifdefs can remain the same rather # than having to switch to using NDEBUG. @@ -34,40 +28,6 @@ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") add_compile_options(-g) add_link_options(-g) -# TODO: Search for clang compiler and set the appropriate C/CXX compiler variables. -#if(NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) -# # TODO: Add local version of clang to use? -# find_program(CLANGCPP -# NAMES clang++-10 -# #PATHS ENV PATH -# ) -# if(CLANGCPP) -# message(WARNING "Forcing CXX compiler to ${CLANGCPP}") -# set(CMAKE_CXX_COMPILER ${CLANGPP}) -# set(CMAKE_CXX_COMPILER_ID "Clang") -# endif() -#endif() - -# For now we just abort if Clang is not the compiler selected. -if(NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) - message(SEND_ERROR - "MLOS currently only supports clang (not '${CMAKE_CXX_COMPILER_ID}') for compilation.\n" - "Please re-run (c)make with 'CC=clang-10 CXX=clang++-10' set.\n") -endif() - -# TODO: This just finds the program, but doesn't actually enable it as a -# target. To use clang-tidy, we will need to provide a .clang-format config -# and probably reformat some code again. -find_program(CLANG_TIDY NAMES clang-tidy clang-tidy-6.0) -if(CLANG_TIDY) - add_custom_target( - clang-tidy - COMMAND ${CLANG_TIDY} - ${SOURCE_FILES} - -- - -I ${CMAKE_SOURCE_DIR}/include) -endif() - # https://github.com/google/sanitizers/wiki/AddressSanitizer # option(ADDRESS_SANITIZER "Enable Clang AddressSanitizer" OFF) diff --git a/source/Examples/SmartCache/Main.cpp b/source/Examples/SmartCache/Main.cpp index 5762627f1d..7c97503c5a 100644 --- a/source/Examples/SmartCache/Main.cpp +++ b/source/Examples/SmartCache/Main.cpp @@ -52,7 +52,6 @@ void ThrowIfFail(HRESULT hr) } int -__cdecl main( _In_ int argc, _In_ char* argv[]) diff --git a/source/Examples/SmartSharedChannel/Main.cpp b/source/Examples/SmartSharedChannel/Main.cpp index f8b57e5303..fe6081de39 100644 --- a/source/Examples/SmartSharedChannel/Main.cpp +++ b/source/Examples/SmartSharedChannel/Main.cpp @@ -72,7 +72,6 @@ void AssertFailed( // NOTES: // int -__cdecl main( _In_ int argc, _In_ char* argv[]) diff --git a/source/Mlos.Core/Mlos.Core.h b/source/Mlos.Core/Mlos.Core.h index 5b749a6a7f..17fd25c561 100644 --- a/source/Mlos.Core/Mlos.Core.h +++ b/source/Mlos.Core/Mlos.Core.h @@ -74,6 +74,16 @@ constexpr int32_t INVALID_FD_VALUE = -1; #define MLOS_RETAIL_ASSERT(result) { if (!result) Mlos::Core::MlosPlatform::TerminateProcess(); } #define MLOS_UNUSED_ARG(x) (void)x +#ifdef _MSC_VER +#define MLOS_SELECTANY_ATTR __declspec(selectany) +#elif __clang__ +#define MLOS_SELECTANY_ATTR __attribute__((weak)) +#elif __GNUC__ +#define MLOS_SELECTANY_ATTR __attribute__((weak)) +#else +#warning Unhandled compiler. +#endif + #include "MlosPlatform.h" #include "BytePtr.h" diff --git a/source/Mlos.Core/ObjectDeserializationCallback.h b/source/Mlos.Core/ObjectDeserializationCallback.h index 95d9905a8a..3545f7b7dc 100644 --- a/source/Mlos.Core/ObjectDeserializationCallback.h +++ b/source/Mlos.Core/ObjectDeserializationCallback.h @@ -53,12 +53,12 @@ class DispatchTable : public std::array<::Mlos::Core::DispatchEntry, N> { DispatchTable result = {}; - for (size_t i = 0; i < N; ++i) + for (size_t i = 0; i != N; ++i) { result[i] = (*this)[i]; } - for (size_t i = 0; i < N1; ++i) + for (size_t i = 0; i != N1; ++i) { result[i + N] = arr[i]; } diff --git a/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppObjectDeserializeHandlerCodeWriter.cs b/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppObjectDeserializeHandlerCodeWriter.cs index 754a984933..4f4759b6ec 100644 --- a/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppObjectDeserializeHandlerCodeWriter.cs +++ b/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppObjectDeserializeHandlerCodeWriter.cs @@ -49,7 +49,7 @@ public override void WriteBeginFile() // Define a global dispatch table. // - WriteLine("__declspec(selectany) ::Mlos::Core::DispatchEntry DispatchTable[] = "); + WriteLine("MLOS_SELECTANY_ATTR ::Mlos::Core::DispatchEntry DispatchTable[] = "); WriteLine("{"); IndentationLevel++; diff --git a/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppObjectDeserializeRuntimeCallbackCodeWriter.cs b/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppObjectDeserializeRuntimeCallbackCodeWriter.cs index 99ececeea5..c00611f77f 100644 --- a/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppObjectDeserializeRuntimeCallbackCodeWriter.cs +++ b/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppObjectDeserializeRuntimeCallbackCodeWriter.cs @@ -82,7 +82,7 @@ public override void BeginVisitType(Type sourceType) // string cppTypeNameAsField = $"{sourceType.Name}_Callback"; - WriteLine($"__declspec(selectany) std::function {cppTypeNameAsField} = nullptr;"); + WriteLine($"MLOS_SELECTANY_ATTR std::function {cppTypeNameAsField} = nullptr;"); WriteLine(); } diff --git a/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppObjectGetVariableDataSizeCodeWriter.cs b/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppObjectGetVariableDataSizeCodeWriter.cs index eac0a4bd1b..9299c342f0 100644 --- a/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppObjectGetVariableDataSizeCodeWriter.cs +++ b/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppObjectGetVariableDataSizeCodeWriter.cs @@ -43,7 +43,7 @@ public override void WriteBeginFile() public override void WriteEndFile() { IndentationLevel--; - WriteLine("};"); + WriteLine("}"); WriteLine(); } diff --git a/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppObjectSerializationVariableDataCodeWriter.cs b/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppObjectSerializationVariableDataCodeWriter.cs index 7eac03fb5a..ab6f49f033 100644 --- a/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppObjectSerializationVariableDataCodeWriter.cs +++ b/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppObjectSerializationVariableDataCodeWriter.cs @@ -50,7 +50,7 @@ public override void WriteBeginFile() public override void WriteEndFile() { IndentationLevel--; - WriteLine("};"); + WriteLine("}"); WriteLine(); } @@ -99,7 +99,7 @@ public override void EndVisitType(Type sourceType) WriteLine("return totalDataSize;"); IndentationLevel--; - WriteLine("};"); + WriteLine("}"); WriteLine(); } diff --git a/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppProxyVerifyVariableDataCodeWriter.cs b/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppProxyVerifyVariableDataCodeWriter.cs index 6fb18a22e6..636a724859 100644 --- a/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppProxyVerifyVariableDataCodeWriter.cs +++ b/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppProxyVerifyVariableDataCodeWriter.cs @@ -40,7 +40,7 @@ public override void WriteBeginFile() public override void WriteEndFile() { IndentationLevel--; - WriteLine("};"); + WriteLine("}"); WriteLine(); } diff --git a/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppTypeReflectionTableCodeWriter.cs b/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppTypeReflectionTableCodeWriter.cs index 4be5940487..6133683df7 100644 --- a/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppTypeReflectionTableCodeWriter.cs +++ b/source/Mlos.SettingsSystem.CodeGen/CodeWriters/CppObjectExchangeCodeWriters/CppTypeReflectionTableCodeWriter.cs @@ -84,7 +84,7 @@ public override void BeginVisitType(Type sourceType) // Write a class name using std::array. // std::array<5, char> = { 'C', 'l', 'a', 's', 's', '\0' }; // - WriteLine($"std::array TypeName_{cppClassName} = {{ {string.Join(",", cppClassName.Select(r => $"'{r}'"))}, '\\0' }};"); + WriteLine($"std::array TypeName_{cppClassName} {{{{ {string.Join(",", cppClassName.Select(r => $"'{r}'"))}, '\\0' }}}};"); metadataOffset += nameLength + sizeof(uint); diff --git a/source/Mlos.UnitTest/Main.cpp b/source/Mlos.UnitTest/Main.cpp index 4772f62413..2ba404a46e 100644 --- a/source/Mlos.UnitTest/Main.cpp +++ b/source/Mlos.UnitTest/Main.cpp @@ -29,7 +29,6 @@ using ::testing::TestPartResult; using ::testing::UnitTest; int -__cdecl main( _In_ int argc, _In_ char* argv[]) diff --git a/source/Mlos.UnitTest/SharedChannelTests.cpp b/source/Mlos.UnitTest/SharedChannelTests.cpp index 0ab45a153e..95dd7a2f23 100644 --- a/source/Mlos.UnitTest/SharedChannelTests.cpp +++ b/source/Mlos.UnitTest/SharedChannelTests.cpp @@ -26,10 +26,10 @@ class TestFlatBuffer : public BytePtr } private: - std::array array = { 0 }; + std::array array { { 0 } }; }; -namespace +namespace SharedChannelTests { #ifndef DEBUG // Verify buffer size. @@ -212,7 +212,7 @@ TEST(SharedChannel, VerifySendingReceivingArrayStruct) ChannelSynchronization sync = {}; TestSharedChannel sharedChannel(sync, buffer, 128); - Mlos::UnitTest::Line line; + Mlos::UnitTest::Line line = {}; line.Points[0] = { 3, 5 }; line.Points[1] = { 7, 9 }; line.Height = { 1.3f, 3.9f }; @@ -222,8 +222,8 @@ TEST(SharedChannel, VerifySendingReceivingArrayStruct) // ObjectDeserializationCallback::Mlos::UnitTest::Line_Callback = [line](Proxy::Mlos::UnitTest::Line&& recvLine) { - EXPECT_EQ(recvLine.Points()[0].X(), 3.0); - EXPECT_EQ(recvLine.Points()[0].Y(), 5); + EXPECT_EQ(recvLine.Points()[0].X(), line.Points[0].X); + EXPECT_EQ(recvLine.Points()[0].Y(), line.Points[0].Y); EXPECT_EQ(recvLine.Points()[1].X(), 7); EXPECT_EQ(recvLine.Points()[1].Y(), 9); EXPECT_EQ(recvLine.Height()[0], 1.3f); @@ -368,6 +368,7 @@ TEST(SharedChannel, StressSendReceive) bool result = resultFromWriter1.get() && resultFromWriter2.get(); + MLOS_UNUSED_ARG(result); sharedChannel.SendMessage(Mlos::Core::TerminateReaderThreadRequestMessage()); @@ -376,5 +377,7 @@ TEST(SharedChannel, StressSendReceive) result = resultFromReader1.get() && resultFromReader2.get(); + + EXPECT_EQ(result, true); } }