abetusk/gbr2ngc

OSX compiling fails

Closed this issue · 12 comments

Hello @abetusk, I reached your project through a thread on KiCad forums.

I tried to compile as shown in the README, but:

$ ./cmp.sh
gerber_interpreter.c:280:10: warning: implicitly declaring library function 'isspace' with type 'int (int)' [-Wimplicit-function-declaration]
    if (!isspace(*op))
         ^
gerber_interpreter.c:280:10: note: include the header <ctype.h> or explicitly provide a declaration for 'isspace'
gerber_interpreter.c:309:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
gerber_interpreter.c:463:8: warning: implicitly declaring library function 'isdigit' with type 'int (int)' [-Wimplicit-function-declaration]
  if (!isdigit(*chp)) parse_error("bad FS format (expected digit after 'X')", gs->line_no, linebuf);
       ^
gerber_interpreter.c:463:8: note: include the header <ctype.h> or explicitly provide a declaration for 'isdigit'
gerber_interpreter.c:1263:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
gerber_interpreter.c:1337:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
5 warnings generated.
test_gerber_interpreter.c:53:3: warning: implicit declaration of function 'gerber_report_state' is invalid in C99 [-Wimplicit-function-declaration]
  gerber_report_state(&gs);
  ^
1 warning generated.
gbl2ngc_aperture.cpp:232:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
1 warning generated.
gbl2ngc_construct.cpp:268:1: warning: control may reach end of non-void function [-Wreturn-type]
}
^
In file included from gbl2ngc_construct.cpp:21:
In file included from ./gbl2ngc.hpp:42:
/Library/Developer/CommandLineTools/usr/include/c++/v1/map:478:17: error: no matching function for call to object of type 'const Gerber_point_2_cmp'
        {return static_cast<const _Compare&>(*this)(__x.__cc.first, __y);}
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/__tree:2454:14: note: in instantiation of member function 'std::__1::__map_value_compare<Gerber_point_2,
      std::__1::__value_type<Gerber_point_2, int>, Gerber_point_2_cmp, true>::operator()' requested here
        if (!value_comp()(__root->__value_, __v))
             ^
/Library/Developer/CommandLineTools/usr/include/c++/v1/__tree:2383:20: note: in instantiation of function template specialization
      'std::__1::__tree<std::__1::__value_type<Gerber_point_2, int>, std::__1::__map_value_compare<Gerber_point_2, std::__1::__value_type<Gerber_point_2, int>, Gerber_point_2_cmp,
      true>, std::__1::allocator<std::__1::__value_type<Gerber_point_2, int> > >::__lower_bound<Gerber_point_2>' requested here
    iterator __p = __lower_bound(__v, __root(), __end_node());
                   ^
/Library/Developer/CommandLineTools/usr/include/c++/v1/map:1220:68: note: in instantiation of function template specialization
      'std::__1::__tree<std::__1::__value_type<Gerber_point_2, int>, std::__1::__map_value_compare<Gerber_point_2, std::__1::__value_type<Gerber_point_2, int>, Gerber_point_2_cmp,
      true>, std::__1::allocator<std::__1::__value_type<Gerber_point_2, int> > >::find<Gerber_point_2>' requested here
    iterator find(const key_type& __k)             {return __tree_.find(__k);}
                                                                   ^
gbl2ngc_construct.cpp:188:19: note: in instantiation of member function 'std::__1::map<Gerber_point_2, int, Gerber_point_2_cmp, std::__1::allocator<std::__1::pair<const
      Gerber_point_2, int> > >::find' requested here
    if ( hole_map.find( p[i] ) != hole_map.end() )
                  ^
gbl2ngc_construct.cpp:43:8: note: candidate function not viable: 'this' argument has type 'const Gerber_point_2_cmp', but method is not marked const
  bool operator()(const Gerber_point_2 &lhs, const Gerber_point_2 &rhs)
       ^
In file included from gbl2ngc_construct.cpp:21:
In file included from ./gbl2ngc.hpp:42:
/Library/Developer/CommandLineTools/usr/include/c++/v1/map:481:17: error: no matching function for call to object of type 'const Gerber_point_2_cmp'
        {return static_cast<const _Compare&>(*this)(__x, __y.__cc.first);}
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/__tree:2384:26: note: in instantiation of member function 'std::__1::__map_value_compare<Gerber_point_2,
      std::__1::__value_type<Gerber_point_2, int>, Gerber_point_2_cmp, true>::operator()' requested here
    if (__p != end() && !value_comp()(__v, *__p))
                         ^
/Library/Developer/CommandLineTools/usr/include/c++/v1/map:1220:68: note: in instantiation of function template specialization
      'std::__1::__tree<std::__1::__value_type<Gerber_point_2, int>, std::__1::__map_value_compare<Gerber_point_2, std::__1::__value_type<Gerber_point_2, int>, Gerber_point_2_cmp,
      true>, std::__1::allocator<std::__1::__value_type<Gerber_point_2, int> > >::find<Gerber_point_2>' requested here
    iterator find(const key_type& __k)             {return __tree_.find(__k);}
                                                                   ^
