1
# CMake file to replace the string contents in ONNX, Caffe, and Caffe2 proto.
3
# cmake -DFILENAME=caffe2.pb.h -DLOCAL_PROTOBUF=ON -P ProtoBufPatch.cmake
5
file(READ ${FILENAME} content)
8
# protobuf-3.6.0 pattern
11
"::google::protobuf::internal::GetEmptyStringAlreadyInited"
12
"GetEmptyStringAlreadyInited"
16
# protobuf-3.8.0+ pattern
19
"::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited"
20
"GetEmptyStringAlreadyInited"
31
# https://github.com/protocolbuffers/protobuf/commit/0400cca3236de1ca303af38bf81eab332d042b7c
32
# changes PROTOBUF_CONSTEXPR to constexpr, which breaks windows
37
"static constexpr ([^ ]+) ([^ ]+) ="
38
"static \\1 const \\2 ="
43
foreach(ns ${NAMESPACES})
44
# Insert "const ::std::string& GetEmptyStringAlreadyInited();" within
45
# the namespace and make sure we only do it once in the file. Unfortunately
46
# using string(REPLACE ...) doesn't work because it will replace at all
47
# locations and there might be multiple declarations of the namespace
48
# depending on how the proto is structured.
49
set(search "namespace ${ns} {")
50
string(LENGTH "${search}" search_len)
51
string(FIND "${content}" "${search}" pos)
53
math(EXPR pos "${pos}+${search_len}")
54
string(SUBSTRING "${content}" 0 ${pos} content_pre)
55
string(SUBSTRING "${content}" ${pos} -1 content_post)
60
" const ::std::string& GetEmptyStringAlreadyInited(); "
65
# The moving constructor is defined in the header file, which will cause
66
# a link error that claims that the vftable is not found. Luckily, we
67
# could move the definition into the source file to solve the problem.
68
list(LENGTH NAMESPACES ns_count)
69
if("${FILENAME}" MATCHES ".pb.h" AND ns_count EQUAL 1)
70
string(REPLACE ".pb.h" ".pb.cc" SOURCE_FILENAME ${FILENAME})
71
file(READ ${SOURCE_FILENAME} content_cc_origin)
73
string(REGEX MATCHALL "([a-zA-Z_]+)\\([a-zA-Z_]+&& from\\) noexcept[^}]*}" content_cc "${content}")
74
string(REGEX REPLACE "};" "}\n" content_cc "${content_cc}")
75
string(REGEX REPLACE "([a-zA-Z_]+)\\([a-zA-Z_]+&& from\\) noexcept" " \\1::\\1(\\1&& from) noexcept" content_cc "${content_cc}")
76
set(content_cc "${content_cc_origin}\nnamespace ${NAMESPACES} {\n#if LANG_CXX11\n${content_cc}\n#endif\n}")
78
string(REGEX REPLACE "([a-zA-Z_]+)\\([a-zA-Z_]+&& from\\) noexcept([^}]*)}" "\\1(\\1&& from) noexcept;" content "${content}")
80
file(WRITE ${SOURCE_FILENAME} "${content_cc}")
82
endif(NOT SYSTEM_PROTOBUF)
84
# constexpr int TensorBoundShape_DimType_DimType_ARRAYSIZE = TensorBoundShape_DimType_DimType_MAX + 1;
86
# error: more than one operator "+" matches these operands:
87
# built-in operator "arithmetic + arithmetic"
88
# function "c10::operator+(int, c10::BFloat16)"
89
# function "c10::operator+(c10::BFloat16, int)"
90
# function "c10::operator+(int, c10::Half)"
91
# function "c10::operator+(c10::Half, int)"
92
# operand types are: const caffe2::ExternalDataProto_SourceType + int
95
"constexpr ([^ ]+) ([^ ]+_ARRAYSIZE) = ([^ ]+_MAX) \\+ 1;"
96
"constexpr \\1 \\2 = static_cast<\\1>(\\3) + 1;"
100
file(WRITE ${FILENAME} "${content}")