Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[vcpkg_fixup_pkgconfig] Handle spaces in path, do not validate individual libraries #13126

Merged
merged 42 commits into from Dec 8, 2020

Conversation

ras0219
Copy link
Contributor

@ras0219 ras0219 commented Aug 25, 2020

Because pkgconfig's recommended approach when using libraries outside pkgconfig is to add them to your .pc file, it is impossible to enumerate the set of external libraries on all possible systems. Therefore we cannot realistically expect libraries to resolve to those inside the current package or installed dir. We run pkgconfig --exists to ensure that the .pc file is able to be loaded in the current environment, but perform no validation of the underlying libraries.

In order for the output of pkg-config to correctly handle spaces in the path, all path-based flags in the .pc file must be quoted:

Libs: -L"${libdir}" -lz

As a drive by, this PR also adds an end-to-end test for zlib with spaces in path.

This may also fix other issues as well due to significant logical simplification.

@Neumann-A for review to ensure this still covers all the important cases -- For example, this currently leaves off handling of -pthread and instead ignores unrecognized arguments

@Hoikas
Copy link
Contributor

Hoikas commented Aug 25, 2020

The path used in #13105 is the appveyor standard path of C:\tools\vcpkg (no spaces). On testing, this PR unfortunately does not fix #13105:

Starting package 1/1: zlib:x86-windows-port-debug
Building package zlib[core]:x86-windows-port-debug...
Could not locate cached archive: C:\Users\appveyor\AppData\Local\vcpkg/archives\3f\3f2d86020d02f900828dce6c44b7411765b79d0c.zip
-- Downloading http://www.zlib.net/zlib-1.2.11.tar.gz...
-- Extracting source C:/tools/vcpkg/downloads/zlib1211.tar.gz
-- Applying patch cmake_dont_build_more_than_needed.patch
-- Applying patch 0001-Prevent-invalid-inclusions-when-HAVE_-is-set-to-0.patch
-- Applying patch add_debug_postfix_on_mingw.patch
-- Using source at C:/tools/vcpkg/buildtrees/zlib/src/1.2.11-63309e48e5.clean
-- Configuring x86-windows-port-debug
-- Building x86-windows-port-debug-dbg
-- Building x86-windows-port-debug-rel
-- Downloading https://repo.msys2.org/mingw/i686/mingw-w64-i686-pkg-config-0.29.2-1-any.pkg.tar.xz...
-- Downloading https://repo.msys2.org/mingw/i686/mingw-w64-i686-libwinpthread-git-8.0.0.5906.c9a21571-1-any.pkg.tar.zst...
-- [DEBUG] Using pkg-config from: C:/tools/vcpkg/downloads/tools/pkg-config/0.29.2-1/mingw32/bin/pkg-config.exe
-- [DEBUG] Release Files: C:/tools/vcpkg/packages/zlib_x86-windows-port-debug/lib/pkgconfig/zlib.pc
-- Fixing pkgconfig file: C:/tools/vcpkg/packages/zlib_x86-windows-port-debug/lib/pkgconfig/zlib.pc
-- [DEBUG] Checking package (RELEASE): zlib
-- [DEBUG] pkg-config returned:0
-- [DEBUG] pkg-config output:
-- [DEBUG] pkg-config error output:
-- [DEBUG] pkg-config returned:0
-- [DEBUG] pkg-config output:-LC:/tools/vcpkg/packages/zlib_x86-windows-port-debug/lib -lzlib
-- [DEBUG] pkg-config error output:
-- [DEBUG] pkg-config processing '-LC:/tools/vcpkg/packages/zlib_x86-windows-port-debug/lib'
-- [DEBUG] pkg-config processing '-lzlib'
-- [DEBUG] STATUS;CHECK_LIB_zlib_RELEASE=C:/Tools/vcpkg/packages/zlib_x86-windows-port-debug/lib/zlib.lib
-- [DEBUG] Debug Files: C:/tools/vcpkg/packages/zlib_x86-windows-port-debug/debug/lib/pkgconfig/zlib.pc
-- Fixing pkgconfig file: C:/tools/vcpkg/packages/zlib_x86-windows-port-debug/debug/lib/pkgconfig/zlib.pc
-- [DEBUG] Checking package (DEBUG): zlib
-- [DEBUG] pkg-config returned:0
-- [DEBUG] pkg-config output:
-- [DEBUG] pkg-config error output:
-- [DEBUG] pkg-config returned:0
-- [DEBUG] pkg-config output:-LC:/Tools/vcpkg/packages/zlib_x86-windows-port-debug/lib -lzlibd
-- [DEBUG] pkg-config error output:
-- [DEBUG] pkg-config processing '-LC:/Tools/vcpkg/packages/zlib_x86-windows-port-debug/lib'
-- [DEBUG] pkg-config processing '-lzlibd'
CMake Error at scripts/cmake/vcpkg_fixup_pkgconfig.cmake:128 (message):
  CHECK_LIB_zlibd_DEBUG=CHECK_LIB_zlibd_DEBUG-NOTFOUND
