cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
515 Views
Registered: ‎07-09-2019

XSDK 2019.1 - Discrepancy between Linux and Windows builds

Hello,

I noticed an interesting bug in SDK that shows different behavior between the Linux and Windows installs of 2019.1. We are using the nlohmann/json C++ header library on a Microblaze, which compiles fine on my machine but fails on my co-worker's otherwise identical Windows install. It's rather easy to reproduce:

  1. Make an empty C++ application project in SDK targeting a Microblaze (we are using v11.0)
  2. Download json.hpp into the src/ folder
  3. Use the following for main.cc:

 

#include "json.hpp"
#include "xil_printf.h"

using json = nlohmann::json;

int main()
{
	json j;
	j["test"] = 1;
	xil_printf("%s", j.dump(4));
	return 0;
}

On an Ubuntu 18.04 SDK install, this builds correctly and has been demonstrated to work on-fabric. On a Windows 10 SDK install, the build fails with the following messages:

make all 
'Building file: ../src/main.cc'
'Invoking: MicroBlaze g++ compiler'
mb-g++ -Wall -O0 -g3 -c -fmessage-length=0 -MT"src/main.o" -I../../test_json_hpp_bsp/os_core_mb/include -mlittle-endian -mxl-barrel-shift -mxl-pattern-compare -mno-xl-soft-div -mcpu=v11.0 -mno-xl-soft-mul -mxl-multiply-high -mhard-float -mxl-float-convert -mxl-float-sqrt -Wl,--no-relax -ffunction-sections -fdata-sections -MMD -MP -MF"src/main.d" -MT"src/main.o" -o "src/main.o" "../src/main.cc"
In file included from ../src/main.cc:1:
../src/json.hpp: In static member function 'static void nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::lexer::strtonum::strtof(float&, const char*, char**)':
../src/json.hpp:11171:26: error: 'strtof' is not a member of 'std'
                 f = std::strtof(str, endptr);
                          ^~~~~~
../src/json.hpp:11171:26: note: suggested alternative: 'strstr'
                 f = std::strtof(str, endptr);
                          ^~~~~~
                          strstr
../src/json.hpp: In static member function 'static void nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::lexer::strtonum::strtof(long double&, const char*, char**)':
../src/json.hpp:11181:26: error: 'strtold' is not a member of 'std'
                 f = std::strtold(str, endptr);
                          ^~~~~~~
../src/json.hpp:11181:26: note: suggested alternative:
In file included from c:\xilinx\sdk\2019.1\gnu\microblaze\nt\microblaze-xilinx-elf\include\c++\8.2.0\cstdlib:75,
                 from c:\xilinx\sdk\2019.1\gnu\microblaze\nt\microblaze-xilinx-elf\include\c++\8.2.0\bits\stl_algo.h:59,
                 from c:\xilinx\sdk\2019.1\gnu\microblaze\nt\microblaze-xilinx-elf\include\c++\8.2.0\algorithm:62,
                 from ../src/json.hpp:33,
                 from ../src/main.cc:1:
c:\xilinx\sdk\2019.1\gnu\microblaze\nt\microblaze-xilinx-elf\include\stdlib.h:320:20: note:   'strtold'
 extern long double strtold (const char *__restrict, char **__restrict);
                    ^~~~~~~
In file included from ../src/main.cc:1:
../src/json.hpp: In member function 'long long int nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::lexer::strtonum::parse_integral(char**, std::true_type) const':
../src/json.hpp:11253:29: error: 'strtoll' is not a member of 'std'
                 return std::strtoll(m_start, endptr, 10);
                             ^~~~~~~
../src/json.hpp:11253:29: note: suggested alternative:
In file included from c:\xilinx\sdk\2019.1\gnu\microblaze\nt\microblaze-xilinx-elf\include\c++\8.2.0\cstdlib:75,
                 from c:\xilinx\sdk\2019.1\gnu\microblaze\nt\microblaze-xilinx-elf\include\c++\8.2.0\bits\stl_algo.h:59,
                 from c:\xilinx\sdk\2019.1\gnu\microblaze\nt\microblaze-xilinx-elf\include\c++\8.2.0\algorithm:62,
                 from ../src/json.hpp:33,
                 from ../src/main.cc:1:
c:\xilinx\sdk\2019.1\gnu\microblaze\nt\microblaze-xilinx-elf\include\stdlib.h:266:11: note:   'strtoll'
 long long strtoll (const char *__restrict __n, char **__restrict __end_PTR, int __base);
           ^~~~~~~
In file included from ../src/main.cc:1:
../src/json.hpp: In member function 'long long unsigned int nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::lexer::strtonum::parse_integral(char**, std::false_type) const':
../src/json.hpp:11258:29: error: 'strtoull' is not a member of 'std'
                 return std::strtoull(m_start, endptr, 10);
                             ^~~~~~~~
../src/json.hpp:11258:29: note: suggested alternative: 'setfill'
                 return std::strtoull(m_start, endptr, 10);
                             ^~~~~~~~
                             setfill
make: *** [src/subdir.mk:23: src/main.o] Error 1

My best guess is that it has something to do with XSDK's Windows compatibility layer, which I think is MinGW? There is a lengthy discussion on this popular library's issue page regarding a very similar issue, and concludes with the author (appropriately) stating that he's not interested in changing the logic of the code to deal with edge cases of compilers not following the C++ spec.

I'm very curious to see if someone can recreate this! I think it's very interesting (and a bit concerning) to see different behavior across 2 installs of the same version of SDK.

 

0 Kudos
3 Replies
ibaie
Xilinx Employee
Xilinx Employee
434 Views
Registered: ‎10-06-2016

Hi @mark.kubiak.aero 

Never saw the issue but what is bit strange for me is that in theory both host machines should be using the same cross-compilation toolchain, so I would expect to have the same libraries. Anyway will try to do some testing to check what's going on.

Regards


Ibai
Don’t forget to reply, kudo, and accept as solution.
0 Kudos
416 Views
Registered: ‎07-09-2019

Thanks for looking into it! You're very close to correct here -- they do share the same toolchain, but built slightly differently. The whole thing is Unix based, so whereas it's natively supported on Linux distros, Windows installs (as far as I can tell) use MinGW to wrap Make and whatnot. This is why I am inclined to believe this to be related to a couple very old (and now fixed) MinGW bugs, as linked above. Let me know what you find!

Thanks, Mark
0 Kudos
ibaie
Xilinx Employee
Xilinx Employee
399 Views
Registered: ‎10-06-2016

Hi @mark.kubiak.aero 

You are right that SDK for windows uses MinGW as adaptation layer and probably the issue is coming from there. My "surprise" was mostly coming from the fact that I was expecting libraries and headers files for cross compiled target to be the same... Anyway will try to give a try :)

Regards


Ibai
Don’t forget to reply, kudo, and accept as solution.
0 Kudos