www.delorie.com/archives/browse.cgi   search  
Mail Archives: geda-user/2015/09/20/15:58:28

X-Authentication-Warning: delorie.com: mail set sender to geda-user-bounces using -f
X-Recipient: geda-user AT delorie DOT com
Date: Sun, 20 Sep 2015 21:57:34 +0200 (CEST)
From: Roland Lutz <rlutz AT hedmen DOT org>
To: geda-user AT delorie DOT com
Subject: [geda-user] Try Xorn now!
Message-ID: <alpine.DEB.2.11.1509201637390.4920@newt>
User-Agent: Alpine 2.11 (DEB 23 2013-08-11)
MIME-Version: 1.0
Reply-To: geda-user AT delorie DOT com

In the previous discussion, I realized that few people had actually looked 
at Xorn.  Since the API documentation didn't seem to be a good starting 
point, I compiled a friendly step-for-step introduction to Xorn, and I 
encourage you to try it now.  Grab a cup of coffee, make yourself 
comfortable, and get on with your first steps:

1. Make sure that, in addition to the usual gEDA build dependencies, a 
C++ compiler (preferably g++) and Python 2.7 (including the development 
headers) are installed on your system.

2. Pull the latest gEDA sources, re-run ./autogen.sh, and configure and 
build the package as usual.  If you prefer downloading a tarball, you can 
pick up the Xorn sources from [0].  In either case, you don't need to 
install the package (but you can if you prefer to).

3a. Invoke the "xorn" executable with the option "--help" to see a list of 
subcommands:

     xorn/src/command/xorn --help

(or "src/command/xorn --help" if you downloaded the Xorn tarball, or just 
"xorn --help" if you installed Xorn to your PATH)

3b. Run the subcommand "xorn netlist" with the options "--help" and 
"--list-backends" to print a list of options and available backends.

     xorn/src/command/xorn netlist --help
     xorn/src/command/xorn netlist --list-backends

3c. Process a schematic with "xorn netlist" (using the "PCB" backend as 
an example):

     xorn/src/command/xorn netlist \
       --symbol-library-search=/usr/share/gEDA/sym \
       -g PCB some-schematic.sch

You now know how to use Xorn as a command-line utility.

4. Write a C program using libxornstorage and link it against the library:

     $ cat > example.c
     #include <stdio.h>
     #include <stdlib.h>
     #include <string.h>
     #include <xornstorage.h>

     int main()
     {
         xorn_revision_t rev;
         xorn_object_t net_ob;
         struct xornsch_net net_data;
         xorn_object_t *objects;
         size_t count;

         rev = xorn_new_revision(NULL);

         memset(&net_data, 0, sizeof net_data);
         net_data.pos.x = 0;
         net_data.pos.y = 200;
         net_data.size.x = 100;
         net_data.size.y = 0;
         net_data.color = 4;
         net_ob = xornsch_add_net(rev, &net_data);

         xorn_finalize_revision(rev);

         xorn_get_objects(rev, &objects, &count);
         printf("%d object(s) found\n", count);
         free(objects);

         xorn_free_revision(rev);
         return 0;
     }
     ^D
     $ gcc -I xorn/include -c example.c
     $ ./libtool --mode=link gcc -o example \
         example.o xorn/src/storage/libxornstorage.la
     $ ./example
     1 object(s)

If you are using a separate build directory, replace "-I xorn/include" 
with the path to the subdirectory "xorn/include" in the source directory.

You now know how to interact with Xorn in a C program.  For more 
information, see the libxornstorage API documentation[1,2].

5. Run the Python 2.7 interpreter with the subdirectory 
"xorn/built-packages" added to the environment variable "PYTHONPATH".

     $ PYTHONPATH=xorn/built-packages python2.7
     Python 2.7.9 (default, Mar  1 2015, 18:22:53)
     [GCC 4.9.2] on linux2
     Type "help", "copyright", "credits" or "license" for more information.
     >>>

Import the module "xorn.storage" and experiment a bit with the API.  Here 
is how to perform the operations equivalent to the C program above:

     >>> import xorn.storage
     >>> rev = xorn.storage.Revision()
     >>> net_data = xorn.storage.Net(
             x = 0, y = 200, width = 100, height = 0, color = 4)
     >>> net_ob = rev.add_object(net_data)
     >>> rev.finalize()
     >>> rev.get_objects()
     [<xorn.storage.Object object at ...>]

Import the module "xorn.geda.read" and load a schematic or symbol file:

     >>> import xorn.geda.read
     >>> rev = xorn.geda.read.read(
             '/usr/share/gEDA/sym/analog/resistor-1.sym')
     >>> for ob in rev.toplevel_objects():
     ...     data = ob.data()
     ...     if isinstance(data, xorn.storage.Text):
     ...         print data.text
     ...
     device=RESISTOR
     refdes=R?
     pins=2
     class=DISCRETE