Call Stack (most recent call first):
  scripts/cmake/vcpkg_fixup_pkgconfig.cmake:224 (vcpkg_fixup_pkgconfig_check_files)
  ports/zlib/portfile.cmake:48 (vcpkg_fixup_pkgconfig)
  scripts/ports.cmake:79 (include)
Error: Building package zlib:x86-windows-port-debug failed with: BUILD_FAILED
Please ensure you're using the latest portfiles with `.\vcpkg update`, then
submit an issue at https://github.com/Microsoft/vcpkg/issues including:
  Package: zlib:x86-windows-port-debug
  Vcpkg version: 2020.06.15-nohash
Additionally, attach any relevant sections from the log files above.

Writing out package directory contents...
    Directory: C:\tools\vcpkg\packages\zlib_x86-windows-port-debug
Mode                LastWriteTime         Length Name                                                                                                                                                                                
----                -------------         ------ ----                                                                                                                                                                                
d-----        8/25/2020   5:18 AM                bin                                                                                                                                                                                 
d-----        8/25/2020   5:18 AM                debug                                                                                                                                                                               
d-----        8/25/2020   5:18 AM                include                                                                                                                                                                             
d-----        8/25/2020   5:18 AM                lib                                                                                                                                                                                 
d-----        8/25/2020   5:18 AM                share                                                                                                                                                                               
    Directory: C:\tools\vcpkg\packages\zlib_x86-windows-port-debug\bin
Mode                LastWriteTime         Length Name                                                                                                                                                                                
----                -------------         ------ ----                                                                                                                                                                                
-a----        8/25/2020   5:18 AM          73216 zlib1.dll                                                                                                                                                                           
    Directory: C:\tools\vcpkg\packages\zlib_x86-windows-port-debug\debug
Mode                LastWriteTime         Length Name                                                                                                                                                                                
----                -------------         ------ ----                                                                                                                                                                                
d-----        8/25/2020   5:18 AM                bin                                                                                                                                                                                 
d-----        8/25/2020   5:18 AM                lib                                                                                                                                                                                 
    Directory: C:\tools\vcpkg\packages\zlib_x86-windows-port-debug\debug\bin
Mode                LastWriteTime         Length Name                                                                                                                                                                                
----                -------------         ------ ----                                                                                                                                                                                
-a----        8/25/2020   5:18 AM         156160 zlibd1.dll                                                                                                                                                                          
    Directory: C:\tools\vcpkg\packages\zlib_x86-windows-port-debug\debug\lib
Mode                LastWriteTime         Length Name                                                                                                                                                                                
----                -------------         ------ ----                                                                                                                                                                                
d-----        8/25/2020   5:18 AM                pkgconfig                                                                                                                                                                           
-a----        8/25/2020   5:18 AM          16842 zlibd.lib                                                                                                                                                                           
    Directory: C:\tools\vcpkg\packages\zlib_x86-windows-port-debug\debug\lib\pkgconfig
