Skip to content

Commit 9bce065

Browse files
committed
Split pybind11 into headers and cpp files to speedup compilation
As discussed at pybind#2322, the split is opt-in. If the PYBIND11_HEADER_ONLY is not defined, then the .cpp files are included in the .h files. PYBIND11_INLINE is introduced because if the header functions are marked inline, then that makes the symbol not show in the object file, so inline must be turned on or off depending on PYBIND11_HEADER_ONLY.
1 parent 1abc4a9 commit 9bce065

File tree

9 files changed

+1309
-1160
lines changed

9 files changed

+1309
-1160
lines changed

CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,3 +269,12 @@ if(NOT PYBIND11_MASTER_PROJECT)
269269
"${PYBIND11_INCLUDE_DIR}"
270270
CACHE INTERNAL "Directory where pybind11 headers are located")
271271
endif()
272+
273+
find_package (Python3 COMPONENTS Development)
274+
include_directories(${Python3_INCLUDE_DIRS})
275+
add_definitions(-DPYBIND11_HEADER_ONLY=1)
276+
file(GLOB SOURCES ${CMAKE_SOURCE_DIR}/include/pybind11/*.cpp)
277+
# Produce libpybind11.a, which contains position independent object files.
278+
# that may be used to create a shared library.
279+
add_library(pybind11 STATIC ${SOURCES})
280+
set_property(TARGET pybind11 PROPERTY POSITION_INDEPENDENT_CODE ON)

include/pybind11/attr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ enum op_id : int;
119119
enum op_type : int;
120120
struct undefined_t;
121121
template <op_id id, op_type ot, typename L = undefined_t, typename R = undefined_t> struct op_;
122-
inline void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret);
122+
void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret);
123123

124124
/// Internal data structure which holds metadata about a keyword argument
125125
struct argument_record {

include/pybind11/cast.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class loader_life_support {
8989
// Gets the cache entry for the given type, creating it if necessary. The return value is the pair
9090
// returned by emplace, i.e. an iterator for the entry and a bool set to `true` if the entry was
9191
// just created.
92-
inline std::pair<decltype(internals::registered_types_py)::iterator, bool> all_type_info_get_cache(PyTypeObject *type);
92+
std::pair<decltype(internals::registered_types_py)::iterator, bool> all_type_info_get_cache(PyTypeObject *type);
9393

9494
// Populates a just-created cache entry.
9595
PYBIND11_NOINLINE inline void all_type_info_populate(PyTypeObject *t, std::vector<type_info *> &bases) {
@@ -481,7 +481,7 @@ inline PyThreadState *get_thread_state_unchecked() {
481481
}
482482

483483
// Forward declarations
484-
inline void keep_alive_impl(handle nurse, handle patient);
484+
void keep_alive_impl(handle nurse, handle patient);
485485
inline PyObject *make_new_instance(PyTypeObject *type);
486486

487487
class type_caster_generic {

include/pybind11/detail/common.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,27 @@
8383
#if defined(_MSC_VER)
8484
# define PYBIND11_NOINLINE __declspec(noinline)
8585
#else
86-
# define PYBIND11_NOINLINE __attribute__ ((noinline))
86+
# if PYBIND11_HEADER_ONLY
87+
# define PYBIND11_NOINLINE __attribute__ ((noinline))
88+
# else
89+
// Otherwise GCC 9 would emit warnings for functions that are marked both
90+
// inline and noinline if we weren't enabling:
91+
// #pragma GCC diagnostic ignored "-Wattributes"
92+
// as is currently done in Pybind11. This way we remove reliance on this
93+
// disabled warning.
94+
# define PYBIND11_NOINLINE
95+
# endif
96+
#endif
97+
98+
// Must be used in every .cpp function definition:
99+
// - on header-only mode, functions must be marked as inline
100+
// to prevent multiple definitions
101+
// - on non-header-only mode, functions must not be marked as inline
102+
// so that the symbols will be visible from other objects
103+
#if PYBIND11_HEADER_ONLY
104+
# define PYBIND11_INLINE
105+
#else
106+
# define PYBIND11_INLINE inline
87107
#endif
88108

89109
#if defined(PYBIND11_CPP14)

include/pybind11/options.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include "options.h"
2+
3+
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
4+
5+
PYBIND11_INLINE options::options() : previous_state(global_state()) {}
6+
7+
PYBIND11_INLINE options::~options() {
8+
global_state() = previous_state;
9+
}
10+
11+
PYBIND11_INLINE options& options::disable_user_defined_docstrings() & { global_state().show_user_defined_docstrings = false; return *this; }
12+
13+
PYBIND11_INLINE options& options::enable_user_defined_docstrings() & { global_state().show_user_defined_docstrings = true; return *this; }
14+
15+
PYBIND11_INLINE options& options::disable_function_signatures() & { global_state().show_function_signatures = false; return *this; }
16+
17+
PYBIND11_INLINE options& options::enable_function_signatures() & { global_state().show_function_signatures = true; return *this; }
18+
19+
PYBIND11_INLINE bool options::show_user_defined_docstrings() { return global_state().show_user_defined_docstrings; }
20+
21+
PYBIND11_INLINE bool options::show_function_signatures() { return global_state().show_function_signatures; }
22+
23+
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

include/pybind11/options.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,32 +17,30 @@ class options {
1717
public:
1818

1919
// Default RAII constructor, which leaves settings as they currently are.
20-
options() : previous_state(global_state()) {}
20+
options();
2121

2222
// Class is non-copyable.
2323
options(const options&) = delete;
2424
options& operator=(const options&) = delete;
2525

2626
// Destructor, which restores settings that were in effect before.
27-
~options() {
28-
global_state() = previous_state;
29-
}
27+
~options();
3028

3129
// Setter methods (affect the global state):
3230

33-
options& disable_user_defined_docstrings() & { global_state().show_user_defined_docstrings = false; return *this; }
31+
options& disable_user_defined_docstrings() &;
3432

35-
options& enable_user_defined_docstrings() & { global_state().show_user_defined_docstrings = true; return *this; }
33+
options& enable_user_defined_docstrings() &;
3634

37-
options& disable_function_signatures() & { global_state().show_function_signatures = false; return *this; }
35+
options& disable_function_signatures() &;
3836

39-
options& enable_function_signatures() & { global_state().show_function_signatures = true; return *this; }
37+
options& enable_function_signatures() &;
4038

4139
// Getter methods (return the global state):
4240

43-
static bool show_user_defined_docstrings() { return global_state().show_user_defined_docstrings; }
41+
static bool show_user_defined_docstrings();
4442

45-
static bool show_function_signatures() { return global_state().show_function_signatures; }
43+
static bool show_function_signatures();
4644

4745
// This type is not meant to be allocated on the heap.
4846
void* operator new(size_t) = delete;
@@ -63,3 +61,7 @@ class options {
6361
};
6462

6563
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
64+
65+
#if !PYBIND11_HEADER_ONLY
66+
#include "options.cpp"
67+
#endif

0 commit comments

Comments
 (0)