Skip to content

Commit 1d65f66

Browse files
committed
fix(ci): pass libstdc++ ABI via CMake for manylinux client-cpp packages
Resolve gcc from PATH in manylinux containers; use -Diotdb.extra.cxx.flags so ABI applies to iotdb_session and Thrift. Document Linux zip linking in README.
1 parent 1992ab4 commit 1d65f66

6 files changed

Lines changed: 144 additions & 55 deletions

File tree

.github/scripts/package-client-cpp-manylinux-glibc217.sh

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@
1818
set -euxo pipefail
1919

2020
MAX_GLIBC=2.17
21-
SYSTEM_GCC=/usr/bin/gcc
22-
SYSTEM_GXX=/usr/bin/g++
21+
IOTDB_EXTRA_CXX_FLAGS=-D_GLIBCXX_USE_CXX11_ABI=0
2322

2423
MACHINE=$(uname -m)
2524
case "${MACHINE}" in
@@ -62,13 +61,23 @@ if [[ ! -x "${JAVA_HOME}/bin/java" ]]; then
6261
JAVA_HOME=/opt/jdk-17
6362
fi
6463

65-
export PATH="${CMAKE_DIR}/bin:${JAVA_HOME}/bin:/usr/bin:${PATH}"
64+
export PATH="${CMAKE_DIR}/bin:${JAVA_HOME}/bin:${PATH}"
6665
export JAVA_HOME
6766

67+
# manylinux images expose gcc under devtoolset paths, not /usr/bin/gcc.
68+
SYSTEM_GCC=$(command -v gcc)
69+
SYSTEM_GXX=$(command -v g++)
70+
if [[ -z "${SYSTEM_GCC}" || ! -x "${SYSTEM_GCC}" ]]; then
71+
echo "ERROR: gcc not found on PATH" >&2
72+
exit 1
73+
fi
74+
if [[ -z "${SYSTEM_GXX}" || ! -x "${SYSTEM_GXX}" ]]; then
75+
echo "ERROR: g++ not found on PATH" >&2
76+
exit 1
77+
fi
78+
6879
export CC="${SYSTEM_GCC}"
6980
export CXX="${SYSTEM_GXX}"
70-
export CFLAGS="-D_GLIBCXX_USE_CXX11_ABI=0 ${CFLAGS:-}"
71-
export CXXFLAGS="-D_GLIBCXX_USE_CXX11_ABI=0 ${CXXFLAGS:-}"
7281

7382
"${SYSTEM_GCC}" --version
7483
"${SYSTEM_GXX}" --version
@@ -78,7 +87,8 @@ java -version
7887
cd "${GITHUB_WORKSPACE:?GITHUB_WORKSPACE is not set}"
7988
./mvnw clean package -P with-cpp -pl iotdb-client/client-cpp -am -DskipTests \
8089
-Dspotless.skip=true \
81-
-Dclient.cpp.package.classifier="${PACKAGE_CLASSIFIER}"
90+
-Dclient.cpp.package.classifier="${PACKAGE_CLASSIFIER}" \
91+
"-Diotdb.extra.cxx.flags=${IOTDB_EXTRA_CXX_FLAGS}"
8292

8393
SO="iotdb-client/client-cpp/target/install/lib/libiotdb_session.so"
8494
test -f "${SO}"

.github/scripts/package-client-cpp-manylinux-glibc224.sh

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616
#
17-
# Default libstdc++ cxx11 ABI on manylinux_2_24; max glibc 2.24.
17+
# cxx11 libstdc++ ABI on manylinux_2_24; max glibc 2.24.
1818
set -euxo pipefail
1919

2020
MAX_GLIBC=2.24
21-
SYSTEM_GCC=/usr/bin/gcc
22-
SYSTEM_GXX=/usr/bin/g++
21+
IOTDB_EXTRA_CXX_FLAGS=-D_GLIBCXX_USE_CXX11_ABI=1
2322

2423
MACHINE=$(uname -m)
2524
case "${MACHINE}" in
@@ -62,9 +61,20 @@ if [[ ! -x "${JAVA_HOME}/bin/java" ]]; then
6261
JAVA_HOME=/opt/jdk-17
6362
fi
6463

65-
export PATH="${CMAKE_DIR}/bin:${JAVA_HOME}/bin:/usr/bin:${PATH}"
64+
export PATH="${CMAKE_DIR}/bin:${JAVA_HOME}/bin:${PATH}"
6665
export JAVA_HOME
6766

67+
SYSTEM_GCC=$(command -v gcc)
68+
SYSTEM_GXX=$(command -v g++)
69+
if [[ -z "${SYSTEM_GCC}" || ! -x "${SYSTEM_GCC}" ]]; then
70+
echo "ERROR: gcc not found on PATH" >&2
71+
exit 1
72+
fi
73+
if [[ -z "${SYSTEM_GXX}" || ! -x "${SYSTEM_GXX}" ]]; then
74+
echo "ERROR: g++ not found on PATH" >&2
75+
exit 1
76+
fi
77+
6878
export CC="${SYSTEM_GCC}"
6979
export CXX="${SYSTEM_GXX}"
7080

@@ -76,7 +86,8 @@ java -version
7686
cd "${GITHUB_WORKSPACE:?GITHUB_WORKSPACE is not set}"
7787
./mvnw clean package -P with-cpp -pl iotdb-client/client-cpp -am -DskipTests \
7888
-Dspotless.skip=true \
79-
-Dclient.cpp.package.classifier="${PACKAGE_CLASSIFIER}"
89+
-Dclient.cpp.package.classifier="${PACKAGE_CLASSIFIER}" \
90+
"-Diotdb.extra.cxx.flags=${IOTDB_EXTRA_CXX_FLAGS}"
8091

8192
SO="iotdb-client/client-cpp/target/install/lib/libiotdb_session.so"
8293
test -f "${SO}"
@@ -104,7 +115,7 @@ fi
104115

105116
echo "glibc compatibility check passed (max=${max_glibc} <= ${MAX_GLIBC})"
106117

107-
echo "=== Optional example link test (default cxx11 ABI) ==="
118+
echo "=== Optional example link test (cxx11 ABI) ==="
108119
INSTALL_ROOT="${GITHUB_WORKSPACE}/iotdb-client/client-cpp/target/install"
109120
EXAMPLE_SRC="${GITHUB_WORKSPACE}/example/client-cpp-example/src"
110121
LINKTEST_BUILD="/tmp/client-cpp-example-linktest-glibc224"
@@ -113,7 +124,8 @@ mkdir -p "${LINKTEST_BUILD}"
113124
unset CC CXX CFLAGS CXXFLAGS
114125
"${CMAKE_DIR}/bin/cmake" -S "${EXAMPLE_SRC}" -B "${LINKTEST_BUILD}" \
115126
-DCMAKE_BUILD_TYPE=Release \
116-
-DIOTDB_SDK_ROOT="${INSTALL_ROOT}"
127+
-DIOTDB_SDK_ROOT="${INSTALL_ROOT}" \
128+
-DCMAKE_CXX_FLAGS=-D_GLIBCXX_USE_CXX11_ABI=1
117129
"${CMAKE_DIR}/bin/cmake" --build "${LINKTEST_BUILD}" --target SessionExample -j"$(nproc)"
118130
test -x "${LINKTEST_BUILD}/SessionExample"
119131
echo "Example link test passed"

iotdb-client/client-cpp/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ endif()
3434

3535
if(NOT MSVC)
3636
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -g -O2")
37+
if(IOTDB_EXTRA_CXX_FLAGS)
38+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${IOTDB_EXTRA_CXX_FLAGS}")
39+
endif()
3740
endif()
3841

3942
if(MSVC)
@@ -44,6 +47,9 @@ endif()
4447
option(WITH_SSL "Build with OpenSSL support" OFF)
4548
option(BUILD_TESTING "Build IT test executables" OFF)
4649
option(IOTDB_OFFLINE "Disable all network access during configure" OFF)
50+
# e.g. -D_GLIBCXX_USE_CXX11_ABI=0 for legacy Linux release zips (Maven: -Diotdb.extra.cxx.flags=...)
51+
set(IOTDB_EXTRA_CXX_FLAGS ""
52+
CACHE STRING "Extra flags appended to CMAKE_CXX_FLAGS (libstdc++ ABI, etc.)")
4753

4854
set(IOTDB_DEPS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third-party"
4955
CACHE PATH "Local tarball cache for third-party dependencies (lives under client-cpp/)")

iotdb-client/client-cpp/README.md

Lines changed: 93 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -93,17 +93,20 @@ deployment environment:
9393
Example file name:
9494
`client-cpp-2.0.7-SNAPSHOT-linux-x86_64-glibc224.zip`.
9595

96-
**Linux ABI and glibc:** Two Linux families are published. **`glibc224`** packages
97-
are built on [`manylinux_2_24`](https://github.com/pypa/manylinux) with the
98-
image default `/usr/bin/g++` and the **new** libstdc++ ABI (symbols contain
99-
`__cxx11`); they require **glibc ≥ 2.24** on the deployment host. Prefer these
100-
on modern distros (Ubuntu 22.04+, Kylin V10, etc.) when your application uses
101-
the default compiler ABI. **`glibc217`** packages are built on `manylinux2014`
102-
with **`-D_GLIBCXX_USE_CXX11_ABI=0`** (no `__cxx11` symbols) for hosts that only
103-
have **glibc 2.17** and cannot upgrade to 2.24+; your application must compile
104-
with the same flag when linking against that SDK. The `manylinux_2_24` image
105-
series is **EOL**; it remains the oldest manylinux image that ships a gcc with
106-
native cxx11 ABI support.
96+
**Linux ABI and glibc:** Two Linux families are published.
97+
98+
| Package | manylinux image | Deployment glibc | libstdc++ ABI | How to match when you build your app |
99+
|---------|-----------------|------------------|---------------|--------------------------------------|
100+
| `*-glibc224` | `manylinux_2_24` | **≥ 2.24** | **cxx11** (`nm` shows `__cxx11`) | Default g++ on Ubuntu 22.04+, Kylin V10, etc. — no extra flags |
101+
| `*-glibc217` | `manylinux2014` | **≥ 2.17** | **legacy** (no `__cxx11`) | Add **`-D_GLIBCXX_USE_CXX11_ABI=0`** to your compile flags |
102+
103+
Prefer **`glibc224`** on modern distros. Use **`glibc217`** only when the target
104+
host cannot run glibc 2.24+ binaries, or you must stay on the legacy ABI.
105+
The `manylinux_2_24` image series is **EOL**; it is the oldest manylinux line
106+
used here that can produce a cxx11-ABI SDK with the image toolchain.
107+
108+
CI passes libstdc++ ABI into CMake via **`-Diotdb.extra.cxx.flags=...`** (see
109+
below). Setting `CXXFLAGS` alone is **not** enough for the Maven/CMake build.
107110

108111
Thrift **0.21.0** is compiled from source during the CMake configure step (see
109112
`cmake/FetchThrift.cmake`). Older releases that used pre-built
@@ -114,21 +117,28 @@ and OS used to build** the SDK, not by that Maven property.
114117

115118
### Local build for a specific classifier
116119

117-
Linux x86_64 (glibc 2.24 + cxx11 ABI — match a modern distro or
118-
`manylinux_2_24`):
120+
Linux x86_64 (**glibc224**, cxx11 ABI — modern distro or `manylinux_2_24`):
119121

120122
```bash
121123
mvn -P with-cpp -pl iotdb-client/client-cpp -am -DskipTests \
122-
-Dclient.cpp.package.classifier=linux-x86_64-glibc224 package
124+
-Dclient.cpp.package.classifier=linux-x86_64-glibc224 \
125+
-Diotdb.extra.cxx.flags=-D_GLIBCXX_USE_CXX11_ABI=1 package
123126
```
124127

125-
Linux x86_64 (glibc 2.17 + legacy ABI — CentOS 7 / manylinux2014; compile with
126-
`-D_GLIBCXX_USE_CXX11_ABI=0`):
128+
Linux x86_64 (**glibc217**, legacy ABI — CentOS 7 / `manylinux2014`):
127129

128130
```bash
129-
export CXXFLAGS="-D_GLIBCXX_USE_CXX11_ABI=0"
130131
mvn -P with-cpp -pl iotdb-client/client-cpp -am -DskipTests \
131-
-Dclient.cpp.package.classifier=linux-x86_64-glibc217 package
132+
-Dclient.cpp.package.classifier=linux-x86_64-glibc217 \
133+
-Diotdb.extra.cxx.flags=-D_GLIBCXX_USE_CXX11_ABI=0 package
134+
```
135+
136+
Standalone CMake (same ABI flags):
137+
138+
```bash
139+
cmake -S iotdb-client/client-cpp -B build \
140+
-DIOTDB_EXTRA_CXX_FLAGS=-D_GLIBCXX_USE_CXX11_ABI=1 # or =0 for glibc217
141+
cmake --build build --target install
132142
```
133143

134144
Windows (match the Visual Studio version you use to build your application):
@@ -163,6 +173,7 @@ pass them as Maven properties (the POM maps them to `-D` options for CMake):
163173
| `BUILD_TESTING` | `build.tests` |
164174
| `IOTDB_DEPS_DIR` | `iotdb.deps.dir` |
165175
| `BOOST_INCLUDEDIR` | `boost.include.dir` (legacy alias) |
176+
| `IOTDB_EXTRA_CXX_FLAGS` | `iotdb.extra.cxx.flags` (e.g. `-D_GLIBCXX_USE_CXX11_ABI=0`) |
166177

167178
For a **standalone** `cmake` configure, pass `-DWITH_SSL=ON`, `-DIOTDB_OFFLINE=ON`,
168179
etc. directly.
@@ -178,6 +189,7 @@ etc. directly.
178189
| `BOOST_ROOT` | (unset) | Existing Boost install to reuse, equivalent to `-Dboost.include.dir=...` from the legacy build. |
179190
| `OPENSSL_ROOT_DIR` | (unset) | Existing OpenSSL install when `WITH_SSL=ON`. |
180191
| `CMAKE_INSTALL_PREFIX`| `<build>/install` | Install location. |
192+
| `IOTDB_EXTRA_CXX_FLAGS` | (empty) | Appended to `CMAKE_CXX_FLAGS` on Linux/macOS (libstdc++ ABI, etc.). Also applied to the Thrift sub-build. |
181193

182194
## Online build (default)
183195

@@ -345,35 +357,75 @@ as a separate install artifact.
345357

346358
## Using the C++ client
347359

360+
### Application code
361+
348362
```cpp
349363
#include "Session.h"
350-
#include <memory>
351-
#include <iostream>
352-
353-
int main() {
354-
auto session = std::make_shared<Session>("127.0.0.1", 6667, "root", "root");
355-
session->open(false);
356-
session->setStorageGroup("root.test01");
357-
if (!session->checkTimeseriesExists("root.test01.d0.s0")) {
358-
session->createTimeseries(
359-
"root.test01.d0.s0",
360-
TSDataType::INT64,
361-
TSEncoding::RLE,
362-
CompressionType::SNAPPY);
363-
}
364-
session->close();
365-
}
364+
#include <iostream>
365+
#include <memory>
366+
367+
int main() {
368+
auto session = std::make_shared<Session>("127.0.0.1", 6667, "root", "root");
369+
session->open(false);
370+
session->setStorageGroup("root.test01");
371+
if (!session->checkTimeseriesExists("root.test01.d0.s0")) {
372+
session->createTimeseries(
373+
"root.test01.d0.s0",
374+
TSDataType::INT64,
375+
TSEncoding::RLE,
376+
CompressionType::SNAPPY);
377+
}
378+
session->close();
379+
}
366380
```
367381

368-
Compile against the produced SDK:
382+
### Link against a pre-built zip (Linux)
383+
384+
1. Unzip `client-cpp-<version>-<classifier>.zip` and note `include/` and `lib/`.
385+
2. Pick the classifier that matches your machine (see table above).
386+
3. Compile with the **same libstdc++ ABI** as the zip:
369387

370388
```bash
371-
clang++ -O2 user-cpp-code.cpp \
372-
-I/path/to/sdk/include \
373-
-L/path/to/sdk/lib \
374-
-liotdb_session -lpthread \
375-
-Wl,-rpath,/path/to/sdk/lib \
376-
-std=c++11
389+
SDK=/path/to/client-cpp-2.0.7-SNAPSHOT-linux-x86_64-glibc224
390+
391+
# glibc224 zip (default g++ ABI on modern Linux):
392+
g++ -std=c++11 -O2 -o myapp myapp.cpp \
393+
-I"${SDK}/include" -L"${SDK}/lib" -liotdb_session -lpthread \
394+
-Wl,-rpath,"${SDK}/lib"
395+
396+
# glibc217 zip (legacy ABI — required):
397+
g++ -std=c++11 -O2 -o myapp myapp.cpp \
398+
-D_GLIBCXX_USE_CXX11_ABI=0 \
399+
-I"${SDK}/include" -L"${SDK}/lib" -liotdb_session -lpthread \
400+
-Wl,-rpath,"${SDK}/lib"
377401
```
378402

403+
If linking fails with `undefined reference to ... __cxx11::basic_string`, the zip
404+
ABI and your compiler flags do not match — switch zip (`glibc224` vs `glibc217`)
405+
or add/remove `-D_GLIBCXX_USE_CXX11_ABI=0`.
406+
407+
At runtime, ensure `libiotdb_session.so` is found (`LD_LIBRARY_PATH` or
408+
`-Wl,-rpath` as above). Thrift is **inside** the SDK shared library; you do not
409+
ship a separate `libthrift.so`.
410+
411+
### Link after a local Maven/CMake build
412+
413+
Install tree: `iotdb-client/client-cpp/target/install/{include,lib}`.
414+
415+
```bash
416+
g++ -std=c++11 -O2 -o myapp myapp.cpp \
417+
-Iiotdb-client/client-cpp/target/install/include \
418+
-Liotdb-client/client-cpp/target/install/lib \
419+
-liotdb_session -lpthread \
420+
-Wl,-rpath,"$PWD/iotdb-client/client-cpp/target/install/lib"
421+
```
422+
423+
Use the same `-D_GLIBCXX_USE_CXX11_ABI=...` flag you passed when building the SDK
424+
(`-Diotdb.extra.cxx.flags=...`).
425+
426+
### Examples
427+
428+
See [client-cpp-example](../../example/client-cpp-example/README.md) for CMake
429+
projects that consume an unpacked SDK (`-DIOTDB_SDK_ROOT=...`).
430+
379431
For full API documentation see the [C++ Native API guide](https://iotdb.apache.org/UserGuide/latest/API/Programming-Cpp-Native-API.html).

iotdb-client/client-cpp/cmake/FetchThrift.cmake

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,15 @@ if(MSVC)
122122
list(APPEND _thrift_cmake_args
123123
"-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDLL")
124124
else()
125+
set(_thrift_cxxflags "-fPIC")
126+
if(IOTDB_EXTRA_CXX_FLAGS MATCHES "_GLIBCXX_USE_CXX11_ABI=0")
127+
set(_thrift_cxxflags "-D_GLIBCXX_USE_CXX11_ABI=0 -fPIC")
128+
elseif(IOTDB_EXTRA_CXX_FLAGS MATCHES "_GLIBCXX_USE_CXX11_ABI=1")
129+
set(_thrift_cxxflags "-D_GLIBCXX_USE_CXX11_ABI=1 -fPIC")
130+
endif()
125131
list(APPEND _thrift_cmake_args
126132
"-DCMAKE_C_FLAGS=-fPIC"
127-
"-DCMAKE_CXX_FLAGS=-fPIC")
133+
"-DCMAKE_CXX_FLAGS=${_thrift_cxxflags}")
128134
endif()
129135

130136
if(WITH_SSL)

iotdb-client/client-cpp/pom.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555
<!-- Optional convenience: when a user still passes -Dboost.include.dir=...
5656
(legacy CLI from the old build), feed it to CMake as BOOST_INCLUDEDIR. -->
5757
<boost.include.dir></boost.include.dir>
58+
<!-- e.g. -D_GLIBCXX_USE_CXX11_ABI=0 for legacy Linux packages (see README). -->
59+
<iotdb.extra.cxx.flags></iotdb.extra.cxx.flags>
5860
<!-- Override via -Dclient.cpp.package.classifier=... for per-toolchain release zips. -->
5961
<client.cpp.package.classifier>${os.classifier}</client.cpp.package.classifier>
6062
</properties>
@@ -92,6 +94,7 @@
9294
<option>-DIOTDB_DEPS_DIR=${iotdb.deps.dir}</option>
9395
<option>-DBOOST_INCLUDEDIR=${boost.include.dir}</option>
9496
<option>-DCMAKE_POLICY_DEFAULT_CMP0091=NEW</option>
97+
<option>-DIOTDB_EXTRA_CXX_FLAGS=${iotdb.extra.cxx.flags}</option>
9598
</options>
9699
</configuration>
97100
</execution>

0 commit comments

Comments
 (0)