Mode                LastWriteTime         Length Name                                                                                                                                                                                
----                -------------         ------ ----                                                                                                                                                                                
-a----        8/25/2020   5:18 AM            499 zlib.pc                                                                                                                                                                             
    Directory: C:\tools\vcpkg\packages\zlib_x86-windows-port-debug\include
Mode                LastWriteTime         Length Name                                                                                                                                                                                
----                -------------         ------ ----                                                                                                                                                                                
-a----        8/25/2020   5:18 AM          17151 zconf.h                                                                                                                                                                             
-a----        1/15/2017   5:29 PM          96239 zlib.h                                                                                                                                                                              
    Directory: C:\tools\vcpkg\packages\zlib_x86-windows-port-debug\lib
Mode                LastWriteTime         Length Name                                                                                                                                                                                
----                -------------         ------ ----                                                                                                                                                                                
d-----        8/25/2020   5:18 AM                pkgconfig                                                                                                                                                                           
-a----        8/25/2020   5:18 AM          16734 zlib.lib                                                                                                                                                                            
    Directory: C:\tools\vcpkg\packages\zlib_x86-windows-port-debug\lib\pkgconfig
Mode                LastWriteTime         Length Name                                                                                                                                                                                
----                -------------         ------ ----                                                                                                                                                                                
-a----        8/25/2020   5:18 AM            483 zlib.pc                                                                                                                                                                             
    Directory: C:\tools\vcpkg\packages\zlib_x86-windows-port-debug\share
Mode                LastWriteTime         Length Name                                                                                                                                                                                
----                -------------         ------ ----                                                                                                                                                                                
d-----        8/25/2020   5:18 AM                zlib                                                                                                                                                                                
    Directory: C:\tools\vcpkg\packages\zlib_x86-windows-port-debug\share\zlib
Mode                LastWriteTime         Length Name                                                                                                                                                                                
----                -------------         ------ ----                                                                                                                                                                                
-a----        8/25/2020   5:18 AM           1348 vcpkg_abi_info.txt   

@JackBoosY
Copy link
Contributor

cc @Neumann-A for review this PR.

@JackBoosY JackBoosY self-assigned this Aug 25, 2020
@JackBoosY JackBoosY added category:tool-update The issue is with build tool or build script, which requires update or should be executed correctly info:internal This PR or Issue was filed by the vcpkg team. labels Aug 25, 2020
@ras0219
Copy link
Contributor Author

ras0219 commented Aug 25, 2020

@Hoikas I've pushed an improvement for the error message as well as a sleep shim -- could you retry using
ce6564d?

@Hoikas
Copy link
Contributor

Hoikas commented Aug 25, 2020

Sadly the build continues to fail.

@JackBoosY JackBoosY linked an issue Aug 25, 2020 that may be closed by this pull request

set(BACKUP_ENV_PKG_CONFIG_PATH "$ENV{PKG_CONFIG_PATH}")
if(ENV{PKG_CONFIG_PATH})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(ENV{PKG_CONFIG_PATH})
if(DEFINED ENV{PKG_CONFIG_PATH})

checking for ENV variables requires DEFINED

endif()
endforeach()

