diff --git a/CMakeLists.txt b/CMakeLists.txt index b4f12825723..ef5bb104cbb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -378,6 +378,16 @@ SET (QGIS_DATA_DIR ${QGIS_DATA_SUBDIR}) SET (QGIS_PLUGIN_DIR ${QGIS_PLUGIN_SUBDIR}) SET (QGIS_INCLUDE_DIR ${QGIS_INCLUDE_SUBDIR}) +# set the default locations where the targets (executables, libraries) will land when compiled +# this is to allow running qgis from the source tree without having to actually do a "make install" +SET (QGIS_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output) +SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/${QGIS_BIN_SUBDIR}) +SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/${QGIS_LIB_SUBDIR}) + +# write a marker with source directory path into the output's bin directory +# if run from the build directory QGIS will detect it and alter the paths +FILE(WRITE ${QGIS_OUTPUT_DIRECTORY}/${QGIS_BIN_SUBDIR}/source_path.txt "${CMAKE_SOURCE_DIR}") + # manual page - makes sense only on unix systems IF (UNIX AND NOT APPLE) SET (DEFAULT_MANUAL_SUBDIR man) diff --git a/i18n/CMakeLists.txt b/i18n/CMakeLists.txt index 472aab76d0e..058492e9d81 100644 --- a/i18n/CMakeLists.txt +++ b/i18n/CMakeLists.txt @@ -6,7 +6,7 @@ MACRO(ADD_TRANSLATION_FILES _sources ) GET_FILENAME_COMPONENT(_in ${_current_FILE} ABSOLUTE) GET_FILENAME_COMPONENT(_basename ${_current_FILE} NAME_WE) - SET(_out ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.qm) + SET(_out ${QGIS_OUTPUT_DIRECTORY}/i18n/${_basename}.qm) ADD_CUSTOM_COMMAND( OUTPUT ${_out} @@ -19,6 +19,8 @@ MACRO(ADD_TRANSLATION_FILES _sources ) ENDFOREACH (_current_FILE) ENDMACRO(ADD_TRANSLATION_FILES) +# make sure the output directory exists +file(MAKE_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/i18n) FILE (GLOB TS_FILES *.ts) diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 25a5c0ffb34..39ee235ebb0 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -1,5 +1,9 @@ ADD_SUBDIRECTORY(plugins) + +SET (PYTHON_OUTPUT_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/python) +SET (QGIS_PYTHON_OUTPUT_DIRECTORY ${PYTHON_OUTPUT_DIRECTORY}/qgis) + IF (WITH_INTERNAL_SPATIALITE) ADD_SUBDIRECTORY(pyspatialite) @@ -9,6 +13,12 @@ IF (WITH_INTERNAL_SPATIALITE) ) ENDIF (WITH_INTERNAL_SPATIALITE) + +SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${QGIS_PYTHON_OUTPUT_DIRECTORY}) +SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${QGIS_PYTHON_OUTPUT_DIRECTORY}) +file(COPY __init__.py utils.py console.py DESTINATION ${QGIS_PYTHON_OUTPUT_DIRECTORY}) + + INCLUDE_DIRECTORIES( ${PYTHON_INCLUDE_PATH} ${SIP_INCLUDE_DIR} @@ -49,6 +59,7 @@ IF(NOT PYQT4_VERSION_NUM LESS 264194) # 0x040802 SET(SIP_DISABLE_FEATURES ${SIP_DISABLE_FEATURES} QSETTYPE_CONVERSION) ENDIF(NOT PYQT4_VERSION_NUM LESS 264194) + # core module FILE(GLOB sip_files_core core/*.sip) SET(SIP_EXTRA_FILES_DEPEND ${sip_files_core}) diff --git a/python/core/qgsapplication.sip b/python/core/qgsapplication.sip index 786af63fad0..4bb950390f6 100644 --- a/python/core/qgsapplication.sip +++ b/python/core/qgsapplication.sip @@ -243,5 +243,22 @@ static void qtgui_UpdatePyArgv(PyObject *argvlist, int argc, char **argv) */ static void registerOgrDrivers(); + /**Converts absolute path to path relative to target + @note: this method was added in version 1.6*/ + static QString absolutePathToRelativePath( QString apath, QString targetPath ); + /**Converts path relative to target to an absolute path + @note: this method was added in version 1.6*/ + static QString relativePathToAbsolutePath( QString rpath, QString targetPath ); + + /** Indicates whether running from build directory (not installed) + @note added in 2.0 */ + static bool isRunningFromBuildDir(); + /** Returns path to the source directory. Valid only when running from build directory + @note added in 2.0 */ + static QString buildSourcePath(); + /** Returns path to the build output directory. Valid only when running from build directory + @note added in 2.0 */ + static QString buildOutputPath(); + }; diff --git a/python/pyspatialite/CMakeLists.txt b/python/pyspatialite/CMakeLists.txt index 6f4e7b180a2..e34a112ee13 100644 --- a/python/pyspatialite/CMakeLists.txt +++ b/python/pyspatialite/CMakeLists.txt @@ -1,3 +1,14 @@ + +SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PYTHON_OUTPUT_DIRECTORY}/pyspatialite) +SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PYTHON_OUTPUT_DIRECTORY}/pyspatialite) +file(COPY + lib/__init__.py + lib/dbapi2.py + lib/dump.py + DESTINATION + ${PYTHON_OUTPUT_DIRECTORY}/pyspatialite) + + INCLUDE_DIRECTORIES( ../../src/core/spatialite/headers ../../src/core/spatialite/headers/spatialite diff --git a/src/core/qgsapplication.cpp b/src/core/qgsapplication.cpp index ad62326c960..4c8115e1c08 100644 --- a/src/core/qgsapplication.cpp +++ b/src/core/qgsapplication.cpp @@ -40,9 +40,14 @@ QStringList QgsApplication::mFileOpenEventList; QString QgsApplication::mPrefixPath; QString QgsApplication::mPluginPath; QString QgsApplication::mPkgDataPath; +QString QgsApplication::mLibraryPath; +QString QgsApplication::mLibexecPath; QString QgsApplication::mThemeName; QStringList QgsApplication::mDefaultSvgPaths; QString QgsApplication::mConfigPath = QDir::homePath() + QString( "/.qgis/" ); +bool QgsApplication::mRunningFromBuildDir = false; +QString QgsApplication::mBuildSourcePath; +QString QgsApplication::mBuildOutputPath; /*! \class QgsApplication @@ -60,14 +65,46 @@ QString QgsApplication::mConfigPath = QDir::homePath() + QString( "/.qgis/" ); QgsApplication::QgsApplication( int & argc, char ** argv, bool GUIenabled, QString customConfigPath ) : QApplication( argc, argv, GUIenabled ) { + // check if QGIS is run from build directory (not the install directory) + QDir appDir( applicationDirPath() ); + if ( appDir.exists( "source_path.txt" ) ) + { + QFile f( applicationDirPath() + "/source_path.txt" ); + if ( f.open( QIODevice::ReadOnly ) ) + { + mRunningFromBuildDir = true; + mBuildSourcePath = f.readAll(); #if defined(Q_WS_MACX) || defined(Q_WS_WIN32) || defined(WIN32) - setPrefixPath( applicationDirPath(), true ); + mBuildOutputPath = applicationDirPath(); #else - QDir myDir( applicationDirPath() ); - myDir.cdUp(); - QString myPrefix = myDir.absolutePath(); - setPrefixPath( myPrefix, true ); + mBuildOutputPath = applicationDirPath() + "/.."; // on linux #endif + qDebug( "Running from build directory!" ); + qDebug( "- source directory: %s", mBuildSourcePath.toAscii().data() ); + qDebug( "- output directory of the build: %s", mBuildOutputPath.toAscii().data() ); + } + } + + if ( mRunningFromBuildDir ) + { + // we run from source directory - not installed to destination (specified prefix) + mPrefixPath = QString(); // set invalid path + setPluginPath( mBuildOutputPath + "/" + QString( QGIS_PLUGIN_SUBDIR ) ); + setPkgDataPath( mBuildSourcePath ); // directly source path - used for: doc, resources, svg + mLibraryPath = mBuildOutputPath + "/" + QGIS_LIB_SUBDIR + "/"; + mLibexecPath = mBuildOutputPath + "/" + QGIS_LIBEXEC_SUBDIR + "/"; + } + else + { +#if defined(Q_WS_MACX) || defined(Q_WS_WIN32) || defined(WIN32) + setPrefixPath( applicationDirPath(), true ); +#else + QDir myDir( applicationDirPath() ); + myDir.cdUp(); + QString myPrefix = myDir.absolutePath(); + setPrefixPath( myPrefix, true ); +#endif + } if ( !customConfigPath.isEmpty() ) { @@ -170,6 +207,8 @@ void QgsApplication::setPrefixPath( const QString thePrefixPath, bool useDefault setPluginPath( mPrefixPath + "/" + QString( QGIS_PLUGIN_SUBDIR ) ); setPkgDataPath( mPrefixPath + "/" + QString( QGIS_DATA_SUBDIR ) ); } + mLibraryPath = mPrefixPath + "/" + QGIS_LIB_SUBDIR + "/"; + mLibexecPath = mPrefixPath + "/" + QGIS_LIBEXEC_SUBDIR + "/"; } void QgsApplication::setPluginPath( const QString thePluginPath ) @@ -180,10 +219,10 @@ void QgsApplication::setPluginPath( const QString thePluginPath ) void QgsApplication::setPkgDataPath( const QString thePkgDataPath ) { mPkgDataPath = thePkgDataPath; - QString svgPath = mPkgDataPath + QString( "/svg/" ); + QString mySvgPath = svgPath(); // avoid duplicate entries - if ( !mDefaultSvgPaths.contains( svgPath ) ) - mDefaultSvgPaths << svgPath; + if ( !mDefaultSvgPaths.contains( mySvgPath ) ) + mDefaultSvgPaths << mySvgPath; } void QgsApplication::setDefaultSvgPaths( const QStringList& pathList ) @@ -193,6 +232,11 @@ void QgsApplication::setDefaultSvgPaths( const QStringList& pathList ) const QString QgsApplication::prefixPath() { + if ( mRunningFromBuildDir ) + { + qWarning( "!!! prefix path was requested, but it is not valid - we do not run from installed path !!!" ); + } + return mPrefixPath; } const QString QgsApplication::pluginPath() @@ -285,12 +329,10 @@ const QString QgsApplication::translatorsFilePath() { return mPkgDataPath + QString( "/doc/TRANSLATORS" ); } -/*! - Returns the path to the developer image directory. -*/ + const QString QgsApplication::developerPath() { - return mPkgDataPath + QString( "/images/developers/" ); + return QString(); // developer images are no longer shipped! } /*! @@ -302,7 +344,7 @@ const QString QgsApplication::helpAppPath() #ifdef Q_OS_MACX helpAppPath = applicationDirPath() + "/bin/qgis_help.app/Contents/MacOS"; #else - helpAppPath = prefixPath() + "/" QGIS_LIBEXEC_SUBDIR; + helpAppPath = libexecPath(); #endif helpAppPath += "/qgis_help"; return helpAppPath; @@ -312,7 +354,10 @@ const QString QgsApplication::helpAppPath() */ const QString QgsApplication::i18nPath() { - return mPkgDataPath + QString( "/i18n/" ); + if ( mRunningFromBuildDir ) + return mBuildOutputPath + QString( "/i18n" ); + else + return mPkgDataPath + QString( "/i18n/" ); } /*! @@ -386,7 +431,8 @@ const QStringList QgsApplication::svgPaths() */ const QString QgsApplication::svgPath() { - return mPkgDataPath + QString( "/svg/" ); + QString svgSubDir( mRunningFromBuildDir ? "/images/svg/" : "/svg/" ); + return mPkgDataPath + svgSubDir; } const QString QgsApplication::userStyleV2Path() @@ -401,12 +447,12 @@ const QString QgsApplication::defaultStyleV2Path() const QString QgsApplication::libraryPath() { - return QgsApplication::prefixPath() + "/" + QGIS_LIB_SUBDIR + "/"; + return mLibraryPath; } const QString QgsApplication::libexecPath() { - return QgsApplication::prefixPath() + "/" QGIS_LIBEXEC_SUBDIR + "/"; + return mLibexecPath; } QgsApplication::endian_t QgsApplication::endian() diff --git a/src/core/qgsapplication.h b/src/core/qgsapplication.h index 7bdb30f931a..9279294aeaf 100644 --- a/src/core/qgsapplication.h +++ b/src/core/qgsapplication.h @@ -84,6 +84,7 @@ class CORE_EXPORT QgsApplication: public QApplication static const QString translatorsFilePath(); //! Returns the path to the developer image directory. + //! @deprecated images are not provided anymore :-P static const QString developerPath(); //! Returns the path to the help application. @@ -208,6 +209,16 @@ class CORE_EXPORT QgsApplication: public QApplication @note: this method was added in version 1.6*/ static QString relativePathToAbsolutePath( QString rpath, QString targetPath ); + /** Indicates whether running from build directory (not installed) + @note added in 2.0 */ + static bool isRunningFromBuildDir() { return mRunningFromBuildDir; } + /** Returns path to the source directory. Valid only when running from build directory + @note added in 2.0 */ + static QString buildSourcePath() { return mBuildSourcePath; } + /** Returns path to the build output directory. Valid only when running from build directory + @note added in 2.0 */ + static QString buildOutputPath() { return mBuildOutputPath; } + signals: void preNotify( QObject * receiver, QEvent * event, bool * done ); @@ -218,10 +229,19 @@ class CORE_EXPORT QgsApplication: public QApplication static QString mPrefixPath; static QString mPluginPath; static QString mPkgDataPath; + static QString mLibraryPath; + static QString mLibexecPath; static QString mThemeName; static QStringList mDefaultSvgPaths; static QString mConfigPath; + + /** true when running from build directory, i.e. without 'make install' */ + static bool mRunningFromBuildDir; + /** path to the source directory. valid only when running from build directory. */ + static QString mBuildSourcePath; + /** path to the output directory of the build. valid only when running from build directory */ + static QString mBuildOutputPath; }; #endif diff --git a/src/crssync/CMakeLists.txt b/src/crssync/CMakeLists.txt index 168be7af814..f40ad2320d4 100644 --- a/src/crssync/CMakeLists.txt +++ b/src/crssync/CMakeLists.txt @@ -1,3 +1,6 @@ +# override default path where built files are put to allow running qgis without installing +SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/${QGIS_LIBEXEC_SUBDIR}) + ADD_EXECUTABLE(crssync main.cpp) INCLUDE_DIRECTORIES( ../core diff --git a/src/helpviewer/CMakeLists.txt b/src/helpviewer/CMakeLists.txt index 8f7179fcbdb..8937f9fe2e0 100644 --- a/src/helpviewer/CMakeLists.txt +++ b/src/helpviewer/CMakeLists.txt @@ -1,3 +1,5 @@ +# override default path where built files are put to allow running qgis without installing +SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/${QGIS_LIBEXEC_SUBDIR}) ######################################################## # Files diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index ed96352143a..4d031a16400 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -1,3 +1,7 @@ +# override default path where built files are put to allow running qgis without installing +SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/${QGIS_PLUGIN_SUBDIR}) +SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/${QGIS_PLUGIN_SUBDIR}) + ADD_SUBDIRECTORY(copyright_label) ADD_SUBDIRECTORY(delimited_text) ADD_SUBDIRECTORY(diagram_overlay) diff --git a/src/plugins/grass/CMakeLists.txt b/src/plugins/grass/CMakeLists.txt index bafa26e6ff1..a02f0ffe71a 100644 --- a/src/plugins/grass/CMakeLists.txt +++ b/src/plugins/grass/CMakeLists.txt @@ -158,6 +158,10 @@ TARGET_LINK_LIBRARIES(grassplugin ${OPENPTY_LIBRARY} ) +# override default path where built files are put to allow running qgis without installing +# the binary goes under libexec subdir +SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/${QGIS_LIBEXEC_SUBDIR}/grass/bin) + ADD_EXECUTABLE(qgis.g.browser ${GRASS_BROWSER_SRCS}) TARGET_LINK_LIBRARIES (qgis.g.browser diff --git a/src/providers/CMakeLists.txt b/src/providers/CMakeLists.txt index eae6ee1a574..e373d075bc0 100644 --- a/src/providers/CMakeLists.txt +++ b/src/providers/CMakeLists.txt @@ -1,3 +1,7 @@ +# override default path where built files are put to allow running qgis without installing +SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/${QGIS_PLUGIN_SUBDIR}) +SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/${QGIS_PLUGIN_SUBDIR}) + ADD_SUBDIRECTORY(memory) ADD_SUBDIRECTORY(ogr) ADD_SUBDIRECTORY(wms) diff --git a/src/providers/grass/CMakeLists.txt b/src/providers/grass/CMakeLists.txt index 3cfc58ed72e..5058e501394 100644 --- a/src/providers/grass/CMakeLists.txt +++ b/src/providers/grass/CMakeLists.txt @@ -60,6 +60,10 @@ ADD_LIBRARY(grassrasterprovider MODULE qgsgrassrasterprovider.cpp ${GRASS_RASTER SET_TARGET_PROPERTIES(grassrasterprovider PROPERTIES COMPILE_FLAGS "\"-DGRASS_EXPORT=${DLLEXPORT}\" \"-DGRASS_LIB_EXPORT=${DLLIMPORT}\"" ) TARGET_LINK_LIBRARIES(grassrasterprovider qgisgrass qgis_core) +# override default path where built files are put to allow running qgis without installing +# the modules go under libexec subdir +SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/${QGIS_LIBEXEC_SUBDIR}/grass/modules) + # # grass raster display module # diff --git a/src/python/qgspythonutilsimpl.cpp b/src/python/qgspythonutilsimpl.cpp index 646e6753356..0c69ea6b4e5 100644 --- a/src/python/qgspythonutilsimpl.cpp +++ b/src/python/qgspythonutilsimpl.cpp @@ -412,15 +412,20 @@ bool QgsPythonUtilsImpl::evalString( const QString& command, QString& result ) return success; } - QString QgsPythonUtilsImpl::pythonPath() { - return QgsApplication::pkgDataPath() + "/python"; + if ( QgsApplication::isRunningFromBuildDir() ) + return QgsApplication::buildOutputPath() + "/python"; + else + return QgsApplication::pkgDataPath() + "/python"; } QString QgsPythonUtilsImpl::pluginsPath() { - return pythonPath() + "/plugins"; + if ( QgsApplication::isRunningFromBuildDir() ) + return QString(); // plugins not used + else + return pythonPath() + "/plugins"; } QString QgsPythonUtilsImpl::homePythonPath()