2017-10-12 18 views
1

J'ai découvert un sérieux goulot d'étranglement dans mon projet - environ un quart du temps d'exécution global est gaspillé dans la fonction tzset (appelée par mktime).Inclure l'en-tête de la glibc

J'ai examiné tzset sources (le code, à partir de la ligne 378) et a constaté que la mise en TZ variable d'environnement une fois réduira considérablement son temps d'exécution, car il lit un fichier de fuseau horaire (par exemple /usr/local/etc/zoneinfo dans mon OS) si TZ La variable d'environnement n'est pas définie.

Je lirais ce fichier et définirais la variable d'environnement, mais l'emplacement du fichier peut différer sur différentes formes de plan. Donc, ce que je vais faire est de réutiliser en quelque sorte le code tzset utilisations à ces fins. Cela peut sembler facile, il suffit d'inclure l'en-tête tzset utilise pour localiser et récupérer les informations de fuseau horaire, et utiliser cette fonctionnalité :)

#include <timezone/tzfile.h> 

mais je ne sais vraiment pas comment le faire, je veux dire en utilisant les en-têtes glibc. Le compilateur ne connaît pas cet en-tête (mon IDE, Clion, ne le voit pas aussi). Je suis vraiment coincé avec ça.

+0

Vous avez deux choix de base. Ajoutez à votre script 'configure' (vous savez comment écrire des scripts' autoconf' - ce qui est une compétence obligatoire pour quiconque développe sur des systèmes d'exploitation POSIX non propriétaires - non?) Qui recherche zoneinfo dans un fixe un ensemble d'emplacements et l'utilise pour compiler une constante d'exécution. Vous pouvez également obtenir l'emplacement à partir d'une variable d'environnement qui doit être définie avant d'exécuter votre application. Cette situation est vraiment ce que 'autoconf', et le reste de la chaîne d'outils GNU, est conçu pour. –

+0

"Utiliser les autotools" n'est pas une réponse utile à quelqu'un qui demande comment faire quelque chose dans CMake. –

Répondre

1

Vous devez inclure un platform check pour tzinfo.h dans votre CMakeLists.txt. Exemple:

INCLUDE (CheckIncludeFiles) 
# usage: CHECK_INCLUDE_FILES (<possible header locations> <RESULT_VARIABLE>) 

if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") 
    CHECK_INCLUDE_FILES("timezone/tzfile.h;sys/tzfile.h" HAVE_TZFILE_H) 
endif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") 

Vous pouvez ensuite utiliser #ifdef HAVE_TZFILE_H

Si vous n'êtes pas inquiet pour vérifier le contenu du fichier, vous pouvez également utiliser FIND_FILE au lieu qui est un peu plus rapide. (CheckIncludeFiles utilise en fait un petit fichier .c et #include s l'en-tête d'essayer de le compiler.)

find_file (<VAR> NAMES name PATHS paths... NO_DEFAULT_PATH)