Installing your C library for end users¶
Your generated project is already a distributable C library. After
cmake --install, end users who don't touch Python at all can link against
it with a single pkg-config or find_package call:
find_package(my_project REQUIRED)
target_link_libraries(my_app PRIVATE my_project::my_project_lib m)
No just-makeit required on the consumer's machine. The sections below walk through prerequisites, build, install, and runtime loading.
Prerequisites¶
The end user needs the following tools — just-makeit itself is not required:
| Tool | Minimum version | Notes |
|---|---|---|
| CMake | 3.16 | Build system; drives configure + install |
| A C99 compiler | GCC 8 / Clang 10 | gcc or clang; on Windows use MinGW/gcc — MSVC rejects float _Complex |
| pkg-config | any | For pkg-config consumers only |
Linux (Debian/Ubuntu):
macOS (Homebrew):
Windows (MSYS2/MinGW):
Overview¶
Every just-makeit project ships a lib<project>.so in addition to its Python
extensions. The same C code drives both: each component compiles once as a
CMake OBJECT library and links into both the Python .so and the combined
shared library. End users who don't use Python at all can consume it via the
standard mechanisms below.
This applies to all project layouts — standalone objects (just-makeit object),
multi-type modules (just-makeit module + just-makeit object --module), or a mix of both.
What gets installed¶
$PREFIX/
├── include/
│ ├── my_project.h # umbrella header — include this
│ ├── component_a/
│ │ └── component_a_core.h
│ └── component_b/
│ └── component_b_core.h
├── lib/
│ ├── libmy_project.so # shared library
│ ├── pkgconfig/
│ │ └── my-project.pc # pkg-config descriptor
│ └── cmake/my_project/
│ ├── my_project-config.cmake
│ └── my_project-config-version.cmake
Build and install¶
Set the install prefix before building — cmake bakes the prefix into the
generated my-project.pc at configure time.
For a non-root local install substitute any writable path:
Note:
make && make testcallscmake -B buildinternally with the default prefix. If you ranmakefirst, re-run thecmake -S .line above before installing to regenerate the.pcfile with the correct prefix.
Using with pkg-config¶
Compile a consumer:
gcc $(pkg-config --cflags my-project) \
consumer.c \
$(pkg-config --libs my-project) \
-lm -o consumer
Linux /
--as-needednote: Split--cflagsand--libswith the source file between them. GNU ld on Debian/Ubuntu uses--as-neededby default, which silently drops any shared library that appears before the object files referencing it. If you merge them with the source last ($(pkg-config --cflags --libs my-project) consumer.c) you will get undefined-reference errors at link time even though the library is present.
If you installed to a non-standard prefix, point pkg-config at it:
Using with CMake¶
cmake_minimum_required(VERSION 3.16)
project(my_consumer C)
find_package(my_project REQUIRED)
add_executable(consumer consumer.c)
target_link_libraries(consumer PRIVATE my_project::my_project_lib m)
Configure with the prefix if it's not on the default search path:
Runtime loading (rpath)¶
The installed .so is not automatically on the dynamic linker's search path
unless you installed to /usr/local (or ran ldconfig after a system-wide
install).
For a custom prefix, embed the library path in the binary at link time:
pkg-config:
LIB_DIR=$(pkg-config --variable=libdir my-project)
gcc $(pkg-config --cflags my-project) \
consumer.c \
$(pkg-config --libs my-project) \
-Wl,-rpath,"$LIB_DIR" \
-lm -o consumer
CMake: set INSTALL_RPATH_USE_LINK_PATH or CMAKE_BUILD_RPATH:
Or pass it on the command line:
Alternatively, set LD_LIBRARY_PATH at runtime (useful for quick testing,
not for deployment):