Policies/CMake and Source Compatibility: Difference between revisions

From KDE Community Wiki
(initial version -- pasted from Alex's original draft email)
 
m (12 revisions imported: Move Policies from techbase)
 
(11 intermediate revisions by 4 users not shown)
Line 3: Line 3:
All KDE 4 releases need to keep binary and source compatibility with KDE 4.0.0. This doesn't affect only the C++ code, but also the CMake modules installed with kdelibs (also the cmake modules of the other KDE modules ?).
All KDE 4 releases need to keep binary and source compatibility with KDE 4.0.0. This doesn't affect only the C++ code, but also the CMake modules installed with kdelibs (also the cmake modules of the other KDE modules ?).


== What does that mean? ==
== What does CMake source compatibility mean? ==


A program which was developed against KDE 4.0.0, must also build against let's say KDE 4.5.9. The CMakeLists.txt may look like that (ignoring KDE specific stuff):
A program which was developed against KDE 4.0.0, must also build against let's say KDE 4.5.9. The CMakeLists.txt may look like that (ignoring KDE specific stuff):


<syntaxhighlight lang="text">
find_package(FooBar)
find_package(FooBar)


Line 26: Line 27:


target_link_libraries(kapp ${MyLinkLibs})
target_link_libraries(kapp ${MyLinkLibs})
</syntaxhighlight>




So here we have a CMakeLists.txt which uses the library/package "FooBar", you can exchange FooBar  
So here we have a CMakeLists.txt which uses the library/package "FooBar", you can exchange FooBar  
with ANY CMake module, e.g. KDE4, Qt4, GIF, Freetype, etc.
with ANY CMake module, e.g. KDE4, Qt4, GIF, Freetype, etc.
== Source compatibility rules ==


In order to stay source compatible, the following has to be kept:
In order to stay source compatible, the following has to be kept:


1) The CMake module FindFooBar.cmake must stay available
* '''1. The CMake module FindFooBar.cmake must stay available'''
 
Otherwise CMake will fail with "could not find FindFooBar.cmake".
Otherwise CMake will fail with "could not find FindFooBar.cmake".
This means either it has to stay in the KDE module, or in the case that KDE would require a newer  
This means either it has to stay in the KDE module, or in the case that KDE would require a newer  
Line 40: Line 43:
version of CMake must ship this module (which must be fully compatible).
version of CMake must ship this module (which must be fully compatible).


 
* '''2. The file name of the CMake module must stay exactly the same'''
2) The file name of the CMake module must stay exactly the same.


E.g. in KDE 4.0.0 we have a FindFreetype.cmake installed by kdelibs. This filename must stay  
E.g. in KDE 4.0.0 we have a FindFreetype.cmake installed by kdelibs. This filename must stay  
Line 47: Line 49:
Otherwise the same as in 1) will happen.
Otherwise the same as in 1) will happen.


* '''3. Macros coming with the module must stay compatible'''


3) Macros coming with the module must stay compatible
So if FindFooBar.cmake in kdelibs 4.0.0 has a macro <tt>FOOBAR_DO_STUFF()</tt>, this macro
 
So if FindFooBar.cmake in kdelibs 4.0.0 has a macro FOOBAR_DO_STUFF(), this macro
must be available in all KDE4 versions, with exactly the same name and the arguments  
must be available in all KDE4 versions, with exactly the same name and the arguments  
supported in KDE 4.0.0 must be supported in all KDE4 versions.
supported in KDE 4.0.0 must be supported in all KDE4 versions.
Line 56: Line 57:
must stay supported.
must stay supported.


 
* '''4. Variables coming with the module must stay compatible'''
4) Variables coming with the module must stay compatible


In the example above several variables from FindFooBar.cmake are used:
In the example above several variables from FindFooBar.cmake are used:
FOOBAR_DEFINITIONS, FOOBAR_INCLUDES, FOOBAR_LIBRARIES and FOOBAR_FOUND.  
<tt>FOOBAR_DEFINITIONS, FOOBAR_INCLUDES, FOOBAR_LIBRARIES</tt> and <tt>FOOBAR_FOUND</tt>.  
At least all "public" variables (i.e. those documented in the header of the cmake
At least all "public" variables (i.e. those documented in the header of the cmake
module) must be available from this module in all releases of KDE4.
module) must be available from this module in all releases of KDE4.
This means
This means
-their case must not change
-they must have equivalent values


