Browse Source

feat: adapt to msvc compiler

master
Dnomd343 7 months ago
parent
commit
76b2f783eb
  1. 68
      CMakeLists.txt
  2. 11
      src/impl/constexpr.inl
  3. 17
      src/impl/core.cc
  4. 8
      src/md5.h
  5. 11
      third_party/ThirdParty.cmake

68
CMakeLists.txt

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.10)
project(md5sum LANGUAGES CXX)
if ("${CMAKE_VERSION}" VERSION_GREATER_EQUAL "3.13")
cmake_policy(SET CMP0077 NEW)
cmake_policy(SET CMP0077 NEW)
endif()
# ------------------------------------------------------------------------------------ #
@ -17,14 +17,14 @@ option(MD5_ENABLE_BENCHMARK "Enable benchmark of the md5sum library." OFF)
set(CXX_STANDARDS)
foreach (CXX_FEATURE ${CMAKE_CXX_COMPILE_FEATURES})
if (CXX_FEATURE MATCHES "^cxx_std_[0-9]+$")
string(REGEX MATCH "[0-9]+$" CXX_STANDARD ${CXX_FEATURE})
list(APPEND CXX_STANDARDS ${CXX_STANDARD}) # supported c++ standards
endif()
if (CXX_FEATURE MATCHES "^cxx_std_[0-9]+$")
string(REGEX MATCH "[0-9]+$" CXX_STANDARD ${CXX_FEATURE})
list(APPEND CXX_STANDARDS ${CXX_STANDARD}) # supported c++ standards
endif()
endforeach()
if (NOT 17 IN_LIST CXX_STANDARDS)
message(FATAL_ERROR "MD5 project require at least C++17.")
message(FATAL_ERROR "MD5 project require at least C++17.")
endif()
list(GET CXX_STANDARDS -1 MD5_CXX_STANDARD) # select the latest C++ standard
@ -34,27 +34,41 @@ set(CMAKE_CXX_STANDARD ${MD5_CXX_STANDARD})
# ------------------------------------------------------------------------------------ #
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release) # using release build in default
set(CMAKE_BUILD_TYPE Release) # using release build in default
endif()
add_compile_options(-Wall -Wextra -Werror)
if (MD5_ENABLE_LTO)
if (MSVC)
add_compile_options(/W4) # TODO: add `/WX` after fix MSVC warnings
if (MD5_ENABLE_LTO)
add_compile_options(/GL)
add_link_options(/LTCG)
endif()
else()
add_compile_options(-Wall -Wextra -Werror)
if (MD5_ENABLE_LTO)
add_compile_options(-flto=auto)
endif()
endif()
# ------------------------------------------------------------------------------------ #
file(GLOB MD5_SRC src/impl/*.cc)
if (NOT MD5_SHARED_LIB)
add_library(md5sum STATIC ${MD5_SRC})
add_library(md5sum STATIC ${MD5_SRC})
else()
add_library(md5sum SHARED ${MD5_SRC})
add_library(md5sum SHARED ${MD5_SRC})
if (NOT MSVC)
target_compile_options(md5sum PRIVATE -fvisibility=hidden)
endif()
endif()
set(MD5_COMPILE_OPTIONS
-fno-rtti
-fno-exceptions
-fno-unwind-tables
-fno-asynchronous-unwind-tables)
if (MSVC)
set(MD5_COMPILE_OPTIONS /GR-)
else()
set(MD5_COMPILE_OPTIONS
-fno-rtti -fno-exceptions
-fno-unwind-tables -fno-asynchronous-unwind-tables)
endif()
target_compile_options(md5sum PRIVATE ${MD5_COMPILE_OPTIONS})
target_include_directories(md5sum PUBLIC src/)
@ -64,9 +78,9 @@ add_library(md5sum::md5 ALIAS md5sum)
# ------------------------------------------------------------------------------------ #
if (MD5_BUILD_DEMO)
add_executable(md5_demo demo.cc)
target_link_libraries(md5_demo PRIVATE md5sum)
target_compile_options(md5_demo PRIVATE ${MD5_COMPILE_OPTIONS})
add_executable(md5_demo demo.cc)
target_link_libraries(md5_demo PRIVATE md5sum)
target_compile_options(md5_demo PRIVATE ${MD5_COMPILE_OPTIONS})
endif()
# ------------------------------------------------------------------------------------ #
@ -74,17 +88,17 @@ endif()
include(third_party/ThirdParty.cmake)
if (MD5_ENABLE_TESTING)
enable_testing()
file(GLOB MD5_TEST_SRC test/*.cc)
add_executable(md5_test ${MD5_TEST_SRC})
target_link_libraries(md5_test PRIVATE md5sum GTest::gtest_main)
add_test(NAME md5_test COMMAND md5_test)
enable_testing()
file(GLOB MD5_TEST_SRC test/*.cc)
add_executable(md5_test ${MD5_TEST_SRC})
target_link_libraries(md5_test PRIVATE md5sum GTest::gtest_main)
add_test(NAME md5_test COMMAND md5_test)
endif()
if (MD5_ENABLE_BENCHMARK)
add_executable(md5_benchmark benchmark.cc)
target_link_libraries(md5_benchmark PRIVATE md5sum benchmark::benchmark_main)
target_compile_options(md5_benchmark PRIVATE ${MD5_COMPILE_OPTIONS})
add_executable(md5_benchmark benchmark.cc)
target_link_libraries(md5_benchmark PRIVATE md5sum benchmark::benchmark_main)
target_compile_options(md5_benchmark PRIVATE ${MD5_COMPILE_OPTIONS})
endif()
# ------------------------------------------------------------------------------------ #

11
src/impl/constexpr.inl

@ -36,10 +36,13 @@ constexpr Block GetBlock(const md5_data &data, const uint64_t index) {
Block block {};
for (int i = 0; i < 16; ++i) {
const auto offset = index + i * 4;
(block[i] <<= 8) |= GetByte(data, offset + 3);
(block[i] <<= 8) |= GetByte(data, offset + 2);
(block[i] <<= 8) |= GetByte(data, offset + 1);
(block[i] <<= 8) |= GetByte(data, offset + 0);
block[i] |= GetByte(data, offset + 3);
block[i] <<= 8;
block[i] |= GetByte(data, offset + 2);
block[i] <<= 8;
block[i] |= GetByte(data, offset + 1);
block[i] <<= 8;
block[i] |= GetByte(data, offset + 0);
}
return block;
}

17
src/impl/core.cc

@ -16,17 +16,24 @@ using md5::value::T;
#define H(x, y, z) (x ^ y ^ z)
#define I(x, y, z) (y ^ (x | ~z))
#define STEP(i, f, a, b, c, d) \
#define MD5_ROUND(i, f, a, b, c, d) \
do { \
a += f(b, c, d) + block[K(i)] + T(i); \
a = a << S(i) | a >> (32 - S(i)); \
a += b; \
} while (0)
#define FF(i, ...) STEP((0x00 | i), F, __VA_ARGS__)
#define GG(i, ...) STEP((0x10 | i), G, __VA_ARGS__)
#define HH(i, ...) STEP((0x20 | i), H, __VA_ARGS__)
#define II(i, ...) STEP((0x30 | i), I, __VA_ARGS__)
#ifdef _MSC_VER
#define EXPAND(...) __VA_ARGS__
#define ROUND(...) EXPAND(MD5_ROUND(__VA_ARGS__))
#else
#define ROUND MD5_ROUND
#endif
#define FF(i, ...) ROUND(i | 0x00, F, __VA_ARGS__)
#define GG(i, ...) ROUND(i | 0x10, G, __VA_ARGS__)
#define HH(i, ...) ROUND(i | 0x20, H, __VA_ARGS__)
#define II(i, ...) ROUND(i | 0x30, I, __VA_ARGS__)
#define MD5_UPDATE(OP) \
OP(0x0, R1); OP(0x1, R2); OP(0x2, R3); OP(0x3, R4); \

8
src/md5.h

@ -7,10 +7,18 @@
static_assert(sizeof(uintptr_t) == 8,
"Project only works on 64-bits architecture.");
#ifdef _MSC_VER
static_assert('\x01\x02\x03\x04' == 0x04030201,
#else
static_assert(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__,
#endif
"Project only works on little-endian architecture.");
#if defined(__clang__) || defined(__GNUC__)
#define MD5_EXPORT __attribute__ ((visibility ("default")))
#else
#define MD5_EXPORT
#endif
#include "impl/value.inl"
#include "impl/constexpr.inl"

11
third_party/ThirdParty.cmake

@ -1,9 +1,14 @@
if (MD5_ENABLE_TESTING)
add_subdirectory(third_party/googletest/ EXCLUDE_FROM_ALL)
if (MSVC)
set(gtest_force_shared_crt ON)
endif()
add_subdirectory(third_party/googletest/ EXCLUDE_FROM_ALL)
endif()
if (MD5_ENABLE_BENCHMARK)
set(BENCHMARK_ENABLE_TESTING OFF)
if (NOT MSVC)
set(BENCHMARK_ENABLE_EXCEPTIONS OFF)
add_subdirectory(third_party/benchmark/ EXCLUDE_FROM_ALL)
endif()
set(BENCHMARK_ENABLE_TESTING OFF)
add_subdirectory(third_party/benchmark/ EXCLUDE_FROM_ALL)
endif()

Loading…
Cancel
Save