Wiki

Clone wiki

SCons / FromQmakeToScons

SCons, from QMake's Point of View

  • root/variables.pri and root/root.pro is now root/SConstruct
  • root/sub1/sub1.pro is now root/sub1/SConscript (Note: NOT SConstruct)
  • You do not need to run any program to generate any Makefiles anymore. So there is no equivalent to 'qmake'.
  • make is now scons. Only run it like this from the root/ dir.
  • make in a subfolder is now scons -u, or scons -U, or scons -D
  • make clean is now scons -c

Tips for New SCons Users

  • Header file dependencies are gathered from the CPPPATH list, so if you have include files that you expect to change often, then add them to CPPPATH, like so: env.Append(CPPPATH=['/usr/local/include','/home/user/somelibrary'])

Note there's not much point adding your QT includes in there, as you will probably want to make-clean and recompile the whole project anyway. Use this technique for that little binary-search library that you occasionally fix bugs for, or update via CVS. Similarly, libraries are found using the same algorithm as the linker uses, using LIBPATH and LIBS. So make sure your libs are findable that way and scons will pick up the dependencies automatically.

Making your .uic files depend on your custom plugin

Please note that this should be in a different page but I had problems editing the new page after linking to it.

(NOTE: This inforomation only applies for qt3. Qt4 .ui files do not need to load the plugin to generate the correct .h file.)

If you are using a custom plugin while building your projects and you use the plugin when generating the form code with uic, you need to explicitly configure the dependiences so the plugin is built before the uics are processed. Since the plugin is implicitly used by uic (uic loads the plugin as a shared library), scons cannot know that the rest of the project depends on the plugin being up to date. (The plugin should always be depended on so you can make sure the autogenerated ui code is correct and will compile.)

Say your current GUIProject SConscript looks like this:

TARGET = 'GUIProject'
SOURCES = ['GUI.cpp']
UICS = ['GUIUI.ui']

# Build the library
ret = env.Program(target = TARGET, source = SOURCES+UICS)
# Return the result of the compilation so another SConscript can use it. Useful when building a library
Return('ret')

and you want to make an explicit dependency of the GUIProject on plugin, so you'll need to tell scons about the dependency:

#!python 
TARGET = 'GUIProject'
SOURCES = ['GUI.cpp']
UICS = ['GUIUI.ui']

# Build the plugin
plugin = env.SConscript('../plugin/SConscript', exports = 'env')

# Generate code and header files from ui files
# and make the uic_XX.cpp files depend on the plugin
uic_sources = []
for ui in UICS:
        (header, uicCode, mocCode) = env.Uic(ui)
        # NOTE: inorder to be safe, all of the generated files depend on the plugin for the plugin to be generated before uic generation occurs. Maybe only the header needs to depend on the plugin... Anyone??
        env.Depends(header, plugin)
        env.Depends(uicCode, plugin)            
        env.Depends(mocCode, plugin)
        uic_sources.append(mocCode)
        uic_sources.append(uicCode)

# Build the library
ret = env.Program(target = TARGET, source = SOURCES+uic_sources)
# Return the result of the compilation so another SConscript can use it. Useful when building a library
Return('ret')

Now the only problem is that uic needs to know the plugin's path so it can load it. This is solved by using an undocumented commandline option in uic '-L'. So the final SConscript looks like:

#!python 
TARGET = 'GUIProject'
SOURCES = ['GUI.cpp']
UICS = ['GUIUI.ui']

# Build the plugin
plugin = env.SConscript('../plugin/SConscript', exports = 'env')
path = str(plugin[0])
# Get the path to the plugin
path = path.split('/')
path = "/".join(path[0:-1])
# print "path = " + path
# Extend the uic command so it uses the directory of the plugin as a search path
libEnv.Append(QT_UIC = " -L " + path)

# Generate code and header files from ui files
# and make the uic_XX.cpp files depend on the plugin
uic_sources = []
for ui in UICS:
        (header, uicCode, mocCode) = env.Uic(ui)
        # NOTE: inorder to be safe, all of the generated files depend on the plugin for the plugin to be generated before uic generation occurs. Maybe only the header needs to depend on the plugin... Anyone??
        env.Depends(header, plugin)
        env.Depends(uicCode, plugin)            
        env.Depends(mocCode, plugin)
        uic_sources.append(mocCode)
        uic_sources.append(uicCode)

# Build the library
ret = env.Program(target = TARGET, source = SOURCES+uic_sources)
# Return the result of the compilation so another SConscript can use it. Useful when building a library
Return('ret')

Hopefully, someone can wrap this up into a builder eventually because it's pretty straight forward code.

Updated