Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

Issues with library selection when using ninja multiconfig generator (Linux/Windows) #18862

Closed
JasonDictos opened this issue Jul 8, 2021 · 4 comments
Assignees
Labels
category:question This issue is a question

Comments

@JasonDictos
Copy link

JasonDictos commented Jul 8, 2021

Describe the bug
MultiConfig generators with custom configurations do not honor what the documentation states.

In my scenario I have configured 3 configure types, Release, Debug, and DebugCoverage.

According to the docs this is supported:

https://vcpkg.readthedocs.io/en/latest/about/faq/

Can I get Vcpkg integration for custom configurations?
Yes. While Vcpkg will only produce the standard "Release" and "Debug" configurations when building a library, you can get integration support for your projects' custom configurations, in addition to your project's standard configurations.

First of all, Vcpkg will automatically assume any custom configuration starting with "Release" (resp. "Debug") as a configuration that is compatible with the standard "Release" (resp. "Debug") configuration and will act accordingly.

I've created a small sample project demonstrating the problem:
https://github.com/JasonDictos/ninja-multiconfig-vcpkg

When I try to build with my configuration type DebugCoverage, it links to the release libs and not the debug ones. On windows this causes the classic _ITERATOR_DEBUG_LEVEL mismatch error (in addition to the MTd/MT divergence).

On linux this mostly isn't a problem as if you link to a release library it will still link as linux does not have different runtimes or compilation flags like windows does.

Environment

  • OS: Ubuntu 20.4, windows 10 x64 (10.0.19043.1083)
  • Compiler: gcc-10, Visual Studio 2019 Preview 2

To Reproduce
Linux:

git clone https://github.com/JasonDictos/ninja-multiconfig-vcpkg
cd ninja-multiconfig-vcpkg
git submodule update --init --recursive
cmake -S . --preset x64-linux

Working example #1:

jason@home:~/ninja-multiconfig-vcpkg$ cmake --build --preset LinuxDebug
[1/2] /usr/bin/g++ -DCMAKE_INTDIR=\"Debug\" -isystem vcpkg_installed/x64-linux/include -g -std=gnu++2a -MD -MT CMakeFiles/example.dir/Debug/main.cpp.o -MF CMakeFiles/example.dir/Debug/main.cpp.o.d -o CMakeFiles/example.dir/Debug/main.cpp.o -c ../main.cpp
[2/2] : && /usr/bin/g++ -g  CMakeFiles/example.dir/Debug/main.cpp.o -o Debug/example  vcpkg_installed/x64-linux/debug/lib/libboost_random.a && :

Note it is linking to the debug library build of libbost_random.a

Problem #1:

jason@home:~/ninja-multiconfig-vcpkg$ cmake --build --preset LinuxRelease
[1/2] /usr/bin/g++ -DCMAKE_INTDIR=\"Release\" -isystem vcpkg_installed/x64-linux/include -O3 -DNDEBUG -std=gnu++2a -MD -MT CMakeFiles/example.dir/Release/main.cpp.o -MF CMakeFiles/example.dir/Release/main.cpp.o.d -o CMakeFiles/example.dir/Release/main.cpp.o -c ../main.cpp
[2/2] : && /usr/bin/g++ -O3 -DNDEBUG  CMakeFiles/example.dir/Release/main.cpp.o -o Release/example  vcpkg_installed/x64-linux/debug/lib/libboost_random.a && :
jason@home:~/ninja-multiconfig-vcpkg$ 

Note it is linking to the debug library build of libbost_random.a shouldn't it be linking to the release version??

Windows:

git clone https://github.com/JasonDictos/ninja-multiconfig-vcpkg
cd ninja-multiconfig-vcpkg
git submodule update --init --recursive
bootstrapenv.bat
cmake -S . --preset x64-windows-static

Working example #1

