#ifndef BATCH_CONFIG_H
#define BATCH_CONFIG_H
+/* Defines the compiler used on Windows */
+#cmakedefine MSVC
+#cmakedefine MINGW
+
/* A path to a rcp-like command */
#define RCP "@RCP@"
/* A path to a sh-like command */
#define SH "@SH@"
+#cmakedefine SH_COMMAND_IS_CMD
/* A path to a ssh-like command */
#define SSH "@SSH@"
ENABLE_TESTING()
-find_package (Threads)
-IF (NOT CMAKE_USE_PTHREADS_INIT)
- MESSAGE(FATAL_ERROR "Mandatory library pthread not found")
-ENDIF (NOT CMAKE_USE_PTHREADS_INIT)
+find_package (PThread REQUIRED)
find_package (Makeinfo)
SET (BUILD_LSF_INTERFACE TRUE CACHE BOOL "Build interface for LSF batch system")
ENDIF (Makeinfo_FOUND)
SET(CPACK_GENERATOR TGZ)
-SET(CPACK_SOURCE_GENERATOR TGZ)
+SET(CPACK_SOURCE_GENERATOR TGZ ZIP)
SET(CPACK_PACKAGE_VERSION_MAJOR 1)
SET(CPACK_PACKAGE_VERSION_MINOR 0)
SET(CPACK_PACKAGE_VERSION_PATCH 0)
ENDMACRO(FIND_LOCAL_COMMAND)
MESSAGE(STATUS "Looking for commands needed for local submission...")
-FIND_LOCAL_COMMAND(RM rm)
-FIND_LOCAL_COMMAND(SH sh)
-FIND_LOCAL_COMMAND(CP cp)
+
+FIND_PROGRAM(RM rm)
+IF (RM)
+ MESSAGE(STATUS "rm found : ${RM}")
+ELSE (RM)
+ IF (WIN32)
+ MESSAGE(STATUS "using 'del' as rm command")
+ SET(RM del)
+ ELSE (WIN32)
+ MESSAGE(STATUS "rm not found, local submission might not work properly")
+ SET(RM /bin/false)
+ ENDIF (WIN32)
+ENDIF (RM)
+MARK_AS_ADVANCED(RM)
+
+FIND_PROGRAM(SH sh)
+IF (SH)
+ MESSAGE(STATUS "sh found : ${SH}")
+ELSE (SH)
+ FIND_PROGRAM(CMD cmd)
+ IF (CMD)
+ MESSAGE(STATUS "cmd found : ${CMD}")
+ SET(SH ${CMD})
+ SET(SH_COMMAND_IS_CMD TRUE)
+ ELSE (CMD)
+ MESSAGE(STATUS "sh not found, local submission might not work properly")
+ SET(SH /bin/false)
+ ENDIF (CMD)
+ENDIF (SH)
+MARK_AS_ADVANCED(CMD SH SH_COMMAND_IS_CMD)
+
+FIND_PROGRAM(CP cp)
+IF (CP)
+ MESSAGE(STATUS "cp found : ${CP}")
+ELSE (CP)
+ IF (WIN32)
+ MESSAGE(STATUS "using 'copy' as cp command")
+ SET(CP copy)
+ ELSE (WIN32)
+ MESSAGE(STATUS "cp not found, local submission might not work properly")
+ SET(CP /bin/false)
+ ENDIF (WIN32)
+ENDIF (CP)
+MARK_AS_ADVANCED(CP)
+
FIND_LOCAL_COMMAND(RSH rsh)
FIND_LOCAL_COMMAND(RCP rcp)
FIND_LOCAL_COMMAND(SSH ssh plink)
--- /dev/null
+# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+IF (NOT PThread_FIND_QUIETLY)
+ MESSAGE(STATUS "Looking for PThread...")
+ENDIF (NOT PThread_FIND_QUIETLY)
+
+FIND_PATH(PTHREAD_INCLUDE_DIR pthread.h)
+FIND_LIBRARY(PTHREAD_LIBRARY NAMES pthread pthreadVC2)
+
+IF (PTHREAD_INCLUDE_DIR AND PTHREAD_LIBRARY)
+ SET(PThread_FOUND True)
+ENDIF (PTHREAD_INCLUDE_DIR AND PTHREAD_LIBRARY)
+
+IF (PThread_FOUND)
+
+ IF (NOT PThread_FIND_QUIETLY)
+ MESSAGE(STATUS "Found PThread:")
+ MESSAGE(STATUS "PThread include directory: ${PTHREAD_INCLUDE_DIR}")
+ MESSAGE(STATUS "PThread library: ${PTHREAD_LIBRARY}")
+ ENDIF (NOT PThread_FIND_QUIETLY)
+
+ELSE (PThread_FOUND)
+
+ IF (PThread_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "PThread not found")
+ ELSE (PThread_FIND_REQUIRED)
+ IF (NOT PThread_FIND_QUIETLY)
+ MESSAGE(STATUS "PThread not found")
+ ENDIF (NOT PThread_FIND_QUIETLY)
+ ENDIF (PThread_FIND_REQUIRED)
+
+ENDIF (PThread_FOUND)
IF (PYTHON_DEBUG)
SET(PYTHON_EXECUTABLE ${PYTHON_DEBUG} CACHE STRING "Python interpreter")
ELSE (PYTHON_DEBUG)
- FIND_PROGRAM(PYTHON_EXECUTABLE python DOC "Python interpreter")
+ IF(MSVC AND NOT CMAKE_BUILD_TYPE STREQUAL Release)
+ MESSAGE(STATUS "Warning! Python debug executable not found. To build Swig module, you will need to install it or compile in Release mode")
+ ELSE(MSVC AND NOT CMAKE_BUILD_TYPE STREQUAL Release)
+ FIND_PROGRAM(PYTHON_EXECUTABLE python DOC "Python interpreter")
+ ENDIF(MSVC AND NOT CMAKE_BUILD_TYPE STREQUAL Release)
ENDIF (PYTHON_DEBUG)
IF (PYTHON_EXECUTABLE)
IF (Python_FOUND)
IF (NOT Python_FIND_QUIETLY)
- MESSAGE(STATUS "Found Python: ${PYTHON_EXECUTABLE} (version ${PYTHON_VERSION})")
+ MESSAGE(STATUS "Found Python:")
+ MESSAGE(STATUS "Python executable: ${PYTHON_EXECUTABLE} (version ${PYTHON_VERSION})")
+ MESSAGE(STATUS "Python include directory: ${PYTHON_INCLUDE_PATH}")
+ MESSAGE(STATUS "Python library: ${PYTHON_LIBRARIES}")
ENDIF (NOT Python_FIND_QUIETLY)
ELSE (Python_FOUND)
this we tested Pthreads-win32 (http://sourceware.org/pthreads-win32/) but other
implementations may exist.
-You will also need a compiler for Win32 platform. We tested MinGW and MSYS
-utilities (http://www.mingw.org/) but another compiler might also work.
+You will also need a compiler for Win32 platform. We tested MinGW with MSYS
+environment (http://www.mingw.org/), and Microsoft Visual C++ 2005 Express.
+Other compilers might also work but it is not guaranteed.
Then you will have to install and run CMake, and you should be able to compile
libBatch and run some basic examples.
ENDFOREACH(CLASS ${ARGV})
ENDMACRO(APPEND_CLASSES_TO_HDR_FILES)
+IF (MSVC)
+ add_definitions(/wd4251 /wd4290) # Disable annoying Visual C++ warnings
+ENDIF (MSVC)
+include_directories(${PTHREAD_INCLUDE_DIR})
add_subdirectory (Core)
add_library (Batch SHARED ${SRC_FILES})
-include_directories(${CMAKE_BINARY_DIR})
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Core)
-
-target_link_libraries(Batch ${CMAKE_THREAD_LIBS_INIT})
+include_directories(${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/Core)
+target_link_libraries(Batch ${PTHREAD_LIBRARY})
IF (WIN32)
target_link_libraries(Batch ws2_32)
#include "Batch_BatchManager_eClient.hxx"
#include "Batch_RunTimeException.hxx"
+#include <ctime>
#include <iostream>
#include <fstream>
#include <sstream>
#ifdef WIN32
#include <direct.h>
+#include <io.h>
#endif
#include "Batch_config.h"
+#ifdef MSVC
+#define EXISTS(path) _access_s(path, 0) == 0
+#else
+#define EXISTS(path) access(path, F_OK) == 0
+#endif
+
using namespace std;
do {
sprintf(randstr, "%06d", rand() % 1000000);
fileName.replace(fileName.size()-6, 6, randstr);
- } while (access(fileName.c_str(), F_OK) == 0);
+ } while (EXISTS(fileName.c_str()));
return fileName;
}
do {
sprintf(randstr, "%06d", rand() % 1000000);
baseName.replace(baseName.size()-6, 6, randstr);
- } while (access(baseName.c_str(), F_OK) == 0);
+ } while (EXISTS(baseName.c_str()));
if (_mkdir(baseName.c_str()) != 0)
throw RunTimeException(string("Can't create temporary directory ") + baseName);
tmpDirName = baseName;
ZeroMemory( &pi, sizeof(pi) );
// Copy the command to a non-const buffer
- size_t str_size = exec_command.size();
- char buffer[str_size+1];
- exec_command.copy(buffer,str_size);
- buffer[str_size]='\0';
+ char * buffer = strdup(exec_command.c_str());
// launch the new process
BOOL res = CreateProcess(NULL, buffer, NULL, NULL, FALSE,
- DETACHED_PROCESS, chNewEnv, NULL, &si, &pi);
+ CREATE_NO_WINDOW, chNewEnv, NULL, &si, &pi);
+ if (buffer) free(buffer);
if (!res) throw RunTimeException("Error while creating new process");
CloseHandle(pi.hThread);
#include "Batch_Defines.hxx"
+#ifdef WIN32
+#include <Windows.h>
+#endif
+
#include <list>
#include <map>
#include <queue>
*
*/
-#ifdef HAVE_CONFIG_H
-# include <SALOMEconfig.h>
-#endif
-
#include <iostream>
#include <fstream>
#include <sstream>
#include <signal.h>
#include <errno.h>
#include <string.h>
+
#include "Batch_IOMutex.hxx"
#include "Batch_BatchManager_Local_RSH.hxx"
namespace Batch {
+ // Simple method to fix path strings depending on the platform. On Windows, it will replace
+ // forward slashes '/' by backslashes '\'. On Unix, the path is just copied without change.
+ string BatchManager_Local_SH::fixPath(const string & path) const
+ {
+ string fixedPath = path;
+#ifdef WIN32
+ for (int i=0 ; i<fixedPath.size() ; i++) {
+ if (fixedPath[i] == '/') fixedPath[i] = '\\';
+ }
+#endif
+ return fixedPath;
+ }
// Constructeur
BatchManager_Local_SH::BatchManager_Local_SH(const FactBatchManager * parent, const char * host) throw(InvalidArgumentException,ConnexionFailureException) : BatchManager_Local(parent, host)
const std::string & destination) const
{
ostringstream copy_cmd;
- copy_cmd << "\"" << CP << "\" \"" << source << "\" \"" << destination << "\"";
+ if (strchr(CP, ' ') == NULL)
+ copy_cmd << CP;
+ else
+ copy_cmd << "\"" << CP << "\"";
+ copy_cmd << " \"" << fixPath(source) << "\" \"" << fixPath(destination) << "\"";
return copy_cmd.str();
}
#ifdef WIN32
exec_sub_cmd << "\"";
#endif
+#ifdef SH_COMMAND_IS_CMD
+ char drive[_MAX_DRIVE];
+ _splitpath_s(fixPath(param[WORKDIR]).c_str(), drive, _MAX_DRIVE, NULL, 0, NULL, 0, NULL, 0);
+ if (strlen(drive) > 0) exec_sub_cmd << drive << " && ";
+ exec_sub_cmd << "cd " << fixPath(param[WORKDIR]) << " && " << fixPath(param[EXECUTABLE]);
+#else
exec_sub_cmd << "cd " << param[WORKDIR] << " && " << param[EXECUTABLE];
+#endif
if (param.find(ARGUMENTS) != param.end()) {
Versatile V = param[ARGUMENTS];
exec_sub_cmd << "\"";
#endif
+#ifdef SH_COMMAND_IS_CMD
+ param[ARGUMENTS] = "/c";
+#else
param[ARGUMENTS] = "-c";
+#endif
param[ARGUMENTS] += exec_sub_cmd.str();
- return SH;
+ return fixPath(SH);
}
// Methode qui renvoie la commande d'effacement du fichier
const std::string & destination) const
{
ostringstream remove_cmd;
- remove_cmd << "\"" << RM << "\" \"" << destination << "\"";
+ if (strchr(RM, ' ') == NULL)
+ remove_cmd << RM;
+ else
+ remove_cmd << "\"" << RM << "\"";
+
+ remove_cmd << " \"" << fixPath(destination) << "\"";
return remove_cmd.str();
}
virtual ~BatchManager_Local_SH();
protected:
+ std::string fixPath(const std::string & path) const;
+
// Methode qui renvoie la commande de copie du fichier source en destination
virtual std::string copy_command( const std::string & user_source,
const std::string & host_source,
SET (TEST_LOCAL_SSH_WORK_DIR "/tmp" CACHE STRING
"Work directory for SSH Batch test (only necessary for test target)")
+# Build the executable to use for the local test program
+add_executable(Exec_Test Exec_Test.cxx)
+GET_TARGET_PROPERTY(EXEC_TEST_FULL_PATH_TEMP Exec_Test LOCATION)
+GET_FILENAME_COMPONENT(EXEC_TEST_NAME_TEMP ${EXEC_TEST_FULL_PATH_TEMP} NAME)
+SET(EXEC_TEST_FULL_PATH ${EXEC_TEST_FULL_PATH_TEMP} CACHE INTERNAL "")
+SET(EXEC_TEST_NAME ${EXEC_TEST_NAME_TEMP} CACHE INTERNAL "")
+
# Configure the config file for all the test scripts
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/Test_Local_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/Test_Local_config.h)
--- /dev/null
+// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * Exec_Test.cxx :
+ *
+ * Author : Renaud BARATE - EDF R&D
+ * Date : May 2009
+ *
+ */
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+using namespace std;
+
+int main(int argc, char** argv)
+{
+ if (argc != 4) {
+ cerr << "Exec_Test expects three parameters, usage: Exec_Test <scriptA> <scriptB> <result>" << endl;
+ return 1;
+ }
+
+ const char * scriptAFileName = argv[1];
+ const char * scriptBFileName = argv[2];
+ const char * resultFileName = argv[3];
+
+ ifstream scriptAStream(scriptAFileName);
+ std::string line;
+ int a = 0;
+ while (getline(scriptAStream, line)) {
+ if (line.compare(0, 2, string("a=")) == 0) {
+ a = strtol(line.substr(2).c_str(), NULL, 10);
+ }
+ }
+ scriptAStream.close();
+ if (a == 0) {
+ cerr << "Exec_Test couldn't parse value \"a\" in " << scriptAFileName << endl;
+ return 1;
+ }
+
+ ifstream scriptBStream(scriptBFileName);
+ int b = 0;
+ while (getline(scriptBStream, line)) {
+ if (line.compare(0, 2, string("b=")) == 0) {
+ b = strtol(line.substr(2).c_str(), NULL, 10);
+ }
+ }
+ scriptBStream.close();
+ if (b == 0) {
+ cerr << "Exec_Test couldn't parse value \"b\" in " << scriptBFileName << endl;
+ return 1;
+ }
+
+ int c = a * b;
+ ofstream resultStream(resultFileName);
+ resultStream << "c = " << c;
+ resultStream.close();
+ return 0;
+}
Job job;
// ... and its parameters ...
Parametre p;
- p["EXECUTABLE"] = "./copied-test-script.sh";
+ p["EXECUTABLE"] = string("./copied-") + EXEC_TEST_NAME;
+ p["ARGUMENTS"] = "copied-seta.sh";
+ p["ARGUMENTS"] += "copied-setb.sh";
+ p["ARGUMENTS"] += "orig-result.txt";
p["NAME"] = "Test_Local_SH";
p["WORKDIR"] = TEST_LOCAL_SH_WORK_DIR;
p["INFILE"] = Couple("seta.sh", "copied-seta.sh");
p["INFILE"] += Couple("setb.sh", "copied-setb.sh");
- p["INFILE"] += Couple("test-script.sh", "copied-test-script.sh");
+ p["INFILE"] += Couple(EXEC_TEST_NAME, string("copied-") + EXEC_TEST_NAME);
p["OUTFILE"] = Couple("result.txt", "orig-result.txt");
job.setParametre(p);
// ... and its environment
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+#define EXEC_TEST_NAME "${EXEC_TEST_NAME}"
+
#define TEST_LOCAL_SH_WORK_DIR "${TEST_LOCAL_SH_WORK_DIR}"
#define TEST_LOCAL_RSH_EXECUTION_HOST "${TEST_LOCAL_RSH_EXECUTION_HOST}"
#define TEST_LOCAL_SSH_WORK_DIR "${TEST_LOCAL_SSH_WORK_DIR}"
#ifdef WIN32
+#include <Windows.h>
#define sleep(seconds) Sleep((seconds)*1000)
#define usleep(useconds) Sleep((useconds)/1000)
#endif
#include <fstream>
#include <sstream>
#include <sys/stat.h>
+
+#include "Batch_config.h"
+
+#ifdef MSVC
+#include <io.h>
+#else
#include <libgen.h>
+#endif
#include "Batch_BatchManager_ePBS.hxx"
-#include "Batch_config.h"
using namespace std;
string::size_type p1 = fileToExecute.find_last_of("/");
string::size_type p2 = fileToExecute.find_last_of(".");
rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
+
+#ifdef MSVC
+ char fname[_MAX_FNAME];
+ char ext[_MAX_EXT];
+ _splitpath_s(fileToExecute.c_str(), NULL, 0, NULL, 0, fname, _MAX_FNAME, ext, _MAX_EXT);
+ string execBaseName = string(fname) + ext;
+#else
char* basec=strdup(fileToExecute.c_str());
- fileNameToExecute = "~/" + dirForTmpFiles + "/" + string(basename(basec));
+ string execBaseName = string(basename(basec));
free(basec);
+#endif
+
+ fileNameToExecute = "~/" + dirForTmpFiles + "/" + execBaseName;
int idx = dirForTmpFiles.find("Batch/");
filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length());
#define TEST_PBS_QUEUE "${TEST_PBS_QUEUE}"
#ifdef WIN32
+#include <Windows.h>
#define sleep(seconds) Sleep((seconds)*1000)
#define usleep(useconds) Sleep((useconds)/1000)
#endif
# Just copy the test scripts to the binary dir
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/seta.sh ${CMAKE_CURRENT_BINARY_DIR}/seta.sh COPYONLY)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/setb.sh ${CMAKE_CURRENT_BINARY_DIR}/setb.sh COPYONLY)
-CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/test-script.sh ${CMAKE_CURRENT_BINARY_DIR}/test-script.sh COPYONLY)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/Test_Python_Local_SH.py
${CMAKE_CURRENT_BINARY_DIR}/Test_Python_Local_SH.py COPYONLY)
job = Job()
# ... and its parameters ...
p = {}
- p['EXECUTABLE'] = './copied-test-script.sh'
- p['NAME'] = 'Test_Local_SH'
- p['WORKDIR'] = '/tmp'
+ p['EXECUTABLE'] = './copied-' + config.EXEC_TEST_NAME
+ p["ARGUMENTS"] = ["copied-seta.sh", "copied-setb.sh", "orig-result.txt"];
+ p['NAME'] = 'Test_Python_Local_SH'
+ p['WORKDIR'] = config.TEST_LOCAL_SH_WORK_DIR
p['INFILE'] = [('seta.sh', 'copied-seta.sh'), ('setb.sh', 'copied-setb.sh'),
- ('test-script.sh', 'copied-test-script.sh')]
+ (config.EXEC_TEST_FULL_PATH, 'copied-' + config.EXEC_TEST_NAME)]
p['OUTFILE'] = [('result.txt', 'orig-result.txt')]
job.setParametre(p)
# ... and its environment
import sys
sys.path.append('${CMAKE_CURRENT_BINARY_DIR}/..')
+
+EXEC_TEST_FULL_PATH = "${EXEC_TEST_FULL_PATH}"
+EXEC_TEST_NAME = "${EXEC_TEST_NAME}"
+
+TEST_LOCAL_SH_WORK_DIR = "${TEST_LOCAL_SH_WORK_DIR}"
+++ /dev/null
-#!/bin/sh
-
-source copied-seta.sh
-source copied-setb.sh
-
-c=`expr $a "*" $b`
-
-echo "c = $c" > orig-result.txt