3 #include <boost/algorithm/string.hpp>
4 #include <boost/filesystem.hpp>
16 filename_base(_filename_base),
21 sout <<
"Error compiling: " <<
filename_base +
".cc" << std::endl;
22 sout <<
"Attempted: " <<
cmd << std::endl;
23 sout <<
result << std::endl;
24 sout << what() << std::endl;
32 filename_base(_filename_base),
37 sout <<
"Error compiling shared object: " <<
filename_base +
".so"
39 sout <<
"Attempted: " <<
cmd << std::endl;
40 sout <<
result << std::endl;
41 sout << what() << std::endl;
48 std::string compile_options,
49 std::string so_options)
50 : m_filename_base(filename_base),
51 m_compile_options(compile_options),
52 m_so_options(so_options),
62 throw std::runtime_error(std::string(
"Error in RuntimeLibrary\n") +
74 throw std::runtime_error(std::string(
"Error in Clexulator constructor\n") +
129 fprintf(stderr,
"dlopen failed: %s\n", dlerror());
130 throw std::runtime_error(std::string(
"Cannot open library: ") +
157 std::vector<std::string> _cxx_env() {
158 return std::vector<std::string>{
"CASM_CXX",
"CXX"};
161 std::vector<std::string> _cxxflags_env() {
162 return std::vector<std::string>{
"CASM_CXXFLAGS"};
165 std::vector<std::string> _soflags_env() {
166 return std::vector<std::string>{
"CASM_SOFLAGS"};
182 std::pair<std::string, std::string> _use_env(std::vector<std::string> var,
183 std::string _default =
"") {
184 for (
const auto &v : var) {
185 char *_env = std::getenv(v.c_str());
186 if (_env !=
nullptr) {
187 return std::make_pair(std::string(_env), v);
190 return std::make_pair(_default,
"default");
193 fs::path find_executable(std::string
name) {
194 char *_env = std::getenv(
"PATH");
195 std::vector<std::string> splt;
196 boost::split(splt, _env, boost::is_any_of(
":"), boost::token_compress_on);
198 for (
const auto &p : splt) {
199 fs::path test{fs::path(p) /
name};
200 if (fs::exists(test)) {
207 fs::path find_include(std::string executable_name, std::string include_name) {
208 fs::path loc = find_executable(executable_name);
212 fs::path maybe_includedir = loc.parent_path().parent_path() /
"include";
213 if (fs::exists(maybe_includedir / include_name)) {
214 return maybe_includedir / include_name;
219 fs::path find_includedir(std::string executable_name,
220 std::string include_name) {
221 return find_include(executable_name, include_name).parent_path();
224 fs::path find_lib(std::string executable_name, std::string lib_name) {
225 fs::path loc = find_executable(executable_name);
229 fs::path maybe_prefix = loc.parent_path().parent_path();
231 auto check_dir = [&](fs::path test_libdir) {
232 std::vector<std::string>
check{
"dylib",
"so"};
233 for (
const auto &
s :
check) {
234 auto res = test_libdir / (lib_name +
"." +
s);
235 if (fs::exists(res)) {
242 auto check_names = [&](fs::path test_prefix) {
243 std::vector<fs::path>
check{
"lib",
"lib64",
"lib/x86_64-linux-gnu"};
244 for (
const auto &
s :
check) {
245 auto res = check_dir(test_prefix /
s);
253 return check_names(maybe_prefix);
256 fs::path find_libdir(std::string executable_name, std::string lib_name) {
257 return find_lib(executable_name, lib_name).parent_path();
268 return _use_env(_cxx_env(),
"g++");
275 return _use_env(_cxxflags_env(),
"-O3 -Wall -fPIC --std=c++17");
282 return _use_env(_soflags_env(),
"-shared -lboost_system");
293 _env = std::getenv(
"CASM_INCLUDEDIR");
294 if (_env !=
nullptr) {
295 return std::make_pair(std::string(_env),
"CASM_INCLUDEDIR");
299 _env = std::getenv(
"CASM_PREFIX");
300 if (_env !=
nullptr) {
301 return std::make_pair(fs::path(_env) /
"include",
"CASM_PREFIX");
305 fs::path _default = find_includedir(
"ccasm",
"casm");
306 if (!_default.empty()) {
307 return std::make_pair(_default,
"relpath");
311 return std::make_pair(fs::path(
"/not/found"),
"notfound");
322 _env = std::getenv(
"CASM_LIBDIR");
323 if (_env !=
nullptr) {
324 return std::make_pair(std::string(_env),
"CASM_LIBDIR");
328 _env = std::getenv(
"CASM_PREFIX");
329 if (_env !=
nullptr) {
330 return std::make_pair(fs::path(_env) /
"lib",
"CASM_PREFIX");
334 fs::path _default = find_libdir(
"ccasm",
"libcasm");
335 if (!_default.empty()) {
336 return std::make_pair(_default,
"relpath");
340 return std::make_pair(fs::path(
"/not/found"),
"notfound");
351 _env = std::getenv(
"CASM_BOOST_INCLUDEDIR");
352 if (_env !=
nullptr) {
353 return std::make_pair(std::string(_env),
"CASM_BOOST_INCLUDEDIR");
357 _env = std::getenv(
"CASM_BOOST_PREFIX");
358 if (_env !=
nullptr) {
359 return std::make_pair(fs::path(_env) /
"include",
"CASM_BOOST_PREFIX");
363 fs::path _default = find_includedir(
"ccasm",
"boost");
364 if (!_default.empty()) {
365 return std::make_pair(_default,
"relpath");
369 return std::make_pair(fs::path(
"/not/found"),
"notfound");
380 _env = std::getenv(
"CASM_BOOST_LIBDIR");
381 if (_env !=
nullptr) {
382 return std::make_pair(std::string(_env),
"CASM_BOOST_LIBDIR");
386 _env = std::getenv(
"CASM_BOOST_PREFIX");
387 if (_env !=
nullptr) {
388 return std::make_pair(fs::path(_env) /
"lib",
"CASM_BOOST_PREFIX");
392 fs::path _default = find_libdir(
"ccasm",
"libboost_system");
393 if (!_default.empty()) {
394 return std::make_pair(_default,
"relpath");
398 return std::make_pair(fs::path(
"/not/found"),
"notfound");
403 return "-I" +
dir.string();
410 return "-L" +
dir.string();
std::set< std::string > & s
Remember how to use popen.
std::string gets() const
Returns the stdout resulting from the last popen call.
void popen(std::string _command)
Execute popen for a given command.
int exit_code() const
Returns pclose(fp)/256.
std::string m_compile_options
static std::pair< std::string, std::string > default_soflags()
Default c++ compiler options.
static std::pair< fs::path, std::string > default_boost_includedir()
Return default includedir for boost.
static std::pair< std::string, std::string > default_cxxflags()
Default c++ compiler options.
void _close()
Close the current library.
RuntimeLibrary(std::string _filename_base, std::string _compile_options, std::string _so_options)
Construct a RuntimeLibrary object, with the options to be used for compile the '.o' file and the '....
static std::pair< fs::path, std::string > default_casm_includedir()
Return default includedir for CASM.
static std::pair< fs::path, std::string > default_boost_libdir()
Return default libdir for boost.
void rm()
Remove the current library and source code.
static std::pair< std::string, std::string > default_cxx()
Return default compiler.
void _load()
Load a library with a given name.
void _compile()
Compile a shared library.
static std::pair< fs::path, std::string > default_casm_libdir()
Return default libdir for CASM.
std::string m_filename_base
std::string filename_base
void print(std::ostream &sout) const
runtime_lib_compile_error(std::string _filename_base, std::string _cmd, std::string _result, std::string _what)
void print(std::ostream &sout) const
runtime_lib_shared_error(std::string _filename_base, std::string _cmd, std::string _result, std::string _what)
std::string filename_base
bool check(const Lattice &lat)
std::string include_path(const fs::path &dir)
GenericDatumFormatter< std::string, DataObject > name()
std::string link_path(const fs::path &dir)
DirectoryStructure const & dir