thelfer/tfel

[mfront] Visual Studio 2022 compiler intrinsic type traits error C2139

Closed this issue · 7 comments

Hey @thelfer,

I just started working on adding windows support for the mfront conda-forge package. After reading through #95 it seems there isn't a working solution yet for VS2019 or VS2022? If that is still the case I would be willing to spend some time on this in order to help support VS2019/2022.

What I have tried to compile so far is mfront v4.1.0 using Visual Studio 2022 (I will try to compile with VS2019 later to compare).

The error i am seeing is this:

C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.39.33519\include\type_traits(994): error C2139: 'tfel::tests::TestResult': an undefined class is not allowed as an argument to compiler intrinsic type trait '__is_nothrow_assignable'

Here is the CMakePresets.json contents describing the "Win Debug" build I am compiling using CLION:

{
  "version": 6,
  "include": [
    ".env.json"
  ],
  "configurePresets": [
    {
      "name": "shared",
      "hidden": true,
      "inherits": [
        "env-vars"
      ],
      "environment": {
        "PREFIX": "$env{MFRONT_PREFIX}"
      },
      "warnings": {
        "dev": false
      },
      "cacheVariables": {
        "CMAKE_VERBOSE_MAKEFILE": "ON"
      }
    },
    {
      "name": "Win debug",
      "generator": "Ninja",
      "inherits": [
        "shared"
      ],
      "hidden": false,
      "environment": {
        "LIBRARY_PREFIX": "$env{PREFIX}/Library"
      },
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Release",
        "enable-fortran": "OFF",
        "enable-python": "ON",
        "enable-python-bindings": "ON",
        "enable-cyrano": "ON",
        "local-castem-header": "OFF",
        "enable-aster": "ON",
        "enable-testing": "OFF",
        "enable-portable-build": "ON",
        "BUILD_SHARED_LIBS": "ON",
        "Python_ADDITIONAL_VERSIONS": "$env{CONDA_PY}",
        "PYTHON_INCLUDE_DIRS": "$env{LIBRARY_PREFIX}/include",
        "PYTHON_LIBRARY": "$env{PREFIX}/libs/python312.lib",
        "USE_EXTERNAL_COMPILER_FLAGS": "ON",
        "CMAKE_FIND_ROOT_PATH": "$env{PREFIX};$env{LIBRARY_PREFIX}",
        "CMAKE_PROGRAM_PATH": "$env{LIBRARY_PREFIX}/bin;$env{PREFIX}/Scripts",
        "CMAKE_PREFIX_PATH": "$env{PREFIX};$env{LIBRARY_PREFIX};$env{LIBRARY_PREFIX}/include;$env{LIBRARY_PREFIX}/lib;$env{LIBRARY_PREFIX}/bin"
      }
    }
  ]
}

The .env.json just contains the location of the conda environment that contains the dependencies such as python, boost, numpy. For completeness, here is the complete dependency list from the conda env:

