saleyn / erlexec

Execute and control OS processes from Erlang/OTP
https://hexdocs.pm/erlexec/readme.html
Other
525 stars 139 forks source link

Does not build with older versions of gcc: -std=c++11 not supported #135

Closed akontsevoy closed 3 years ago

akontsevoy commented 4 years ago

Builds fail with gcc version 4.4 (Debian 6, CentOS 6) despite Erlang OTP 21.x/22.x building fine from source on these platforms:

==> erlexec (compile)
Compiled src/exec_app.erl

Compiled src/exec.erl
Compiling ../deps/erlexec/c_src/ei++.cpp
cc1plus: error: unrecognized command line option "-std=c++11"
ERROR: compile failed while processing ../deps/erlexec: rebar_abort

For portability reasons, please avoid relying on compiler options/language features which are not required by OTP itself, if possible.

saleyn commented 4 years ago

Though I didn't plan to support older C++ versions, this change seems to have been pretty simple. See if the latest commit works for you. C++11 has been out for 9 years, it's about time to upgrade ;) It's not surprising that older OTP versions don't have issues with C++11, since none of the Erlang/OTP is built with C++.

akontsevoy commented 4 years ago

Still does not work because the original change that required -std=c++11 was this: https://github.com/saleyn/erlexec/commit/45b3fa77a41ea24e53b327d5fd141f4df5efccaa, where you've used this construct:

enum class FileOpenFlag {
    READ     = 0,
    APPEND   = O_APPEND,
    TRUNCATE = O_TRUNC
};

Different gcc versions will default to different versions of the standard; to test if it compiles across the board, you could explicitly use -std=c++98 (just for testing -- I don't know if it should actually be in the makefiles, as it wouldn't be inconceivable for some compilers not to support it, or for future gcc versions to drop it).

==> erlexec (compile)
Compiling c_src/ei++.cpp
Compiling c_src/exec.cpp
In file included from c_src/exec.cpp:58:
c_src/exec.hpp:99: warning: scoped enums only available with -std=c++0x or -std=gnu++0x
Compiling c_src/exec_impl.cpp
In file included from c_src/exec_impl.cpp:2:
c_src/exec.hpp:99: warning: scoped enums only available with -std=c++0x or -std=gnu++0x
c_src/exec_impl.cpp: In function ‘pid_t ei::start_child(ei::CmdOptions&, std::string&)’:
c_src/exec_impl.cpp:300: error: ‘FileOpenFlag’ is not a class or namespace
c_src/exec_impl.cpp:301: error: ‘FileOpenFlag’ is not a class or namespace
c_src/exec_impl.cpp:302: error: ‘FileOpenFlag’ is not a class or namespace
c_src/exec_impl.cpp: In function ‘int ei::open_file(const char*, ei::FileOpenFlag, const char*, ei::StringBuffer<128, std::allocator<char> >&, int)’:
c_src/exec_impl.cpp:931: error: ‘FileOpenFlag’ is not a class or namespace
c_src/exec_impl.cpp:939: error: ‘FileOpenFlag’ is not a class or namespace
c_src/exec_impl.cpp:940: error: ‘FileOpenFlag’ is not a class or namespace
c_src/exec_impl.cpp: In member function ‘int ei::CmdOptions::init_cenv()’:
c_src/exec_impl.cpp:1350: error: ‘nullptr’ was not declared in this scope
ERROR: compile failed while processing /root/erlexec: rebar_abort
saleyn commented 4 years ago

Should be good now. Though I am not too fond of back-porting this C++11 code... So, cannot guarantee that future new versions will maintain pre-C++11 compatibility.

akontsevoy commented 4 years ago

Thanks -- it compiles and works now; one of the unit tests fails, but this existed before the compatibility changes and manifested with newer compiler versions, so I can only assume it's unrelated to the current problem.

==> erlexec (eunit)
Compiled test/test_exec.erl
Compiled src/exec_app.erl
Compiled src/exec.erl
exec:1236: exec_test_...*failed*
in function exec:'-test_winsz/0-fun-4-'/0 (src/exec.erl, line 1286)
in call from eunit_test:run_testfun/1 (eunit_test.erl, line 71)
in call from eunit_proc:run_test/1 (eunit_proc.erl, line 510)
in call from eunit_proc:with_timeout/3 (eunit_proc.erl, line 335)
in call from eunit_proc:handle_test/2 (eunit_proc.erl, line 493)
in call from eunit_proc:tests_inorder/3 (eunit_proc.erl, line 435)
in call from eunit_proc:with_timeout/3 (eunit_proc.erl, line 325)
in call from eunit_proc:run_group/2 (eunit_proc.erl, line 549)
**error:{assertMatch,[{module,exec},
              {line,1286},
              {expression,"timeout"},
              {pattern,"{ 'DOWN' , _ , process , P , normal }"},
              {value,timeout}]}
  output:<<"">>

exec:1237: exec_test_...*timed out*
undefined
=======================================================
  Failed: 1.  Skipped: 0.  Passed: 4.
One or more tests were cancelled.
=INFO REPORT==== 6-Aug-2020::20:37:00.964720 ===
    application: erlexec
    exited: killed
    type: temporary
ERROR: One or more eunit tests failed.
akontsevoy commented 3 years ago

Broken again as of 1.18.3

saleyn commented 3 years ago

At this point the C++11 compatible compiler is mandatory.

akontsevoy commented 3 years ago

But what versions of Erlang are we targeting now -- do we still support 21 and 22? Because if we do -- those OTP versions build just fine on a compiler without C++11. Since one of the main features of Erlang is portability, as long as I can build and run a given OTP version, as a user I should likewise be able to build and run Erlang projects targeting that version.

Of course this project is not part of the OTP (so it's up to maintainers what should be supported), and for our purposes we can just pin an older version, but IMO projects targeting a specific version of OTP should not require any port compiler features that the OTP itself does not require to build.

saleyn commented 3 years ago

Unfortunately given the very limited time resources available to maintain this open source project, I can only offer compatibility with versions of C++ compiler >= c++11. This project is not part of the OTP, and may have its own minimum requirements, especially that OTP prior to ver 24 didn't even use the C++ compiler.