Opened 10 years ago
Last modified 9 years ago
#7440 new Bugs
boost::filesystem compile error on solaris 10
| Reported by: | Owned by: | Beman Dawes | |
|---|---|---|---|
| Milestone: | To Be Determined | Component: | filesystem |
| Version: | Boost 1.51.0 | Severity: | Problem |
| Keywords: | Cc: |
Description
It fails to compile on gcc 4.7.2 with compile flags cxxflags=-std=c++0x
libs/filesystem/src/operations.cpp: In function 'void boost::filesystem::detail: :permissions(const boost::filesystem::path&, boost::filesystem::perms, boost::system::error_code*)': libs/filesystem/src/operations.cpp:1412:11: error: '::fchmodat' has not been declared
in line 1410 there is:
&& !(defined(__SUNPRO_CC) || defined(sun)) \
proper check for solaris would be:
&& !(defined(__SUNPRO_CC) || defined(sun) || defined(__sun)) \
Attachments (1)
Change History (8)
comment:1 by , 10 years ago
| Component: | None → filesystem |
|---|---|
| Owner: | set to |
follow-up: 3 comment:2 by , 10 years ago
comment:3 by , 10 years ago
Did you try it on solaris 10 , gcc 4.7.2 with -std=c++0x switch enabled ? gcc should not define SunOS , you can try gcc -dM -E - < /dev/null it will print all predefined macros
gcc claims that sun and sun should be defined both , and they are if std=c++0x not used, but when using std=c++0x than only sun is defined. I am not sure if this is proper behavior of gcc, but doc says that "platform" macros like sun , linux and so on are newer than sun or linux. For fchmodat issue boost already uses
| defined(linux) | defined(linux)) for linux platform and it works perfectly well. |
comment:4 by , 10 years ago
No, and I don't have gcc 4.7.2 easily available. I built on Solaris 10 with Oracle Solaris Studio 12 update 3, which is Oracle's latest compiler for Solaris. The compilation fails because in that case __SUNPRO_CC is defined as 0x5200 but fchmodat is not available on Solaris 10. However, fchmodat is available on Solaris 11. We can't tell for sure what will be in future versions of Solaris, but my guess is that fchmodat will stay, as I doubt Oracle would break the Solaris Binary Guarantee.
So, how to fix this? I think Oracle's toolchain is probably what most people prefer on Solaris but Boost needs to work regardless of choice of compiler.
Also, it would be good to fix this correctly, or at least as correctly as we can with the efffort we can spare. With gcc, there's no way to test the version of Solaris, so only thing we can test easily, is whether __sun is defined. (The harder way would be to delve into configure magic and test there whether fchmodat is available, but I've never done something like that myself.)
So, assuming we don't go the configure route, if __SUNPRO_CC is defined, then if __SunOS_5_10 is defined we're on Solaris 10 so we don't have fchmodat, and otherwise we do have fchmodat. But if __SUNPRO_CC is not defined, then if __sun is defined we're on Solaris, of unknown version, so we have to assume we don't have fchmodat.
Does that make sense?
comment:5 by , 10 years ago
From boost 1.51 it seems that fchmodat is disabled (according to source code) for all solaris platforms (although solaris 11 has fchmodat). I can agree with comment in source code that runtime check is too much trouble. There is compile error when using gcc with compile switch std=c++0x (works without) and we should use __sun macro to fix compile error. I am not sure if this is gcc or boost bug.
comment:6 by , 9 years ago
The actual issue is caused by libs/locale/src/util/gregorian.cpp
int first_day_of_week(char const *terr) {
static char const * const sat[] = {
"AE","AF","BH","DJ","DZ","EG","ER","ET","IQ","IR",
"JO","KE","KW","LY","MA","OM","QA","SA","SD","SO",
"SY","TN","YE"
};
// workaround for Sun Solaris !@#%@#$%@#$%234
#ifdef sun
#undef sun
#endif
static char const * const sun[] = {
"AR","AS","AZ","BW","CA","CN","FO","GE","GL","GU",
"HK","IL","IN","JM","JP","KG","KR","LA","MH","MN",
"MO","MP","MT","NZ","PH","PK","SG","TH","TT","TW",
"UM","US","UZ","VI","ZW"
};
if(strcmp(terr,"MV") == 0)
return 5; // fri
if(std::binary_search<char const * const *>(sat,sat+sizeof(sat)/(sizeof(sat[0])),terr,comparator))
return 6; // sat
if(std::binary_search<char const * const *>(sun,sun+sizeof(sun)/(sizeof(sun[0])),terr,comparator))
return 0; // sun
// default
return 1; // mon
}
sun has actually been redefined!
I will attach a patch that fixes this issue (and also adds the additional check for __sun to perform better detection of Solaris).

Actually the OS, not the compiler or compiler version, determines whether or not
fchmodatis defined, so a better fix is to test against the OS.One possible fix is per this diff (relative to boost 1.50.0).
% diff -c libs/filesystem/src/operations.cpp.ori libs/filesystem/src/operations.cpp *** libs/filesystem/src/operations.cpp.ori Mon Jun 18 04:40:57 2012 --- libs/filesystem/src/operations.cpp Fri Feb 22 15:00:15 2013 *************** *** 1397,1403 **** // Mac OS X Lion and some other platforms don't support fchmodat() # if defined(AT_FDCWD) && defined(AT_SYMLINK_NOFOLLOW) \ ! && (!defined(__SUNPRO_CC) || __SUNPRO_CC > 0x5100) if (::fchmodat(AT_FDCWD, p.c_str(), mode_cast(prms), !(prms & symlink_perms) ? 0 : AT_SYMLINK_NOFOLLOW)) # else // fallback if fchmodat() not supported --- 1397,1403 ---- // Mac OS X Lion and some other platforms don't support fchmodat() # if defined(AT_FDCWD) && defined(AT_SYMLINK_NOFOLLOW) \ ! && (!defined(__SunOS)) if (::fchmodat(AT_FDCWD, p.c_str(), mode_cast(prms), !(prms & symlink_perms) ? 0 : AT_SYMLINK_NOFOLLOW)) # else // fallback if fchmodat() not supported %