9 std::string compile_options,
10 std::string so_options,
11 std::string compile_msg,
14 m_filename_base(filename_base),
15 m_compile_options(compile_options),
16 m_so_options(so_options),
28 log() << compile_msg << std::endl;
32 catch(std::exception &e) {
33 log() <<
"Error compiling clexulator. To fix: \n";
34 log() <<
" - Check compiler error messages.\n";
35 log() <<
" - Check compiler options with 'casm settings -l'\n";
36 log() <<
" - Update compiler options with 'casm settings --set-compile-options '...options...'\n";
37 log() <<
" - Make sure the casm headers can be found by including '-I/path/to/casm'\n";
40 log() <<
"compile time: " <<
log().
lap_time() <<
" (s)\n" << std::endl;
43 throw std::runtime_error(
44 std::string(
"Error in RuntimeLibrary\n") +
57 throw std::runtime_error(
58 std::string(
"Error in Clexulator constructor\n") +
88 err_log() <<
"Error compiling: " << m_filename_base +
".cc" << std::endl;
89 err_log() <<
"Attempted: " << cmd << std::endl;
91 throw std::runtime_error(
"Can not compile " + m_filename_base +
".cc");
94 cmd =
m_so_options +
" -o " + m_filename_base +
".so" +
" " + m_filename_base +
".o";
97 err_log() <<
"Error compiling shared object: " << m_filename_base +
".so" << std::endl;
98 err_log() <<
"Attempted: " << cmd << std::endl;
100 throw std::runtime_error(
"Can not compile " + m_filename_base +
".o");
112 fprintf(stderr,
"dlopen failed: %s\n", dlerror());
113 throw std::runtime_error(std::string(
"Cannot open library: ") +
m_filename_base +
".so");
137 std::vector<std::string> _cxx_env() {
138 return std::vector<std::string> {
144 std::vector<std::string> _cxxflags_env() {
145 return std::vector<std::string> {
150 std::vector<std::string> _soflags_env() {
151 return std::vector<std::string> {
169 std::pair<std::string, std::string> _use_env(std::vector<std::string> var, std::string _default =
"") {
170 for(
const auto &v : var) {
171 char *_env = std::getenv(v.c_str());
172 if(_env !=
nullptr) {
173 return std::make_pair(std::string(_env), v);
176 return std::make_pair(_default,
"default");
179 fs::path find_executable(std::string name) {
180 char *_env = std::getenv(
"PATH");
181 std::vector<std::string> splt;
182 boost::split(splt, _env, boost::is_any_of(
":"), boost::token_compress_on);
184 for(
const auto &p : splt) {
186 if(fs::exists(
test)) {
193 fs::path find_include(std::string executable_name, std::string include_name) {
194 fs::path loc = find_executable(executable_name);
198 fs::path maybe_includedir = loc.parent_path().parent_path() /
"include";
199 if(fs::exists(maybe_includedir / include_name)) {
200 return maybe_includedir / include_name;
205 fs::path find_includedir(std::string executable_name, std::string include_name) {
206 return find_include(executable_name, include_name).parent_path();
209 fs::path find_lib(std::string executable_name, std::string lib_name) {
210 fs::path loc = find_executable(executable_name);
214 fs::path maybe_prefix = loc.parent_path().parent_path();
216 auto check_dir = [&](
fs::path test_libdir) {
217 std::vector<std::string>
check {
"dylib",
"so"};
218 for(
const auto &s :
check) {
219 auto res = test_libdir / (lib_name +
"." + s);
220 if(fs::exists(res)) {
227 auto check_names = [&](
fs::path test_prefix) {
228 std::vector<fs::path> check {
"lib",
"lib64",
"lib/x86_64-linux-gnu"};
229 for(
const auto &s : check) {
230 auto res = check_dir(test_prefix / s);
238 return check_names(maybe_prefix);
241 fs::path find_libdir(std::string executable_name, std::string lib_name) {
242 return find_lib(executable_name, lib_name).parent_path();
253 return _use_env(_cxx_env(),
"g++");
260 return _use_env(_cxxflags_env(),
"-O3 -Wall -fPIC --std=c++11");
267 return _use_env(_soflags_env(),
"-shared -lboost_system");
278 _env = std::getenv(
"CASM_INCLUDEDIR");
279 if(_env !=
nullptr) {
280 return std::make_pair(std::string(_env),
"CASM_INCLUDEDIR");
284 _env = std::getenv(
"CASM_PREFIX");
285 if(_env !=
nullptr) {
286 return std::make_pair(
fs::path(_env) /
"include",
"CASM_PREFIX");
290 fs::path _default = find_includedir(
"ccasm",
"casm");
291 if(!_default.empty()) {
292 return std::make_pair(_default,
"relpath");
296 return std::make_pair(
fs::path(
"/not/found"),
"notfound");
307 _env = std::getenv(
"CASM_LIBDIR");
308 if(_env !=
nullptr) {
309 return std::make_pair(std::string(_env),
"CASM_LIBDIR");
313 _env = std::getenv(
"CASM_PREFIX");
314 if(_env !=
nullptr) {
315 return std::make_pair(
fs::path(_env) /
"lib",
"CASM_PREFIX");
319 fs::path _default = find_libdir(
"ccasm",
"libcasm");
320 if(!_default.empty()) {
321 return std::make_pair(_default,
"relpath");
325 return std::make_pair(
fs::path(
"/not/found"),
"notfound");
336 _env = std::getenv(
"CASM_BOOST_INCLUDEDIR");
337 if(_env !=
nullptr) {
338 return std::make_pair(std::string(_env),
"CASM_BOOST_INCLUDEDIR");
342 _env = std::getenv(
"CASM_BOOST_PREFIX");
343 if(_env !=
nullptr) {
344 return std::make_pair(
fs::path(_env) /
"include",
"CASM_BOOST_PREFIX");
348 fs::path _default = find_includedir(
"ccasm",
"boost");
349 if(!_default.empty()) {
350 return std::make_pair(_default,
"relpath");
354 return std::make_pair(
fs::path(
"/not/found"),
"notfound");
365 _env = std::getenv(
"CASM_BOOST_LIBDIR");
366 if(_env !=
nullptr) {
367 return std::make_pair(std::string(_env),
"CASM_BOOST_LIBDIR");
371 _env = std::getenv(
"CASM_BOOST_PREFIX");
372 if(_env !=
nullptr) {
373 return std::make_pair(
fs::path(_env) /
"lib",
"CASM_BOOST_PREFIX");
377 fs::path _default = find_libdir(
"ccasm",
"libboost_system");
378 if(!_default.empty()) {
379 return std::make_pair(_default,
"relpath");
383 return std::make_pair(
fs::path(
"/not/found"),
"notfound");
388 return "-I" + dir.string();
395 return "-L" + dir.string();
RuntimeLibrary(std::string _filename_base, std::string _compile_options, std::string _so_options, std::string compile_msg, const Logging &logging=Logging())
Construct a RuntimeLibrary object, with the options to be used for compile the '.o' file and the '...
static std::pair< std::string, std::string > default_cxxflags()
Default c++ compiler options.
void _load()
Load a library with a given name.
static std::pair< fs::path, std::string > default_casm_includedir()
Return default includedir for CASM.
std::string include_path(const fs::path &dir)
std::string gets() const
Returns the stdout resulting from the last popen call.
std::string link_path(const fs::path &dir)
static std::pair< std::string, std::string > default_cxx()
Return default compiler.
void _close()
Close the current library.
void popen(std::string _command)
Execute popen for a given command.
std::string m_compile_options
Remember how to use popen.
static const int standard
static std::pair< fs::path, std::string > default_boost_libdir()
Return default libdir for boost.
static std::pair< fs::path, std::string > default_casm_libdir()
Return default libdir for CASM.
static std::pair< std::string, std::string > default_soflags()
Default c++ compiler options.
std::string m_filename_base
void compiling(const std::string &what)
bool check(std::string test, const jsonParser &expected, const jsonParser &calculated, fs::path test_cases_path, bool quiet, double tol=0.0)
Check expected JSON vs calculated JSON using BOOST_CHECK_EQUAL.
int exit_code() const
Returns pclose(fp)/256.
void _compile()
Compile a shared library.
void rm()
Remove the current library and source code.
static std::pair< fs::path, std::string > default_boost_includedir()
Return default includedir for boost.