-
Notifications
You must be signed in to change notification settings - Fork 227
Description
Hello, I'm currently learning how to use CMake and pybind11 with this project. As part of the installation process, I need to build and install a C++ source file. To ensure that everything is clear, I've included the reproduction code below.
Description
- My project structure: It's basically the same except there is my cpp source file
helloworld.cpp
insrc/
folder.
$ tree -L 2
.
├── CMakeLists.txt
├── pybind11
├── pyproject.toml
├── setup.py
└── src
├── helloworld.cpp
└── main.cpp
src/helloworld.cpp
: A trivial helloworld program.$ cat src/helloworld.cpp
#include <iostream>
int main(int argc, char **argv) {
std::cout << "Hello World!!!\n";
return 0;
}
CMakeLists.txt
: It's basically the same as CMakeLists.tx exceptadd_executable(helloworld src/helloworld.cpp)
is added to build executable.
$ cat CMakeLists.txt
cmake_minimum_required(VERSION 3.22)
project(cmake_example)
add_executable(helloworld src/helloworld.cpp)
add_subdirectory(pybind11)
pybind11_add_module(cmake_example src/main.cpp)
target_compile_definitions(cmake_example
PRIVATE VERSION_INFO=${EXAMPLE_VERSION_INFO})
pyproject.toml
:
$ cat pyproject.toml
[build-system]
requires = ["setuptools>=62.0.0", "wheel", "cmake>=3.22"]
build-backend = "setuptools.build_meta"
pybind11
is a git submodule, andsetup.py
is exactly the same as this setup.py.
Build in normal mode.
- Create virtual env and update pip:
python3 -m venv venv && source venv/bin/activate && python3 -m pip install --upgrade pip
- Install in normal mode:
python3 -m pip install .
cmake_example
library is installed correctly but myhelloworld
program is not. There is nohelloworld
program invenv
.
$ ls venv/lib/python3.8/site-packages/
cmake_example-0.0.1.dist-info
cmake_example.cpython-38-x86_64-linux-gnu.so
Build in editable mode.
- Create virtual env and update pip:
python3 -m venv venv && source venv/bin/activate && python3 -m pip install --upgrade pip
- Install in editable mode:
python3 -m pip install -e .
cmake_example
library is also installed correctly but myhelloworld
program is not. There is nohelloworld
program created in the current folder.
$ ls
cmake_example.cpython-38-x86_64-linux-gnu.so cmake_example.egg-info CMakeLists.txt pybind11 pyproject.toml setup.py src venv
My experiment:
I actually tried to make it work by modifying setup.py
with the following way.
- Add code snippet in
setup.py
in Line:47.
bindir = extdir / "bin"
print(f"User's executables resides in {bindir}")
cmake_args = [
# My innovation. helloworld can be called in scripts.
f"-DCMAKE_RUNTIME_OUTPUT_DIRECTORY={bindir}{os.sep}",
f"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={extdir}{os.sep}",
f"-DPYTHON_EXECUTABLE={sys.executable}",
f"-DCMAKE_BUILD_TYPE={cfg}", # not used on MSVC, but no harm
]
This approach kind of work. Now I can do pip install .
and helloworld
program appears in venv/lib/python3.8/site-packages/bin/helloworld
. However, this approach doesn't work in editable model. I.e., I do pip install -e .
, but helloworld
program is no created anywhere in the project.
My question is how to achieve the following goal: I would like the helloworld
program to be created automatically when I run pip install .
and pip install -e .
, and I want this program to be installed in the correct Python root path in both modes. Do you have any suggestions or advice on how I can make this happen? Thank you for your help!
System info:
OS: ubuntu20.04
Python: Python3.8