Accueil > > > GÉNÉRATEUR DE MAKEFILE
GÉNÉRATEUR DE MAKEFILE
Information sur la source
Description
Bonjour, Ce script est un générateur simple de Makefile, une sorte de mini-autotool mais en moins bien. Il est utilisable dans le plupart des projets compilés, aussi bien pour des exécutables que pour des librairies, et ce dans pas mal de langage. Problématique : Lorsque les sources projet sont réparties dans plusieurs sous-dossiers il devient hardu de n'avoir qu'un seule Makefile pour compiler tout ceci. Les comportements antagonistes de make et gmake font que n'avoir qu'un seul Makefile pour son projet est une chose compliquée a obtenir et très peu efficace. Le meilleur moyen pour garder une compatibilité entre ces deux outils est d'avoir un Makefile par sous-dossier, chose complexe a mettre en place a la main. Solution : Ce script va générer de lui même chacun des Makefile dans tous les sous-dossiers. Pour ceci il se base sur un fichier de configuration en xml et sur un modèle de Makefile (template). Utilisation : cf man donné dans l'archive (attention il est en mauvais anglais :p). Cette dernière contient également des exemples de templates et de fichier de configuration (les observer aide énormément a comprendre). Rappel : man -M ./ my_makefile Spécificités : Cet outil se base sur une configuration minimale du projet : - Un dossier includes contenant les headers a inclure. - Un dossier src contenant les sources du projet, ces dernières pouvant être réparties dans autant de sous-dossiers que souhaité. - Le script et son fichier de configuration a la racine du projet. Le choix du compilateur, du linker et de l'outil make est basé sur la variable d'environnement OSTYPE. J'utilise régulièrement ce procédé afin de pouvoir compiler sur une machine spécifique dont le PATH est mal configuré (je doit préciser a la main je chemin vers gcc). ceci entraine un gros point faible du script : il faut préciser le compilateur pour chaque OSTYPE. cependant, ce soucis peu être relativisé car tous les shells (en particulier le bash) n'ont pas OSTYPE dans leur environnement : il est possible de définir un compilateur pour ce genre de cas (chose recommandée). Il est important de noter qu'une fois les Makefiles générés le script devient inutile si l'architecture du projet de change pas (ajout de fichiers etc) : c'est le Makefile qui s'adapte a l'OSTYPE et non le script, ce dernier étant indépendant de toute architecture. Ceci vous permet d'utiliser un modèle de Makefile définissant CC, LD et MAKE "en dur" si vous n'appréciez pas l'adaptation a l'OSTYPE.
Source
- #!/usr/bin/php
- <?php
- // do_makefiles.php for my_makefile in /media/tycho/sources/php/my_makefile
- //
- // Made by Rodolphe Breard
- // Mail <rodolphe.breard@laposte.net>
- //
- // Started on Thu Jan 29 21:12:19 2009 Rodolphe Breard
- // Last update Wed Feb 4 23:07:26 2009 Rodolphe Breard
- //
- // my_makefile Copyright (C) 2008 Rodolphe Breard
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program. If not, see <http://www.gnu.org/licenses/>.
- //
-
- define('FILE_CONFIG', 'config.xml');
- define('DIR_SRC', 'src');
- define('DIR_INCLUDES', 'includes');
- define('ERR_LOAD_FILE', "unable to load file.\n --> %s");
- define('ERR_CNF_MISS', "missing configuration element.\n --> %s");
- define('ERR_CNF_SYNTAX', "unknown configuration element.\n --> %s");
- define('ERR_DIR_MISS', "missing directory.\n --> %s");
- error_reporting(0);
-
- // -----------------------------------
- // --- XML configuration functions ---
- // -----------------------------------
-
- function load_cnf()
- {
- if (($cnf = simplexml_load_file(FILE_CONFIG)) === false)
- throw new Exception(sprintf(ERR_LOAD_FILE, FILE_CONFIG));
- return ($cnf);
- }
-
- function cnf_get_name($cnf, $argc, $argv)
- {
- if ($argc > 1)
- return ($argv[1]);
- if (($ret = (string)$cnf->name) == '')
- return (basename(getcwd()));
- return ($ret);
- }
-
- function cnf_get_make($cnf)
- {
- $ret = NULL;
- foreach($cnf->make->children() as $archi)
- $ret .= "\nMAKE_" . ($archi->getName() != 'unknown' ?
- $archi->getName() : "\t") . "\t= " . $archi . "\n";
- if ($ret === NULL || $ret == '')
- throw new Exception(sprintf(ERR_CNF_MISS, '<make>'));
- return ($ret);
- }
-
- function cnf_get_cc($cnf)
- {
- $ret = NULL;
- foreach($cnf->cc->children() as $archi)
- $ret .= "\nCC_" . ($archi->getName() != 'unknown' ?
- $archi->getName() : "\t") . "\t= " . $archi . "\n";
- if ($ret === NULL || $ret == '')
- throw new Exception(sprintf(ERR_CNF_MISS, '<cc>'));
- return ($ret);
- }
-
- function cnf_get_ld($cnf)
- {
- $ret = NULL;
- foreach($cnf->ld->children() as $archi)
- $ret .= "\nLD_" . ($archi->getName() != 'unknown' ?
- $archi->getName() : "\t") . "\t= " . $archi . "\n";
- if ($ret === NULL || $ret == '')
- throw new Exception(sprintf(ERR_CNF_MISS, '<ld>'));
- return ($ret);
- }
-
- function cnf_get_cflags($cnf, $deb=false)
- {
- $ret = NULL;
- foreach($cnf->cflags->children() as $flag)
- {
- if (($flag->getName() == 'flag') ||
- ($flag->getName() == 'optflag' && !$deb) ||
- ($flag->getName() == 'debflag' && $deb))
- $ret .= ($ret === NULL ? '-' : "\\\n\t\t-") . $flag;
- elseif ($flag->getName() != 'optflag' && $flag->getName() != 'debflag')
- throw new Exception(sprintf(ERR_CNF_SYNTAX, $flag));
- }
- return ($ret);
- }
-
- function cnf_get_ldflags($cnf)
- {
- $ret = NULL;
- foreach($cnf->ldflags->children() as $flag)
- {
- if (($flag->getName() == 'lib'))
- {
- if ($flag->name == false)
- throw new Exception(sprintf(ERR_CNF_MISS, '<name>'));
- if ($flag->dir != false)
- $tmp = 'L' . $flag->dir . ' -l';
- else
- $tmp = 'l';
- $ret .= ($ret === NULL ? '-' : "\\\n\t\t-") . $tmp . $flag->name;
- }
- elseif ($flag->getName() != 'optflag' && $flag->getName() != 'debflag')
- throw new Exception(sprintf(ERR_CNF_SYNTAX, $flag->getName()));
- }
- return ($ret);
- }
-
- function cnf_get_files($cnf, $elem)
- {
- $ret = NULL;
- if ($elem != 'tpl_main' && $elem != 'tpl_sub' &&
- $elem != 'src' && $elem != 'obj')
- throw new Exception(sprintf(ERR_CNF_SYNTAX, $elem));
- $ret = (string)$cnf->files->{$elem};
- if ($ret === NULL || $ret == '')
- throw new Exception(sprintf(ERR_CNF_MISS, '<' . $elem . '>'));
- return ($ret);
- }
-
- // ------------------------------
- // --- Verification functions ---
- // ------------------------------
-
- function check_files()
- {
- $dir_list = array(DIR_SRC, DIR_INCLUDES);
- foreach ($dir_list as $to_check)
- {
- if (!is_dir($to_check))
- throw new Exception(sprintf(ERR_DIR_MISS, $to_check));
- }
- }
-
- // -----------------------------------
- // --- Makefile creation functions ---
- // -----------------------------------
-
- function get_includes($lvl)
- {
- $ret = '-I';
- while ($lvl-- > 0)
- $ret .= '../';
- return ($ret . DIR_INCLUDES);
- }
-
- function get_submake($dir, $opt = NULL)
- {
- foreach (scandir($dir) as $rep)
- if ($rep != '.' && $rep != '..' && is_dir($dir . '/' . $rep))
- $ret .= "\t" . '$(MAKE) ' . $rep . ($opt != NULL ? ' ' . $opt : '')."\n";
- return ($ret);
- }
-
- function get_local_src($dir)
- {
- $ret = NULL;
- foreach (scandir($dir) as $src)
- {
- if (!is_dir($src) && strstr($dir . '/' . $src, '.c') == '.c')
- $ret .= ($ret !== NULL ? " \\\n\t\t" : '') . $src;
- }
- return ($ret);
- }
-
- function get_glob_src($dir)
- {
- static $start = 0;
-
- foreach (scandir($dir) as $src)
- {
- if (!is_dir($dir .'/'. $src) && strstr($dir .'/'. $src, '.c') == '.c')
- {
- $ret .= ($start != 0 ? " \\\n\t\t" : '') . $dir . '/' . $src;
- $start = 1;
- }
- elseif (is_dir($dir .'/'. $src) && $src != '.' && $src != '..')
- {
- $ret .= get_glob_src($dir .'/'. $src, $start);
- }
- }
- return ($ret);
- }
-
- function get_makefile($tpl, $changes, $rep = '.')
- {
- $changes['{SUB_MAKE_ALL}'] = get_submake($rep);
- $changes['{SUB_MAKE_DEBUG}'] = get_submake($rep, 'debug');
- $changes['{SUB_MAKE_CLEAN}'] = get_submake($rep, 'clean');
- $changes['{SOURCES}'] = ($rep != '.' ? get_local_src($rep) :
- get_glob_src(DIR_SRC));
- if (!($make = file_get_contents($tpl)))
- throw new Exception(sprintf(ERR_LOAD_FILE, $tpl));
- return (strtr((string)$make, $changes));
- }
-
- function create_submakefile($cnf, $dir, $lvl, $changes)
- {
- if ($changes['{CFLAGS}'] != '')
- $changes['{CFLAGS}'] .= "\\\n\t\t";
- $changes['{CFLAGS}'] .= get_includes($lvl);
- if ($changes['{DEBUGFLAGS}'] != '')
- $changes['{DEBUGFLAGS}'] .= "\\\n\t\t";
- $changes['{DEBUGFLAGS}'] .= get_includes($lvl);
- file_put_contents($dir . '/Makefile',
- get_makefile(cnf_get_files($cnf, 'tpl_sub'),
- $changes, $dir));
- echo $dir, '/Makefile', "\n";
- foreach (scandir($dir) as $rep)
- {
- if ($rep != '.' && $rep != '..' && is_dir($dir . '/' . $rep))
- create_submakefile($cnf, $dir . '/' . $rep, $lvl + 1, $changes);
- }
- }
-
- // --------------------------
- // --- Main (entry point) ---
- // --------------------------
-
- try
- {
- check_files();
- $cnf = load_cnf();
- $changes = array('{NAME}' => cnf_get_name($cnf, $argc, $argv),
- '{MAKE_OS}' => cnf_get_make($cnf),
- '{CC_OS}' => cnf_get_cc($cnf),
- '{LD_OS}' => cnf_get_ld($cnf),
- '{CFLAGS}' => cnf_get_cflags($cnf),
- '{DEBUGFLAGS}' => cnf_get_cflags($cnf, true),
- '{LDFLAGS}' => cnf_get_ldflags($cnf),
- '{FILES_SRC}' => cnf_get_files($cnf, 'src'),
- '{FILES_OBJ}' => cnf_get_files($cnf, 'obj'),
- '{SOURCES}' => NULL,
- '{SUB_MAKE_ALL}' => NULL,
- '{SUB_MAKE_DEBUG}' => NULL,
- '{SUB_MAKE_CLEAN}' => NULL);
- echo 'Creating main Makefile ...', "\n";
- file_put_contents('Makefile',
- get_makefile(cnf_get_files($cnf, 'tpl_main'), $changes));
- echo 'Creating sub-Makefile ...', "\n";
- create_submakefile($cnf, DIR_SRC, 1, $changes);
- }
- catch (Exception $e)
- {
- fprintf(STDERR, "Error : %s\n", $e->getMessage());
- exit (1);
- }
-
- ?>
#!/usr/bin/php
<?php
// do_makefiles.php for my_makefile in /media/tycho/sources/php/my_makefile
//
// Made by Rodolphe Breard
// Mail <rodolphe.breard@laposte.net>
//
// Started on Thu Jan 29 21:12:19 2009 Rodolphe Breard
// Last update Wed Feb 4 23:07:26 2009 Rodolphe Breard
//
// my_makefile Copyright (C) 2008 Rodolphe Breard
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
define('FILE_CONFIG', 'config.xml');
define('DIR_SRC', 'src');
define('DIR_INCLUDES', 'includes');
define('ERR_LOAD_FILE', "unable to load file.\n --> %s");
define('ERR_CNF_MISS', "missing configuration element.\n --> %s");
define('ERR_CNF_SYNTAX', "unknown configuration element.\n --> %s");
define('ERR_DIR_MISS', "missing directory.\n --> %s");
error_reporting(0);
// -----------------------------------
// --- XML configuration functions ---
// -----------------------------------
function load_cnf()
{
if (($cnf = simplexml_load_file(FILE_CONFIG)) === false)
throw new Exception(sprintf(ERR_LOAD_FILE, FILE_CONFIG));
return ($cnf);
}
function cnf_get_name($cnf, $argc, $argv)
{
if ($argc > 1)
return ($argv[1]);
if (($ret = (string)$cnf->name) == '')
return (basename(getcwd()));
return ($ret);
}
function cnf_get_make($cnf)
{
$ret = NULL;
foreach($cnf->make->children() as $archi)
$ret .= "\nMAKE_" . ($archi->getName() != 'unknown' ?
$archi->getName() : "\t") . "\t= " . $archi . "\n";
if ($ret === NULL || $ret == '')
throw new Exception(sprintf(ERR_CNF_MISS, '<make>'));
return ($ret);
}
function cnf_get_cc($cnf)
{
$ret = NULL;
foreach($cnf->cc->children() as $archi)
$ret .= "\nCC_" . ($archi->getName() != 'unknown' ?
$archi->getName() : "\t") . "\t= " . $archi . "\n";
if ($ret === NULL || $ret == '')
throw new Exception(sprintf(ERR_CNF_MISS, '<cc>'));
return ($ret);
}
function cnf_get_ld($cnf)
{
$ret = NULL;
foreach($cnf->ld->children() as $archi)
$ret .= "\nLD_" . ($archi->getName() != 'unknown' ?
$archi->getName() : "\t") . "\t= " . $archi . "\n";
if ($ret === NULL || $ret == '')
throw new Exception(sprintf(ERR_CNF_MISS, '<ld>'));
return ($ret);
}
function cnf_get_cflags($cnf, $deb=false)
{
$ret = NULL;
foreach($cnf->cflags->children() as $flag)
{
if (($flag->getName() == 'flag') ||
($flag->getName() == 'optflag' && !$deb) ||
($flag->getName() == 'debflag' && $deb))
$ret .= ($ret === NULL ? '-' : "\\\n\t\t-") . $flag;
elseif ($flag->getName() != 'optflag' && $flag->getName() != 'debflag')
throw new Exception(sprintf(ERR_CNF_SYNTAX, $flag));
}
return ($ret);
}
function cnf_get_ldflags($cnf)
{
$ret = NULL;
foreach($cnf->ldflags->children() as $flag)
{
if (($flag->getName() == 'lib'))
{
if ($flag->name == false)
throw new Exception(sprintf(ERR_CNF_MISS, '<name>'));
if ($flag->dir != false)
$tmp = 'L' . $flag->dir . ' -l';
else
$tmp = 'l';
$ret .= ($ret === NULL ? '-' : "\\\n\t\t-") . $tmp . $flag->name;
}
elseif ($flag->getName() != 'optflag' && $flag->getName() != 'debflag')
throw new Exception(sprintf(ERR_CNF_SYNTAX, $flag->getName()));
}
return ($ret);
}
function cnf_get_files($cnf, $elem)
{
$ret = NULL;
if ($elem != 'tpl_main' && $elem != 'tpl_sub' &&
$elem != 'src' && $elem != 'obj')
throw new Exception(sprintf(ERR_CNF_SYNTAX, $elem));
$ret = (string)$cnf->files->{$elem};
if ($ret === NULL || $ret == '')
throw new Exception(sprintf(ERR_CNF_MISS, '<' . $elem . '>'));
return ($ret);
}
// ------------------------------
// --- Verification functions ---
// ------------------------------
function check_files()
{
$dir_list = array(DIR_SRC, DIR_INCLUDES);
foreach ($dir_list as $to_check)
{
if (!is_dir($to_check))
throw new Exception(sprintf(ERR_DIR_MISS, $to_check));
}
}
// -----------------------------------
// --- Makefile creation functions ---
// -----------------------------------
function get_includes($lvl)
{
$ret = '-I';
while ($lvl-- > 0)
$ret .= '../';
return ($ret . DIR_INCLUDES);
}
function get_submake($dir, $opt = NULL)
{
foreach (scandir($dir) as $rep)
if ($rep != '.' && $rep != '..' && is_dir($dir . '/' . $rep))
$ret .= "\t" . '$(MAKE) ' . $rep . ($opt != NULL ? ' ' . $opt : '')."\n";
return ($ret);
}
function get_local_src($dir)
{
$ret = NULL;
foreach (scandir($dir) as $src)
{
if (!is_dir($src) && strstr($dir . '/' . $src, '.c') == '.c')
$ret .= ($ret !== NULL ? " \\\n\t\t" : '') . $src;
}
return ($ret);
}
function get_glob_src($dir)
{
static $start = 0;
foreach (scandir($dir) as $src)
{
if (!is_dir($dir .'/'. $src) && strstr($dir .'/'. $src, '.c') == '.c')
{
$ret .= ($start != 0 ? " \\\n\t\t" : '') . $dir . '/' . $src;
$start = 1;
}
elseif (is_dir($dir .'/'. $src) && $src != '.' && $src != '..')
{
$ret .= get_glob_src($dir .'/'. $src, $start);
}
}
return ($ret);
}
function get_makefile($tpl, $changes, $rep = '.')
{
$changes['{SUB_MAKE_ALL}'] = get_submake($rep);
$changes['{SUB_MAKE_DEBUG}'] = get_submake($rep, 'debug');
$changes['{SUB_MAKE_CLEAN}'] = get_submake($rep, 'clean');
$changes['{SOURCES}'] = ($rep != '.' ? get_local_src($rep) :
get_glob_src(DIR_SRC));
if (!($make = file_get_contents($tpl)))
throw new Exception(sprintf(ERR_LOAD_FILE, $tpl));
return (strtr((string)$make, $changes));
}
function create_submakefile($cnf, $dir, $lvl, $changes)
{
if ($changes['{CFLAGS}'] != '')
$changes['{CFLAGS}'] .= "\\\n\t\t";
$changes['{CFLAGS}'] .= get_includes($lvl);
if ($changes['{DEBUGFLAGS}'] != '')
$changes['{DEBUGFLAGS}'] .= "\\\n\t\t";
$changes['{DEBUGFLAGS}'] .= get_includes($lvl);
file_put_contents($dir . '/Makefile',
get_makefile(cnf_get_files($cnf, 'tpl_sub'),
$changes, $dir));
echo $dir, '/Makefile', "\n";
foreach (scandir($dir) as $rep)
{
if ($rep != '.' && $rep != '..' && is_dir($dir . '/' . $rep))
create_submakefile($cnf, $dir . '/' . $rep, $lvl + 1, $changes);
}
}
// --------------------------
// --- Main (entry point) ---
// --------------------------
try
{
check_files();
$cnf = load_cnf();
$changes = array('{NAME}' => cnf_get_name($cnf, $argc, $argv),
'{MAKE_OS}' => cnf_get_make($cnf),
'{CC_OS}' => cnf_get_cc($cnf),
'{LD_OS}' => cnf_get_ld($cnf),
'{CFLAGS}' => cnf_get_cflags($cnf),
'{DEBUGFLAGS}' => cnf_get_cflags($cnf, true),
'{LDFLAGS}' => cnf_get_ldflags($cnf),
'{FILES_SRC}' => cnf_get_files($cnf, 'src'),
'{FILES_OBJ}' => cnf_get_files($cnf, 'obj'),
'{SOURCES}' => NULL,
'{SUB_MAKE_ALL}' => NULL,
'{SUB_MAKE_DEBUG}' => NULL,
'{SUB_MAKE_CLEAN}' => NULL);
echo 'Creating main Makefile ...', "\n";
file_put_contents('Makefile',
get_makefile(cnf_get_files($cnf, 'tpl_main'), $changes));
echo 'Creating sub-Makefile ...', "\n";
create_submakefile($cnf, DIR_SRC, 1, $changes);
}
catch (Exception $e)
{
fprintf(STDERR, "Error : %s\n", $e->getMessage());
exit (1);
}
?>
Conclusion
Comme beaucoup d'outils libres, ce script a été créé a la base pour un usage personnel. Lorsque j'ai écrit ce script j'ai fait face a des problèmes particuliers que je me posais et non a des problèmes trop génériques, ce qui en fait un outil très critiquable car ne répondant pas forcément au besoin général, et ce d'autant plus qu'il existe déjà des outils bien plus performants dans le domaine. Je suis tout a fait conscient de ce fait, il est inutile de me le faire remarquer a nouveau.
Ceci dit, je vous laisse regarder le code suis impatient de voir vos critiques a son sujet afin de pouvoir l'améliorer.
Historique
- 31 janvier 2009 17:11:24 :
- Modification de la description.
- 02 février 2009 19:26:40 :
- Correction d'un bug sous php6.
- 04 février 2009 23:10:29 :
- Faute de frappe.
Sources du même auteur
Sources de la même categorie
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
Repertoire d'installation du Makefile [ par v86 ]
Bonjour j'ai suivi le tutoriel d'installation d'apache 2.0, php5.0 et mysql4.1 d'eXon disponible à cette adresse : http://www.phpcs.com/tutorial.aspx?
|
Derniers Blogs
IMAGINE CUP 2012, MAKE A SIGN EN FINALEIMAGINE CUP 2012, MAKE A SIGN EN FINALE par junarnoalg
Voilà qui est fait, la nouvelle est officielle ! L'équipe belge "Make a Sign" va au pays des kangourous défendre son projet dans la catégorie Software Design. http://www.imaginecup.com/CompetitionsContent/Competition/WorldwideFinalists.aspx V...
Cliquez pour lire la suite de l'article par junarnoalg KINECT 1.5 IS OUT !KINECT 1.5 IS OUT ! par Vko
La version 1.5 du Kinect For Microsoft vient tout juste de sortir ! Plein de nouveautés: Tracking de squelette en Near Mode Détection en position assise Détection faciale avec un SDK dédié Documentation et des guideline (enfin) Un out...
Cliquez pour lire la suite de l'article par Vko LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) par richardc
Mise à jour des Web API du 14 Mai
Réservez dès maintenant votre journée du 20 juin pour le Windows Azure Dev Camp 2012 à Paris
Mise à jour de Team Foundation Service
MechCommander 2 sur Windows 8
Entity Framework 5 Release Candidate e...
Cliquez pour lire la suite de l'article par richardc REACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITERREACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITER par Groc
Une mauvaise utilisation de rx lors de l'écriture d'une couche d'accès à des services peut conduire à des cas embarassants avec des erreurs mal gérées, des appels qui ne partent lorsqu'ils le devraient, et même des résultats incorrects . le tout nuis...
Cliquez pour lire la suite de l'article par Groc SHAREPOINT BLOG SITE, PROBLèME D'ARCHIVESSHAREPOINT BLOG SITE, PROBLèME D'ARCHIVES par junarnoalg
Dernièrement, nous avons migré le site
myTIC
vers un nouveau serveur SharePoint 2010. Dans les contenus que nous vouloins récupérer, nous avions un certain nombre de blogs.
Nous avons utilisé les commandes Power...
Cliquez pour lire la suite de l'article par junarnoalg
Logiciels
sDEVIS-FACTURES vlPRO (8.1.0.3)SDEVIS-FACTURES VLPRO (8.1.0.3)sDEVIS-FACTURES vlPRO a été mis au point pour les particuliers, créateurs, entrepreneurs, artisa... Cliquez pour télécharger sDEVIS-FACTURES vlPRO 974 Application Server (12.2.4.6)974 APPLICATION SERVER (12.2.4.6)Développez de puissantes applications dans un environnement de 'cloud computing', clusterisé, séc... Cliquez pour télécharger 974 Application Server vPicture (1.4.2.1)VPICTURE (1.4.2.1)Avec vPicture, hébergez vos images facilement et rapidement.
vPicture est un utilitaire simple, ... Cliquez pour télécharger vPicture Easy-Planning (2.2.1.6)EASY-PLANNING (2.2.1.6)Easy-Planning permet de créer des plannings sous la représentation de diagrammes et est adapté au... Cliquez pour télécharger Easy-Planning COM-BACKUP (2.0)COM-BACKUP (2.0)
COM-BACKUP est un logiciel de sauvegarde qui permet de planifier les sauvegardes de vos dossiers ...
Cliquez pour télécharger COM-BACKUP
|