Navigation Menu

Skip to content

Commit

Permalink
[FEATURE] Allow running QGIS from build directory without installing
Browse files Browse the repository at this point in the history
  • Loading branch information
wonder-sk committed Jul 25, 2011
1 parent 257ae38 commit 90eaa87
Show file tree
Hide file tree
Showing 14 changed files with 164 additions and 21 deletions.
10 changes: 10 additions & 0 deletions CMakeLists.txt
Expand Up @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion i18n/CMakeLists.txt
Expand Up @@ -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}
Expand All @@ -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)

Expand Down
11 changes: 11 additions & 0 deletions 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)

Expand All @@ -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}
Expand Down Expand Up @@ -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})
Expand Down
17 changes: 17 additions & 0 deletions python/core/qgsapplication.sip
Expand Up @@ -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();

};

11 changes: 11 additions & 0 deletions 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
Expand Down
80 changes: 63 additions & 17 deletions src/core/qgsapplication.cpp
Expand Up @@ -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
Expand All @@ -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)
mBuildOutputPath = applicationDirPath();
#else
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 );
setPrefixPath( applicationDirPath(), true );
#else
QDir myDir( applicationDirPath() );
myDir.cdUp();
QString myPrefix = myDir.absolutePath();
setPrefixPath( myPrefix, true );
QDir myDir( applicationDirPath() );
myDir.cdUp();
QString myPrefix = myDir.absolutePath();
setPrefixPath( myPrefix, true );
#endif
}

if ( !customConfigPath.isEmpty() )
{
Expand Down Expand Up @@ -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 )
Expand All @@ -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 )
Expand All @@ -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()
Expand Down Expand Up @@ -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!
}

/*!
Expand All @@ -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;
Expand All @@ -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/" );
}

/*!
Expand Down Expand Up @@ -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()
Expand All @@ -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()
Expand Down
20 changes: 20 additions & 0 deletions src/core/qgsapplication.h
Expand Up @@ -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.
Expand Down Expand Up @@ -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 );

Expand All @@ -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
3 changes: 3 additions & 0 deletions 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
Expand Down
2 changes: 2 additions & 0 deletions 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
Expand Down
4 changes: 4 additions & 0 deletions 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)
Expand Down
4 changes: 4 additions & 0 deletions src/plugins/grass/CMakeLists.txt
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions 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)
Expand Down
4 changes: 4 additions & 0 deletions src/providers/grass/CMakeLists.txt
Expand Up @@ -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
#
Expand Down
11 changes: 8 additions & 3 deletions src/python/qgspythonutilsimpl.cpp
Expand Up @@ -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()
Expand Down

0 comments on commit 90eaa87

Please sign in to comment.