Difference between revisions of "CMake Policies Design Discussion"

From KitwarePublic
Jump to navigationJump to search
(Replace content with link to new CMake community wiki)
 
(30 intermediate revisions by 2 users not shown)
Line 1: Line 1:
This page describes a proposal for a formal backwards/forwards compatibility feature.
{{CMake/Template/Moved}}


=Motivating Examples=
This page has moved [https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/dev/Policies-Design-Discussion here].
 
==The ADD_DEFINITIONS Command==
 
Consider code such as
 
  add_definitions("-DFOO=\\\"hello\\ world\\\"")
 
which tries to add the option
 
  -DFOO=\"hello\ world\"
 
to the compile command line.  The code works in CMake 2.4's <code>Unix Makefiles</code> generator and produces a definition as if
 
  #define FOO "hello world"
 
appeared in the source code.  It works only because of the way the makefile generator happens to place the definition string in the command line.  It may not work with the VS IDE generators.
In CMake HEAD we provide the <code>COMPILE_DEFINITIONS</code> directory property so that one may write
 
  set_property(DIRECTORY PROPERTY COMPILE_DEFINITIONS "FOO=\"hello world\"")
 
to get the correct behavior on all generators.  Since CMake HEAD contains the appropriate escaping support it is desirable to allow the user to write
 
  add_definitions("-DFOO=\"hello world\"")
 
and get the expected behavior.  Unfortunately if we were to start escaping the definitions given to <code>add_definitions</code> we would break compatibility with projects that are already adding their own escapes.  In hindsight we should have either supported escapes from the beginning or make the command give an error that the definition value is not supported, but it is too late now.
A similar problem appears in the <code>add_custom_command</code> command where support for properly escaping all arguments was added late.  The solution currently used by that command is to require the user to add a <code>VERBATIM</code> argument to the command to get proper escaping.  Using that solution for <code>add_definitions</code> would make the user write
 
  add_definitions(VERBATIM "-DFOO=\"hello world\"")
 
just to get CMake to do the right thing.  For compatibility CMake would have to implement the wrong behavior by default forever.
 
==Missing Link Directories==
 
Projects used to be able to write this (wrong) code and it would work 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. It used to work by accident because the
<code>-L/path/to</code> would get added as part of the implementation of linking to
A. 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)
 
Currently we provide the <code>CMAKE_OLD_LINK_PATHS</code> variable to allow projects or users to quickly work around the problem.  Full compatibility would require us to support thie behavior by default forever.  That would allow new projects to be written with the same bug.
 
An alternative is to require all libraries to be linked via full path (where target names are expanded automatically).  Whenever a non-full-path is given we could produce a warning that tells the user to start using <code>find_library</code> or something like that but then implement the old linker search path computation for compatibility.  It is desirable to let projects that have been updated for newer CMake versions tell CMake that they know what they are doing and to not warn or use the compatibility behavior.
 
=Proposed Solution=
 
We propose the following solution to this problem.
 
Each change that introduces a compatibility issue is assigned a new identification number (like CM00001 or something).  Then we try to detect cases in user code where it '''might''' be an issue.
 
Brainstorming:
 
  cmake_feature(PUSH)
  cmake_feature(SET CM00001 FIXED)
  cmake_feature(VERSION 2.6)
  cmake_feature(POP)
 
  REQUIRED - Project must declare fixed
  FIXED - New behavior
  QUIET - Old behavior
  WARN - Old behavior, emit warning
  ERROR - No behavior, emit error

Latest revision as of 15:41, 30 April 2018


The CMake community Wiki has moved to the Kitware GitLab Instance.

This page has moved here.