set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_BACKUP})
set(ENV{PKG_CONFIG_PATH} "${BACKUP_ENV_PKG_CONFIG_PATH}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I always wonder if this is ok and undefines ENV{PKG_CONFIG_PATH} if "${BACKUP_ENV_PKG_CONFIG_PATH}" is empty or if it defines it to an empty string

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will define it to empty string, but I don't think undefined vs empty string is something that can be reasonably distinguished; enough programs consider them equivalent that it's unreasonable to require the user to use one or the other.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

undefined vs empty string is something that can be reasonably distinguished

it can and is. Empty string in path like variables typically mean ./ so the current working directory. I have seen issue with it in vcpkg_configure_make once which is why this whole ENV checking and setting/appending is required.

@Neumann-A
Copy link
Contributor

(Probably) Fixes #13105

nope since the error is not in the check but in the replacement before. Prefix was somehow not correctly replaced.

For example, this currently leaves off handling of -pthread and instead ignores unrecognized arguments

that is potentially dangerous since LFLAGS might contain gcc specific linker flags. (-Wl,something,someotherthing) It won't affect build with autotools but meson and cmake builds will most likely choke on it on Windows.

debug_message("${_libname} detected as an existing full path!")
continue() # fullpath in -l argument and exists; all ok
set(SEARCH_PATHS)
string(REGEX MATCHALL "([^ \t\\\\]+|\\\\.)+" LIBS_ARGS "${_pkg_libs_output}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

([^ \t\\\\]+|\\\\.)+
will probably fail with:
"mypath\ -Lotherpath\ -llib"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah you assume that the path separator is / ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The desired outcome of that regex is to parse all that as a single blob -- which is how it is intended to be parsed afaik:

  • mypath\ -Lotherpath\ -llib -> mypath\ -Lotherpath\ -llib
  • mypath\ -Lotherpath -llib -> mypath\ -Lotherpath;-llib
  • mypath -Lotherpath -llib -> mypath;-Lotherpath;-llib

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, in my local environment, pkg-config is emitting / for all path separators.

debug_message("pkg-config output:${_pkg_lib_paths_output}")
debug_message("pkg-config error output:${_pkg_error_out}")
if(VCPKG_TARGET_IS_WINDOWS)
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES .lib .dll.a .a)
Copy link
Contributor

@Neumann-A Neumann-A Aug 25, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still wondering if we should allow .dll.lib as a suffix since this is the default for autotools shared builds which get currently renamed. The only issue with that is that it must also be set in vcpkg.cmake

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My not-fully-informed position is that we should always rename them all to be just .lib / .dll when targeting Windows and not Mingw. However, I don't have all the facts to be completely sure of that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The naming probably originates from wanting to have static/shared libraries in the same directory. There is some story about it in meson including a discussion of the names of the generated pdbs which is why they name static libraries as lib<name>.a by default on windows.

Comment on lines 113 to 114
if(LIBS_ARG MATCHES "^-L(.*)")
list(APPEND SEARCH_PATHS "${CMAKE_MATCH_1}")
Copy link
Contributor

@Neumann-A Neumann-A Aug 25, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason I ask pkg-config for the search paths is to make sure pkg-config returns the correct string.

The problem currently is that if libdir contains spaces due to the prefix being on a path with spaces pkg-config is not returning the correct path.
One solution is to transform -L${libdir} to -L"${libdir}" in the steps before. the checks.

Copy link
Contributor Author

@ras0219 ras0219 Aug 25, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I'm seeing, pkg-config emits -LC:/src/vcpkg\ space/installed/x86-windows/lib when presented with spaces (C:\src\vcpkg space as the vcpkg root).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok that is different from what the msys pkg-config. The msys version was just returning -LC:/src/vcpkg in these cases. Can cmake correctly deal with the escaped spaces \ ? Otherwise you need to replace that with a non escaped version

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because CMake uses semicolons to delimit lists, I think it "correctly deals with escaped spaces" by sidestepping the issue entirely. Instead, it means the resulting items get the escaped forms verbatim, which is why this change manually evaluates them.

@ras0219
Copy link
Contributor Author

ras0219 commented Aug 26, 2020

that is potentially dangerous since LFLAGS might contain gcc specific linker flags. (-Wl,something,someotherthing) It won't affect build with autotools but meson and cmake builds will most likely choke on it on Windows.

My current thinking is that this is just acceptable tradeoffs, since we can't really intend to keep up with every compiler's command line arguments and pkg-config allows users to reasonably include compiler-specific flags.

@ras0219
Copy link
Contributor Author

ras0219 commented Aug 26, 2020

root@5178487134bb:/vcpkg# cat "/packaG es/zlib_x64-linux/lib/pkgconfig/zlib.pc"
prefix=${pcfiledir}/../..
exec_prefix=${prefix}
libdir=${prefix}/lib
sharedlibdir=${prefix}/lib
includedir=${prefix}/include

Name: zlib
Description: zlib compression library
Version: 1.2.11

Requires:
Libs: -L${libdir} -L${sharedlibdir} -lz
Cflags: -I${includedir}
root@5178487134bb:/vcpkg# PKG_CONFIG_PATH=/packaG\ es/zlib_x64-linux/lib/pkgconfig pkg-config --libs zlib
-L/packaG es/zlib_x64-linux/lib/pkgconfig/../../lib -lz
root@5178487134bb:/vcpkg# PKG_CONFIG_PATH=/packaG\ es/zlib_x64-linux/lib/pkgconfig pkg-config --libs-only-L zlib
-L/packaG
root@5178487134bb:/vcpkg# PKG_CONFIG_PATH=/packaG\ es/zlib_x64-linux/lib/pkgconfig pkg-config --libs-only-other zlib
es/zlib_x64-linux/lib/pkgconfig/../../lib

:( it looks like ${pcfiledir} here is sortof fundamentally broken for many libraries because it isn't escaped and they don't wrap their -L calls in quotes

@Neumann-A
Copy link
Contributor

Neumann-A commented Aug 26, 2020

@ras0219 Regex replace [[-I(${[^}]+})]] to [[-I"${\1}"]]and the same for the -L flags?

@Hoikas
Copy link
Contributor

Hoikas commented Aug 26, 2020

This fixes #13166.

@ras0219
Copy link
Contributor Author

ras0219 commented Aug 26, 2020

Regex replace [[-I(${[^}]+})]] to [[-I"${\1}"]]and the same for the -L flags?