D:\ninja-multiconfig-vcpkg>cmake --build --preset WindowsRelease
[1/2] C:\PROGRA~2\MICROS~2\2019\Preview\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\cl.exe  /nologo /TP -DCMAKE_INTDIR=\"Release\" -Ivcpkg_installed\x64-windows-static\include /DNOMINMAX /bigobj /EHsc -MT -std:c++20 /showIncludes /FoCMakeFiles\example.dir\Release\main.cpp.obj /FdCMakeFiles\example.dir\Release\ /FS -c ..\main.cpp
[2/2] cmd.exe /C "cd . && "C:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe --intdir=CMakeFiles\example.dir\Release --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\mt.exe --manifests  -- C:\PROGRA~2\MICROS~2\2019\Preview\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\link.exe /nologo CMakeFiles\example.dir\Release\main.cpp.obj  /out:Release\example.exe /implib:Release\example.lib /pdb:Release\example.pdb /version:0.0 /subsystem:console  vcpkg_installed\x64-windows-static\lib\boost_random-vc140-mt.lib  kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cmd.exe /C "cd /D D:\ninja-multiconfig-vcpkg\build && C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noprofile -executionpolicy Bypass -file D:/ninja-multiconfig-vcpkg/vcpkg/scripts/buildsystems/msbuild/applocal.ps1 -targetBinary D:/ninja-multiconfig-vcpkg/build/Release/example.exe -installedDir D:/ninja-multiconfig-vcpkg/build/vcpkg_installed/x64-windows-static/bin -OutVariable out""

D:\ninja-multiconfig-vcpkg>

We can see here it is linking to the release library of libboost_random-vc140-mt.lib
(unlike linux which incorrectly linked to the debug version of the same library above).

Working example #2

D:\ninja-multiconfig-vcpkg>cmake --build --preset WindowsDebug
[1/2] C:\PROGRA~2\MICROS~2\2019\Preview\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\cl.exe  /nologo /TP -DCMAKE_INTDIR=\"Debug\" -Ivcpkg_installed\x64-windows-static\include /DNOMINMAX /bigobj /EHsc -MTd -std:c++20 /showIncludes /FoCMakeFiles\example.dir\Debug\main.cpp.obj /FdCMakeFiles\example.dir\Debug\ /FS -c ..\main.cpp
[2/2] cmd.exe /C "cd . && "C:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe --intdir=CMakeFiles\example.dir\Debug --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\mt.exe --manifests  -- C:\PROGRA~2\MICROS~2\2019\Preview\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\link.exe /nologo CMakeFiles\example.dir\Debug\main.cpp.obj  /out:Debug\example.exe /implib:Debug\example.lib /pdb:Debug\example.pdb /version:0.0 /subsystem:console  vcpkg_installed\x64-windows-static\debug\lib\boost_random-vc140-mt-gd.lib  kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cmd.exe /C "cd /D D:\ninja-multiconfig-vcpkg\build && C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noprofile -executionpolicy Bypass -file D:/ninja-multiconfig-vcpkg/vcpkg/scripts/buildsystems/msbuild/applocal.ps1 -targetBinary D:/ninja-multiconfig-vcpkg/build/Debug/example.exe -installedDir D:/ninja-multiconfig-vcpkg/build/vcpkg_installed/x64-windows-static/debug/bin -OutVariable out""

D:\ninja-multiconfig-vcpkg>

Here we can see it is properly linking to the debug library of libboost_random-vc140-mt-gd.lib
(Note Linux did not do this, it incorrectly linked to the debug version of the boost dependency)

Problem #1

