nickg / nvc

VHDL compiler and simulator
https://www.nickg.me.uk/nvc/
GNU General Public License v3.0
635 stars 80 forks source link

dlopen() not available in MinGW #306

Closed girivs closed 6 years ago

girivs commented 7 years ago

dlopen() is not available in MinGW. Would you be open to supporting portability for this function?

hiyuh commented 7 years ago

IMHO, one of following looks promising,

maybe, larter one is simpler?

girivs commented 7 years ago

I already tried option 2. I can go past it by commenting out the search for libdl or libdld as in MinGW dlfcn is just a wrapper, not a library like in linux.

AC_SEARCH_LIBS([dlopen], [dl dld], [], [
AC_MSG_ERROR([unable to find the dlopen() function])
])

Perhaps switch this check on by platform and/or search for dlfcn headers as well?

hiyuh commented 7 years ago

IIUC, checking for dlfcn.h in auto* can skip if --disable-native and --disable-vhpi, but current src has incomplete #ifdef ENABLE_{NATIVE,VHPI} businesses.

UPDATE: Fix a typo.

nickg commented 7 years ago

I started working on a mingw32 last year and made a bit of progress. See the mingw32 branch here, I just rebased it on master. It doesn't work yet but I made some progress #ifdef-ing things. If you want to help get it working that would be very useful.

girivs commented 7 years ago

Will look into this and update the bug if I can get it working.

girivs commented 7 years ago

I got it to compile all the way through to get nvc.exe, but on runtime, get segfaults. Very likely some of the WIN32 function porting causes this. Can anyone help?

Attaching patch. nvc_mingw.patch.txt

nickg commented 7 years ago

Does it crash when running nvc -a or only when running the compiled code with nvc -r? If it's the latter then it might be the same as issue #283 on Cygwin.

nickg commented 7 years ago

@girivs I applied your patch with a couple of formatting changes

girivs commented 7 years ago

The SIGSEGV happens during the make itself. Once nvc.exe is compiled it tries to compile the IEEE standard libraries and it fails right there.

gdb logs for the SIGSEGV.

gdb ./bin/nvc GNU gdb (GDB) 7.12 Copyright (C) 2016 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-w64-mingw32". Type "show configuration" for configuration details. For bug reporting instructions, please see: http://www.gnu.org/software/gdb/bugs/. Find the GDB manual and other documentation resources online at: http://www.gnu.org/software/gdb/documentation/. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ./bin/nvc...done. (gdb) r --force-init --work=lib/std -a --bootstrap ./lib/std/standard.vhd Starting program: C:\home\src\nvc\bin\nvc.exe --force-init --work=lib/std -a --bootstrap ./lib/std/standard.vhd [New Thread 11364.0x10a0]

Program received signal SIGSEGV, Segmentation fault. get_next_char (b=0x1d36450 "", max_buffer=) at src/parse.c:5526 5526 b = read_ptr++; (gdb) bt

0 get_next_char (b=0x1d36450 "", max_buffer=)

at src/parse.c:5526

1 0x000000000041c72f in yy_get_next_buffer () at src/lexer.c:2177

2 yylex () at src/lexer.c:2047

3 0x0000000000406c76 in peek_nth (n=0, n@entry=1) at src/parse.c:209

4 0x000000000041a5b5 in parse () at src/parse.c:5576

5 0x00000000004028bc in analyse (argv=0x1de2de0, argc=4) at src/nvc.c:159

6 process_command (argc=argc@entry=4, argv=argv@entry=0x1de2de0)

at src/nvc.c:948

7 0x00000000012f6a93 in main (argc=4, argv=0x1de2de0) at src/nvc.c:1051

(gdb) p b $1 = 0x1d36450 "" (gdb) p read_ptr $2 = 0x1 <error: Cannot access memory at address 0x1> (gdb)

girivs commented 7 years ago

if (file_sz > 0) file_start = map_file(fd, file_sz); else file_start = NULL;

So it does look like a bug in my map_file MINGW port.

girivs commented 7 years ago

Oh brother! Silly bug. fix_map_file_mingw.patch.txt

girivs commented 7 years ago

It's still failing, but no SIGSEGV. I'm looking further.

girivs commented 7 years ago

Now the error is here: bin/nvc.exe -L lib/ --work=lib/ieee -a ./lib/ieee/std_logic_1164.vhdl ** Fatal: file C:\home\src\nvc\lib\std/STD.STANDARD has invalid compression format 2

girivs commented 7 years ago

Here's a patch for some remaining MinGW ports of unimplemented functions (file_read_lock, file_write_lock and file_unlock). file_lock_unlock_mingw.patch.txt

nickg commented 7 years ago

I applied those two, thanks. Did you get anywhere with the "invalid compression format"? If not I might be able to have a look tomorrow.

girivs commented 7 years ago

May not get to it tomorrow. Would appreciate you having a look, if you have time.

nickg commented 7 years ago

OK I fixed that: it was because binary files were not being opened with the "b" binary mode so newlines were converted to CRLF. Now it fails due to a mixup of slashes in LLVM_CONFIG_BINDIR.

girivs commented 7 years ago

I did a temporary hack to proceed further. Basically, when doing the codegen, the path has mismatched slashes. So I put quotes around the path string.

However, make still seems to fail in codegen, but if I run the corresponding command directly, it seems to work. Any ideas?

 NVC      lib/ieee/IEEE.NUMERIC_STD
  NVC      lib/ieee/IEEE.STD_LOGIC_1164-body
  NATIVE   lib/ieee/IEEE.STD_LOGIC_1164-body
make[1]: *** [Makefile:2504: lib/ieee/IEEE.STD_LOGIC_1164-body] Error 127
make: *** [Makefile:941: all] Error 2

but this passes: bin/nvc -L lib/ --work=lib/ieee --codegen std_logic_1164

Patch below

diff --git a/src/link.c b/src/link.c
index e6fd95e..2c399d5 100644
--- a/src/link.c
+++ b/src/link.c
@@ -290,6 +290,9 @@ static void link_exec(void)
    }

 #if defined __CYGWIN__ || defined __MINGW32__
+   char tmpPath[strlen(args[2])+2];
+   snprintf(tmpPath, sizeof(tmpPath), "\"%s\"", args[2]);
+   args[2] = tmpPath;
    int status = spawnv(_P_WAIT, args[0], (char * const *)args);
    if (status != 0)
       fatal("%s failed with status %d", args[0], status);
nickg commented 7 years ago

With the above changes I can run some tests when elaborating with --native (i.e. compiling the simulation to a DLL). The LLVM JIT is not working however - it fails in the same way as Cygwin with LLVM 3.5 and later.

nickg commented 7 years ago

I merged the mingw32 branch into master as it was getting hard to maintain separately. The current status is that most things work when using JIT, except a few IEEE libraries.

nickg commented 6 years ago

Finally, running make check on 64-bit MSYS2 has no failures for me. 32-bit still has some issues, same as Cygwin. Going to close this now and we can open other issues for more specific problems.

nickg commented 6 years ago

Works on 32-bit MSYS2 as well, and I've added CI on AppVeyor: https://ci.appveyor.com/project/nickg72247/nvc

Immortalin commented 6 years ago

@nickg same issue when building with emcc for webassembly

nickg commented 6 years ago

@Immortalin a webassembly port is definitely an interesting project, but requires a lot more work than just getting it to build with emcc. For example we use dlopen to load the shared library generated by LLVM from the filesystem. That doesn't really make sense in the browser, where I guess we'd need a separate backend that generates WASM/JS directly. The fixes for Windows were just replacing the unix calls with Windows equivalents - e.g. dlopen -> LoadLibrary.