Skip to content
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

Attempt to build for Windows #398

Open
cinco-de-mayonnaise opened this issue Apr 3, 2023 · 7 comments
Open

Attempt to build for Windows #398

cinco-de-mayonnaise opened this issue Apr 3, 2023 · 7 comments

Comments

@cinco-de-mayonnaise
Copy link

Hiya, since I'm really interested in finite automata, and this is one of the few FSM libraries in C/C++ that seem to have the feature I want without me having to code it from scratch (regex -> minimized DFA). However, I use Windows and I'd really prefer to have a cross-platform FSM library and would like to contribute towards making this a reality.

I have no prior experience in build systems, so the reason I'm making this post is to

  1. Document my experience towards building this for Windows, so that snags/things preventing this from building can hopefully be fixed
  2. Hopefully garner some support for when I inevitably run into problems that don't seem to be documented anywhere on the Internet that I can't fix on my own.

Here's hoping for the best

@cinco-de-mayonnaise
Copy link
Author

cinco-de-mayonnaise commented Apr 3, 2023

So here is my strategy: technically speaking there should be no reason why I can't compile this for Windows, seeing as it uses pretty much the C standard library, and the only thing getting in the way of me just copying out the source files and compiling them on windows is the annoying build system, so I plan on using x86_64-w64-mingw32-gcc on Ubuntu 20 WSL2 for the cross-compiling.

Then, I had to painstakingly figure out where all the variables of a Makefile exist and change each and every one of the tools required into the mingw variant, for example,

  • In root(the main) Makefile
# things to override
CC     ?= x86_64-w64-mingw32-gcc-win32 -mwin32
  • In so.mk, the file responsible for linking different object files together (producing the stuff) [error occured: relocatable linking with relocations from format pe-x86-64 to format elf64-x86-64... ]
.if ${CC:T:Memcc*}
LD ?= ${CC}
.else
LD ?= x86_64-w64-mingw32-ld
.endif
  • In ar.mk, responsible for linking with standard library [error occurred: undefined reference to 'cstdlibfunction']
AR     ?= x86_64-w64-mingw32-ar
RANLIB ?=  x86_64-w64-mingw32-ar s

And so on and so forth, ... OH YEAH, I also had to disable documentation with -DNODOC, because otherwise it was throwing an error and preventing me from compiling, I guess this is a major problem on Linux..., not being able to build is a bigger fish to fry though, so I'll worry about the documentation later...

@cinco-de-mayonnaise
Copy link
Author

cinco-de-mayonnaise commented Apr 3, 2023

Snag: undefined references to C standard library functions

Unfortunately this is the point at which I was stuck for the last few months: I've tried fiddling with a lot of the settings, but it seems that gcc fails to find references to the C standard functions in the compiled .opic files that were generated.

From my limited knowledge, I assume it is because of the strip whose job is to remove symbols, but it also ends up removing symbols to the C standard functions, and so the linker can't find them when it needs to link. Aarrrgh, it looks like I'm so close because there were no points of failure throughout the entire object files and .opic compilation process.

/src/libfsm/walk2.opic build/src/libfsm/lexer.opic build/src/libfsm/parser.opic
x86_64-w64-mingw32-nm -P -g build/lib/libfsm.opic | awk '/^__/ && $2 != "U" {print $1}' >> build/src/libfsm/libfsm.syms
x86_64-w64-mingw32-objcopy --keep-global-symbols=build/src/libfsm/libfsm.syms build/lib/libfsm.opic build/lib/libfsm.opic
x86_64-w64-mingw32-strip -x build/lib/libfsm.opic
x86_64-w64-mingw32-ld -o build/lib/libfsm.so -shared  build/lib/adt.opic build/lib/print.opic build/lib/libfsm.opic
x86_64-w64-mingw32-ld: build/lib/adt.opic:alloc.c:(.text+0x1f): undefined reference to `free'
x86_64-w64-mingw32-ld: build/lib/adt.opic:alloc.c:(.text+0x6c): undefined reference to `calloc'
x86_64-w64-mingw32-ld: build/lib/adt.opic:alloc.c:(.text+0xb8): undefined reference to `malloc'
x86_64-w64-mingw32-ld: build/lib/adt.opic:alloc.c:(.text+0x105): undefined reference to `realloc'
x86_64-w64-mingw32-ld: build/lib/adt.opic:alloc.c:(.text+0x173): undefined reference to `__mingw_vfprintf'
x86_64-w64-mingw32-ld: build/lib/adt.opic:alloc.c:(.text+0x22c): undefined reference to `__popcountdi2'
x86_64-w64-mingw32-ld: build/lib/adt.opic:bitmap.c:(.text+0x491): undefined reference to `fputs'
x86_64-w64-mingw32-ld: build/lib/adt.opic:bitmap.c:(.text+0x572): undefined reference to `__imp_isalnum'
...<hundreds of lines>

The full log has been attached for more info. libfsm_build_failure.log

@katef
Copy link
Owner

katef commented Apr 3, 2023

This is fantastic, thank you. I'd absolutely love to add support for this once we figure out what's needed!

About strip, you can pass NOSTRIP=1 to the makefiles when building

@cinco-de-mayonnaise
Copy link
Author

bmake -r -DNODOC -DNOSTRIP=1
Still strips after producing every intermediate object file

x86_64-w64-mingw32-objcopy --keep-global-symbols=build/src/libfsm/libfsm.syms build/lib/libfsm.opic build/lib/libfsm.opic
x86_64-w64-mingw32-strip -x build/lib/libfsm.opic
x86_64-w64-mingw32-ld -o build/lib/libfsm.so -shared  build/lib/adt.opic build/lib/print.opic build/lib/libfsm.opic
x86_64-w64-mingw32-ld: build/lib/adt.opic:alloc.c:(.text+0x1f): undefined reference to `free'
x86_64-w64-mingw32-ld: build/lib/adt.opic:alloc.c:(.text+0x6c): undefined reference to `calloc'
x86_64-w64-mingw32-ld: build/lib/adt.opic:alloc.c:(.text+0xb8): undefined reference to `malloc'

@katef
Copy link
Owner

katef commented Apr 18, 2023

I'm just gonna remove symbol stripping. @dhobsd, you win 💜

@katef
Copy link
Owner

katef commented Apr 21, 2023

Oh huh. Try passing either NOSTRIP=1 (without the -D) or -DNOSTRIP, not both, please.

@cinco-de-mayonnaise
Copy link
Author

cinco-de-mayonnaise commented Nov 13, 2023

Snag: We cannot handle .OBJDIR other than .CURDIR

After being stuck on this for many months, I realised that MSYS2 exists and works wonderfully for compiling many Linux projects on Windows. So I proceeded to install bmake on MSYS2, and it works great (i think). Unfortunately, now I see a different error message before the compilation can even start.

We cannot handle .OBJDIR other than .CURDIR

So I was curious to see what OBJDIR and CURDIR actually is,

$ bmake -r
.OBJDIR = /D/Code/libfsm  
.CURDIR =
OBJDIR =
CURDIR =
We cannot handle .OBJDIR other than .CURDIR
*** Error code 1

Stop.
bmake.exe[1]: stopped in D:/Code/libfsm

Where D:/Code is the directory into which I cloned libfsm. (Keep in mind MSYS2 pretends that its a fully functional bash shell, so it turns the Windows style directory into Linux-like folders)
I have no idea how bmake works so I'd like some enlightenment on this issue, exactly what are .OBJDIR and .CURDIR supposed to represent?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants