Search code examples
amazon-s3aws-sdksolaris

How to build AWS C++ SDK on Solaris?


I am trying to build the AWS C++ SDK on Solaris, but I cannot do so successfully.

I found this open issue on the AWS C++ SDK page that says it is possible, but there is no guide on it and I am hoping somebody here can help.

Here is the command I use to build it:

$ cmake ../aws-sdk-cpp/ -DCMAKE_BUILD_TYPE=Debug -DBUILD_ONLY="s3"

Here is the output:

-- TARGET_ARCH not specified; inferring host OS to be platform compilation target
-- Building AWS libraries as shared objects
-- Generating linux build config
-- Building project version: 1.7.134
-- Configuring done
-- Generating done
-- Build files have been written to: /workspace/dmoini/sdk_build/.deps
gmake: Warning: File 'Makefile' has modification time 267 s in the future
gmake[1]: Warning: File 'CMakeFiles/Makefile2' has modification time 267 s in the future
gmake[2]: Warning: File 'CMakeFiles/AwsCCommon.dir/progress.make' has modification time 267 s in the future
gmake[2]: warning:  Clock skew detected.  Your build may be incomplete.
gmake[2]: Warning: File 'CMakeFiles/AwsCCommon.dir/progress.make' has modification time 267 s in the future
[  4%] Performing build step for 'AwsCCommon'
[  1%] Building C object CMakeFiles/aws-c-common.dir/source/array_list.c.o
In file included from /usr/include/stdio.h:37:0,
                 from /workspace/dmoini/sdk_build/.deps/build/src/AwsCCommon/include/aws/common/common.h:22,
                 from /workspace/dmoini/sdk_build/.deps/build/src/AwsCCommon/include/aws/common/array_list.h:18,
                 from /workspace/dmoini/sdk_build/.deps/build/src/AwsCCommon/source/array_list.c:16:
/opt/gcc-5.1.0/lib/gcc/i386-pc-solaris2.11/5.1.0/include-fixed/sys/feature_tests.h:405:2: error: #error "Compiler or options invalid for pre-UNIX 03 X/Open applications        and pre-2001 POSIX applications"
 #error "Compiler or options invalid for pre-UNIX 03 X/Open applications \
  ^
gmake[5]: *** [CMakeFiles/aws-c-common.dir/build.make:63: CMakeFiles/aws-c-common.dir/source/array_list.c.o] Error 1
gmake[4]: *** [CMakeFiles/Makefile2:484: CMakeFiles/aws-c-common.dir/all] Error 2
gmake[3]: *** [Makefile:139: all] Error 2
gmake[2]: *** [CMakeFiles/AwsCCommon.dir/build.make:112: build/src/AwsCCommon-stamp/AwsCCommon-build] Error 2
gmake[1]: *** [CMakeFiles/Makefile2:68: CMakeFiles/AwsCCommon.dir/all] Error 2
gmake: *** [Makefile:84: all] Error 2
CMake Error at CMakeLists.txt:193 (message):
  Failed to build third-party libraries.

Additionally, here is my system information:

$ uname -a
SunOS bld-dmoini-01-sv4b 5.11 omnios-r151020-4151d05 i86pc i386 i86pc

Any and all help/guidance is greatly appreciated.