Yeah, this appears to work:

        string(REGEX REPLACE " -L(\\\${[^}]*}[^ \n\t]*)" " -L\"\\1\"" _contents "${_contents}")
        string(REGEX REPLACE " -I(\\\${[^}]*}[^ \n\t]*)" " -I\"\\1\"" _contents "${_contents}")
        string(REGEX REPLACE " -l(\\\${[^}]*}[^ \n\t]*)" " -l\"\\1\"" _contents "${_contents}")

@ras0219
Copy link
Contributor Author

ras0219 commented Aug 26, 2020

Ok, so on Windows I believe there's a double-escaping bug that does the right thing if there aren't quotes, but if you actually quote things it causes pkg-config to spit out stuff like -LC:/vcpkg\\\ spaces/installed.

I can hack and hardcode things to unescape triple-slash correctly, but the real question is who's going to consume this? Meson? Autoconf in msys2? How do they handle this?

@BillyONeal
Copy link
Member

I just asked @JackBoosY if his concerns are still outstanding

@JackBoosY JackBoosY added the info:reviewed Pull Request changes follow basic guidelines label Dec 7, 2020
@JackBoosY
Copy link
Contributor

LGTM, @Neumann-A do you have other questions about this changes?

@Neumann-A
Copy link
Contributor

@JackBoosY No

@BillyONeal
Copy link
Member

Thanks for your help folks!

@BillyONeal BillyONeal merged commit dd44218 into microsoft:master Dec 8, 2020
@BillyONeal
Copy link
Member

Thanks again for your contribution Robert!

@ras0219
Copy link
Contributor Author

ras0219 commented Dec 8, 2020

TYVM for pushing it through :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category:tool-update The issue is with build tool or build script, which requires update or should be executed correctly info:internal This PR or Issue was filed by the vcpkg team. info:reviewed Pull Request changes follow basic guidelines
Projects
None yet
6 participants