microsoft / vcpkg

C++ Library Manager for Windows, Linux, and MacOS
MIT License
23.41k stars 6.47k forks source link

Libraries which use expat should define XML_STATIC when using static linkage #1100

Closed brad-anderson closed 7 years ago

brad-anderson commented 7 years ago

Without this you'll get a bunch of LNK4217.

At the moment the ports that directly depend on expat are:

The proper modern CMake way to do this would be to have an import target that defines XML_STATIC using the INTERFACE_COMPILE_DEFINITIONS target property.

ras0219-msft commented 7 years ago

In order to support non-CMake buildsystems, we should also look at simply patching the installed expat headers with a #define XML_STATIC.

brad-anderson commented 7 years ago

Is there any particular way to apply a patch only for static builds. My first approach is this:

if(VCPKG_LIBRARY_LINKAGE STREQUAL dynamic)
    set(EXPAT_LINKAGE ON)
else()
    set(EXPAT_LINKAGE OFF)
    vcpkg_apply_patches(
        SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/expat-2.1.1
        PATCHES "${CMAKE_CURRENT_LIST_DIR}/use-xml-static-for-static-builds.patch"
    )
endif()

But it seems like that will be a problem because the buildtrees are shared between the different triplets.

ras0219-msft commented 7 years ago

You're totally right that conditional patching of the main sources is not a good idea.

The way we've accomplished this with other libraries is to actually patch the headers post build inside CURRENT_PACKAGES_DIR. This directory is cleaned and regenerated with every build, so there's no problem with conditional patches.

For example, in @codicodi's recent libuv PR [1], he did:

file(READ ${CURRENT_PACKAGES_DIR}/include/uv.h UV_H)
if(VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic")
    string(REPLACE "defined(USING_UV_SHARED)" "1" UV_H "${UV_H}")
else()
    string(REPLACE "defined(USING_UV_SHARED)" "0" UV_H "${UV_H}")
endif()
file(WRITE ${CURRENT_PACKAGES_DIR}/include/uv.h "${UV_H}")

[1] https://github.com/codicodi/vcpkg/blob/eacc0e9ffba598ad4f9f01d5eae6dc56f6c53763/ports/libuv/portfile.cmake#L20-L26