Skip to content

[WIP][vcpkg] vcpkg can link wrong libraries (issue #5540 b)#5543

Closed
Neumann-A wants to merge 132 commits intomicrosoft:masterfrom
Neumann-A:patch-2
Closed

[WIP][vcpkg] vcpkg can link wrong libraries (issue #5540 b)#5543
Neumann-A wants to merge 132 commits intomicrosoft:masterfrom
Neumann-A:patch-2

Conversation

@Neumann-A
Copy link
Contributor

@Neumann-A Neumann-A commented Mar 5, 2019

fixes #5540 b

Feel free to change. Is just an example how to solve part of the problem.

Overview
TODOs: #5543 (comment)
OLD FIND_PACKAGE PORTS: #5543 (comment)
AFFECTED PORTS: #5543 (comment) (not updated; too many)
CMAKE_DEBUG_SUFFIX LIST: #5543 (comment)

Some Numbers:
Number of packages which needed changed variables: around 60; (Thats somewhere around 6% of all packages)
Number of packages which consume those variables: around 120; (which is more than 10% of all packages)
Number of packages which actually fix the linkage issue in their target files: ???

Status
REMAINING ISSUES: all current regressions are errors on the package side logic to find a library and must be fixed.
CURRENT STATUS: closed due to wrong approach

@Rastaban Rastaban added category:vcpkg-bug The issue is with the vcpkg system (including helper scripts in `scripts/cmake/`) wip labels Mar 5, 2019
@Rastaban Rastaban changed the title WIP: Solve #5540 b [WIP][vcpkg] vcpkg can link wrong libraries (issue #5540 b) Mar 5, 2019
@cenit
Copy link
Contributor

cenit commented Mar 6, 2019

another path is working with every upstream package to export proper config file and getting in contact with Kitware to update many modules to find package and deal with release/debug libraries (which should have different names also...). I tried this path, it is very long, and very very slow. Some shortcuts would be extremely appreciated.

@Neumann-A
Copy link
Contributor Author

Neumann-A commented Mar 6, 2019

@cenit The problem is not only to update find_package and that libraries should export configs but also consuming libraries need to update their build scripts. I think that is something which will never 100% happen so vcpkg must support a shortcut.

the complete fix will probably look something like:

get_cmake_property(ALL_VARS VARIABLES)
list(FILTER ${ALL_VARS} INCLUDE REGEX "^[${name}|${uppercasename}|${lowercasename}][0-9]*_[INC|LIB]")
foreach(PACKAGE_VAR ${ALL_VARS})
 #fix the paths here
endforeach()
unset(ALL_VARS)

will implement it if i have the time.

@cenit
Copy link
Contributor

cenit commented Mar 6, 2019

@Neumann-A why do you say so? optimized;path_to_release_lib;debug;path_to_debug_lib works as expected and is filled inside <PackageName>_LIBRARY by the wonderful select_library_configurations(basename) function inside a proper Find<PackageName>.cmake... so if the downstream project just links to <PackageName>_LIBRARY everything works as expected and you have config support "for free".
Anyway, I fully support you when you say that this is a way-too-long road, which will never achieve 100% completion

@Neumann-A
Copy link
Contributor Author

hmm can somebody get the regex correctly to also include HDF5 and possible others?
https://cmake.org/cmake/help/v3.14/module/FindHDF5.html

something like:
"^[${name}|${uppercasename}|${lowercasename}][^INC|^LIB]_[INC|LIB]"

@cenit
Copy link
Contributor

cenit commented Mar 6, 2019

The procedure is to open a PR on https://gitlab.kitware.com/cmake/cmake
Unfortunately at the moment I am too busy on other tasks, otherwise I'd have helped you

@Neumann-A
Copy link
Contributor Author

Can somebody from the team supply me with all cmake config logs from CI after the last commit?
I would like to filter them for Value of to see which package variables are not properly set.

@Rastaban
Copy link
Contributor

@Neumann-A, the CI system does not keep around the logs from passing builds and the files edited are not part of the set that triggers a rebuild of ports so nothing was actually built as part of the CI test for the last commit. Supporting this kind of thing in the test system is on my backlog, but I am not sure when I will be able to make those changes. You can run the ci command on your own machine (vcpkg ci [triplet].) It takes about 14 hours to finish on our VMs but you would have all of the logs. If you don't want to tie up your machine for that long then let me know and I can run it on my own over the weekend.

@Neumann-A
Copy link
Contributor Author

Neumann-A commented Apr 8, 2019

DECIDED:

  • decide if <packagename>_LIBRARY|LIBRARIES should always contain keywords debug and optimized even if not required to build (could solve the problem of debug/release targets being overwritten) Yes -> Multi configuration generators require that to work correctly
  • decide if variables <packagename>_LIBRARY_RELEASE|DEBUG should be defined if CMake is not doing it (does not really matter since nobody will use those/depend on those since CMake does not define them.) No. Why should they be defined?
  • decide if MinSizeRelease and RelWithDebInfo should always be mapped to Release using CMAKE_MAP_IMPORTED_CONFIG_<config> if not set (issue vcpkg doesn't install CMake targets for RelWithDebInfo and MinSizeRel #5621) Yes because we should not suprise users

@Neumann-A
Copy link
Contributor Author

decide if _LIBRARY|LIBRARIES should always contain keywords debug and optimized even if not required to build (could solve the problem of debug/release targets being overwritten)

this is required because of multi configuration generators like visual studio. Linkage of libraries for debug/release may not be correct if the cmake files link directly to either debug or release library files instead of targets or using optimized/debug. (old find_package style)

@Neumann-A
Copy link
Contributor Author

note to #5625 (comment)
1 and 2 (fix at start): fixes the multi configuration generator issue of find_package
3 and 4 (fix at end): will not fix this issue

@Neumann-A
Copy link
Contributor Author

@cenit: This fixes your opencv issue ... .

Lets see what CI says to this one (probably needs to be triggered manually?)

@Neumann-A
Copy link
Contributor Author

Neumann-A commented Apr 8, 2019

TODOs:

  • Wait for CI regressions (if any)
  • Remove/Comment out cmake messages. Too helpful to comment out ....
  • Bump Control for all ports in ([WIP][vcpkg] vcpkg can link wrong libraries (issue #5540 b) #5543 (comment))
  • cleanup dependent portfiles with unnecessary string replacements for dependencies in target files.
    (Can be another issue/pr)
  • Understand CMake Warning: CMake Warning (dev) at G:/vcpkg_test/vcpkg/scripts/buildsystems/vcpkg.cmake:257 (if):
    Policy CMP0054 is not set: Only interpret if() arguments as variables or
    keywords when unquoted. Run "cmake --help-policy CMP0054" for policy
    details. Use the cmake_policy command to set the policy and suppress this
    warning.
  • add warning to vcpkg_fixup_cmake if debug and release *.cmake files do not have the same content! (Probably different PR/Issue)
  • fix/check _RELEASE and _DEBUG variables (Example: netcdf-c -> SZIP, CURL)
  • skip variable loop if _CONFIG is found and hope for the best....

@Neumann-A
Copy link
Contributor Author

Neumann-A commented Apr 9, 2019

List of ports linked wrongly (marked means fixed by this PR; List will be updated and extended when my CI runs or throws errors. Currently @ 958/958):

  • LIBLZMA
  • GIF
  • GIFLIB (same as GIF?)
  • SDL also had the d problem but fixed
  • OpenSSL
  • PostgreSQL (linkage only release, wrong due to extra d in debug)
  • PCRE (related to [poco] fix pcre linking against pcred on release #5994 only links pcred currently; probably poco portbug) PCRE itself installs pcre and pcred but only on windows. So this is a special kind of butterfly ....
  • EXPAT
  • LIBEVENT
  • OGG
  • DOUBLE-CONVERSION
  • LZ4 broken due to extra "d"
  • NETCDF
  • THEORA
  • JsonCpp
  • SQLite3
  • FLANN
  • QHULL
  • GLEW
  • FLAC
  • MINIZIP
  • URIPARSER
  • OPENAL
  • GLOG
  • LCMS2 extra d
  • CIVETWEB
  • VORBIS
  • Iconv
  • LAPACK (from issue)
  • OpenBLAS (from issue)
  • SNAPPY broken due to added d
  • CFITSIO
  • GMP
  • MPFR
  • OpenCL
  • FFTW (if targets are not used?!?!)
  • ZeroMQ (does exports targets; should probably delete the variable)
  • LIBCMS2
  • ARMADILLO
  • OCTOMAP extra d (exports targets; should probably delete the variable)
  • CCD extra d (exports targets; should probably delete the variable)
  • LIBZIP
  • LibUSB
  • TurboJPEG extra d (Probably no fix required; usage is against ${JPEG_LIBRARIES} [wondering if this is correct] )
  • GLFW3
  • PROJ4 (if LIBRARY_DIRS is used instead of targets)
  • PCAP
  • SHAPELIB
  • BROTLI
  • POPT due to extra d librsync does not find it; But there is no port for popt? So where is it comming from?
  • COINUTILS
  • CLP
  • LEMON
  • OSI
  • TBB has targets. Debug adds _debug (Should probably delete the set variables)
  • FFMPEG
  • APR
  • ODBC_LIBRARIES <- this one is kind of strange
  • LUA
  • GLUT
  • TinyXML
  • PHYSFS
  • ZSTD extra d
  • FreeImage extra d (Generator expression in ogre but not in forge)
  • PugiXML
  • FONTCONFIG
  • HTTP_PARSER
  • ZZip_LIBRARIES: (Generator expression in ogre. ogre is manually patching that should probably either remove the patch or also not change the variables if a generator expression is found)
  • LASZIP
  • LUA
  • ODE extra d; (This actual seems to be intended by the package itself.)

Possible Issue (needs checking):

  • VTK_(package_)RUNTIME_LIBRARY_DIRS [Probably not an issue and the correct behavior.]

Note the list contains only packages where ports have dependencies of these packages.
The list might be even longer for ports not yet included in vcpkg. (Would require a find_package call to all libraries build by vcpkg to discover all possible fixed variables.)
(The cmake messages really help to find those wrongly linked libraries)

@Neumann-A
Copy link
Contributor Author

Neumann-A commented Apr 9, 2019

@Rastaban: Can you create a list of ports which have indirect dependencies (meaning dependencies which dependent on the list in #5543 (comment); second level dependencies; don't know how to call those)? All those ports must be checked for correct linkage of its second level dependencies because the target file of the direct dependent might be wrong if the target is not manually fixed within the portfile.

Don't mind I can simply do that while updating the list above and look at the folder name where I find replacements.

@Neumann-A
Copy link
Contributor Author

Neumann-A commented Apr 9, 2019

porbably affected libraries
(incomplete list as of 740/958 (sdl ports dependencies not yet included due to cascade failure))

  • allegro 5
  • apr-util
  • aubio
  • avro-c
  • blaze
  • blosc
  • boost-iostream
  • caf
  • ccfits
  • ceres
  • cgal
  • clapack
  • clblas
  • clfft
  • collada-dom
  • cppfs
  • cpprestsdk
  • cppzmq
  • cutelyst2
  • devil
  • dlib
  • ensmallen
  • exiv2
  • fcl
  • fizz
  • fmi4cpp
  • folly
  • fontconfig
  • g2o
  • gdcm2
  • grpc
  • geogram
  • google-cloud-cpp
  • graphicsmagick
  • grpc
  • kd-soap
  • kf5plotting
  • leptonics
  • libarchive
  • libevent
  • libfreenect2
  • libgeotiff
  • libkml
  • libmysql
  • libodb-pgsql
  • libpng
  • libpq
  • libsndfile
  • libssh
  • libtheora
  • libtins
  • libwebp
  • libxml2
  • mlpack
  • opencv
  • pcl
  • plplot
  • poco
  • podofo
  • promotheus-cpp
  • sfml
  • signalrclient
  • sophus
  • suiteparse
  • tesseract
  • thrift
  • tiff
  • vtk
  • wavepack
  • yara

This list must be checked if any of those export dependencies to any of the ports in the list #5543 (comment)

@seanwarren
Copy link
Contributor

@Neumann-A, I've tested this on quite a large project and it seems to do a pretty good job. I'm seeing two issues:

Building with x64-windows-static using visual studio I'm seeing two regressions.

qt5
In the link line for the debug configuration I have:
${VCPKG_ROOT}\installed\x64-windows-static\plugins\platforms\qwindows.lib
where it should be:
${VCPKG_ROOT}\installed\x64-windows-static\debug\plugins\platforms\qwindows.lib

libpq
In the link line for the debug configuration I have:
C:\Users\CIMLab\Documents\vcpkg-pristine\installed\x64-windows-static\debug\lib\libpq.lib
where it should be
C:\Users\CIMLab\Documents\vcpkg-pristine\installed\x64-windows-static\debug\lib\libpqd.lib

@Neumann-A
Copy link
Contributor Author

@seanwarren: Can you attach the CMake configurations logs (config-triplet-(detailed-stuff).out.log) for those failing projects? There should be lines reading Replacing: <Something> \n with: <Someotherthing>

Neumann-A and others added 17 commits May 29, 2019 12:04
# Conflicts:
#	ports/libgeotiff/portfile.cmake
#	ports/pdal/portfile.cmake
# Conflicts:
#	ports/ceres/CONTROL
#	ports/ceres/portfile.cmake
#	ports/gdal/portfile.cmake
…version.

names position is sometimes not the second one.
in these cases additional unused arguments are passe to find_library.
Due to that the NAMES position is variable and must be found.
# Conflicts:
#	ports/glib/CONTROL
#	ports/libraw/CONTROL
#	scripts/buildsystems/vcpkg.cmake
# Conflicts:
#	ports/fizz/CONTROL
#	ports/folly/CONTROL
#	ports/libmysql/CONTROL
#	ports/zstd/CONTROL
@Neumann-A
Copy link
Contributor Author

documenting another approach:

  • do not fix find_library -> fix target_link_libraries instead
  • requires correct imported targets defined in findModule.cmake (will require set_property fix from this PR)

@Fleischner
Copy link

pybind11 installed cmake targets look suspicious. There seems to be a quite complicated machinery that searches for an python.exe and once found it searches for the python libraries relative to this python.exe.

However vcpkg port python3 currently only builds python.dlls. So pybind11 will certainly find completely wrong .lib files in this case.
Also it seems debug libraries are not handled.

It should just use the python libraries of the python3 port instead

@angelmixu
Copy link
Contributor

Hi @Neumann-A ! Thanks for all the work!
What happened with this PR? Has it been merged, or are you working on a different approach?

@Neumann-A
Copy link
Contributor Author

@angelmixu.
It requires a different approach. It is not possibly to simply inject the variable returned by find_library with a generator expression because of:
Antipattern: if(EXISTS LIBRARY_VAR) after a find_library call
Usage of CMAKE_REQUIRED_LIBRARIES for CheckFunctionExists not working with generator expressions and small other minor blockers.

So an alternativ approach is necessary with the following attributes:

fix find_library calls with variables:
LIBRARY_VAR -> point to release
LIBRARY_VAR_RELEASE -> point to release
LIBRARY_VAR_DEBUG ->point to debug
generate VCPKG_LIB_NAMES_libname_VAR with VCPKGPATH/.lib and set it to names used in the find_library call. (is properly not required but it is good to have the search names stored somewhere)
generate VCPKG_LIB_GENEXP_libname_VAR generator expression with the correct paths to release/debug

fix set_property on targets and target_set_properties:
IMPORTED_LOCATION -> Generate IMPORTED_LOCATION_RELEASE and IMPORTED_LOCATION_DEBUG (properly requires the searchnames to do an extra find_library call in release or debug folder)
IMPORTED_LOCATION_RELEASE -> check if release path
IMPORTED_LOCATION_DEBUG -> check if debug path

fix target_link_libraries and link_libraries:
Check every library which is linked having the vcpkg base path and replace it with VCPKG_LIB_GENEXP_libname_VAR if necessary (e.g. if debug/optimized keywords are not used)

So I have a plan but no time to do it currently

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

category:vcpkg-bug The issue is with the vcpkg system (including helper scripts in `scripts/cmake/`)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

vcpkg (silently) links wrong libraries

9 participants