This means that e.g. FOOBAR_LIBRARIES must always contain all libraries required to link to
* their case must not change
in order to use the package FooBar.  
* they must have equivalent values
 
This means that e.g. <tt>FOOBAR_LIBRARIES</tt> must always contain all libraries required to link to in order to use the package FooBar.  
Maybe this would be in KDE 4.0.0 something like "-lfoobar -lz".
Maybe this would be in KDE 4.0.0 something like "-lfoobar -lz".
This could be changed later on to the recommended format: "/usr/lib/libfoobar.so;/usr/lib/libz.so"
This could be changed later on to the recommended format: "/usr/lib/libfoobar.so;/usr/lib/libz.so"
It must not be changed in a way so that then additional variables would be required for successful linking.
It must not be changed in a way so that then additional variables would be required for successful linking.
E.g. the following change would be wrong:
E.g. the following change would be wrong:
<pre>
FOOBAR_LIBRARIES="/usr/lib/libfoobar.so"
FOOBAR_LIBRARIES="/usr/lib/libfoobar.so"
FOOBAR_EXTRA_LIBRARIES="/usr/lib/libz.so"
FOOBAR_EXTRA_LIBRARIES="/usr/lib/libz.so"
</pre>


== What changes are possible? ==


== What changes are possible? ==
* '''1. New modules can be added'''
1) New modules can be added.


2) New variables can be added to existing modules.
* '''2. New variables can be added to existing modules'''


It has to be made sure that the existing ones stay working, s.a.
It has to be made sure that the existing ones stay working, s.a.


3) New macros can be added.
* '''3. New macros can be added'''


It has to be made sure that the existing ones stay working, s.a.
It has to be made sure that the existing ones stay working, s.a.
If a new and better alternative to an existing macro is added, the old one may be marked as deprecated like this:
If a new and better alternative to an existing macro is added, the old one may be marked as deprecated like this:


<syntaxhighlight lang="text">
macro(OLD_SIMPLE_MACRO args...)
macro(OLD_SIMPLE_MACRO args...)
   message(STATUS "OLD_SIMPLE_MACRO() is deprecated, use NEW_FANCY_MACRO() instead")
   message(STATUS "OLD_SIMPLE_MACRO() is deprecated,  
   ...keep the macro implementation here, so the macro keeps working
                  use NEW_FANCY_MACRO() instead")
   # ...keep the macro implementation here,  
  # so the macro keeps working
endmacro(OLD_SIMPLE_MACRO)
endmacro(OLD_SIMPLE_MACRO)


macro(NEW_FANCY_MACRO args...)
macro(NEW_FANCY_MACRO args...)
   ... new fancy implementation
   # ... new fancy implementation
endmacro(NEW_FANCY_MACRO)
endmacro(NEW_FANCY_MACRO)
</syntaxhighlight>
* '''4. More arguments can be added to existing macros'''
It has to be made sure that the macro stays working as it did before with the old set of arguments.


==If nothing else helps...==


4) More arguments can be added to existing macros.
If you are developing an application with the KDE 4, but don't trust the KDE developer team that they will be able to keep the one CMake module you are
interested in compatible, there is still an option left for you.


It has to be made sure that the macro stays working as it did before with the old set of arguments.
We take the same example as above, i.e. your application uses package
FooBar. If you want to make sure that one specific version of FindFooBar.cmake
is used, just add this module to your application, put it e.g. in myapp/cmake/FindFooBar.cmake. To make CMake look in this directory if it searches the file FindFooBar.cmake, you have to adjust the <tt>CMAKE_MODULE_PATH</tt> CMake variable, so that the top of your top level
CMakeLists.txt will look something like this:
<syntaxhighlight lang="text">
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake
                      ${CMAKE_MODULE_PATH})
 
find_package(KDE4)
 
find_package(FooBar)
 
...
 
</syntaxhighlight>

Latest revision as of 16:12, 8 March 2016

Introduction

All KDE 4 releases need to keep binary and source compatibility with KDE 4.0.0. This doesn't affect only the C++ code, but also the CMake modules installed with kdelibs (also the cmake modules of the other KDE modules ?).

What does CMake source compatibility mean?

A program which was developed against KDE 4.0.0, must also build against let's say KDE 4.5.9. The CMakeLists.txt may look like that (ignoring KDE specific stuff):

find_package(FooBar)

