Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add python bindings for configurations #125

Open
wants to merge 15 commits into
base: vara-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion bindings/python/vara-feature/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pybind11_add_module(
vara_feature
pybind_Init.cpp
pybind_Configuration.cpp
pybind_Constraint.cpp
pybind_Feature.cpp
pybind_FeatureModel.cpp
Expand All @@ -12,4 +13,10 @@ pybind11_add_module(

set(LLVM_LINK_COMPONENTS Core Support)

target_link_libraries(vara_feature LINK_PUBLIC VaRAFeature ${STD_FS_LIB})
target_link_libraries(
vara_feature
LINK_PUBLIC
VaRAFeature
VaRASolver
${STD_FS_LIB}
)
45 changes: 45 additions & 0 deletions bindings/python/vara-feature/pybind_Configuration.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "pybind_common.h"
#include "vara/Configuration/Configuration.h"
#include "vara/Solver/ConfigurationFactory.h"

#include "pybind11/detail/common.h"
#include "pybind11/pybind11.h"

#include <filesystem>
#include <iostream>

namespace vf = vara::feature;
namespace vs = vara::solver;
namespace py = pybind11;

void init_configuration_module(py::module &M) {
py::class_<vf::ConfigurationOption>(M, "ConfigurationOption")
.def_property_readonly(
"name", [](vf::ConfigurationOption &CO) { return CO.name().str(); },
R"pbdoc(Returns the name of the ConfigurationOption.)pbdoc")
.def_property_readonly(
"value", &vf::ConfigurationOption::asString,
R"pbdoc(Returns the value of the ConfigurationOption as str.)pbdoc");
py::class_<vf::Configuration>(M, "Configuration")
.def("__str__", [](vf::Configuration &C) { return C.dumpToString(); })
.def("getOptions", [](vf::Configuration &C) {
std::vector<vf::ConfigurationOption> V;
for (auto &O : C) {
V.push_back(*O.getValue());
}

return V;
});
M.def(
"getAllConfigs",
[](vf::FeatureModel &FM) {
return vs::ConfigurationFactory::getAllConfigs(FM).extractValue();
},
R"pbdoc(Get all configurations of FeatureModel.

Args:
fm (FeatureModel): the FeatureModel

Returns: list of all configurations.
)pbdoc");
}
3 changes: 3 additions & 0 deletions bindings/python/vara-feature/pybind_Init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ void init_feature_location_module(py::module &M);
void init_feature_model_module(py::module &M);
void init_feature_model_builder_module(py::module &M);
void init_xml_writer(py::module &M);
void init_configuration_module(py::module &M);

PYBIND11_MODULE(vara_feature, M) {
auto LLVMModule = M.def_submodule("llvm_util");
Expand All @@ -27,4 +28,6 @@ PYBIND11_MODULE(vara_feature, M) {
init_xml_writer(FMWriterModule);
auto FeatureModelBuilderModule = M.def_submodule("feature_model_builder");
init_feature_model_builder_module(FeatureModelBuilderModule);
auto ConfigurationModule = M.def_submodule("configuration");
init_configuration_module(ConfigurationModule);
}
4 changes: 3 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ def build_extension(self, ext):
'-DPYTHON_EXECUTABLE=' + sys.executable,
'-DVARA_FEATURE_USE_Z3_SOLVER=True'
]
if os.path.exists('/lib/x86_64-linux-gnu/libz3.so'):
cmake_args.append('-DVARA_FEATURE_BUILD_Z3_SOLVER=False')
Comment on lines +50 to +51
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is a good way to determine if we should build the solver.

  1. the path is a system specific
  2. we might want to build the solver from scratch even for those system, as we depend on a very specific version of z3. (The debian 11 can cause problems)

Maybe we should keep building the solver as the default and give the user a option to disable that? Or, if it works for you, only you use the local one.


cfg = 'Debug' if self.debug else 'Release'
build_args = ['--config', cfg]
Expand All @@ -61,7 +63,7 @@ def build_extension(self, ext):
build_args += ['--', '/m']
else:
cmake_args += ['-DCMAKE_BUILD_TYPE=' + cfg]
build_args += ['--', '-j2']
build_args += ['--', f'-j{os.cpu_count()}']

env = os.environ.copy()
env['CXXFLAGS'] = '{} -DVERSION_INFO=\\"{}\\"'.format(
Expand Down
Loading