D:\ninja-multiconfig-vcpkg>cmake --build --preset WindowsCoverage
[1/2] C:\PROGRA~2\MICROS~2\2019\Preview\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\cl.exe  /nologo /TP -DCMAKE_INTDIR=\"DebugCoverage\" -Ivcpkg_installed\x64-windows-static\include /DNOMINMAX /bigobj /EHsc -MTd -std:c++20 /showIncludes /FoCMakeFiles\example.dir\DebugCoverage\main.cpp.obj /FdCMakeFiles\example.dir\DebugCoverage\ /FS -c ..\main.cpp
[2/2] cmd.exe /C "cd . && "C:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe --intdir=CMakeFiles\example.dir\DebugCoverage --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\mt.exe --manifests  -- C:\PROGRA~2\MICROS~2\2019\Preview\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\link.exe /nologo CMakeFiles\example.dir\DebugCoverage\main.cpp.obj  /out:DebugCoverage\example.exe /implib:DebugCoverage\example.lib /pdb:DebugCoverage\example.pdb /version:0.0 /subsystem:console  vcpkg_installed\x64-windows-static\lib\boost_random-vc140-mt.lib  kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cmd.exe /C "cd /D D:\ninja-multiconfig-vcpkg\build && C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noprofile -executionpolicy Bypass -file D:/ninja-multiconfig-vcpkg/vcpkg/scripts/buildsystems/msbuild/applocal.ps1 -targetBinary D:/ninja-multiconfig-vcpkg/build/DebugCoverage/example.exe -installedDir D:/ninja-multiconfig-vcpkg/build/vcpkg_installed/x64-windows-static/bin -OutVariable out""
FAILED: DebugCoverage/example.exe
cmd.exe /C "cd . && "C:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe --intdir=CMakeFiles\example.dir\DebugCoverage --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\mt.exe --manifests  -- C:\PROGRA~2\MICROS~2\2019\Preview\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\link.exe /nologo CMakeFiles\example.dir\DebugCoverage\main.cpp.obj  /out:DebugCoverage\example.exe /implib:DebugCoverage\example.lib /pdb:DebugCoverage\example.pdb /version:0.0 /subsystem:console  vcpkg_installed\x64-windows-static\lib\boost_random-vc140-mt.lib  kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cmd.exe /C "cd /D D:\ninja-multiconfig-vcpkg\build && C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noprofile -executionpolicy Bypass -file D:/ninja-multiconfig-vcpkg/vcpkg/scripts/buildsystems/msbuild/applocal.ps1 -targetBinary D:/ninja-multiconfig-vcpkg/build/DebugCoverage/example.exe -installedDir D:/ninja-multiconfig-vcpkg/build/vcpkg_installed/x64-windows-static/bin -OutVariable out""
LINK: command "C:\PROGRA~2\MICROS~2\2019\Preview\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\link.exe /nologo CMakeFiles\example.dir\DebugCoverage\main.cpp.obj /out:DebugCoverage\example.exe /implib:DebugCoverage\example.lib /pdb:DebugCoverage\example.pdb /version:0.0 /subsystem:console vcpkg_installed\x64-windows-static\lib\boost_random-vc140-mt.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:DebugCoverage\example.exe.manifest" failed (exit code 1319) with the following output:
boost_random-vc140-mt.lib(random_device.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in main.cpp.obj
boost_random-vc140-mt.lib(random_device.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MT_StaticRelease' doesn't match value 'MTd_StaticDebug' in main.cpp.obj
LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library
DebugCoverage\example.exe : fatal error LNK1319: 2 mismatches detected
ninja: build stopped: subcommand failed.

D:\ninja-multiconfig-vcpkg>

And here is my main problem, although my configuration is called DebugCoverage, the find_package hooks built into the vcpkg cmake tooling select the release version of the boost dependency.

DebugCoverage is a build preset which selects the DebugCoverage configuration type here in the presets file:

        {
            "name": "WindowsCoverage",
            "configurePreset": "x64-windows-static",
            "configuration": "DebugCoverage",
            "verbose": true
        },

Configuration types are defined in the root buildConfig

 "configurePresets": [
        {
            "name": "default",
            "generator": "Ninja Multi-Config",
            "hidden": false,
            "binaryDir": "${sourceDir}/build/",
            "cacheVariables": {
                "CMAKE_EXPORT_COMPILE_COMMANDS": "On",
                "CMAKE_INSTALL_PREFIX": "${sourceDir}/installed",
                "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake",
                "CMAKE_CONFIGURATION_TYPES": "Debug;Release;DebugCoverage",
                "CMAKE_DEFAULT_BUILD_TYPE": "Debug"
            }
        },

Expected behavior
I expected Debug/Release to select the appropriate libraries

@JasonDictos
Copy link
Author

JasonDictos commented Jul 8, 2021

Upon further analysis I think this may be the source of the problem, in my CMakeCache.txt file this is set:

build/CMakeCache.txt:Boost_LIBRARY_DIR_RELEASE:PATH=/home/jason/ninja-multiconfig-vcpkg/build/vcpkg_installed/x64-linux/debug/lib

//Path to a file.
Boost_INCLUDE_DIR:PATH=/home/jason/ninja-multiconfig-vcpkg/build/vcpkg_installed/x64-linux/include

//Boost library directory DEBUG
Boost_LIBRARY_DIR_DEBUG:PATH=/home/jason/ninja-multiconfig-vcpkg/build/vcpkg_installed/x64-linux/debug/lib

//Boost library directory RELEASE
Boost_LIBRARY_DIR_RELEASE:PATH=/home/jason/ninja-multiconfig-vcpkg/build/vcpkg_installed/x64-linux/debug/lib

//Boost random library (debug)
Boost_RANDOM_LIBRARY_DEBUG:FILEPATH=/home/jason/ninja-multiconfig-vcpkg/build/vcpkg_installed/x64-linux/debug/lib/libboost_random.a

//Boost random library (release)
Boost_RANDOM_LIBRARY_RELEASE:FILEPATH=/home/jason/ninja-multiconfig-vcpkg/build/vcpkg_installed/x64-linux/debug/lib/libboost_random.a


@JasonDictos
Copy link
Author

JasonDictos commented Jul 8, 2021

Well after some digging I found a workaround:

set(CMAKE_MAP_IMPORTED_CONFIG_DEBUGCOVERAGE "DebugCoverage;Debug")
find_package(Boost REQUIRED COMPONENTS random)
unset(CMAKE_MAP_IMPORTED_CONFIG_DEBUGCOVERAGE

Seems to guide the library discovery properly for the Windows case with DebugCoverage anyhow (updated the example project).

Note linux is still incorrectly linking to the debug boost_random instead of release:

jason@home:~/ninja-multiconfig-vcpkg$ cmake --build --preset LinuxRelease
[1/2] /usr/bin/g++ -DCMAKE_INTDIR=\"Release\" -isystem vcpkg_installed/x64-linux/include -O3 -DNDEBUG -std=gnu++2a -MD -MT CMakeFiles/example.dir/Release/main.cpp.o -MF CMakeFiles/example.dir/Release/main.cpp.o.d -o CMakeFiles/example.dir/Release/main.cpp.o -c ../main.cpp
[2/2] : && /usr/bin/g++ -O3 -DNDEBUG  CMakeFiles/example.dir/Release/main.cpp.o -o Release/example  vcpkg_installed/x64-linux/debug/lib/libboost_random.a && :
jason@home:~/ninja-multiconfig-vcpkg$

Note I cannot leave that setting on globally, lotta errors with targets missing IMPORTED_LOCATION property or what not.

@JasonDictos
Copy link
Author

More reading, and this can now be set globally in the preset file:

			"CMAKE_MAP_IMPORTED_CONFIG_DEBUGCOVERAGE": ";DebugCoverage;Debug"

However, although everything now builds, cmake still things my target that I just build should reside in Debug, but it resides in DebugCoverage... But that's certainly better than it not compiling.

@JackBoosY
Copy link
Contributor

For configuration types, we currently only support Debug, Release and RelWithDbg three modes in cmake. In msbuild, we can specify the corresponding configuration type.

cc @vicroms

@JackBoosY JackBoosY added the category:question This issue is a question label Jul 8, 2021
@microsoft microsoft locked and limited conversation to collaborators Aug 3, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
category:question This issue is a question
Projects
None yet
Development

No branches or pull requests

4 participants