(mfront-deps) C:\work\code\admin\codeaster\mfront>mamba list
# packages in environment at C:\work\miniforge3\envs\mfront-deps:
#
# Name                    Version                   Build  Channel
boost                     1.84.0               hd42ba9a_1    conda-forge
bzip2                     1.0.8                hcfcfb64_5    conda-forge
ca-certificates           2024.2.2             h56e8100_0    conda-forge
cmake                     3.28.3               hf0feee3_0    conda-forge
intel-openmp              2024.0.0         h57928b3_49841    conda-forge
krb5                      1.21.2               heb0366b_0    conda-forge
libblas                   3.9.0              21_win64_mkl    conda-forge
libboost                  1.84.0               hcc118f5_1    conda-forge
libboost-devel            1.84.0               h91493d7_1    conda-forge
libboost-headers          1.84.0               h57928b3_1    conda-forge
libboost-python           1.84.0          py312h4f1204c_1    conda-forge
libboost-python-devel     1.84.0          py312hd42ba9a_1    conda-forge
libcblas                  3.9.0              21_win64_mkl    conda-forge
libcurl                   8.5.0                hd5e4a3a_0    conda-forge
libexpat                  2.6.2                h63175ca_0    conda-forge
libffi                    3.4.2                h8ffe710_5    conda-forge
libhwloc                  2.9.3           default_haede6df_1009    conda-forge
libiconv                  1.17                 hcfcfb64_2    conda-forge
liblapack                 3.9.0              21_win64_mkl    conda-forge
libsqlite                 3.45.2               hcfcfb64_0    conda-forge
libssh2                   1.11.0               h7dfc565_0    conda-forge
libuv                     1.48.0               hcfcfb64_0    conda-forge
libxml2                   2.12.5               hc3477c8_0    conda-forge
libzlib                   1.2.13               hcfcfb64_5    conda-forge
m2w64-gcc-libgfortran     5.3.0                         6    conda-forge
m2w64-gcc-libs            5.3.0                         7    conda-forge
m2w64-gcc-libs-core       5.3.0                         7    conda-forge
m2w64-gmp                 6.1.0                         2    conda-forge
m2w64-libwinpthread-git   5.0.0.4634.697f757               2    conda-forge
make                      4.3                  h3d2af85_1    conda-forge
mkl                       2024.0.0         h66d3029_49657    conda-forge
msys2-conda-epoch         20160418                      1    conda-forge
ninja                     1.11.1               h91493d7_0    conda-forge
numpy                     1.26.4          py312h8753938_0    conda-forge
openssl                   3.2.1                hcfcfb64_0    conda-forge
pip                       24.0               pyhd8ed1ab_0    conda-forge
pthreads-win32            2.9.1                hfa6e2cd_3    conda-forge
python                    3.12.0          h2628c8c_0_cpython    conda-forge
python_abi                3.12                    4_cp312    conda-forge
setuptools                69.2.0             pyhd8ed1ab_0    conda-forge
tbb                       2021.11.0            h91493d7_1    conda-forge
tk                        8.6.13               h5226925_1    conda-forge
tzdata                    2024a                h0c530f3_0    conda-forge
ucrt                      10.0.22621.0         h57928b3_0    conda-forge
vc                        14.3                hcf57466_18    conda-forge
vc14_runtime              14.38.33130         h82b7239_18    conda-forge
vs2015_runtime            14.38.33130         hcb4865c_18    conda-forge
vswhere                   3.1.4                h57928b3_0    conda-forge
wheel                     0.42.0             pyhd8ed1ab_0    conda-forge
xz                        5.2.6                h8d14728_0    conda-forge
zlib                      1.2.13               hcfcfb64_5    conda-forge
zstd                      1.5.5                h12be248_0    conda-forge

I also tried to compile mfront v4.2.0 using the same compiler and approximately the same compiler options and dependencies, and I got a different error:

C:\work\code\tfel\include\TFEL/Math/Array/GenericFixedSizeArray.ixx(200): error C2244: 'tfel::math::GenericFixedSizeArray<Child,ArrayPolicy,N>::operator *=': unable to match function definition to an existing declaration

While I continue reading and poking around with the errors I am seeing, any hints on how I might proceed would be most welcome!

Best Regards
Kristoffer

@Krande Thank you very much for this kind proposal. For the moment, Visual Studio support (15 and 17) is limited to version 3.x of TFEL (including TFEL-3.4.x). Packaging those versions seems a easy step, although not very satisfying.

I honestly gave up Visual Studio support for Version 4 of TFEL when I rewritten the TFEL/Math library in C++-17. I planned to give it a try for Version 5.0 which will be based on C++-20. For the moment windows support is "limited" to intel clang and mingw compilers :)

