|
|
(25 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
| |
− | #* The new behavior is enabled only when the project has somehow indicated it is supported
| |
− | # '''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
| |