E3SM-Project / scorpio

A high-level Parallel I/O Library for structured grid applications
18 stars 16 forks source link

Specify the POSIX standard required for the C library #580

Closed jayeshkrishna closed 2 months ago

jayeshkrishna commented 2 months ago

Some compilers (Intel icx on Perlmutter) require this for enabling (declaring) support for symlink(), which is required for ADIOS support.

Without this fix SCORPIO builds with ADIOS support fails on Perlmutter when using the Intel compiler.

jayeshkrishna commented 2 months ago

Without this fix SCREAM/E3SM/SCORPIO builds with SCORPIO 1.6.2 fails on Perlmutter+Intel compiler with the following error message,

E3SM/externals/scorpio/src/clib/pioc_support.c:3020:24: error: call to undeclared function 'symlink'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
                ierr = symlink(file->filename, filename);

The error is caused by missing (not included) declaration in unistd.h for symlink().

Note: GNU builds do not show this error.

dqwu commented 2 months ago

Here is a simple test program (test.c):

#include <unistd.h>

int main() {
  char fn[]="test.file";
  char sln[]="test.symlink";
  symlink(fn, sln);

  return 0;
}

On Perlmutter, GCC does not show this error. intel-oneapi/2022.1.0 does not show this error, either. intel-oneapi/2023.0.0 shows this error:

gcc --version
gcc (SUSE Linux) 12.3.0

gcc -std=c99 test.c
test.c: In function ‘main’:
test.c:6:3: warning: implicit declaration of function ‘symlink’ [-Wimplicit-function-declaration]
    6 |   symlink(fn, sln);
      |   ^~~~~~~

module load intel-oneapi/2022.1.0

icx --version
Intel(R) oneAPI DPC++/C++ Compiler 2022.1.0 (2022.1.0.20220316)

icx -std=c99 test.c 
test.c:6:3: warning: implicit declaration of function 'symlink' is invalid in C99 [-Wimplicit-function-declaration]
  symlink(fn, sln);
  ^
1 warning generated.

module load intel-oneapi/2023.0.0

icx --version
Intel(R) oneAPI DPC++/C++ Compiler 2023.0.0 (2023.0.0.20221201)

icx -std=c99 test.c 
test.c:6:3: error: call to undeclared function 'symlink'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
  symlink(fn, sln);
  ^
1 error generated.
dqwu commented 2 months ago

By defining _POSIX_C_SOURCE to a value greater than or equal to 200112L before including unistd.h, no warnings or errors occur when using GCC and Intel compilers.

#define _POSIX_C_SOURCE 200112L
#include <unistd.h>

int main() {
  char fn[]="test.file";
  char sln[]="test.symlink";
  symlink(fn, sln);

  return 0;
}
dqwu commented 2 months ago

_POSIX_C_SOURCE macro is used to control the feature-test macros that determine which parts of the POSIX standard are exposed.

When _POSIX_C_SOURCE is defined to a value greater than or equal to 200112L, it indicates that the program intends to use features from the POSIX.1-2001 standard or later. This may enable declarations or definitions in unistd.h that are not available when _POSIX_C_SOURCE is not defined or is defined to a lower value.

By ensuring that _POSIX_C_SOURCE is defined appropriately before including unistd.h, we can ensure that the necessary declarations and definitions are available, potentially avoiding warnings or errors related to missing symbols or declarations.