PMunch / futhark

Automatic wrapping of C headers in Nim
MIT License
393 stars 22 forks source link

Cannot generate `importc` statements using Nim templates. #125

Closed 8bitprodigy closed 1 month ago

8bitprodigy commented 1 month ago

So I'm trying to generate individual nim wrapper files for each header in a library (libDragon, to be specific), and I figured the best way to go about this was to create a template that I could call that would be expanded before compiling, but it doesn't seem to work, giving the following error:

chris@stanford:~/gits/Nimtendo64/src$ nim c create_wrapper.nim
Hint: used config file '/home/chris/.choosenim/toolchains/nim-#devel/config/nim.cfg' [Conf]
Hint: used config file '/home/chris/.choosenim/toolchains/nim-#devel/config/config.nims' [Conf]
..............................................................................................................................................
stack trace: (most recent call last)
/home/chris/.nimble/pkgs2/futhark-0.13.6-3483cfec18042ba11474675ec7a3648492e4d583/futhark.nim(656, 19) importc
/home/chris/gits/Nimtendo64/src/create_wrapper.nim(12, 11) template/generic instantiation of `wrapHeader` from here
/home/chris/.nimble/pkgs2/futhark-0.13.6-3483cfec18042ba11474675ec7a3648492e4d583/futhark.nim(656, 19) Error: node lacks field: strVal

Here's the template I wrote:

template wrapHeader(name: string): untyped = 
    importc:
        outputPath "Nimtendo64" / name & ".nim"
        path n64_inst
        name & ".h"
PMunch commented 1 month ago

Even if you solved the initial problem you'd be very likely to run into further issues using Futhark that way. What I'd recommend instead is using project mode. What it allows you to do is simply specify all the paths you want to wrap, and then it will wrap all the header files in those paths and recreate the same folder structure. Your example would be something like:

importc:
  outputPath "Nimtendo64"
  path n64_inst # Assuming this is a constant holding the path to a folder

Then every header file in the folder pointed to by n64_inst would get wrapped into separate Nim files and placed in the "Nimtendo64" folder.

8bitprodigy commented 1 month ago

Awesome! Thank you! One problem with project mode, however, is that those header files are stored alongside other header files, as they're part of a toolkit. I'll have to figure something out. Currently, I have separate importc statements, and that one seems to fail on one of the header files, though that's a separate issue.

PMunch commented 1 month ago

Well you can always use the ignore function to ignore header files you don't want to wrap.

8bitprodigy commented 1 month ago

Actually, maybe I could do that to ignore the c++ folder, which seems to be the biggest issue when trying to use project mode.

8bitprodigy commented 1 month ago

Am I using ignore correctly, here?

importc:
    outputPath "Nimtendo64"
    path n64_inst
    ignore "c++" 
    ignore "libdragon.h"

Because it doesn't seem to be ignoring the c++ directory and the readme doesn't give an example of the syntax for how to use it.

PMunch commented 1 month ago

Hard to tell without knowing the folder structure, but ignore needs to be relative to the project being compiled, or absolute. I typically have something like:

const relPath = currentSourcePath().parentDir

importc:
  path relPath / "cfiles"
  ignore relPath / "cfiles" / "somefolder"
8bitprodigy commented 1 month ago

ignore needs to be relative to the project being compiled

Okay, gotcha! I'll try that out. I'm not sure why that didn't occur to me, but I know it was getting late when I tried that, so that might have something to do with it.