Супер марио на баяне
Использование precompiled headers в CMake – 2
Еще один один вариант использования precompiled headers в CMake. Подсмотрено в Ogre3D:
#-------------------------------------------------------------------
# This file is part of the CMake build system for OGRE
# (Object-oriented Graphics Rendering Engine)
# For the latest info, see http://www.ogre3d.org/
#
# The contents of this file are placed in the public domain. Feel
# free to make use of it in any way you like.
#-------------------------------------------------------------------
##################################################################
# Support macro to use a precompiled header
# Usage:
# use_precompiled_header(TARGET HEADER_FILE SRC_FILE)
##################################################################
macro(use_precompiled_header TARGET HEADER_FILE SRC_FILE)
get_filename_component(HEADER ${HEADER_FILE} NAME)
if (MSVC)
add_definitions(/Yu"${HEADER}")
set_source_files_properties(${SRC_FILE}
PROPERTIES COMPILE_FLAGS /Yc"${HEADER}"
)
elseif (CMAKE_COMPILER_IS_GNUCXX)
# disabled because it seems to increase compile time
## this is some serious hack... we definitely need native
## support in CMake for this!
## we will generate the precompiled header via a workaround
## first give the header a new name with the proper extension
#set(PRECOMP_HEADER ${CMAKE_CURRENT_BINARY_DIR}/hacked/${HEADER}.gch)
#configure_file(${HEADER_FILE} ${PRECOMP_HEADER} COPYONLY)
## retrieve some info about the target's build settings
#get_target_property(${TARGET} PRECOMP_TYPE TYPE)
#if (PRECOMP_TYPE STREQUAL "SHARED_LIBRARY")
# set(PRECOMP_LIBTYPE "SHARED")
#else ()
# set(PRECOMP_LIBTYPE "STATIC")
#endif ()
#get_target_property(${TARGET} PRECOMP_DEFINITIONS COMPILE_DEFINITIONS)
#get_target_property(${TARGET} PRECOMP_FLAGS COMPILE_FLAGS)
#
## add a new target which compiles the header
#add_library(__precomp_header ${PRECOMP_LIBTYPE} ${PRECOMP_HEADER})
#add_dependencies(${TARGET} __precomp_header)
#set_target_properties(__precomp_header PROPERTIES
# COMPILE_DEFINITIONS ${PRECOMP_DEFINITIONS}
# COMPILE_FLAGS ${PRECOMP_FLAGS}
# HAS_CXX TRUE
#)
#set_source_files_properties(${PRECOMP_HEADER} PROPERTIES
# HEADER_FILE_ONLY FALSE
# KEEP_EXTENSION TRUE
# COMPILE_FLAGS "-x c++-header"
# LANGUAGE CXX
#)
#
## finally, we need to ensure that gcc can find the precompiled header
## this is another dirty hack
#include_directories(BEFORE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/__precomp_header.dir/hacked")
endif ()
endmacro(use_precompiled_header)
Использование также тривиально:
FILE( GLOB_RECURSE SRC *.cpp )
USE_PRECOMPILED_HEADER( projectName "precompiled.h" "precompiled.cpp" )
UPDATE: Окончательный вариант precompiled headers смотрим здесь.
Создание модуля расширения для Python на языке Си
Простой, а главное — рабочий пример модуля расширения на языке C для питона. Модуль называется example, а реализовывает одну функцию hello, которая вызывается с параметром who и возвращает «Hello %s» % who.
Листинг модуля example.c
Python 2.xx
#include <Python.h>
PyObject *hello( PyObject *self, PyObject *args, PyObject *kwargs )
{
char *who = 0;
static char *keywords[] = {"who", NULL};
PyObject *result = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", keywords, &who))
{
return NULL;
}
result = PyString_FromString("Hello ");
PyString_Concat(&result, PyString_FromString(who));
return result;
}
static PyMethodDef example_methods[] =
{
{ "hello", (PyCFunction) hello, METH_KEYWORDS, "hello(who) -- return "Hello who"" },
{ NULL, 0, 0, NULL }
};
PyMODINIT_FUNC initexample()
{
(void) Py_InitModule("example", example_methods);
if (PyErr_Occurred())
{
PyErr_SetString(PyExc_ImportError, "example module init failed");
}
}
Python 3.xx
#include <Python.h>
PyObject *hello( PyObject *self, PyObject *args, PyObject *kwargs )
{
char *who = 0;
static char *keywords[] = {"who", NULL};
if (PyArg_ParseTupleAndKeywords(args, kwargs, "s", keywords, &who))
{
return PyUnicode_FromFormat("Hello %s", who);
}
return NULL;
}
static PyMethodDef example_methods[] =
{
{ "hello", (PyCFunction) hello, METH_KEYWORDS, "hello(who) -- return "Hello who"" },
{ NULL, 0, 0, NULL }
};
static struct PyModuleDef example_module =
{
PyModuleDef_HEAD_INIT,
"example",
NULL,
-1,
example_methods
};
PyMODINIT_FUNC PyInit_example(void)
{
return PyModule_Create(&example_module);
}
Листинг setup.py
setup.py
from distutils.core import setup
from distutils.extension import Extension
examplemodule = Extension(name="example", sources=['example.c', ])
setup(name="example", ext_modules=[examplemodule])
Компилируем:
python setup.py build
Инсталлируем:
python setup.py install
Выполняем простенький тест:
from example import hello
print hello(who="world!")
Радуемся :)
Hello world!
Полезные ссылки (на английском):
Цикл статей про Boost.Python на хабре:
- Объединяя C++ и Python. Тонкости Boost.Python. Часть первая
- Объединяя C++ и Python. Тонкости Boost.Python. Часть вторая
- Конвертация типов в Boost.Python. Делаем преобразование между привычными типами C++ и Python
- Путешествие исключений между C++ и Python или «Туда и обратно»
P.S. По своему опыту могу сказать, что Boost.Python — редкостное барахло, возьмите лучше библиотеку PyCXX.
Определитель матрицы 3×3
Определитель матрицы 3×3 вычисляется следующим образом:
\Delta(A)=\begin{bmatrix}a_{11}&a_{12}&a_{13}\\a_{21}&a_{22}&a_{23}\\a_{31}&a_{32}&a_{33}\end{bmatrix}=a_{11}\begin{bmatrix}a_{22}&a_{23}\\a_{32}&a_{33}\end{bmatrix}-a_{12}\begin{bmatrix}a_{21}&a_{23}\\a_{31}&a_{33}\end{bmatrix}+a_{13}\begin{bmatrix}a_{21}&a_{22}\\a_{31}&a_{32}\end{bmatrix}=a_{11}(a_{22}a_{33}-a_{23}a_{32})-a_{12}(a_{23}a_{33}-a_{23}a_{31})+a_{13}(a_{21}a_{32}-a_{22}a_{31})