ament / ament_index

Apache License 2.0
13 stars 27 forks source link

Problem with compiling ament_index_cpp with x64 architecture #82

Open iqedgarmg opened 2 years ago

iqedgarmg commented 2 years ago

Hi everyone!, thanks a lot for this amazing project!

I have an Issue while compiling this package for ros2 foxy with colcon, where the following error appears:

 C:\ws_new\ros_msft_mrtk_native\tools\src\ament\ament_index\ament_index_cpp\src\get_resources.cpp(74,67): error C2664: 'HANDLE FindFirstFileW(LPCWSTR,LPWIN32_FIND_DATAW)': cannot convert argument 1 from 'const _Elem *' to 'LPCWSTR' [C:\ws_new\ros_msft_mrtk_native\tools\x64_build\ament_index_cpp\ament_index_cpp.vcxproj]
          with
          [
              _Elem=char
          ]
C:\ws_new\ros_msft_mrtk_native\tools\src\ament\ament_index\ament_index_cpp\src\get_resources.cpp(89,10): message : Reason: cannot convert from 'WCHAR [260]' to 'const std::basic_string<char,std::char_traits<char>,std::allocator<char>>' [C:\ws_new\ros_msft_mrtk_native\tools\x64_build\ament_index_cpp\ament_index_cpp.vcxproj]
C:\ws_new\ros_msft_mrtk_native\tools\src\ament\ament_index\ament_index_cpp\src\get_resources.cpp(89,10): message : No constructor could take the source type, or constructor overload resolution was ambiguous [C:\ws_new\ros_msft_mrtk_native\tools\x64_build\ament_index_cpp\ament_index_cpp.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\xtree(1370,25): message : see declaration of 'std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::find' [C:\ws_new\ros_msft_mrtk_native\tools\x64_build\ament_index_cpp\ament_index_cpp.vcxproj]

By looking into the get_resources.cpp file, I found that the following code is executed when a different architecture than win32 is used:

#else
    std::string pattern = path + "/*";
    WIN32_FIND_DATA find_data;
    HANDLE find_handle = FindFirstFile(pattern.c_str(), &find_data);
    if (find_handle == INVALID_HANDLE_VALUE) {
      continue;
    }
    do {
      // ignore directories
      if ((find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
        continue;
      }

      // ignore files starting with a dot
      if (find_data.cFileName[0] == '.') {
        continue;
      }

      if (resources.find(find_data.cFileName) == resources.end()) {
        resources[find_data.cFileName] = base_path;
      }
    } while (FindNextFile(find_handle, &find_data));
    FindClose(find_handle);
#endif
  }
  return resources;
}

As the errors says, the problem is that the compiler can't convert the string from char to wchar. By looking some related issues, I added this additional functions to the main file:

std::wstring s2ws(const std::string& str)
{
    using convert_typeX = std::codecvt_utf8<wchar_t>;
    std::wstring_convert<convert_typeX, wchar_t> converterX;

    return converterX.from_bytes(str);
}

std::string ws2s(const std::wstring& wstr)
{
    using convert_typeX = std::codecvt_utf8<wchar_t>;
    std::wstring_convert<convert_typeX, wchar_t> converterX;

    return converterX.to_bytes(wstr);
}

and then, I developed the required conversions to make the compilation works:

#else

    std::string pattern = path + "/*";

    //---> Patch added
    std::wstring wpattern = s2ws(pattern);

    WIN32_FIND_DATA find_data;
    HANDLE find_handle = FindFirstFile(wpattern.c_str(), &find_data);
    if (find_handle == INVALID_HANDLE_VALUE) {
      continue;
    }
    do {
      // ignore directories
      if ((find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
        continue;
      }

      // ignore files starting with a dot
      if (find_data.cFileName[0] == '.') {
        continue;
      }

      //---> Patch added
      if (resources.find(ws2s(find_data.cFileName)) == resources.end())
      {
          resources[ws2s(find_data.cFileName)] = base_path;
      }

    } while (FindNextFile(find_handle, &find_data));
    FindClose(find_handle);
#endif
  }
  return resources;
}

In order to skip de error. Nevertheless, despite the package can compile with no problems I am getting an execution error when I create a ros2 node instance. I am not sure if this error is caused by the previous modification, or if I am making a mistake when I try to compile the package. I have a Windows 10 machine with a /x64 architecture, and Visual Studio Community 2019.

Thanks in advance for your response!

clalancette commented 2 years ago

Hm, it is interesting that you are running into that problem, since we compile this nightly on Windows 10 x64 architecture with Visual Studio 2019. You can see the results in https://ci.ros2.org/view/nightly/job/nightly_win_rel/ .

I guess one possibility is that we have our system set to English/ASCII, and you are using a different character set. What character set do you have your Windows machine set to?

iqedgarmg commented 2 years ago

Thanks @clalancette for your quick response!.

Maybe that could be the problem, this is the output of my computer when i run the command "[System.Text.Encoding]::Default":

 IsSingleByte      : True
BodyName          : iso-8859-1
EncodingName      : Western European (Windows)
HeaderName        : Windows-1252
WebName           : Windows-1252
WindowsCodePage   : 1252
IsBrowserDisplay  : True
IsBrowserSave     : True
IsMailNewsDisplay : True
IsMailNewsSave    : True
EncoderFallback   : System.Text.InternalEncoderBestFitFallback
DecoderFallback   : System.Text.InternalDecoderBestFitFallback
IsReadOnly        : True
CodePage          : 1252

As far as I understand, CP-1252 is extended ASCII right?, English is also my system default language.

I tried the compilation in a different Windows 10 machine but the problem still persists.

Thanks in advance for your help and response!