For more information, see the API documentation of xorn.storage[3] and 
xorn.geda[4].

6. Write and execute a Python program which uses the xorn package:

     $ cat > print-attributes.py
     #!/usr/bin/env python2
     import sys
     import xorn.storage
     import xorn.geda.read

     rev = xorn.geda.read.read(sys.argv[1])
     for ob in rev.toplevel_objects():
         data = ob.data()
         if isinstance(data, xorn.storage.Text):
             print data.text
     ^D
     $ chmod +x print-attributes.py
     $ PYTHONPATH=xorn/built-packages ./print-attributes.py \
         /usr/share/gEDA/sym/analog/resistor-1.sym
     device=RESISTOR
     refdes=R?
     pins=2
     class=DISCRETE

You now know how to use Xorn as a library in your own programs.

7. Invoke "xorn netlist" on your schematic as above, but instead of 
specifying a netlist backend, use the option "-i":

     $ xorn/src/command/xorn netlist \
         --symbol-library-search=/usr/share/gEDA/sym \
         -i some-schematic.sch
     Python 2.7.9 (default, Mar  1 2015, 18:22:53)
     [GCC 4.9.2] on linux2
     Type "help", "copyright", "credits" or "license" for more information.
     (InteractiveConsole)
     >>>

This option causes "xorn netlist" to enter interactive mode.  You are now 
in an interactive Python interpreter session, just like above, but have 
the additional global variable "netlist" available which contains the 
netlist's contents.

     >>> netlist
     <xorn.geda.netlist.netlist.Netlist instance at ...>
     >>> netlist.nets
     [<xorn.geda.netlist.net.Net instance at ...>, ...]
     >>> [net.name for net in netlist.nets]
     [..., 'GND', ...]
     >>> netlist.nets_by_name['GND']
     <xorn.geda.netlist.net.Net instance at ...>
     >>> netlist.nets_by_name['GND'].name
     'GND'
     >>> netlist.nets_by_name['GND'].connections
     [<xorn.geda.netlist.package.PackagePin instance at ...>, ...]
     >>> netlist.nets_by_name['GND'].connections[0].package
     <xorn.geda.netlist.package.Package instance at ...>
     >>> netlist.nets_by_name['GND'].connections[0].package.refdes
     'U100'
     >>> netlist.nets_by_name['GND'].connections[0].number
     '7'

     >>> netlist.packages
     [<xorn.geda.netlist.package.Package instance at ...>]
     >>> netlist.packages_by_refdes
     {..., 'U100': <xorn.geda.netlist.package.Package instance at ...>, ...}
     >>> netlist.packages_by_refdes['U100'].get_attribute('device')
     ...
     >>> netlist.packages_by_refdes['U100'].pins
     [<xorn.geda.netlist.package.PackagePin instance at ...>, ...]
     >>> netlist.packages_by_refdes['U100'].pins_by_number
     {..., '7': <xorn.geda.netlist.package.PackagePin instance at ...>, ...}
     >>> netlist.packages_by_refdes['U100'].pins_by_number['7'].net
     <xorn.geda.netlist.net.Net instance at ...>
     >>> netlist.packages_by_refdes['U100'].pins_by_number['7'].net.name
     'GND'

8. Write a Python module whose name starts with "gnet_" and which contains 
a function "run(f, netlist)".  Use this module as a netlist backend:

     $ cat > gnet_count.py
     def run(f, netlist):
         f.write("%d packages found\n" % len(netlist.packages))
         f.write("%d nets found\n" % len(netlist.nets))
     ^D
     $ xorn/src/command/xorn netlist \
         --symbol-library-search=/usr/share/gEDA/sym \
         -L . -g count some-schematic.sch
     1 packages found
     4 nets found

You now know how to write your own netlist backends to generate a custom 
netlist format from a set of schematics.

I hope this little introduction helped reduce the barrier to get started 
with Xorn.  If you have any questions, feel free to ask, either on the 
list or privately.  And finally, don't hesitate to look at the code if 
something is unclear--I've put much work into making it as readable as 
possible, and even if you're not familiar with Python, you'll probably be 
able to understand what's going on.

Roland


[0] http://hedmen.org/xorn/xorn-netlist-20150903.tar.gz
[1] http://hedmen.org/xorn/doc/api/html/xornstorage_8h.html
[2] http://hedmen.org/xorn/doc/api/html/storage.html
[3] http://hedmen.org/xorn/doc/api/html/namespacexorn_1_1storage.html
[4] http://hedmen.org/xorn/doc/api/html/namespacexorn_1_1geda.html

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019