Solution

  • I've successfully completed compiling the AWS C++ SDK on a stock install of Solaris 11.4, and found several issues that could cause the problems noted.

    Start with a clean source tree.

    Remove -Werror

    The first thing do to is remove the -Werror compiler options. The version of OpenSSL installed by default on Solaris 11.4 has quite a few deprecated functions, and the -Werror option causes the build to fail when it runs into those deprecations. I used this find command run from the topmost directory of the AWS SDK source tree to remove all the -Werror options:

    vi `find . | xargs grep -l Werror`
    

    You'll get about three or four files, only two of which are actually setting the -Werror as a compiler option. Just remove the "-Werror" strings from those files.

    Fix the POSIX defines

    Then run cmake . in the topmost directory. It will fail because the cmake files that it downloads will have improper POSIX command-line options - -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=500. That 500 is wrong. _POSIX_C_SOURCE=200809L corresponds to _XOPEN_SOURCE=700. _XOPEN_SOURCE=500 is SUSv2, circa 1997. It's not proper to compile a SUSv2 application with C99.

    Per 2.2.1 Strictly Conforming POSIX Application, paragraph 8:

    1. For the C programming language, shall define _POSIX_C_SOURCE to be 200809L before any header is included

    and 2.2.4 Strictly Conforming XSI Application, paragraph 8:

    1. For the C programming language, shall define _XOPEN_SOURCE to be 700 before any header is included

    Per the Illumos sys/feature_tests.h file (based on OpenSolaris, which was also the basis for Solaris 11):

     * Feature Test Macro                                Specification
     * ------------------------------------------------  -------------
     * _XOPEN_SOURCE                                         XPG3
     * _XOPEN_SOURCE && _XOPEN_VERSION = 4                   XPG4
     * _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED = 1           XPG4v2
     * _XOPEN_SOURCE = 500                                   XPG5
     * _XOPEN_SOURCE = 600  (or POSIX_C_SOURCE=200112L)      XPG6
     * _XOPEN_SOURCE = 700  (or POSIX_C_SOURCE=200809L)      XPG7
    

    The files cmake downloads via git need to be edited:

    vi `find .deps | xargs grep -l XOPEN_SOURCE`
    

    Change any -D_XOPEN_SOURCE=500 to -D_XOPEN_SOURCE=700 and rerun cmake .. It should complete successfully this time.

    Then run gmake. (I find gmake works much better on Solaris for just about all open source projects, as many open source projects use GNU-specific make extensions.)

    Now you get to fix any broken source code you run into.

    Fix broken source code

    1

    The file aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/OSVersionInfo.cpp has the following wrong code:

    Aws::String ComputeOSVersionString()
    {
        utsname name;
        int32_t success = uname(&name);
    

    Per POSIX, the correct type is struct utsname, not just utsname:

     int uname(struct utsname *name);
    

    The AWS code needs to be:

    Aws::String ComputeOSVersionString()
    {
        struct utsname name;
        int success = uname(&name);
    

    And no, I'm most certainly not impressed with the quality of the AWS code, given this, umm, laugher:

     while (!feof(outputStream))
    

    Yes, an actual while (!feof()) loop...

    2

    The file aws-sdk-cpp/aws-cpp-sdk-mediaconvert/include/aws/mediaconvert/model/M2tsSegmentationMarkers.h uses an enumeration with the value EBP, which conflicts with the EBP register #define in /usr/include/sys/regset.h.

    I just changed it to EBP_HASH as that seems to match the code somewhat:

    vi `find . | xargs grep -l EBP`
    

    3

    The file aws-sdk-cpp/aws-cpp-sdk-route53domains/include/aws/route53domains/model/CountryCode.h creates an enumeration value ES that conflicts with the ES register #define in /usr/include/sys/regset.h. I just added

    #ifdef ES
    #undef ES
    #endif 
    

    and the compile continued. I don't know if that #undef could have broken anything.

    4

    The file aws-sdk-cpp/aws-cpp-sdk-waf/include/aws/waf/model/GeoMatchConstraintValue.h has ES, GS, and SS enumeration value that conflict with the ES, GS, and SS register #define's in /usr/include/sys/regset.h.

    Again, I just added a few more #undef's:

    #ifdef ES
    #undef ES
    #endif
    
    #ifdef GS
    #undef GS
    #endif
    
    #ifdef SS
    #undef SS
    #endif
    

    I'm really wondering why sys/regset.h is being #include'd in just about everything in the AWS SDK.

    5

    Same problem in aws-sdk-cpp/aws-cpp-sdk-waf-regional/include/aws/waf-regional/model/GeoMatchConstraintValue.h. Same fix, add:

    #ifdef ES
    #undef ES
    #endif
    
    #ifdef GS
    #undef GS
    #endif
    
    #ifdef SS
    #undef SS
    #endif
    

    Note that compiling on SPARC hardware means the #define value from sys/regset.h will be completely different, and any errors will be completely different.

    6

    The file aws-sdk-cpp/aws-cpp-sdk-core-tests/utils/FileSystemUtilsTest.cpp incorrectly assumes the POSIX NAME_MAX value is defined. Per the POSIX Pathname Variable Values standard (bolding mine):

    Pathname Variable Values

    The values in the following list may be constants within an implementation or may vary from one pathname to another. For example, file systems or directories may have different characteristics.

    A definition of one of the symbolic constants in the following list shall be omitted from the <limits.h> header on specific implementations where the corresponding value is equal to or greater than the stated minimum, but where the value can vary depending on the file to which it is applied. The actual value supported for a specific pathname shall be provided by the pathconf() function.

    Again: the "definition ... shall be omitted ... where the value can vary".

    The AWS code wrongly assumes NAME_MAX must be #define'd.

    I just hardcoded a value of 255 to get past this point, although using something like _POSIX_NAME_MAX or _XOPEN_NAME_MAX is probably better.

    7

    File aws-sdk-cpp/ws-cpp-sdk-core-tests/http/HttpClientTest.cpp seems to be incorrectly assuming a std::shared_ptr will be 8 bytes. This question and answer provides a good example of how that's wrong.

    I just ignored this error as it's just a test and continued with gmake -i, which completed successfully outside of this one error.