Skip to content

Commit e693e9c

Browse files
committed
Fix issue with escape_json
1 parent 899ad05 commit e693e9c

File tree

6 files changed

+142
-29
lines changed

6 files changed

+142
-29
lines changed

binlog_json_parser/CMakeLists.txt

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,19 @@ project(binlog_json_parser)
55
set(CMAKE_CXX_STANDARD 23)
66
set(CMAKE_CXX_STANDARD_REQUIRED ON)
77

8+
include(CheckIPOSupported)
9+
include(CheckCSourceCompiles)
10+
check_ipo_supported(RESULT IPO_SUPPORTED OUTPUT IPO_OUTPUT)
11+
12+
if(IPO_SUPPORTED)
13+
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
14+
message(STATUS "Interprocedural optimization (IPO/LTO) enabled globally.")
15+
else()
16+
message(STATUS "IPO/LTO is not supported: ${IPO_OUTPUT}")
17+
endif()
18+
819
# Check if the build type is Release
920
if(CMAKE_BUILD_TYPE STREQUAL "Release")
10-
1121
# Set optimization level to -O3 for release builds
1222
if(NOT CMAKE_CXX_FLAGS_RELEASE MATCHES "-O")
1323
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
@@ -28,28 +38,47 @@ if(CMAKE_BUILD_TYPE STREQUAL "Release")
2838
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -march=skylake")
2939
endif()
3040
endif()
41+
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|ARM64")
42+
if(USE_MARCH_NATIVE)
43+
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -march=native")
44+
else()
45+
if(NOT CMAKE_CXX_FLAGS_RELEASE MATCHES "march=")
46+
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -march=armv8.2-a")
47+
endif()
48+
endif()
3149
else()
32-
message(WARNING "The -march option will not be set because the system is not x86 or x64.")
33-
endif()
34-
35-
# Check for LTO support
36-
include(CheckCXXCompilerFlag)
37-
38-
check_cxx_compiler_flag("-flto" COMPILER_SUPPORTS_LTO)
39-
40-
if(COMPILER_SUPPORTS_LTO)
41-
message(STATUS "Link Time Optimization (LTO) is supported by the compiler.")
42-
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto")
43-
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto")
44-
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -flto")
45-
else()
46-
message(WARNING "Link Time Optimization (LTO) is not supported by the compiler.")
50+
message(WARNING "The -march option will not be set because the system is not x86, x64, or ARM64.")
4751
endif()
4852

4953
# Export compile flags to a file
5054
file(WRITE "${CMAKE_BINARY_DIR}/compile_flags.txt" "CXXFLAGS: ${CMAKE_CXX_FLAGS_RELEASE}\n")
5155
file(APPEND "${CMAKE_BINARY_DIR}/compile_flags.txt" "LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}\n")
52-
5356
endif()
5457

