Commit 6bbc7d2b authored by saubatn's avatar saubatn

FIXED CEP architecture, step #1.6: Fixed windows plugins loading with...

FIXED CEP architecture, step #1.6: Fixed windows plugins loading with ExtensionManager in Debug / Release version (Commit technic).
FIXED CEP architecture, step #1.6: CamiTKCore and QtPropertyBrowser are built in build\bin directory on MSVC.
FIXED CEP architecture, step #1.6: CamiTKCore changes PATH environment variable on the fly to include the private lib dir.
FIXED CEP architecture, step #1.6: CamiTK now depends on Qt version 4.7 (we need qputenv(), qgetenv()).

git-svn-id: svn+ssh://scm.forge.imag.fr/var/lib/gforge/chroot/scmrepos/svn/camitk/trunk/camitk@749 ec899d31-69d1-42ba-9299-647d76f65fb3
parent f70dc2b6
......@@ -15,9 +15,9 @@ set(CAMITK_VERSION_MINOR "@CAMITK_VERSION_MINOR@")
set(CAMITK_SHORT_VERSION_STRING "camitk-${CAMITK_VERSION_MAJOR}.${CAMITK_VERSION_MINOR}")
#-- Check dependencies: Qt and VTK
find_package(Qt4 "4.6" COMPONENTS QtCore QtGui QtXml REQUIRED)
find_package(Qt4 "4.7" COMPONENTS QtCore QtGui QtXml REQUIRED)
if(NOT QT4_FOUND)
message(SEND_ERROR "Failed to find Qt 4.6 or greater. This is needed by CamiTK.")
message(SEND_ERROR "Failed to find Qt 4.7 or greater. This is needed by CamiTK.")
endif()
include(${QT_USE_FILE})
set (QT_USE_QT3SUPPORT OFF)
......
......@@ -129,18 +129,18 @@ macro(camitk_library)
# Specify, regarding the platform where to build the binaries depending on the library type (public / private)
if (${DEFAULT_LIBRARY_NAME_CMAKE}_PUBLIC) # Public library => build in the bin folder
if (MSVC)
message("Library ${LIBRARY_NAME} is public and will be built in ${CAMITK_BUILD_BIN_DIR}")
set_target_properties(${LIBRARY_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CAMITK_BUILD_PUBLIC_LIB_DIR}
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_PUBLIC_LIB_DIR}
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_PUBLIC_LIB_DIR}
# With Visual Studio, public libraries are built in build\bin directory, else it's in build\lib
set_target_properties(${LIBRARY_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CAMITK_BUILD_BIN_DIR}
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_BIN_DIR}
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_BIN_DIR}
)
set_target_properties(${LIBRARY_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CAMITK_BUILD_PUBLIC_LIB_DIR}
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_PUBLIC_LIB_DIR}
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_PUBLIC_LIB_DIR}
set_target_properties(${LIBRARY_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CAMITK_BUILD_BIN_DIR}
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_BIN_DIR}
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_BIN_DIR}
)
set_target_properties(${LIBRARY_NAME} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CAMITK_BUILD_PUBLIC_LIB_DIR}
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_PUBLIC_LIB_DIR}
ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_PUBLIC_LIB_DIR}
set_target_properties(${LIBRARY_NAME} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CAMITK_BUILD_BIN_DIR}
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_BIN_DIR}
ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_BIN_DIR}
)
set_target_properties(${LIBRARY_NAME} PROPERTIES DEBUG_POSTFIX ${CAMITK_DEBUG_POSTFIX})
else()
......@@ -150,7 +150,6 @@ macro(camitk_library)
endif()
else() # Private library => build in lib folder
if (MSVC)
message("Library ${LIBRARY_NAME} is private and will be built in ${CAMITK_BUILD_PRIVATE_LIB_DIR}")
set_target_properties(${LIBRARY_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CAMITK_BUILD_PRIVATE_LIB_DIR}
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_PRIVATE_LIB_DIR}
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_PRIVATE_LIB_DIR}
......
......@@ -28,8 +28,7 @@ set(CAMITKCORE_LIBRARY_PROPERTIES ${CAMITKCORE_LIBRARY_PROPERTIES}
# camitkcore only depends on qtpropertybrowser, which is a public library
# add the library path as an additionnal to look for.
link_directories(${CAMITK_BUILD_PUBLIC_LIB_DIR})
message("Core is looking for qtpropertybrowser in ${CAMITK_BUILD_PUBLIC_LIB_DIR}")
link_directories(${CAMITK_BUILD_BIN_DIR})
# CAMITK_CORE_LIB needs to be SHARED and loaded only ONCE otherwise the extensions
# can have their own copy of CAMITK_CORE_LIB, which will generates loads of problems
......@@ -52,18 +51,18 @@ endif()
target_link_libraries(${CAMITK_CORE_LIB} ${CAMITK_LIBRARIES})
# output directory
if (WIN32 AND MSVC)
set_target_properties(${CAMITK_CORE_LIB} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CAMITK_BUILD_PUBLIC_LIB_DIR}
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_PUBLIC_LIB_DIR}
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_PUBLIC_LIB_DIR}
if (MSVC)
set_target_properties(${CAMITK_CORE_LIB} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CAMITK_BUILD_BIN_DIR}
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_BIN_DIR}
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_BIN_DIR}
)
set_target_properties(${CAMITK_CORE_LIB} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CAMITK_BUILD_PUBLIC_LIB_DIR}
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_PUBLIC_LIB_DIR}
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_PUBLIC_LIB_DIR}
set_target_properties(${CAMITK_CORE_LIB} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CAMITK_BUILD_BIN_DIR}
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_BIN_DIR}
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_BIN_DIR}
)
set_target_properties(${CAMITK_CORE_LIB} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CAMITK_BUILD_PUBLIC_LIB_DIR}
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_PUBLIC_LIB_DIR}
ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_PUBLIC_LIB_DIR}
set_target_properties(${CAMITK_CORE_LIB} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CAMITK_BUILD_BIN_DIR}
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_BIN_DIR}
ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_BIN_DIR}
)
else()
set_target_properties(${CAMITK_CORE_LIB} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CAMITK_BUILD_PUBLIC_LIB_DIR})
......
......@@ -41,6 +41,18 @@ namespace camitk {
// -------------------- autoload --------------------
void ExtensionManager::autoload() {
// add the private lib dir to the current application environment's PATH variable
// This modifies the current PATH variable in order for the OS to find the private
// libraries compiled as shared objects/dll/dylib needed by some extensions
QDir privateLibDir(Core::getGlobalInstallDir());
if (privateLibDir.cd("lib/"+QString(Core::shortVersion))) {
QByteArray privateLibDirPath = privateLibDir.canonicalPath().toUtf8();
QByteArray path = qgetenv("PATH");
path.append(";");
path.append(privateLibDirPath);
qputenv("PATH",path);
}
autoloadComponentExtensions();
autoloadActionExtensions();
}
......@@ -83,21 +95,7 @@ void ExtensionManager::loadComponentExtension(QDir extensionsDir) {
QMessageBox::information(NULL, "ExtensionManager Autoload Error", "Cannot access to component extension directory:<br/><tt>" + extensionsDir.absolutePath() + "</tt><br/>Directory does not exist!");
}
else {
// add component directory to library paths (needed especially for internal dependencies)
Application::instance()->addLibraryPath(Core::getCoreLibDir());
Application::instance()->addLibraryPath(extensionsDir.canonicalPath());
CAMITK_DEBUG("ExtensionManager", "autoloadExtensions",
"corelib=" << Core::getCoreLibDir().toStdString() << endl
<< "components=" << Core::getComponentDir().toStdString() << endl
<< "application library paths=" << Application::instance()->libraryPaths().join(",").toStdString()
);
// loop to load component plugin, taking into account internal dependencies (i.e. dependency between
// one component and another one.
QStringList pluginFileNames = extensionsDir.entryList(getExtensionFilter(), QDir::Files);
if (!Core::isDebugBuild()) {
pluginFileNames.replaceInStrings(QString(Core::debugPostfix),"").removeDuplicates();
}
QStringList pluginFileNames = getPluginFileNames(extensionsDir);
// if there is more than 5 dependency levels, then you have two choices:
// - consider simplifying your component
......@@ -139,8 +137,7 @@ void ExtensionManager::loadComponentExtension(QDir extensionsDir) {
QMessageBox::warning(NULL, "ExtensionManager Opening Error...",
"AutoLoad plugin failed after " + QString::number(tryNr) + " tries for the following component(s):<ul><li>"
+ errorStrings.join("</li><li>")
+ "</li></ul>Component extension directory: <tt>"
+ Core::getComponentDir() + "</tt><br/>"
+ "</li></ul>From directory:<br/><tt>" + extensionsDir.canonicalPath().toUtf8() + "</tt><br/>"
+ "List of library paths:<ul><li>"
+ Application::instance()->libraryPaths().join("</li><li>")
+ "</li></ul>");
......@@ -316,13 +313,7 @@ void ExtensionManager::loadActionExtension(QDir actionsDir) {
QMessageBox::information(NULL, "ExtensionManager Autoload Error", "Cannot access to actions directory:<br/><tt>" + actionsDir.absolutePath() + "</tt><br/>Directory does not exist!");
}
else {
// loop to load action extension, taking into account internal dependencies (i.e. dependency between
// one action and another one.
int i = 0;
QStringList extensionFileNames = actionsDir.entryList(getExtensionFilter(), QDir::Files);
if (!Core::isDebugBuild()) {
extensionFileNames.replaceInStrings(QString(Core::debugPostfix),"").removeDuplicates();
}
QStringList pluginFileNames = getPluginFileNames(actionsDir);
// if there is more than 5 dependency levels, then you have two choices:
// - consider simplifying your component
......@@ -331,22 +322,25 @@ void ExtensionManager::loadActionExtension(QDir actionsDir) {
int tryNr = 0;
do {
i = 0;
int i = 0;
while (i < extensionFileNames.size()) {
if (loadActionExtension(actionsDir.absoluteFilePath(extensionFileNames.at(i))))
while (i < pluginFileNames.size()) {
if (loadActionExtension(actionsDir.absoluteFilePath(pluginFileNames.at(i))))
// this one is loaded, remove it from the list to load
extensionFileNames.removeAt(i);
pluginFileNames.removeAt(i);
else
i++;
}
tryNr++;
}
while (tryNr < maxNumberOfTries && extensionFileNames.size() > 0);
while (tryNr < maxNumberOfTries && pluginFileNames.size() > 0);
if (extensionFileNames.size() > 0) {
QMessageBox::warning(NULL, "ExtensionManager Opening Error...", "AutoLoad Extension failed after " + QString::number(tryNr) + " tries for the following action(s):<ul><li>" + extensionFileNames.join("</li><li>") + "</li></ul>Actions extension directory: <tt>" + Core::getActionDir() + "</tt>");
if (pluginFileNames.size() > 0) {
QMessageBox::warning(NULL, "ExtensionManager Opening Error...", "AutoLoad Extension failed after " + QString::number(tryNr) + " tries for the following action(s):<ul><li>" + pluginFileNames.join("</li><li>") + "</li></ul>" + ">From directory:<br/><tt>" + actionsDir.canonicalPath().toUtf8() + "</tt><br/>"
+ "List of library paths:<ul><li>"
+ Application::instance()->libraryPaths().join("</li><li>")
+ "</li></ul>");
}
}
}
......@@ -462,4 +456,24 @@ QStringList ExtensionManager::getExtensionFilter() {
return pluginFilter;
}
// -------------------- getPluginFileNames --------------------
QStringList ExtensionManager::getPluginFileNames(QDir extensionsDir) {
// loop to load component plugin, taking into account internal dependencies (i.e. dependency between
// one component and another one.
QStringList pluginFileNames = extensionsDir.entryList(getExtensionFilter(), QDir::Files);
// Get the MSVC debug dlls
QStringList pluginFileNamesDebug = pluginFileNames.filter(QRegExp(".*"+QString(Core::debugPostfix)+".dll"));
if (Core::isDebugBuild()) {
return pluginFileNamesDebug;
}
else {
// remove debug dll one by one
foreach(QString debugDLL, pluginFileNamesDebug) {
pluginFileNames.removeAll(debugDLL);
}
return pluginFileNames;
}
}
}
......@@ -169,6 +169,9 @@ private:
/// return the extensions file filter
static QStringList getExtensionFilter();
/// return the list of shared objects in a directory considering debug/release on MSVC
static QStringList getPluginFileNames(QDir);
};
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment