Skip to content

Commit

Permalink
[C++] Fix Windows build issues about static library (apache#10956)
Browse files Browse the repository at this point in the history
### Motivation

On Windows Platform, .lib files can be either **static libraries** or **import libraries**. For example, when we build an executable with dynamic linking, we need to link to `xxx.lib` during compilation and `xxx.dll` for running. The `xxx.lib` here is not the static library but the import library that is associated with the dynamic library.

Currently if C++ library is built on Windows using release mode, following files wil be generated under `<BUILD_DIR>\lib\Release`:
- pulsar.dll
- pulsar.lib

However, the associated import library (`pulsar.lib`) of `pulsar.dll` is overwritten by the static library because they share the same name. So we must set `-DBUILD_STATIC_LIB=OFF` option to disable building static libraries. However, it will fail on Windows:

```
CMake Error at lib/CMakeLists.txt:100 (target_include_directories):
  Cannot specify include directories for target "pulsarStatic" which is not
  built by this project.
```

### Modifications

- For MSVC compiler on Windows, use a different name for the static library to avoid overwriting the import library.
- Fix the CMake failure when `-DBUILD_STATIC_LIB=OFF` is configured.
- Add CI to build C++ client without static library on Windows.

After this change, if C++ library is built on Windows using release mode, following files wil be generated under `<BUILD_DIR>\lib\Release`:
- pulsar.dll: the dynamic library
- pulsar.lib: the import library associated with pulsar.dll
- pulsar-static.lib: the static library
  • Loading branch information
BewareMyPower authored Jun 18, 2021
1 parent cea2a5b commit b827f6e
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 9 deletions.
29 changes: 27 additions & 2 deletions .github/workflows/ci-cpp-build-windows.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ jobs:
run: |
cd pulsar-client-cpp && vcpkg install --triplet ${{ matrix.triplet }}
- name: Configure
- name: Configure (default)
if: ${{ steps.check_changes.outputs.docs_only != 'true' }}
shell: bash
run: |
Expand All @@ -95,4 +95,29 @@ jobs:
if [ "$RUNNER_OS" == "Windows" ]; then
cd pulsar-client-cpp && \
cmake --build ./build
fi
fi
- name: Configure (dynamic library only)
if: ${{ steps.check_changes.outputs.docs_only != 'true' }}
shell: bash
run: |
if [ "$RUNNER_OS" == "Windows" ]; then
cd pulsar-client-cpp && \
cmake \
-B ./build-1 \
-G "${{ matrix.generator }}" ${{ matrix.arch }} \
-DBUILD_PYTHON_WRAPPER=OFF -DBUILD_TESTS=OFF \
-DVCPKG_TRIPLET=${{ matrix.triplet }} \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_STATIC_LIB=OFF \
-S .
fi
- name: Compile
if: ${{ steps.check_changes.outputs.docs_only != 'true' }}
shell: bash
run: |
if [ "$RUNNER_OS" == "Windows" ]; then
cd pulsar-client-cpp && \
cmake --build ./build-1
fi
17 changes: 10 additions & 7 deletions pulsar-client-cpp/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ if (BUILD_DYNAMIC_LIB)
set_property(TARGET pulsarShared PROPERTY OUTPUT_NAME ${LIB_NAME_SHARED})
set_property(TARGET pulsarShared PROPERTY VERSION ${LIBRARY_VERSION})
target_link_libraries(pulsarShared ${COMMON_LIBS} ${CMAKE_DL_LIBS})
if (MSVC)
target_include_directories(pulsarShared PRIVATE ${dlfcn-win32_INCLUDE_DIRS})
target_link_options(pulsarShared PRIVATE $<$<CONFIG:DEBUG>:/NODEFAULTLIB:MSVCRT>)
endif()
endif()


Expand All @@ -87,17 +91,16 @@ endif()

if (BUILD_STATIC_LIB)
add_library(pulsarStatic STATIC $<TARGET_OBJECTS:PULSAR_OBJECT_LIB>)
set_property(TARGET pulsarStatic PROPERTY OUTPUT_NAME ${LIB_NAME})
if (MSVC)
set_property(TARGET pulsarStatic PROPERTY OUTPUT_NAME "${LIB_NAME}-static")
target_include_directories(pulsarStatic PRIVATE ${dlfcn-win32_INCLUDE_DIRS})
else ()
set_property(TARGET pulsarStatic PROPERTY OUTPUT_NAME ${LIB_NAME})
endif()
set_property(TARGET pulsarStatic PROPERTY VERSION ${LIBRARY_VERSION})
target_compile_definitions(pulsarStatic PRIVATE PULSAR_STATIC)
endif()

if (MSVC)
target_include_directories(pulsarStatic PRIVATE ${dlfcn-win32_INCLUDE_DIRS})
target_include_directories(pulsarShared PRIVATE ${dlfcn-win32_INCLUDE_DIRS})
target_link_options(pulsarShared PRIVATE $<$<CONFIG:DEBUG>:/NODEFAULTLIB:MSVCRT>)
endif()

# When linking statically, install a libpulsar.a that contains all the
# required dependencies except ssl
if (LINK_STATIC AND BUILD_STATIC_LIB)
Expand Down

0 comments on commit b827f6e

Please sign in to comment.