55-
add_library(mysqljsonparse SHARED mysqljsonparse.cpp mysql_json_parser.cpp)
58+
check_c_source_compiles("
59+
#include <features.h>
60+
#if defined(__GLIBC__)
61+
#error \"This is glibc, not musl\"
62+
#endif
63+
#include <stdio.h>
64+
int main() { return 0; }
65+
" IS_MUSL)
66+
67+
option(ALPINE_STATIC "Force fully static build when using musl/Alpine" ${IS_MUSL})
68+
69+
if(ALPINE_STATIC)
70+
add_definitions(-D_FORTIFY_SOURCE=0)
71+
message(STATUS "musl detected → producing shared library with static musl linking")
72+
73+
add_library(mysqljsonparse SHARED mysqljsonparse.cpp mysql_json_parser.cpp)
74+
target_link_options(mysqljsonparse PRIVATE
75+
-static
76+
-static-libgcc
77+
-static-libstdc++
78+
-fPIC
79+
)
80+
target_compile_options(mysqljsonparse PRIVATE -fPIC)
81+
else()
82+
message(STATUS "musl not detected → building shared library with dynamic glibc")
83+
add_library(mysqljsonparse SHARED mysqljsonparse.cpp mysql_json_parser.cpp)
84+
endif()

binlog_json_parser/Dockerfile

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
FROM alpine:3.22 AS build
2+
3+
RUN apk add --no-cache \
4+
build-base \
5+
clang \
6+
lld \
7+
llvm \
8+
cmake \
9+
ninja \
10+
musl-dev \
11+
binutils
12+
13+
WORKDIR /src
14+
15+
COPY . .
16+
17+
RUN cmake -S . -B build -G Ninja \
18+
-DCMAKE_BUILD_TYPE=Release \
19+
-DCMAKE_C_COMPILER=clang \
20+
-DCMAKE_CXX_COMPILER=clang++ \
21+
-DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" \
22+
-DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld" \
23+
&& ninja -C build -v \
24+
&& strip --strip-unneeded build/libmysqljsonparse.so \
25+
&& echo "Library dependencies:" && ldd build/libmysqljsonparse.so
26+
27+
FROM scratch AS artifact
28+
29+
COPY --from=build /src/build/libmysqljsonparse.so /
30+
31+
CMD [""]

binlog_json_parser/build_static.sh

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
IMAGE_TAG=${1:-mysqljsonparse:alpine-static}
5+
ARTIFACT_BASE=${2:-libmysqljsonparse.so}
6+
7+
if ! docker buildx version >/dev/null 2>&1; then
8+
echo "[ERROR] Docker buildx is not available. Please install Docker Desktop or enable buildx." >&2
9+
exit 1
10+
fi
11+
12+
BUILDER_NAME="multiarch-builder"
13+
if ! docker buildx inspect "$BUILDER_NAME" >/dev/null 2>&1; then
14+
echo "[INFO] Creating buildx builder '$BUILDER_NAME'..."
15+
docker buildx create --name "$BUILDER_NAME" --driver docker-container --use
16+
fi
17+
18+
docker buildx use "$BUILDER_NAME"
19+
20+
extract_artifact() {
21+
local platform=$1
22+
local artifact_name=$2
23+
local platform_tag="${IMAGE_TAG}-${platform//\//-}"
24+
25+
echo "[INFO] Building single-platform image for $platform..."
26+
docker buildx build --platform "$platform" -t "$platform_tag" --load .
27+
28+
echo "[INFO] Creating temporary container from $platform image..."
29+
local cid=$(docker create "$platform_tag")
30+
trap "docker rm -fv '$cid' >/dev/null" EXIT
31+
32+
echo "[INFO] Copying '$artifact_name' from $platform container to host..."
33+
if docker cp "${cid}:/${ARTIFACT_BASE}" "./${artifact_name}"; then
34+
echo "[SUCCESS] Artifact '$artifact_name' extracted to $(pwd)"
35+
else
36+
echo "[ERROR] Failed to find '${ARTIFACT_BASE}' inside the $platform image." >&2
37+
return 1
38+
fi
39+
}
40+
41+
# Extract ARM64 artifact
42+
extract_artifact "linux/arm64" "libmysqljsonparse.so"
43+
44+
# Extract AMD64 artifact
45+
extract_artifact "linux/amd64" "libmysqljsonparse_x86_64.so"
46+
47+
echo "[SUCCESS] Both artifacts built successfully:"
48+
echo " - libmysqljsonparse.so (ARM64)"
49+
echo " - libmysqljsonparse_x86_64.so (AMD64)"

binlog_json_parser/mysql_json_parser.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -120,24 +120,28 @@ static bool read_variable_length(const char *data, size_t data_length,
120120

121121
std::string escape_json(const std::string &s) {
122122
std::ostringstream o;
123-
for (auto c = s.cbegin(); c != s.cend(); c++) {
124-
switch (*c) {
125-
case '"': o << "\\\""; break;
123+
124+
for (const unsigned char uc : s) {
125+
switch (uc) {
126+
case '"': o << "\\\""; break;
126127
case '\\': o << "\\\\"; break;
127-
case '\b': o << "\\b"; break;
128-
case '\f': o << "\\f"; break;
129-
case '\n': o << "\\n"; break;
130-
case '\r': o << "\\r"; break;
131-
case '\t': o << "\\t"; break;
128+
case '\b': o << "\\b"; break;
129+
case '\f': o << "\\f"; break;
130+
case '\n': o << "\\n"; break;
131+
case '\r': o << "\\r"; break;
132+
case '\t': o << "\\t"; break;
133+
132134
default:
133-
if (*c <= '\x1f') {
135+
if (uc <= 0x1F) {
134136
o << "\\u"
135-
<< std::hex << std::setw(4) << std::setfill('0') << static_cast<int>(*c);
137+
<< std::hex << std::setw(4) << std::setfill('0') << static_cast<int>(uc)
138+
<< std::dec;
136139
} else {
137-
o << *c;
140+
o << static_cast<char>(uc);
138141
}
139142
}
140143
}
144+
141145
return o.str();
142146
}
143147

Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)