ExternalProject_Add 使用 pybind11 进行 CMake 项目的智能方法
Posted
技术标签:
【中文标题】ExternalProject_Add 使用 pybind11 进行 CMake 项目的智能方法【英文标题】:Smart way to CMake a project using pybind11 by ExternalProject_Add 【发布时间】:2017-10-31 04:07:38 【问题描述】:我正在使用pybind11
和CMake
3.9.4 编写一个python 模块。
为方便起见,我希望在我的CMakeLists.txt
中使用ExternalProject_Add
下载pybind11
源文件。
当我运行cmake .
时,它没有下载pybind11
源文件,并抛出错误。
CMake Error at CMakeLists.txt:21 (add_subdirectory):
The source directory
/Users/me/foo/pybind11_external-prefix/src/pybind11_external
does not contain a CMakeLists.txt file.
CMake Error at CMakeLists.txt:22 (pybind11_add_module):
Unknown CMake command "pybind11_add_module".
有一个解决方法:
-
注释掉 CMakeLists.txt 中的最后 3 行
运行
cmake .
运行make
(然后,它会下载pybind11
源文件)
恢复 CMakeLists.txt 的最后 3 行
运行cmake .
运行make
但是,这并不聪明...有没有办法使用ExternalProject_Add
下载pybind11
而无需注释掉并恢复它们(并且无需运行cmake
和make
两次)?
/Users/me/foo/CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(foo)
set(CMAKE_CXX_STANDARD 14)
include(ExternalProject)
ExternalProject_Add(
pybind11_external
GIT_REPOSITORY https://github.com/pybind/pybind11.git
GIT_TAG v2.2.1
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
set(PYBIND11_CPP_STANDARD -std=c++14)
ExternalProject_Get_Property(pybind11_external source_dir)
include_directories($source_dir/include)
add_subdirectory($source_dir) # comment out, then restore this line
pybind11_add_module(foo SHARED foo.cpp) # comment out, then restore this line
add_dependencies(foo pybind11_external) # comment out, then restore this line
/Users/me/foo/foo.hpp
#ifndef FOO_LIBRARY_H
#define FOO_LIBRARY_H
#include<pybind11/pybind11.h>
int add(int i, int j);
#endif
/Users/me/foo/foo.cpp
#include "foo.hpp"
int add(int i, int j)
return i + j;
PYBIND11_MODULE(example, m)
m.doc() = "pybind11 example plugin";
m.def("add", &add, "A function which adds two numbers");
【问题讨论】:
您的问题是 ExternalProject 仅在主项目的 build stage 构建。所以add_subdirectory()
进入 ExternalProject 是行不通的,因为它是在配置阶段处理的。 That question 描述了在配置阶段构建 ExternalProject。
【参考方案1】:
使用 CMake 的 FetchContent 模块(版本 3.11+),您可以这样做:
include(FetchContent)
FetchContent_Declare(
pybind11
GIT_REPOSITORY https://github.com/pybind/pybind11
GIT_TAG v2.2.3
)
FetchContent_GetProperties(pybind11)
if(NOT pybind11_POPULATED)
FetchContent_Populate(pybind11)
add_subdirectory($pybind11_SOURCE_DIR $pybind11_BINARY_DIR)
endif()
这将在配置时下载 pybind11,并add_subdirectory
它。然后你就可以打电话给pybind11_add_module
了。
【讨论】:
以上是关于ExternalProject_Add 使用 pybind11 进行 CMake 项目的智能方法的主要内容,如果未能解决你的问题,请参考以下文章
ExternalProject_Add 使用 pybind11 进行 CMake 项目的智能方法
CMake ExternalProject_Add() 和 FindPackage()
如何将环境变量传递给 ExternalProject_Add CONFIGURE_COMMAND?
cmake:ExternalProject_Add() 不应用 cmake 参数