Skip to content

Commit

Permalink
Merge branch 'stable' of github.com:tbenthompson/cppimport into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
tbenthompson committed Jun 7, 2016
2 parents 80af82c + 61cf225 commit 620cdcd
Showing 1 changed file with 27 additions and 6 deletions.
33 changes: 27 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,36 @@ I'm a big fan of the workflow that this enables, where you can edit both C++ fil

# What's actually going on?

**The technical description:** cppimport looks for a C or C++ source file that matches the requested module. If such a file exists, the file is compiled as a Python extension using the options in a Mako header. The extension (shared library) that is produced is placed in the same folder as the C++ source file. Then, the extension is loaded.
**The technical description:** cppimport looks for a C or C++ source file that matches the requested module. If such a file exists, the file is first run through the Mako templating system. The compilation options produced by the Mako pass are then use to compile the file as a Python extension. The extension (shared library) that is produced is placed in the same folder as the C++ source file. Then, the extension is loaded.

**Simpler language please:** Sometimes Python just isn't fast enough. Or you have existing code in a C++ library. So, you write a Python *extension module*, a library of compiled code. I recommend [pybind11](https://github.com/pybind/pybind11) for C++ to Python bindings or [cffi](https://cffi.readthedocs.io/en/latest/) for C to Python bindings. I've done this a lot over the years. But, I discovered that my productivity goes through the floor when my development process goes from *Edit -> Test* in just Python to *Edit -> Compile -> Test* in Python plus C++. So, `cppimport` combines the process of compiling and importing an extension in Python so that you can type `modulename = cppimport.imp("modulename")` and not have to worry about multiple steps. Internally, when no matching Python module is found, `cppimport` looks for a file `modulename.cpp`. If one is found, it's compiled and loaded as an extension module.
**Simpler language please:** Sometimes Python just isn't fast enough. Or you have existing code in a C++ library. So, you write a Python *extension module*, a library of compiled code. I recommend [pybind11](https://github.com/pybind/pybind11) for C++ to Python bindings or [cffi](https://cffi.readthedocs.io/en/latest/) for C to Python bindings. I've done this a lot over the years. But, I discovered that my productivity goes through the floor when my development process goes from *Edit -> Test* in just Python to *Edit -> Compile -> Test* in Python plus C++. So, `cppimport` combines the process of compiling and importing an extension in Python so that you can type `modulename = cppimport.imp("modulename")` and not have to worry about multiple steps. Internally, `cppimport` looks for a file `modulename.cpp`. If one is found, it's run through the Mako templating system to gather compiler options, then it's compiled and loaded as an extension module.

# Notes
[1]: The compilation should only happen the first time the module is imported. The C++ source is compared with a checksum on each import to determine if the file has changed. Included files are also incorporated into the checksum so recompilation happens automatically when a header file is edited.
### Recompilation only happens when necessary:
Compilation should only happen the first time the module is imported. The C++ source is compared with a checksum on each import to determine if the file has changed. Additional dependencies (header files!) can be tracked by adding to the Mako header:
```
cfg['dependencies'] = ['file1.h', 'file2.h']
```

### I need to set the compiler or linker args!
```
cfg['linker_args'] = ['...']
cfg['compiler_args'] = ['...']
cfg['libraries'] = ['...']
cfg['include_dirs'] = ['...']
```

### I want multiple source files for one extension!
```
cfg['sources'] = ['...']
```

### I need more output!
Calling `cppimport.set_quiet(False)` will result in output that will be helpful in debugging compile errors.

[2]: Calling `cppimport.set_quiet(False)` will result in output that will be helpful in debugging compile errors. The default is to make the import process completely silent.
### Sometimes I need to force a rebuild even when the checksum matches
Call `cppimport.force_rebuild()` before running `cppimport.imp(...)`.

[3]: cppimport currently does not work on Windows. If you're on Windows and you really want cppimport, I'll happily accept a pull request.
### Windows?
I don't know if `cppimport` works on Windows. If you're on Windows, try it out and I'll happily accept a pull request for any issues that you fix.

# cppimport uses the MIT License

0 comments on commit 620cdcd

Please sign in to comment.