gbl2ngc_construct.cpp:188:19: note: in instantiation of member function 'std::__1::map<Gerber_point_2, int, Gerber_point_2_cmp, std::__1::allocator<std::__1::pair<const
      Gerber_point_2, int> > >::find' requested here
    if ( hole_map.find( p[i] ) != hole_map.end() )
                  ^
gbl2ngc_construct.cpp:43:8: note: candidate function not viable: 'this' argument has type 'const Gerber_point_2_cmp', but method is not marked const
  bool operator()(const Gerber_point_2 &lhs, const Gerber_point_2 &rhs)
       ^
In file included from gbl2ngc_construct.cpp:21:
In file included from ./gbl2ngc.hpp:42:
In file included from /Library/Developer/CommandLineTools/usr/include/c++/v1/map:442:
/Library/Developer/CommandLineTools/usr/include/c++/v1/__tree:1978:17: error: no matching function for call to object of type 'value_compare' (aka
      'std::__1::__map_value_compare<Gerber_point_2, std::__1::__value_type<Gerber_point_2, int>, Gerber_point_2_cmp, true>')
            if (value_comp()(__v, __nd->__value_))
                ^~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/map:1349:44: note: in instantiation of function template specialization
      'std::__1::__tree<std::__1::__value_type<Gerber_point_2, int>, std::__1::__map_value_compare<Gerber_point_2, std::__1::__value_type<Gerber_point_2, int>, Gerber_point_2_cmp,
      true>, std::__1::allocator<std::__1::__value_type<Gerber_point_2, int> > >::__find_equal<Gerber_point_2>' requested here
    __node_base_pointer& __child = __tree_.__find_equal(__parent, __k);
                                           ^
gbl2ngc_construct.cpp:190:19: note: in instantiation of member function 'std::__1::map<Gerber_point_2, int, Gerber_point_2_cmp, std::__1::allocator<std::__1::pair<const
      Gerber_point_2, int> > >::operator[]' requested here
      k = hole_map[ p[i] ];
                  ^
/Library/Developer/CommandLineTools/usr/include/c++/v1/map:474:10: note: candidate function not viable: no known conversion from 'const Gerber_point_2' to
      'const std::__1::__value_type<Gerber_point_2, int>' for 1st argument
    bool operator()(const _CP& __x, const _CP& __y) const
         ^
1 warning and 3 errors generated.

@brainstorm, Thank you for the bug report and for trying out gbl2ngc!

I'm using a Linux distribution and I think you're running into some differences between the g++ compiler on OSX from my system.

I believe the issue is that the comparison function I'm using wasn't declared const. On my system this doesn't generate a compilation error but maybe the OSX compiler is pickier. I've updated the function in question (the operator() method in the Gerber_point_2_cmp struct) and have confirmed it still compiles and works on my system.

This might require a little few back and forth, if you're willing, to make sure the fix corrects the issue and to work out any other errors that might occur.

Regardless, I would try grabbing the latest source and trying to compile again. I would appreciate letting me know if there are any more issues or if it was successful.

Thanks @abetusk! It did compile with your changes after removing the linker's -lboost_thread flag.

Unfortunately my KiCad board does not seem to be parseable with your gerber parser:

$ ../src/gbl2ngc --input breakouts-B.Cu.gbl --output test.ngc
PARSE ERROR: unknown image parameter code at line 1 '%TF.GenerationSoftware,KiCad,Pcbnew,(2017-10-17revision537804b)-master*%'

Please have a look at https://github.com/brainstorm/gbl2ngc/commit/82093e3c00bf8ba2892233b9b73c99a27d797d3f for more details and an example, thanks for writing this software ;)

@brainstorm, for what it's worth, I extended gbl2ngc to parse (and ignore) the failing lines (the TF etc.). I tested it on the file you pointed to and it seems to work fine. If you'd like to test it out, please feel free and let me know if you run into any more errors.

I didn't add your example file breakouts-B.Cu.gbl because I wasn't sure if it was something you wanted shared in this repo. I would be happy to accept it and add it to a (now non-existent) test suite to try and catch errors in the future. If you'd like to issue a pull request, I'd happily take it, so long as you update your repo with the latest.

It would also be good to get some type of conditional compilation so you didn't have to hand tweak the compilation script. Maybe it's time to move to a makefile or something more exotic.

Just so you know, the current parser is incomplete and will fail on some Gerber features that haven't been implemented, such as aperture macros and circle arcs. Hopefully I'll get to implementing these sometime in the future, especially now that I have some sample Gerber files to test against.

Sure! Please add my example in there, no worries ;)

Yesterday I had to resort to FlatCAM to get things done(tm). But since I'm seeing that you are rekindling development of this neat little tool, it would be great to have those GCodes supported as close as possible from FlatCAM outputs:

https://mega.nz/#F!qkJgybhD!b3Frag1qgZpu4sKHPOe0SQ

Those are from the same .gbr mentioned before. Those GCode outputs above worked surprisingly well for this little SMD breakout board. With some more G-Code based autolevelling (candidate feature to add into your code?):

http://www.autoleveller.co.uk/

I bet the results would be just perfect :)