set(MySources main.cpp)
set(MyLinkLibs ...)

if(FOOBAR_FOUND)
   add_definitions(-D_USE_FOOBAR ${FOOBAR_DEFINITIONS} )
   set(MySources ${MySources} foobarwidget.cpp)
   include_directories(${FOOBAR_INCLUDES})
   set(MyLinkLibs ${MyLinkLibs} ${FOOBAR_LIBRARIES})
   
   foobar_do_stuff()
endif(FOOBAR_FOUND)

...
add_executable(kapp ${MySources})
...

target_link_libraries(kapp ${MyLinkLibs})


So here we have a CMakeLists.txt which uses the library/package "FooBar", you can exchange FooBar with ANY CMake module, e.g. KDE4, Qt4, GIF, Freetype, etc.

Source compatibility rules

In order to stay source compatible, the following has to be kept:

  • 1. The CMake module FindFooBar.cmake must stay available

Otherwise CMake will fail with "could not find FindFooBar.cmake". This means either it has to stay in the KDE module, or in the case that KDE would require a newer version of CMake which comes with a (for KDE) usable version of that module, that the minimum required version of CMake must ship this module (which must be fully compatible).

  • 2. The file name of the CMake module must stay exactly the same

E.g. in KDE 4.0.0 we have a FindFreetype.cmake installed by kdelibs. This filename must stay exactly the same, also the case must not change (e.g. FindFreeType.cmake). Otherwise the same as in 1) will happen.

  • 3. Macros coming with the module must stay compatible

So if FindFooBar.cmake in kdelibs 4.0.0 has a macro FOOBAR_DO_STUFF(), this macro must be available in all KDE4 versions, with exactly the same name and the arguments supported in KDE 4.0.0 must be supported in all KDE4 versions. It is possible to add new or alternative arguments to a macro, but the old behaviour must stay supported.

  • 4. Variables coming with the module must stay compatible

In the example above several variables from FindFooBar.cmake are used: FOOBAR_DEFINITIONS, FOOBAR_INCLUDES, FOOBAR_LIBRARIES and FOOBAR_FOUND. At least all "public" variables (i.e. those documented in the header of the cmake module) must be available from this module in all releases of KDE4. This means

  • their case must not change
  • they must have equivalent values

This means that e.g. FOOBAR_LIBRARIES must always contain all libraries required to link to in order to use the package FooBar. Maybe this would be in KDE 4.0.0 something like "-lfoobar -lz". This could be changed later on to the recommended format: "/usr/lib/libfoobar.so;/usr/lib/libz.so" It must not be changed in a way so that then additional variables would be required for successful linking. E.g. the following change would be wrong:

FOOBAR_LIBRARIES="/usr/lib/libfoobar.so"
FOOBAR_EXTRA_LIBRARIES="/usr/lib/libz.so"

What changes are possible?

  • 1. New modules can be added
  • 2. New variables can be added to existing modules

It has to be made sure that the existing ones stay working, s.a.

  • 3. New macros can be added

It has to be made sure that the existing ones stay working, s.a. If a new and better alternative to an existing macro is added, the old one may be marked as deprecated like this:

macro(OLD_SIMPLE_MACRO args...)
   message(STATUS "OLD_SIMPLE_MACRO() is deprecated, 
                   use NEW_FANCY_MACRO() instead")
   # ...keep the macro implementation here, 
   # so the macro keeps working
endmacro(OLD_SIMPLE_MACRO)

macro(NEW_FANCY_MACRO args...)
   # ... new fancy implementation
endmacro(NEW_FANCY_MACRO)
  • 4. More arguments can be added to existing macros

It has to be made sure that the macro stays working as it did before with the old set of arguments.

If nothing else helps...

If you are developing an application with the KDE 4, but don't trust the KDE developer team that they will be able to keep the one CMake module you are interested in compatible, there is still an option left for you.

We take the same example as above, i.e. your application uses package FooBar. If you want to make sure that one specific version of FindFooBar.cmake is used, just add this module to your application, put it e.g. in myapp/cmake/FindFooBar.cmake. To make CMake look in this directory if it searches the file FindFooBar.cmake, you have to adjust the CMAKE_MODULE_PATH CMake variable, so that the top of your top level CMakeLists.txt will look something like this:

set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake 
                      ${CMAKE_MODULE_PATH})

find_package(KDE4)

find_package(FooBar)

...