pocoproject / poco

The POCO C++ Libraries are powerful cross-platform C++ libraries for building network- and internet-based applications that run on desktop, server, mobile, IoT, and embedded systems.
https://pocoproject.org
Other
8.36k stars 2.16k forks source link

Poco does not build on AIX #4742

Open Enc-EE opened 2 days ago

Enc-EE commented 2 days ago

Describe the bug Poco does not build on AIX

To Reproduce

cmake ../source -DENABLE_ACTIVERECORD=OFF -DENABLE_ACTIVERECORD_COMPILER=OFF -DENABLE_APACHECONNECTOR=OFF -DENABLE_CPPPARSER=OFF -DENABLE_DATA=OFF -DENABLE_DATA_MYSQL=OFF -DENABLE_DATA_ODBC=OFF -DENABLE_DATA_POSTGRESQL=OFF -DENABLE_DATA_SQLITE=OFF -DENABLE_ENCODINGS=OFF -DENABLE_ENCODINGS_COMPILER=OFF -DENABLE_JSON=OFF -DENABLE_JWT=OFF -DENABLE_MONGODB=OFF -DENABLE_NETSSL_WIN=OFF -DENABLE_PAGECOMPILER=OFF -DENABLE_PAGECOMPILER_FILE2PAGE=OFF -DENABLE_PDF=OFF -DENABLE_POCODOC=OFF -DENABLE_PROMETHEUS=OFF -DENABLE_REDIS=OFF -DENABLE_SEVENZIP=OFF -DENABLE_TESTS=OFF -DENABLE_ZIP=OFF -DBUILD_SHARED_LIBS=OFF -DOPENSSL_ROOT_DIR=../../openssl/install -DCMAKE_INSTALL_PREFIX=../install
cmake  --build . --config Release

Expected behavior Poco should build on AIX

Please add relevant environment information: AIX: 7.3 CMake: 3.16.0 GCC: 11.2.0

Additional information I'm trying to build with cmake on AIX and get some errors. I also tried to fix them.

First Problem

In file included from /path/to/Foundation/src/Thread.cpp:28:
/path/to/Foundation/src/Thread_POSIX.cpp: In function 'void {anonymous}::setThreadName(const string&)':
/path/to/Foundation/src/Thread_POSIX.cpp:107:23: error: 'PR_SET_NAME' was not declared in this scope
  107 |                 prctl(PR_SET_NAME, truncName(threadName).c_str());
      |                       ^~~~~~~~~~~
/path/to/Foundation/src/Thread_POSIX.cpp:107:17: error: 'prctl' was not declared in this scope; did you mean 'vpmctl'?
  107 |                 prctl(PR_SET_NAME, truncName(threadName).c_str());
      |                 ^~~~~
      |                 vpmctl
/path/to/Foundation/src/Thread_POSIX.cpp: In function 'std::string {anonymous}::getThreadName()':
/path/to/Foundation/src/Thread_POSIX.cpp:126:23: error: 'PR_GET_NAME' was not declared in this scope
  126 |                 prctl(PR_GET_NAME, name);
      |                       ^~~~~~~~~~~
/path/to/Foundation/src/Thread_POSIX.cpp:126:17: error: 'prctl' was not declared in this scope; did you mean 'vpmctl'?
  126 |                 prctl(PR_GET_NAME, name);
      |                 ^~~~~
      |                 vpmctl
gmake[2]: *** [Foundation/CMakeFiles/Foundation.dir/src/Thread.cpp.o] Error 1
gmake[1]: *** [Foundation/CMakeFiles/Foundation.dir/all] Error 2
gmake: *** [all] Error 2

The function prctl(PR_SET_NAME, ...) as well as its alternative pthread_setname_np are not available on AIX. I fixed it by excluding these methods on AIX: Foundation/src/Thread_POSIX.cpp

...
#elif (POCO_OS == POCO_OS_QNX)
        pthread_setname_np(pthread_self(), truncName(threadName, _NTO_THREAD_NAME_MAX).c_str());
#elif (POCO_OS == POCO_OS_AIX)
    // not supported on AIX
#else
        prctl(PR_SET_NAME, truncName(threadName).c_str());
#endif
...

Should the whole method be excluded on AIX? There might be tests failing. Didn't know how to run them

Second Problem

In file included from /path/to/Foundation/src/Timezone.cpp:29:
/path/to/Foundation/src/Timezone_UNIX.cpp:60:14: error: 'mutex' in namespace 'std' does not name a type
   60 |         std::mutex _mutex;
      |              ^~~~~
In file included from /path/to/Foundation/src/Timezone.cpp:29:
/path/to/Foundation/src/Timezone_UNIX.cpp:19:1: note: 'std::mutex' is defined in header '<mutex>'; did you forget to '#include <mutex>'?
   18 | #include <ctime>
  +++ |+#include <mutex>
   19 |