@brainstorm, could you formalize what it is you want and maybe open a few issues? For example, is it the GCode at the beginning and end that you would like to see added?

Also, would it be possible to use your SMD files as a test? The one in your fork looks to only be pads with no connections.

In terms of autolevelling, I built some tools a while back to do some simple "GCode forming" based off of a uniform grid of samples. The one that uses Catmul-Rom interpolation can be found in my abes_cnc_utilities repository.

While I'm not opposed to autolevelling, it seems a little 'tacked on' in terms of this tool. It might be better to update something like grecode rather than extend this tool.

What do you mean by SMD files? Here's the full KiCAD project, feel free to use all those files in any way or form you wish (including more flatcam-generated G-Codes as example):

https://mega.nz/#!n8ZV2AaA!ks5VlRxgdJi_Y_Xct82e5UiAlXZYZu_63IhFlx3sLFk

My objective is to have a CLI/automated toolchain to mill my boards as fast as possible, with the least amount of UI clicking and adjusting parameters around possible. This is why I highly appreciate your software and its potential.

This is also why I just successfully ported FlatCAM to a more modern/supported state via this pullrequest:

https://bitbucket.org/jpcgt/flatcam/pull-requests/75/initial-port-to-python3-and-pyqt5/diff

So that, at least, I can have a local toolchain on my laptop that does not require windows.

Also, auto leveling is rather crucial feature (for me) since our CNC mill will not produce valid PCBs otherwise, see:

https://bitbucket.org/jpcgt/flatcam/issues/72/z-profile-feature#comment-43324228

I totally see your angle though, small tools that can be easily combined as in the good UNIX philosophy. It would be quite rad if your small tools could be combined in such a way!

Anything works for me as long as it's as automated as possible. I hope my intentions are clearer now :)

@brainstorm , for what it's worth, there's a good page on the RepRap Wiki about different Gerber to PCB milling options. In particular there's the command line tool pcb2gcode that is mature and has a community around it. I believe it even has autoleveller functionality (see their manual for details).

One of the reasons I created gbl2ngc was because pcb2gcode renders to a picture and then converts to gcode, which introduces many small 'jaggies'. Presumably this isn't a problem for "everyday" use but that was the motivation to create this tool, so that the geometry could be translated in a more direct way.

Thank you for the example project, I'm going to add it in the next update.

Considering pcb2gcode has an autoleveller, maybe it's fair game to add it. Do you have any thoughts on what kind of autolevelling you would want for non-uniform grids?

And how is the CLI version of FlatCAM going? Is it something you're happy with?

Yes, I've tried pcb2gcode before but I became quite jaded with:

  1. The ton of dependencies it requires (as packaged nowadays in OSX's brew).
  2. Kilometric commadline arguments instead of .rc/config files (I might have missed this possibility in the docs?).
  3. UI-centric instead of CLI/API focused.
  4. Not updated for newest KiCad gerbers fileformat.

Here's my summarized experience with it:

$ pcb2gcode --zsafe 10 --zchange 10 --zwork=-0.05 --offset=0.1 --software mach3 --drill fab/breakouts.drl --front fab/breakouts-F.Cu.gbr --outline fab/breakouts-Edge.Cuts.gbr --output-dir mill --dpi 1000 --metric true --cut-feed 250 --mill-feed 600 --mill-speed 1000 --zcut -1.56 --cutter-diameter=3 --cut-speed 12000 --cut-infeed 0.5 --zdrill -1.6 --drill-feed 1000 --drill-speed 10000

Importing front side...
** (process:58701): CRITICAL **: In file fab/breakouts-F.Cu.gbr,
unknown RS-274X extension found %TF%
(... many CRITICAL errors after...)
DONE.
Processing input files... libc++abi.dylib: terminating with uncaught exception of type Glib::FileError
Abort trap: 6

I might report this issue, but as per the points above, I wanted something a bit more lightweight/modern like you seem to be aiming at with your project. Glad to hear you are not losing precision either, that image transformation process you mention does seem problematic.

FlatCAM's CLI is a bit confusing with all that TCL layer... I haven't tried it yet because I was getting the tests passing first, but as far as I saw in the code, they seem to be in the middle of some kind of migration with it, so not totally convinced it'll work reliably.

I don't know, I think I would love to have something I could just call from KiCAD like Eagle does, I'll see.

Thanks for the RepRap wiki reference too!

Ha, it looks like they ran into exactly the same issue I did. I think the Gerber specification has been updated to include new fields and so all the tools that haven't been updated in a couple of years have started breaking.

I'm still updating gbl2ngc with arc support, aperture blocks and aperture macros but if your Gerber files don't use them, gbl2ngc might be usable for you now.

If you wouldn't mind, please let me know how things turn out with you. Please feel free to email me if you'd like to take this discussion off of the issue tracker.

My current bottleneck is indeed autolevelling, boards look good-ish but they are clearly not leveled in one side making them useless, I really need that feature for a functional toolchain.

No idea on non-uniform grids levelling, I would probably start looking at bCNC's autoleveller since it looks relatively advanced.

Sure, feel free to reach me at: brainstorm at nopcode dot org.