You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by mm...@apache.org on 2022/10/29 17:59:20 UTC
[pulsar-client-cpp] branch main updated: Support linking static dependencies when building with MSVC (#73)
This is an automated email from the ASF dual-hosted git repository.
mmerli pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/pulsar-client-cpp.git
The following commit(s) were added to refs/heads/main by this push:
new 93a44c8 Support linking static dependencies when building with MSVC (#73)
93a44c8 is described below
commit 93a44c856805e7f9b0b5ad342770c42495bd543d
Author: Yunze Xu <xy...@163.com>
AuthorDate: Sun Oct 30 01:59:15 2022 +0800
Support linking static dependencies when building with MSVC (#73)
* Support linking static dependencies when building with MSVC
### Motivation
Currently it's impossible to build Pulsar C++ client on Windows with
`LINK_STATIC=ON`. It means users have to package all 3rd-party DLLs as
well as `pulsar.dll`, which harms the experience.
### Modifications
Enable `LINK_STATIC` when the Vcpkg triplet is `xxx-static`. In this
case, find the 3rd party libraries with correct names on Windows. And
replace `Threads::Threads` with `CMAKE_THREAD_LIB_INIT`.
The most important change is replacing the `/MD` compile option with
`/MT`. It should have been done by setting the
[`MSVC_RUNTIME_LIBRARY`](https://cmake.org/cmake/help/latest/prop_tgt/MSVC_RUNTIME_LIBRARY.html)
property, but it seems not work. So this PR just modifies the
`CMAKE_CXX_FLAGS_<CONFIG>` variables.
For `pulsarWithAllDeps.lib`, add the actual library (`*.lib`) to
`COMMON_LIBS` instead of the target name (`dlfcn-win32::dl`).
Some warnings on Windows caused by incorrect compile options are fixed
as well.
A workflow is added to verify the static build for x64 and x86 Windows.
And a simple example is added as `win-examples` to show the
`pulsarWithAllDeps.lib` can be linked without any other dependency to
run an executable.
Change the existing release workflow to release two `*.zip` files:
- pulsar-client-cpp-x64-windows-static.zip
- pulsar-client-cpp-x86-windows-static.zip
Each zip file consists of:
```
bin/pulsar.dll - The dynamic library that links statically to dependencies
include/pulsar/ - Headers
lib/
pulsar.lib - The import library of pulsar.dll
pulsar-static.lib - The static library
pulsarWithDeps.lib - The static library with all dependnecies included
dependencies.txt - The vcpkg outputs, which contains the dependency versions
```
* Support Debug build and upload debug binaries
* Fix $ is missing
* Fix apt-get install failure
* Remove default LINK_STATIC build
* Use upload-artifact for Linux packages
---
.github/workflows/ci-build-binary-artifacts.yaml | 77 ++++++++++++-----------
.github/workflows/ci-pr-validation.yaml | 51 ++++++++++------
CMakeLists.txt | 78 +++++++++++++++++++-----
lib/CMakeLists.txt | 8 ++-
win-examples/CMakeLists.txt | 49 +++++++++++++++
win-examples/example.cc | 26 ++++++++
6 files changed, 219 insertions(+), 70 deletions(-)
diff --git a/.github/workflows/ci-build-binary-artifacts.yaml b/.github/workflows/ci-build-binary-artifacts.yaml
index f24dd7a..8e2a6ea 100644
--- a/.github/workflows/ci-build-binary-artifacts.yaml
+++ b/.github/workflows/ci-build-binary-artifacts.yaml
@@ -75,14 +75,11 @@ jobs:
- name: Zip artifact
run: zip -r ${{matrix.pkg.type}}-${{matrix.cpu.platform}}.zip ${{matrix.pkg.path}}
- - name: Upload binaries to release
- uses: svenstaro/upload-release-action@v2
+ - name: Upload artifacts
+ uses: actions/upload-artifact@v3
with:
- repo_token: ${{ secrets.GITHUB_TOKEN }}
- file: ${{matrix.pkg.type}}-${{matrix.cpu.platform}}.zip
- asset_name: ${{matrix.pkg.type}}-${{matrix.cpu.platform}}.zip
- tag: ${{ github.ref }}
- overwrite: true
+ name: ${{matrix.pkg.type}}-${{matrix.cpu.platform}}
+ path: ${{matrix.pkg.path}}
package-windows:
timeout-minutes: 120
@@ -90,21 +87,20 @@ jobs:
runs-on: ${{ matrix.os }}
env:
VCPKG_ROOT: '${{ github.workspace }}/vcpkg'
+ INSTALL_DIR: 'C:\\pulsar-cpp'
strategy:
fail-fast: false
matrix:
include:
- name: 'Windows x64'
os: windows-2022
- triplet: x64-windows
- vcpkg_dir: 'C:\vcpkg'
+ triplet: x64-windows-static
suffix: 'windows-win64'
generator: 'Visual Studio 17 2022'
arch: '-A x64'
- name: 'Windows x86'
os: windows-2022
- triplet: x86-windows
- vcpkg_dir: 'C:\vcpkg'
+ triplet: x86-windows-static
suffix: 'windows-win32'
generator: 'Visual Studio 17 2022'
arch: '-A Win32'
@@ -145,7 +141,7 @@ jobs:
run: |
${{ env.VCPKG_ROOT }}\vcpkg.exe install --triplet ${{ matrix.triplet }} > dependencies.txt
- - name: Configure and build
+ - name: Build and package
shell: bash
run: |
BUILD_DIR=./build
@@ -154,36 +150,45 @@ jobs:
-G "${{ matrix.generator }}" ${{ matrix.arch }} \
-DBUILD_TESTS=OFF \
-DVCPKG_TRIPLET=${{ matrix.triplet }} \
+ -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} \
-S .
cmake --build $BUILD_DIR --parallel --config Release
+ cmake --install $BUILD_DIR
+ cp dependencies.txt ${{ env.INSTALL_DIR }}
- - name: Package
+ - name: Zip artifact
+ shell: bash
+ run: 7z a -tzip pulsar-client-cpp-${{ matrix.triplet }}.zip ${{ env.INSTALL_DIR }}/*
+
+ - name: Upload artifacts
+ uses: actions/upload-artifact@v3
+ with:
+ name: ${{ matrix.triplet }}
+ path: ${{ env.INSTALL_DIR }}
+
+ - name: Build and package (Debug)
shell: bash
run: |
- BUILD_DIR=./build
- PACKAGE_DIR=./package
- LIB_DIR=$PACKAGE_DIR/lib/Release
- VCPKG_INSTALLED_DIR=$PACKAGE_DIR/vcpkg_installed
- mkdir -p $PACKAGE_DIR
- mkdir -p $LIB_DIR
- mkdir -p $VCPKG_INSTALLED_DIR/${{ matrix.triplet }}
-
- cp dependencies.txt $PACKAGE_DIR
- cp -r ./include $PACKAGE_DIR
- cp -r $BUILD_DIR/include/ $PACKAGE_DIR
- cp -r $BUILD_DIR/lib/Release/*.lib $LIB_DIR
- cp -r $BUILD_DIR/lib/Release/*.dll $LIB_DIR
- cp -r ./vcpkg_installed/${{ matrix.triplet }}/* $VCPKG_INSTALLED_DIR/${{ matrix.triplet }}
+ BUILD_DIR=./build-debug
+ INSTALL_DIR_DEBUG=${{ env.INSTALL_DIR }}-Debug
+ mkdir -p $BUILD_DIR
+ cmake -B $BUILD_DIR \
+ -G "${{ matrix.generator }}" ${{ matrix.arch }} \
+ -DBUILD_TESTS=OFF \
+ -DVCPKG_TRIPLET=${{ matrix.triplet }} \
+ -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR_DEBUG \
+ -DCMAKE_BUILD_TYPE=Debug \
+ -S .
+ cmake --build $BUILD_DIR --parallel --config Debug
+ cmake --install $BUILD_DIR --config Debug
+ cp dependencies.txt $INSTALL_DIR_DEBUG
- - name: Zip artifact
+ - name: Zip artifact (Debug)
shell: bash
- run: 7z a -tzip Windows-${{ matrix.triplet }}.zip ./package
+ run: 7z a -tzip pulsar-client-cpp-${{ matrix.triplet }}-Debug.zip ${{ env.INSTALL_DIR }}-Debug/*
- - name: Upload binaries to release
- uses: svenstaro/upload-release-action@v2
+ - name: Upload artifacts (Debug)
+ uses: actions/upload-artifact@v3
with:
- repo_token: ${{ secrets.GITHUB_TOKEN }}
- file: Windows-${{ matrix.triplet }}.zip
- asset_name: Windows-${{ matrix.triplet }}.zip
- tag: ${{ github.ref }}
- overwrite: true
+ name: ${{ matrix.triplet }}-Debug
+ path: ${{ env.INSTALL_DIR }}-Debug
diff --git a/.github/workflows/ci-pr-validation.yaml b/.github/workflows/ci-pr-validation.yaml
index 1607997..64a39d0 100644
--- a/.github/workflows/ci-pr-validation.yaml
+++ b/.github/workflows/ci-pr-validation.yaml
@@ -82,21 +82,20 @@ jobs:
runs-on: ${{ matrix.os }}
env:
VCPKG_ROOT: '${{ github.workspace }}/vcpkg'
+ INSTALL_DIR: 'C:\\pulsar-cpp'
strategy:
fail-fast: false
matrix:
include:
- name: 'Windows x64'
os: windows-2022
- triplet: x64-windows
- vcpkg_dir: 'C:\vcpkg'
+ triplet: x64-windows-static
suffix: 'windows-win64'
generator: 'Visual Studio 17 2022'
arch: '-A x64'
- name: 'Windows x86'
os: windows-2022
- triplet: x86-windows
- vcpkg_dir: 'C:\vcpkg'
+ triplet: x86-windows-static
suffix: 'windows-win32'
generator: 'Visual Studio 17 2022'
arch: '-A Win32'
@@ -137,44 +136,60 @@ jobs:
run: |
${{ env.VCPKG_ROOT }}\vcpkg.exe install --triplet ${{ matrix.triplet }}
- - name: Configure (default)
-
+ - name: Configure
shell: bash
run: |
if [ "$RUNNER_OS" == "Windows" ]; then
cmake \
- -B ./build-0 \
+ -B ./build-1 \
-G "${{ matrix.generator }}" ${{ matrix.arch }} \
-DBUILD_TESTS=OFF \
- -DVCPKG_TRIPLET=${{ matrix.triplet }} \
+ -DVCPKG_TRIPLET="${{ matrix.triplet }}" \
+ -DCMAKE_INSTALL_PREFIX="${{ env.INSTALL_DIR }}" \
-S .
fi
- - name: Compile
+ - name: Install
shell: bash
run: |
if [ "$RUNNER_OS" == "Windows" ]; then
- cmake --build ./build-0 --parallel --config Release
+ cmake --build ./build-1 --parallel --config Release
+ cmake --install ./build-1
fi
- - name: Configure (dynamic library only)
+ - name: Test examples
shell: bash
run: |
if [ "$RUNNER_OS" == "Windows" ]; then
+ cd win-examples
cmake \
- -B ./build-1 \
-G "${{ matrix.generator }}" ${{ matrix.arch }} \
- -DBUILD_TESTS=OFF \
- -DVCPKG_TRIPLET=${{ matrix.triplet }} \
- -DBUILD_STATIC_LIB=OFF \
- -S .
+ -DLINK_STATIC=OFF \
+ -DCMAKE_PREFIX_PATH=${{ env.INSTALL_DIR }} \
+ -B build-dynamic
+ cmake --build build-dynamic --config Release
+ cmake \
+ -G "${{ matrix.generator }}" ${{ matrix.arch }} \
+ -DLINK_STATIC=ON \
+ -DCMAKE_PREFIX_PATH=${{ env.INSTALL_DIR }} \
+ -B build-static
+ cmake --build build-static --config Release
+ ./build-static/Release/win-example.exe
fi
- - name: Compile
+ - name: Build (Debug)
shell: bash
run: |
if [ "$RUNNER_OS" == "Windows" ]; then
- cmake --build ./build-1 --parallel --config Release
+ cmake \
+ -B ./build-2 \
+ -G "${{ matrix.generator }}" ${{ matrix.arch }} \
+ -DBUILD_TESTS=OFF \
+ -DVCPKG_TRIPLET="${{ matrix.triplet }}" \
+ -DCMAKE_INSTALL_PREFIX="${{ env.INSTALL_DIR }}" \
+ -DCMAKE_BUILD_TYPE=Debug \
+ -S .
+ cmake --build ./build-2 --parallel --config Debug
fi
package:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6e4d7f5..28be829 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -33,6 +33,7 @@ message(STATUS "Pulsar Client version macro: ${PULSAR_CLIENT_VERSION_MACRO}")
set(PVM_COMMENT "This is generated from Version.h.in by CMAKE. DO NOT EDIT DIRECTLY")
configure_file(templates/Version.h.in include/pulsar/Version.h @ONLY)
+option(LINK_STATIC "Link against static libraries" OFF)
if (VCPKG_TRIPLET)
message(STATUS "Use vcpkg, triplet is ${VCPKG_TRIPLET}")
set(CMAKE_PREFIX_PATH "${CMAKE_SOURCE_DIR}/vcpkg_installed/${VCPKG_TRIPLET}")
@@ -43,8 +44,15 @@ if (VCPKG_TRIPLET)
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(ZLIB_ROOT ${VCPKG_DEBUG_ROOT})
set(OPENSSL_ROOT_DIR ${VCPKG_DEBUG_ROOT})
+ set(CMAKE_PREFIX_PATH ${VCPKG_DEBUG_ROOT} ${CMAKE_PREFIX_PATH})
+ endif ()
+ if (VCPKG_TRIPLET MATCHES ".*-static")
+ set(LINK_STATIC ON)
+ else ()
+ set(LINK_STATIC OFF)
endif ()
endif()
+MESSAGE(STATUS "LINK_STATIC: " ${LINK_STATIC})
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
@@ -69,9 +77,6 @@ MESSAGE(STATUS "BUILD_WIRESHARK: " ${BUILD_WIRESHARK})
option(BUILD_PERF_TOOLS "Build Pulsar CLI perf producer/consumer" OFF)
MESSAGE(STATUS "BUILD_PERF_TOOLS: " ${BUILD_PERF_TOOLS})
-option(LINK_STATIC "Link against static libraries" OFF)
-MESSAGE(STATUS "LINK_STATIC: " ${LINK_STATIC})
-
option(USE_LOG4CXX "Build with Log4cxx support" OFF)
MESSAGE(STATUS "USE_LOG4CXX: " ${USE_LOG4CXX})
@@ -93,7 +98,7 @@ set(CMAKE_C_STANDARD 11)
# https://stackoverflow.com/questions/10046114/in-cmake-how-can-i-test-if-the-compiler-is-clang
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
add_definitions(-DWIN32_LEAN_AND_MEAN -DNOGDI -D_WIN32_WINNT=0x0501 -D_CRT_SECURE_NO_WARNINGS)
- add_compile_options(/wd4244 /wd4267 /wd4018 /wd4715 /wd4251 /wd4275)
+ add_compile_options(/wd4244 /wd4267 /wd4018 /wd4715 /wd4251 /wd4275 /wd4819)
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
# ?? Don't have this to test with
else() # GCC or Clang are mostly compatible:
@@ -168,7 +173,7 @@ if (NOT ZLIB_INCLUDE_DIRS OR NOT ZLIB_LIBRARIES)
message(FATAL_ERROR "Could not find zlib")
endif ()
-if (LINK_STATIC)
+if (LINK_STATIC AND NOT VCPKG_TRIPLET)
find_library(LIB_ZSTD NAMES libzstd.a)
message(STATUS "ZStd: ${LIB_ZSTD}")
find_library(LIB_SNAPPY NAMES libsnappy.a)
@@ -195,6 +200,37 @@ if (LINK_STATIC)
if (MSVC)
add_definitions(-DCURL_STATICLIB)
endif()
+elseif (LINK_STATIC AND VCPKG_TRIPLET)
+ find_package(protobuf REQUIRED)
+ message(STATUS "Found protobuf static library: " ${Protobuf_LIBRARIES})
+ if (MSVC AND (${CMAKE_BUILD_TYPE} STREQUAL Debug))
+ find_library(ZLIB_LIBRARIES NAMES zlibd)
+ else ()
+ find_library(ZLIB_LIBRARIES NAMES zlib z)
+ endif ()
+ if (ZLIB_LIBRARIES)
+ message(STATUS "Found zlib static library: " ${ZLIB_LIBRARIES})
+ else ()
+ message(FATAL_ERROR "Failed to find zlib static library")
+ endif ()
+ if (MSVC AND (${CMAKE_BUILD_TYPE} STREQUAL Debug))
+ find_library(CURL_LIBRARIES NAMES libcurl-d)
+ else ()
+ find_library(CURL_LIBRARIES NAMES libcurl)
+ endif ()
+ if (CURL_LIBRARIES)
+ message(STATUS "Found libcurl: ${CURL_LIBRARIES}")
+ else ()
+ message(FATAL_ERROR "Cannot find libcurl")
+ endif ()
+ find_library(LIB_ZSTD zstd)
+ if (LIB_ZSTD)
+ message(STATUS "Found ZSTD library: ${LIB_ZSTD}")
+ endif ()
+ find_library(LIB_SNAPPY NAMES snappy)
+ if (LIB_SNAPPY)
+ message(STATUS "Found Snappy library: ${LIB_SNAPPY}")
+ endif ()
else()
if (MSVC AND (${CMAKE_BUILD_TYPE} STREQUAL Debug))
find_library(LIB_ZSTD zstdd HINTS "${VCPKG_DEBUG_ROOT}/lib")
@@ -211,7 +247,7 @@ else()
find_library(LOG4CXX_LIBRARY_PATH log4cxx)
find_path(LOG4CXX_INCLUDE_PATH log4cxx/logger.h)
endif (USE_LOG4CXX)
-endif (LINK_STATIC)
+endif ()
if (Boost_MAJOR_VERSION EQUAL 1 AND Boost_MINOR_VERSION LESS 69)
# Boost System does not require linking since 1.69
@@ -220,7 +256,7 @@ if (Boost_MAJOR_VERSION EQUAL 1 AND Boost_MINOR_VERSION LESS 69)
endif()
if (MSVC)
- set(BOOST_COMPONENTS ${BOOST_COMPONENTS} date_time)
+ set(BOOST_COMPONENTS ${BOOST_COMPONENTS} date_time)
endif()
if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
@@ -228,7 +264,7 @@ if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} regex)
set(CMAKE_CXX_FLAGS " -DPULSAR_USE_BOOST_REGEX")
MESSAGE(STATUS "Using Boost::Regex")
-else()
+elseif (CMAKE_COMPILER_IS_GNUCC)
MESSAGE(STATUS "Using std::regex")
# Turn on color error messages and show additional help with errors (only available in GCC v4.9+):
add_compile_options(-fdiagnostics-show-option -fdiagnostics-color)
@@ -295,7 +331,7 @@ include_directories(
set(COMMON_LIBS
${COMMON_LIBS}
- Threads::Threads
+ ${CMAKE_THREAD_LIBS_INIT}
${Boost_REGEX_LIBRARY}
${Boost_SYSTEM_LIBRARY}
${Boost_DATE_TIME_LIBRARY}
@@ -307,13 +343,25 @@ set(COMMON_LIBS
${CMAKE_DL_LIBS}
)
-if (NOT MSVC)
- set(COMMON_LIBS ${COMMON_LIBS} m)
-else()
+if (MSVC)
set(COMMON_LIBS
- ${COMMON_LIBS}
- wldap32.lib
- Normaliz.lib)
+ ${COMMON_LIBS}
+ ${Boost_DATE_TIME_LIBRARY}
+ wldap32.lib
+ Normaliz.lib)
+ if (LINK_STATIC)
+ # add external dependencies of libcurl
+ set(COMMON_LIBS ${COMMON_LIBS} ws2_32.lib crypt32.lib)
+ # the default compile options have /MD, which cannot be used to build DLLs that link static libraries
+ string(REGEX REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
+ string(REGEX REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
+ string(REGEX REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO})
+ message(STATUS "CMAKE_CXX_FLAGS_DEBUG: " ${CMAKE_CXX_FLAGS_DEBUG})
+ message(STATUS "CMAKE_CXX_FLAGS_RELEASE: " ${CMAKE_CXX_FLAGS_RELEASE})
+ message(STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO: " ${CMAKE_CXX_FLAGS_RELWITHDEBINFO})
+ endif ()
+else()
+ set(COMMON_LIBS ${COMMON_LIBS} m)
endif()
if (USE_LOG4CXX)
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index fb89a23..ae2c8ac 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -46,6 +46,12 @@ endif(NOT LIBRARY_VERSION)
if (MSVC)
find_package(dlfcn-win32 REQUIRED)
set(CMAKE_DL_LIBS dlfcn-win32::dl psapi.lib)
+ if (CMAKE_BUILD_TYPE STREQUAL "Debug")
+ get_target_property(dlfcn-win32_LIBRARY dlfcn-win32::dl IMPORTED_LOCATION_DEBUG)
+ else ()
+ get_target_property(dlfcn-win32_LIBRARY dlfcn-win32::dl IMPORTED_LOCATION_RELEASE)
+ endif ()
+ message(STATUS "dlfcn-win32_LIBRARY: " ${dlfcn-win32_LIBRARY})
endif(MSVC)
@@ -88,7 +94,7 @@ endif()
# required dependencies except ssl
if (LINK_STATIC AND BUILD_STATIC_LIB)
if (MSVC)
-
+ set(COMMON_LIBS ${COMMON_LIBS} ${dlfcn-win32_LIBRARY})
# This function is to remove either "debug" or "optimized" library names
# out of the COMMON_LIBS list and return the sanitized list of libraries
function(remove_libtype LIBLIST LIBTYPE OUTLIST)
diff --git a/win-examples/CMakeLists.txt b/win-examples/CMakeLists.txt
new file mode 100644
index 0000000..3998c43
--- /dev/null
+++ b/win-examples/CMakeLists.txt
@@ -0,0 +1,49 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+cmake_minimum_required(VERSION 3.4)
+project(pulsar-cpp-win-examples)
+
+find_path(PULSAR_INCLUDES NAMES "pulsar/Client.h")
+if (PULSAR_INCLUDES)
+ message(STATUS "PULSAR_INCLUDES: " ${PULSAR_INCLUDES})
+else ()
+ message(FATAL_ERROR "Failed to find PULSAR_INCLUDES")
+endif ()
+option(LINK_STATIC "Link statically to pulsar" ON)
+if (LINK_STATIC)
+ find_library(PULSAR_LIBRARIES NAMES "pulsarWithDeps")
+else ()
+ find_library(PULSAR_LIBRARIES NAMES "pulsar")
+endif ()
+if (PULSAR_LIBRARIES)
+ message(STATUS "PULSAR_LIBRARIES: " ${PULSAR_LIBRARIES})
+else ()
+ message(FATAL_ERROR "Failed to find PULSAR_LIBRARIES")
+endif ()
+
+if (LINK_STATIC)
+ string(REGEX REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
+ add_definitions(-DPULSAR_STATIC)
+endif ()
+message(STATUS "CMAKE_CXX_FLAGS_RELEASE: " ${CMAKE_CXX_FLAGS_RELEASE})
+
+add_executable(win-example "example.cc")
+include_directories(${PULSAR_INCLUDES})
+target_link_libraries(win-example PRIVATE ${PULSAR_LIBRARIES})
diff --git a/win-examples/example.cc b/win-examples/example.cc
new file mode 100644
index 0000000..ddab3d2
--- /dev/null
+++ b/win-examples/example.cc
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include <pulsar/Client.h>
+using namespace pulsar;
+
+int main() {
+ Client client("pulsar://localhost:6650");
+ client.close();
+ return 0;
+}