Browse Source

feat: adapt to msvc compiler

master
Dnomd343 5 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) project(md5sum LANGUAGES CXX)
if ("${CMAKE_VERSION}" VERSION_GREATER_EQUAL "3.13") if ("${CMAKE_VERSION}" VERSION_GREATER_EQUAL "3.13")
cmake_policy(SET CMP0077 NEW) cmake_policy(SET CMP0077 NEW)
endif() endif()
# ------------------------------------------------------------------------------------ # # ------------------------------------------------------------------------------------ #
@ -17,14 +17,14 @@ option(MD5_ENABLE_BENCHMARK "Enable benchmark of the md5sum library." OFF)
set(CXX_STANDARDS) set(CXX_STANDARDS)
foreach (CXX_FEATURE ${CMAKE_CXX_COMPILE_FEATURES}) foreach (CXX_FEATURE ${CMAKE_CXX_COMPILE_FEATURES})
if (CXX_FEATURE MATCHES "^cxx_std_[0-9]+$") if (CXX_FEATURE MATCHES "^cxx_std_[0-9]+$")
string(REGEX MATCH "[0-9]+$" CXX_STANDARD ${CXX_FEATURE}) string(REGEX MATCH "[0-9]+$" CXX_STANDARD ${CXX_FEATURE})
list(APPEND CXX_STANDARDS ${CXX_STANDARD}) # supported c++ standards list(APPEND CXX_STANDARDS ${CXX_STANDARD}) # supported c++ standards
endif() endif()
endforeach() endforeach()
if (NOT 17 IN_LIST CXX_STANDARDS) 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() endif()
list(GET CXX_STANDARDS -1 MD5_CXX_STANDARD) # select the latest C++ standard 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) 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() endif()
add_compile_options(-Wall -Wextra -Werror) if (MSVC)
if (MD5_ENABLE_LTO) 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) add_compile_options(-flto=auto)
endif()
endif() endif()
# ------------------------------------------------------------------------------------ #
file(GLOB MD5_SRC src/impl/*.cc) file(GLOB MD5_SRC src/impl/*.cc)
if (NOT MD5_SHARED_LIB) if (NOT MD5_SHARED_LIB)
add_library(md5sum STATIC ${MD5_SRC}) add_library(md5sum STATIC ${MD5_SRC})
else() else()
add_library(md5sum SHARED ${MD5_SRC}) add_library(md5sum SHARED ${MD5_SRC})
if (NOT MSVC)
target_compile_options(md5sum PRIVATE -fvisibility=hidden) target_compile_options(md5sum PRIVATE -fvisibility=hidden)
endif()
endif() endif()
set(MD5_COMPILE_OPTIONS if (MSVC)
-fno-rtti set(MD5_COMPILE_OPTIONS /GR-)
-fno-exceptions else()
-fno-unwind-tables set(MD5_COMPILE_OPTIONS
-fno-asynchronous-unwind-tables) -fno-rtti -fno-exceptions
-fno-unwind-tables -fno-asynchronous-unwind-tables)
endif()
target_compile_options(md5sum PRIVATE ${MD5_COMPILE_OPTIONS}) target_compile_options(md5sum PRIVATE ${MD5_COMPILE_OPTIONS})
target_include_directories(md5sum PUBLIC src/) target_include_directories(md5sum PUBLIC src/)
@ -64,9 +78,9 @@ add_library(md5sum::md5 ALIAS md5sum)
# ------------------------------------------------------------------------------------ # # ------------------------------------------------------------------------------------ #
if (MD5_BUILD_DEMO) if (MD5_BUILD_DEMO)
add_executable(md5_demo demo.cc) add_executable(md5_demo demo.cc)
target_link_libraries(md5_demo PRIVATE md5sum) target_link_libraries(md5_demo PRIVATE md5sum)
target_compile_options(md5_demo PRIVATE ${MD5_COMPILE_OPTIONS}) target_compile_options(md5_demo PRIVATE ${MD5_COMPILE_OPTIONS})
endif() endif()
# ------------------------------------------------------------------------------------ # # ------------------------------------------------------------------------------------ #
@ -74,17 +88,17 @@ endif()
include(third_party/ThirdParty.cmake) include(third_party/ThirdParty.cmake)
if (MD5_ENABLE_TESTING) if (MD5_ENABLE_TESTING)
enable_testing() enable_testing()
file(GLOB MD5_TEST_SRC test/*.cc) file(GLOB MD5_TEST_SRC test/*.cc)
add_executable(md5_test ${MD5_TEST_SRC}) add_executable(md5_test ${MD5_TEST_SRC})
target_link_libraries(md5_test PRIVATE md5sum GTest::gtest_main) target_link_libraries(md5_test PRIVATE md5sum GTest::gtest_main)
add_test(NAME md5_test COMMAND md5_test) add_test(NAME md5_test COMMAND md5_test)
endif() endif()
if (MD5_ENABLE_BENCHMARK) if (MD5_ENABLE_BENCHMARK)
add_executable(md5_benchmark benchmark.cc) add_executable(md5_benchmark benchmark.cc)
target_link_libraries(md5_benchmark PRIVATE md5sum benchmark::benchmark_main) target_link_libraries(md5_benchmark PRIVATE md5sum benchmark::benchmark_main)
target_compile_options(md5_benchmark PRIVATE ${MD5_COMPILE_OPTIONS}) target_compile_options(md5_benchmark PRIVATE ${MD5_COMPILE_OPTIONS})
endif() endif()
# ------------------------------------------------------------------------------------ # # ------------------------------------------------------------------------------------ #

11
src/impl/constexpr.inl

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

17
src/impl/core.cc

@ -16,17 +16,24 @@ using md5::value::T;
#define H(x, y, z) (x ^ y ^ z) #define H(x, y, z) (x ^ y ^ z)
#define I(x, y, z) (y ^ (x | ~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 { \ do { \
a += f(b, c, d) + block[K(i)] + T(i); \ a += f(b, c, d) + block[K(i)] + T(i); \
a = a << S(i) | a >> (32 - S(i)); \ a = a << S(i) | a >> (32 - S(i)); \
a += b; \ a += b; \
} while (0) } while (0)
#define FF(i, ...) STEP((0x00 | i), F, __VA_ARGS__) #ifdef _MSC_VER
#define GG(i, ...) STEP((0x10 | i), G, __VA_ARGS__) #define EXPAND(...) __VA_ARGS__
#define HH(i, ...) STEP((0x20 | i), H, __VA_ARGS__) #define ROUND(...) EXPAND(MD5_ROUND(__VA_ARGS__))
#define II(i, ...) STEP((0x30 | i), I, __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) \ #define MD5_UPDATE(OP) \
OP(0x0, R1); OP(0x1, R2); OP(0x2, R3); OP(0x3, R4); \ 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, static_assert(sizeof(uintptr_t) == 8,
"Project only works on 64-bits architecture."); "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__, static_assert(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__,
#endif
"Project only works on little-endian architecture."); "Project only works on little-endian architecture.");
#if defined(__clang__) || defined(__GNUC__)
#define MD5_EXPORT __attribute__ ((visibility ("default"))) #define MD5_EXPORT __attribute__ ((visibility ("default")))
#else
#define MD5_EXPORT
#endif
#include "impl/value.inl" #include "impl/value.inl"
#include "impl/constexpr.inl" #include "impl/constexpr.inl"

11
third_party/ThirdParty.cmake

@ -1,9 +1,14 @@
if (MD5_ENABLE_TESTING) 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() endif()
if (MD5_ENABLE_BENCHMARK) if (MD5_ENABLE_BENCHMARK)
set(BENCHMARK_ENABLE_TESTING OFF) if (NOT MSVC)
set(BENCHMARK_ENABLE_EXCEPTIONS OFF) 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() endif()

Loading…
Cancel
Save