|
|
(27 intermediate revisions by 3 users not shown) |
Line 1: |
Line 1: |
| The CMake Policy mechanism provides backwards compatibility as a
| | {{CMake/Template/Moved}} |
| first-class feature.
| |
|
| |
|
| =Motivation=
| | This page has moved [https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/Policies here]. |
| | |
| CMake is an evolving project. The developers strive to support
| |
| existing projects as much as possible as changes are made.
| |
| Unfortunately there are some cases where it is not possible to fix
| |
| bugs and preserve backwards compatibility at the same time. We give
| |
| some examples here.
| |
| | |
| ==Interface of ADD_DEFINITIONS==
| |
| | |
| Consider the <code>add_definitions</code> command:
| |
| | |
| add_definitions(-DFOO)
| |
| | |
| When originally introduced the command was intended only to add simple
| |
| definitions. Its implementation was simply to pass its arguments on
| |
| to the compiler's command line. Since CMake supports configured
| |
| header files using the <code>configure_file</code> command it is not
| |
| necessary to pass complicated definitions on compile command lines.
| |
| However, some project authors tried to do so anyway with code like
| |
| | |
| add_definitions("-DFOO=\"some string\"")
| |
| | |
| but found that it did not work. The string
| |
| | |
| -DFOO="some string"
| |
| | |
| would appear on the command line and the compiler would receive a
| |
| definition equivalent to
| |
| | |
| #define FOO some string
| |
| | |
| Some authors proceeded to work around the problem by adding escape
| |
| sequences manually:
| |
| | |
| add_definitions("-DFOO=\"\\\"some string\\\"\"")
| |
| | |
| The escape sequences work for some native build tools (such as Unix
| |
| Makefiles) but not others. The proper way to deal with this issue was
| |
| to fix the implementation in CMake to actually produce the correct
| |
| escape sequences for each native build tool automatically.
| |
| | |
| Unfortunately introducing the fix would break existing projects that
| |
| add their own escape sequences because the escapes themselves would be
| |
| escaped. In order to support such projects no fix was introduced for
| |
| years. This allowed many more projects to continue to suffer from the
| |
| problem and add their own work-arounds which must now also be
| |
| supported.
| |
| | |
| This problem with <code>add_definitions</code> is an example of a
| |
| class of problems: how are we to fix an interface without breaking
| |
| work-arounds for the very problem being fixed? The policy mechanism
| |
| is a solution to this problem.
| |
| | |
| ==Magic Link Directories==
| |
| | |
| When using CMake 2.4 or below projects may write this (wrong) code and it works by accident:
| |
| | |
| add_executable(myexe myexe.c)
| |
| target_link_libraries(myexe /path/to/libA.so B)
| |
| | |
| where "<code>B</code>" is meant to link "<code>/path/to/libB.so</code>". This code is incorrect because it asks CMake to link to <code>B</code> but does not provide the proper linker search path for it. The correct code would be
| |
| | |
| link_directories(/path/to)
| |
| add_executable(myexe myexe.c)
| |
| target_link_libraries(myexe /path/to/libA.so B)
| |
| | |
| or even better
| |
| | |
| add_executable(myexe myexe.c)
| |
| target_link_libraries(myexe /path/to/libA.so /path/to/libB.so)
| |
| | |
| CMake 2.4 implemented the link to library A partly by adding
| |
| <code>-L/path/to</code> to the linker command line. This allowed
| |
| library B to be found even though no linker search path was provided
| |
| for it. CMake 2.6 implements linking to library A by passing
| |
| <code>/path/to/libA.so</code> directly to the linker as a path. This
| |
| leaves out the <code>-L/path/to</code> which may prevent library B
| |
| from being found.
| |
| | |
| While the code above leading to this problem is technically wrong it
| |
| worked with a previous CMake release and needs to be supported.
| |
| Therefore CMake 2.6 has support for passing the directories containing
| |
| libraries whose full paths are known as linker search paths even
| |
| though they are not needed for correct user code. Full compatibility
| |
| would require us to support this behavior by default forever. That
| |
| would allow new projects to be written with the same bug.
| |
| | |
| This problem is an example of a class of problems: how are we to fix
| |
| an implementation without breaking projects depending on undocumented
| |
| details of the original implementation? The policy mechanism is a
| |
| solution to this problem.
| |
| | |
| =Design Goals=
| |
| | |
| The design goals for the CMake Policy mechanism were as follows:
| |
| | |
| # Existing projects should build with versions of CMake newer than that used by the project authors
| |
| #* Users should not need to edit code to get the projects to build
| |
| #* Warnings may be issued but the projects should build
| |
| # Correctness of new interfaces or bugs fixed in old ones should not be inhibited by compatibility requirements
| |
| #* Any reduction in correctness of the latest interface is not fair to new projects
| |
| # Every change to CMake that may require changes to project code should be documented
| |
| #* Each change should also have a unique identifier that can be referenced by warning and error messages
| |
| # We must be able to eventually remove code implementing compatibility with ancient CMake versions
| |
| #* Such removal is necessary to keep the code clean and allow internal refactoring
| |
| #* After such removal attempts to build projects written for ancient versions must fail with an informative message
| |