/path/to/Foundation/src/Timezone_UNIX.cpp: In member function 'int Poco::TZInfo::timeZone()':
/path/to/Foundation/src/Timezone_UNIX.cpp:34:38: error: 'mutex' is not a member of 'std'
   34 |                 std::lock_guard<std::mutex> lock(_mutex);
      |                                      ^~~~~
/path/to/Foundation/src/Timezone_UNIX.cpp:34:38: note: 'std::mutex' is defined in header '<mutex>'; did you forget to '#include <mutex>'?
/path/to/Foundation/src/Timezone_UNIX.cpp:34:43: error: template argument 1 is invalid
   34 |                 std::lock_guard<std::mutex> lock(_mutex);
      |                                           ^
/path/to/Foundation/src/Timezone_UNIX.cpp:34:50: error: '_mutex' was not declared in this scope
   34 |                 std::lock_guard<std::mutex> lock(_mutex);
      |                                                  ^~~~~~
In file included from /path/to/Foundation/src/Timezone.cpp:29:
/path/to/Foundation/src/Timezone_UNIX.cpp: In member function 'const char* Poco::TZInfo::name(bool)':
/path/to/Foundation/src/Timezone_UNIX.cpp:53:38: error: 'mutex' is not a member of 'std'
   53 |                 std::lock_guard<std::mutex> lock(_mutex);
      |                                      ^~~~~
/path/to/Foundation/src/Timezone_UNIX.cpp:53:38: note: 'std::mutex' is defined in header '<mutex>'; did you forget to '#include <mutex>'?
/path/to/Foundation/src/Timezone_UNIX.cpp:53:43: error: template argument 1 is invalid
   53 |                 std::lock_guard<std::mutex> lock(_mutex);
      |                                           ^
/path/to/Foundation/src/Timezone_UNIX.cpp:53:50: error: '_mutex' was not declared in this scope
   53 |                 std::lock_guard<std::mutex> lock(_mutex);
      |                                                  ^~~~~~
gmake[2]: *** [Foundation/CMakeFiles/Foundation.dir/src/Timezone.cpp.o] Error 1
gmake[1]: *** [Foundation/CMakeFiles/Foundation.dir/all] Error 2
gmake: *** [all] Error 2

Turns out this is related to not correctly adding the -pthread flag. I fixed this by doing this in Foundation/CMakeLists.txt starting at Line 160:

    elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "AIX"  OR "${CMAKE_SYSTEM_NAME}" STREQUAL "GNU")
        #target_compile_definitions(Foundation PUBLIC _XOPEN_SOURCE=500 POCO_HAVE_FD_POLL)
        #target_link_libraries(Foundation PUBLIC pthread ${CMAKE_DL_LIBS} rt)
        set(THREADS_PREFER_PTHREAD_FLAG ON)
        find_package(Threads REQUIRED)
        target_link_libraries(Foundation PUBLIC Threads::Threads)
    else()

https://stackoverflow.com/questions/1620918/cmake-and-libpthread I don't know why this is happening/working. Maybe this also concerns other modules/flags/libraries.

Third Problem

/path/to/Net/src/SocketImpl.cpp: In member function 'Poco::Int64 Poco::Net::SocketImpl::sendFile(Poco::FileInputStream&, Poco::UInt64)':
/path/to/Net/src/SocketImpl.cpp:1442:9: error: 'sighandler_t' was not declared in this scope; did you mean 'vmhandle_t'?
 1442 |         sighandler_t sigPrev = signal(SIGPIPE, SIG_IGN);
      |         ^~~~~~~~~~~~
      |         vmhandle_t
/path/to/Net/src/SocketImpl.cpp:1448:25: error: 'sigPrev' was not declared in this scope
 1448 |         signal(SIGPIPE, sigPrev != SIG_ERR ? sigPrev : SIG_DFL);
      |                         ^~~~~~~
gmake[2]: *** [Net/CMakeFiles/Net.dir/src/SocketImpl.cpp.o] Error 1
gmake[1]: *** [Net/CMakeFiles/Net.dir/all] Error 2
gmake: *** [all] Error 2

This is also a problem here: https://github.com/pocoproject/poco/issues/4604

I replaced signal with sigaction method.

    //sighandler_t sigPrev = signal(SIGPIPE, SIG_IGN);
    struct sigaction sa, old_sa;
    sa.sa_handler = SIG_IGN;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction(SIGPIPE, &sa, &old_sa);

    while (sent == 0)
    {
        errno = 0;
        sent = _sendfile(_sockfd, fd, offset, sentSize);
    }
    sigaction(SIGPIPE, &old_sa, nullptr);
    //signal(SIGPIPE, sigPrev != SIG_ERR ? sigPrev : SIG_DFL);

I'm not completely sure whether this is correct.

Can someone review these modifications? I'm sure there is still some work to do.

matejk commented 18 hours ago

@Enc-EE , thank you for reporting this issue.

Unfortunately none of the maintainers has access to an AIX system.

Would you be so kind and prepare a pull request with fixes for the branch main. Next release (1.14) is planned to be released soon and your PR could make it to be include in that release.