我正在努力使以下代码在基于Linux和FreeBSD的系统上都能工作,这是对宏__GLIBC__
和__USE_XOPEN2K8
的有效使用吗?
#include <stdio.h>
#include <langinfo.h>
#include <locale.h>
#include <xlocale.h>
int main(void) {
//#if defined(__GLIBC__) && defined (__USE_XOPEN2K8)
locale_t loc;
char *locale_messages = "en-US.utf-8";
loc = newlocale(LC_ALL_MASK, locale_messages, (locale_t)0);
if (loc != NULL)
{
char result[256];
sprintf(result, "%s_%s.%s",
nl_langinfo_l(_NL_IDENTIFICATION_LANGUAGE, loc),
nl_langinfo_l(_NL_IDENTIFICATION_TERRITORY, loc),
nl_langinfo_l(CODESET, loc));
}
//#endif
}
如果我不使用这些指令,我会在macOS上得到以下错误。我想禁用该代码以避免出现以下错误。
error: use of undeclared identifier '_NL_IDENTIFICATION_LANGUAGE'
nl_langinfo_l(_NL_IDENTIFICATION_LANGUAGE, loc),
^
error: use of undeclared identifier '_NL_IDENTIFICATION_TERRITORY'
nl_langinfo_l(_NL_IDENTIFICATION_TERRITORY, loc),
我发现一个线程建议使用_GNU_SOURCE和_XOPEN_SOURCE,但结果上面的代码在我的linux系统上也被禁用了。在使用它之前,我似乎需要定义_GNU_SOURCE,但在继续使用这个想法之前,我们可以使用__GLIBC__
和__USE_XOPEN2K8
吗。
您可以使用
#indef __FreeBSD__
#endif
预处理器指令来忽略不应该在FreeBSD上构建的代码。然而,FreeBSD上的man nl_langinfo_l
说,这个函数在FreeBSD中存在,所以你应该不会有任何问题
最好的方法是使用构建系统来检测该选项是否可用,然后根据检测结果有条件地启用该部分代码。autotools
项目就是这样产生的——检测操作系统之间的差异。
在cmake中,您可以:
include(CheckCSourceCompiles)
check_c_source_compiles("
#define _GNU_SOURCE
#define _SOMETHING_READ_FEATURE_TEST_MACROS
#include <something something that is needed.h>
int main() { return _NL_IDENTIFICATION_TERRITORY; }
" WE_HAVE_NL_IDENTIFICATION_TERRITORY)
if(WE_HAVE_NL_IDENTIFICATION_TERRITORY)
target_add_definitions(your_target PUBLIC LIB_HAS_NL_IDENTIFICATION_TERRITORY)
endif()
然后使用您自己的LIB_HAS_NL_IDENTIFICATION_TERRITORY
宏来检测该选项是否可用。这样的解决方案稳定、易于移植,并对环境变化做出动态反应。