The main reason was that this compiler have the kind of error you mentionned (i.e. for him, the declaration of some methods don't match the implementation). It's scary...

But don't hesitate to give a try, that would really help. Do not hesitate to make a for of the rliv-4.2 branch.

@thelfer Thank you for replying so quickly!

Okay, I'll give it a shot :)

Just a quick question. How does rliv-4.2 compare with the master branch? Is rliv-4.2 what is to become v5?

I hope it's okay that I document the steps I take (even though they might be extremely dumb as I yet have a lot to learn about c++) and add some questions here and there wherever I poke around and try to naively fix the errors my compiler is seeing :)

So far I've worked my way through the following errors thrown by the VS2022 compiler when trying to compiler mfront v4.1.0.

TestResult.hxx

C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.39.33519\include\type_traits(994): error C2139: 'tfel::tests::TestResult': an undefined class is not allowed as an argument to compiler intrinsic type trait '__is_nothrow_assignable'

To get past this issue I simply removed the files from the compilation by wrapping the Tests subdirectory inclusion in a "enable-testing" conditional (assuming this is only needed for testing).

# src/CMakeLists.txt

...
if (enable-testing)
    add_subdirectory(Tests)
endif()

GenTypeBase.hxx and std::monospace()

C:\work\code\tfel\include\TFEL/Utilities/GenTypeBase.hxx(198): error C2665: 'tfel::utilities::GenTypeBase<tfel::utilities::DataTypes>::operator =': no overloaded function could convert all the argument types

GenTypeBase.hxx:198:

TFEL_INLINE void clear() { this->operator=(std::monostate()); }

So this seems to be caused by passing in std::monostate()

I couldn't find where the "clear()" method was used anywhere else in the code, so I just removed the method.

GenTypeSpecialisation.ixx

Here is where I am at now. It seems like MSVC has issues with the TFEL_UTILITIES_GENTYPESPECIALIZEDACCESSOR

C:\work\code\tfel\include\TFEL/Utilities/GenTypeSpecialisation.ixx(52): error C2664: 'void tfel::utilities::GenTypeBase<tfel::utilities::DataTypes>::set<bool>(T1 &&)': cannot convert argument 1 from 'const bool' to 'T1 &&'

Hi again, @thelfer.

I thought I might explore some alternatives to Visual Studio c compilers for the conda-forge packaging.

Do you think it might be easier to add support of llvm clang (which is also available as conda-forge compiler package)?

I just tried llvm clang v18.1.1 from https://github.com/llvm/llvm-project (conda-forge clang package) and I managed to compile a bit more of mfront v4.1.0 compared with VS2022 before running into the following error:

C:\work\miniforge3\envs\mfront-deps\Library\bin\clang++.exe -DASTER_ARCH=64 -DCYRANO_ARCH=64 -DHAVE_ASTER=1 -DHAVE_CYRANO=1 -DHAVE_FENV -DHAVE_PYTHON=1 -DTFELUtilities_EXPORTS -DTFEL_ARCH64 -DTFEL_PYTHON_BINDINGS -DWIN64 -IC:/work/code/tfel/include -O3 -DNDEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrt -std=gnu++17   -DVERSION=\""4.1.0"\" -DTFEL_SVN_REVISION=\"""\" -DTFEL_CMAKE_GENERATOR=\""Ninja"\" -DOPTIMISATION_FLAGS0=\""-fvisibility-inlines-hidden -fvisibility=hidden  -O2 -DNDEBUG -DTFEL_NO_RUNTIME_CHECK_BOUNDS "\" -DOPTIMISATION_FLAGS=\""-march=native "\" -DOPTIMISATION_FLAGS2=\""-ffast-math "\" -DCOMPILER_WARNINGS=\""-Wno-unused-macros -Wno-weak-vtables -Wno-missing-declarations -Wno-sign-compare -Wno-covered-switch-default -Wno-covered-switch-default -Wno-switch-enum -Wsuggest-override -Wint-in-bool-context -Wregister -Wmisleading-indentation -Wnull-dereference -Wtautological-compare -Wshift-overflow -Wshift-negative-value -Wsizeof-array-argument -Wlogical-not-parentheses -Wswitch-bool -Wsequence-point -Wignored-qualifiers -Wold-style-cast -Wmissing-include-dirs -Winit-self -Wdouble-promotion -Wno-conversion -Wreorder -Wundef -Wunknown-pragmas -Wredundant-decls -Wpacked -Wno-deprecated-declarations -Wno-multichar -Wmissing-format-attribute -Wno-endif-labels -Wfloat-equal -Wreturn-type -Woverloaded-virtual -Wnon-virtual-dtor -Wctor-dtor-privacy -Wwrite-strings -Wcast-align -Wcast-qual -Wpointer-arith -Wshadow -W -Wall -Wno-c++98-compat -Wno-inconsistent-missing-destructor-override -Wmicrosoft -Wcomma -Wno-missing-variable-declarations -Winfinite-recursion -Wmove -Wrange-loop-analysis -Wno-missing-braces -Wno-global-constructors -Wno-exit-time-destructors -Wno-documentation-unknown-command -Wno-documentation -Wno-padded -Wno-c++98-compat-pedantic -Weverything "\" -DCOMPILER_FLAGS=\"""\" -DCOMPILER_CXXFLAGS=\"" -DTFEL_HAVE_NORETURN_ATTRIBUTE"\" -DCASTEM_CPPFLAGS=\""-DWIN64"\" -DTFEL_PYTHON_INCLUDES=\""-IC:/work/miniforge3/envs/mfront-deps/include"\" -DTFEL_PYTHON_LIBRARY_PATH=\""C:/work/miniforge3/envs/mfront-deps/libs"\" -DTFEL_PYTHON_LIBRARY=\""python312.lib"\" -DTFEL_PYTHON_LIBS=\""-LC:/work/miniforge3/envs/mfront-deps/libs -lpython312.lib"\" -MD -MT src/Utilities/CMakeFiles/TFELUtilities.dir/Data.obj -MF src\Utilities\CMakeFiles\TFELUtilities.dir\Data.obj.d -o src/Utilities/CMakeFiles/TFELUtilities.dir/Data.obj -c C:/work/code/tfel/src/Utilities/Data.cxx
In file included from C:/work/code/tfel/src/Utilities/Data.cxx:19:
In file included from C:/work/code/tfel/include\TFEL/Utilities/Data.hxx:24:
In file included from C:/work/code/tfel/include\TFEL/Utilities/GenTypeBase.hxx:370:
C:/work/code/tfel/include\TFEL/Utilities/GenTypeSpecialisation.ixx:85:43: error: no matching member function for call to 'set'
   85 |       static_cast<Child*>(this)->template set<std::string>(src);
      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
C:\work\code\tfel\include\TFEL/Utilities/GenTypeSpecialisation.ixx(69,10): note: in instantiation of member function 'tfel::utilities::internals::GenTypeSpecializedAccessor<tfel::utilities::GenTypeBase<tfel::meta::TLNode<bool, tfel::meta::TLNode<int, tfel::meta::TLNode<double, tfel::meta::TLNode<std::basic_string<char>, tfel::meta::TLNode<std::vector<tfel::utilities::Data>, tfel::meta::TLNode<std::map<double, double>, tfel::meta::TLNode<std::map<std::basic_string<char>, tfel::utilities::Data, std::less<void>>, tfel::meta::TLNode<tfel::utilities::DataStructure, tfel::meta::TLE>>>>>>>>>, std::basic_string<char>>::setString' requested here
   69 |   struct GenTypeSpecializedAccessor<Child, std::string> {
      |          ^
C:\work\code\tfel\include\TFEL/Utilities/GenTypeBase.hxx(173,38): note: candidate function template not viable: 1st argument ('const std::string' (aka 'const basic_string<char, char_traits<char>, allocator<char>>')) would lose const qualifier
  173 |     TFEL_INLINE type_check<T1, void> set(T1 &&src) {
      |                                      ^   ~~~~~~~~

I guess, what I am mostly concerned about regarding using clang is whether or not the compiled library will work with other dependencies of Code Aster compiled with MSVC.

Do you have any thoughts on the matter? If other variants of clang works better with mfront and/or has better interoperability with libraries compiled with MSVC I'll take that into consideration when considering the amount of work bringing in external compilers into the conda-forge build.

Update:

I see that I can use clang-cl which ought to be ABI compatible with MSVC. I just tried to compile with clang-cl and it ran into the exact same error I got using clang/clang++.

Update 2:

for mfront v4.2.0 clang-cl manages to compile almost 1/3 ending with the error:

FAILED: bindings/python/tfel/system.pyd 
LINK: command "C:\work\miniforge3\envs\mfront-deps\Library\bin\lld-link.exe bindings\python\tfel\CMakeFiles\py_tfel_system.dir\system.obj bindings\python\tfel\CMakeFiles\py_tfel_system.dir\LibraryInformation.obj bindings\python\tfel\CMakeFiles\py_tfel_system.dir\ExternalLibraryManager.obj bindings\python\tfel\CMakeFiles\py_tfel_system.dir\ExternalBehaviourDescription.obj /out:bindings\python\tfel\system.pyd /implib:bindings\python\tfel\system.lib /pdb:bindings\python\tfel\system.pdb /dll /version:0.0 /machine:x64 /INCREMENTAL:NO src\System\TFELSystem.lib C:\work\miniforge3\envs\mfront-deps\Library\lib\boost_python312.lib C:\work\miniforge3\envs\mfront-deps\libs\python312.lib src\Exception\TFELException.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST:EMBED,ID=2" failed (exit code 1) with the following output:
lld-link: error: undefined symbol: void __cdecl declareExternalMaterialKnowledgeDescription(void)
>>> referenced by bindings\python\tfel\CMakeFiles\py_tfel_system.dir\system.obj:(void __cdecl init_module_system(void))

lld-link: error: undefined symbol: void __cdecl declareExternalMaterialPropertyDescription(void)
>>> referenced by bindings\python\tfel\CMakeFiles\py_tfel_system.dir\system.obj:(void __cdecl init_module_system(void))

So I finally managed to successfully compile mfront v4.2.0 for windows using clang-cl v18.1.1 with only a minor change (see fix_v4_2_0_clang_win.patch)

(v4.1.0 required a bit more patching to be able to compile. I had especially some issues with constexpr).

I also noticed that the python site-package location was hardcoded to a specific relative path (which seems to match conda site-packages dir for Linux, but as far as I can tell not on windows). So I added an override for setting the SITE_PACKAGES_DIR to a non-default location in override_site_package_dir_for_windows.patch

I haven't checked if v4.2.0 works with the latest Code Aster (v17) (I have only previously tested Code Aster for linux using mfront 4.1.0). But hopefully in the coming days I'll be able to test it and see if Code Aster works with mfront v4.2.0 and also using dependencies compiled with clang-cl and VS2022.

fix_v4_2_0_clang_win.patch
override_site_package_dir_for_windows.patch

Let me know if you'd like me to create a PR with any of these changes?

Update:

FYI: For completeness here is the errorI was unable resolve when trying to compile mfront v4.1.0 using clang-cl v18.1.1

C:\Work\code\tfel\mtest\src\PipeCubicElement.cxx(83,36): error: constexpr function never produces a constant expression [-Winvalid-constexpr]
   83 |   constexpr real PipeCubicElement::sf0(const real x) {
      |                                    ^~~

And here is the patch I made for v4.1.0 to fix a few issues before running into the above mentioned error

fix_v4_1_0_clang_win.patch

Thank you very much ! I do apprecitate your contribution !

I never compiled the python bindings under windows. I am very glad that we can do it now.

I made some minor changes to your patches and applied them everything in master, rliv-4.2, rliv-4.1 and rliv-4.0.

I also fixed your current compilation issue in , rliv-4.1 and rliv-4.0.

I haven't checked if v4.2.0 works with the latest Code Aster (v17)

I think it will. Anyway, rliv-4.1 shall compile as well now.

Thank you for the help:)

I believe you can close this issue whenever you feel like it!

@Krande Thank again. Let me know if you need anything. We can make a release from the rliv-4.x at anytime