Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Nils Gladitz
CMake
Commits
d67cc488
Commit
d67cc488
authored
Apr 15, 2021
by
Marc Chevrier
🌴
Committed by
Brad King
Apr 15, 2021
Browse files
Xcode: Add support of DEPFILE for add_custom_command
Issue: #20286
parent
498b916c
Changes
9
Hide whitespace changes
Inline
Side-by-side
Help/command/add_custom_command.rst
View file @
d67cc488
...
...
@@ -271,32 +271,42 @@ The options are:
``DEPFILE``
.. versionadded:: 3.7
Specify a ``.d`` depfile for the :generator:`Ninja` generator and
:ref:`Makefile Generators`. The depfile may use "generator expressions" with
the syntax ``$<...>``. See the :manual:`generator-expressions(7)
<cmake-generator-expressions(7)>` manual for available expressions.
A ``.d`` file holds dependencies usually emitted by the custom
command itself.
Using ``DEPFILE`` with other generators than :generator:`Ninja` or
:ref:`Makefile Generators` is an error.
Specify a ``.d`` depfile for the :generator:`Ninja`, :generator:`Xcode` and
:ref:`Makefile <Makefile Generators>` generators. The depfile may use
"generator expressions" with the syntax ``$<...>``. See the
:manual:`generator-expressions(7) <cmake-generator-expressions(7)>` manual
for available expressions. A ``.d`` file holds dependencies usually emitted
by the custom command itself.
Using ``DEPFILE`` with other generators than :generator:`Ninja`,
:generator:`Xcode` or :ref:`Makefile <Makefile Generators>` is an error.
.. versionadded:: 3.20
Added the support of :ref:`Makefile Generators`.
.. versionadded:: 3.21
Added the support of :manual:`generator expressions <cmake-generator-expressions(7)>`.
Added the support of :generator:`Xcode` generator and
:manual:`generator expressions <cmake-generator-expressions(7)>`.
If the ``DEPFILE`` argument is relative, it should be relative to
:variable:`CMAKE_CURRENT_BINARY_DIR`, and any relative paths inside the
``DEPFILE`` should also be relative to :variable:`CMAKE_CURRENT_BINARY_DIR`
(see policy :policy:`CMP0116`. This policy is always ``NEW`` for
:ref:`Makefile
Generators`
).
:ref:`Makefile
<Makefile Generators>` and :generator:`Xcode` generators
).
.. note::
For :ref:`Makefile Generators`, this option cannot be specified at the
same time as ``IMPLICIT_DEPENDS`` option.
.. note::
For the :generator:`Xcode` generator, this option requires that the
:ref:`Xcode Build System Selection` uses the ``buildsystem=12`` variant
or higher. This is the default when using Xcode 12 or above.
The :variable:`CMAKE_XCODE_BUILD_SYSTEM` variable indicates which variant
of the Xcode build system is used.
Examples: Generating Files
^^^^^^^^^^^^^^^^^^^^^^^^^^
...
...
Help/release/dev/Xcode-add_custom_command-DEPFILE.rst
0 → 100644
View file @
d67cc488
Xcode-add_custom_command-DEPFILE
--------------------------------
* The :command:`add_custom_command` command gained ``DEPFILE`` support on
:generator:`Xcode` generator.
Source/cmCustomCommandGenerator.cxx
View file @
d67cc488
...
...
@@ -151,7 +151,9 @@ std::string EvaluateDepfile(std::string const& path,
cmCustomCommandGenerator
::
cmCustomCommandGenerator
(
cmCustomCommand
const
&
cc
,
std
::
string
config
,
cmLocalGenerator
*
lg
,
bool
transformDepfile
,
cm
::
optional
<
std
::
string
>
crossConfig
)
bool
transformDepfile
,
cm
::
optional
<
std
::
string
>
crossConfig
,
std
::
function
<
std
::
string
(
const
std
::
string
&
,
const
std
::
string
&
)
>
computeInternalDepfile
)
:
CC
(
&
cc
)
,
OutputConfig
(
crossConfig
?
*
crossConfig
:
config
)
,
CommandConfig
(
std
::
move
(
config
))
...
...
@@ -159,7 +161,15 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(
,
OldStyle
(
cc
.
GetEscapeOldStyle
())
,
MakeVars
(
cc
.
GetEscapeAllowMakeVars
())
,
EmulatorsWithArguments
(
cc
.
GetCommandLines
().
size
())
,
ComputeInternalDepfile
(
std
::
move
(
computeInternalDepfile
))
{
if
(
!
this
->
ComputeInternalDepfile
)
{
this
->
ComputeInternalDepfile
=
[
this
](
const
std
::
string
&
cfg
,
const
std
::
string
&
file
)
->
std
::
string
{
return
this
->
GetInternalDepfileName
(
cfg
,
file
);
};
}
cmGeneratorExpression
ge
(
cc
.
GetBacktrace
());
const
cmCustomCommandLines
&
cmdlines
=
this
->
CC
->
GetCommandLines
();
...
...
@@ -413,13 +423,9 @@ std::string cmCustomCommandGenerator::GetFullDepfile() const
return
cmSystemTools
::
CollapseFullPath
(
depfile
);
}
std
::
string
cmCustomCommandGenerator
::
GetInternalDepfile
()
const
std
::
string
cmCustomCommandGenerator
::
GetInternalDepfileName
(
const
std
::
string
&
/*config*/
,
const
std
::
string
&
depfile
)
{
std
::
string
depfile
=
this
->
GetFullDepfile
();
if
(
depfile
.
empty
())
{
return
""
;
}
cmCryptoHash
hash
(
cmCryptoHash
::
AlgoSHA256
);
std
::
string
extension
;
switch
(
*
this
->
LG
->
GetGlobalGenerator
()
->
DepfileFormat
())
{
...
...
@@ -434,6 +440,16 @@ std::string cmCustomCommandGenerator::GetInternalDepfile() const
hash
.
HashString
(
depfile
),
extension
);
}
std
::
string
cmCustomCommandGenerator
::
GetInternalDepfile
()
const
{
std
::
string
depfile
=
this
->
GetFullDepfile
();
if
(
depfile
.
empty
())
{
return
""
;
}
return
this
->
ComputeInternalDepfile
(
this
->
OutputConfig
,
depfile
);
}
const
char
*
cmCustomCommandGenerator
::
GetComment
()
const
{
return
this
->
CC
->
GetComment
();
...
...
Source/cmCustomCommandGenerator.h
View file @
d67cc488
...
...
@@ -4,6 +4,7 @@
#include
"cmConfigure.h"
// IWYU pragma: keep
#include
<functional>
#include
<set>
#include
<string>
#include
<utility>
...
...
@@ -19,6 +20,8 @@ class cmLocalGenerator;
class
cmCustomCommandGenerator
{
std
::
string
GetInternalDepfileName
(
const
std
::
string
&
,
const
std
::
string
&
);
cmCustomCommand
const
*
CC
;
std
::
string
OutputConfig
;
std
::
string
CommandConfig
;
...
...
@@ -32,15 +35,19 @@ class cmCustomCommandGenerator
std
::
vector
<
std
::
string
>
Depends
;
std
::
string
WorkingDirectory
;
std
::
set
<
BT
<
std
::
pair
<
std
::
string
,
bool
>>>
Utilities
;
std
::
function
<
std
::
string
(
const
std
::
string
&
,
const
std
::
string
&
)
>
ComputeInternalDepfile
;
void
FillEmulatorsWithArguments
();
std
::
vector
<
std
::
string
>
GetCrossCompilingEmulator
(
unsigned
int
c
)
const
;
const
char
*
GetArgv0Location
(
unsigned
int
c
)
const
;
public:
cmCustomCommandGenerator
(
cmCustomCommand
const
&
cc
,
std
::
string
config
,
cmLocalGenerator
*
lg
,
bool
transformDepfile
=
true
,
cm
::
optional
<
std
::
string
>
crossConfig
=
{});
cmCustomCommandGenerator
(
cmCustomCommand
const
&
cc
,
std
::
string
config
,
cmLocalGenerator
*
lg
,
bool
transformDepfile
=
true
,
cm
::
optional
<
std
::
string
>
crossConfig
=
{},
std
::
function
<
std
::
string
(
const
std
::
string
&
,
const
std
::
string
&
)
>
computeInternalDepfile
=
{});
cmCustomCommandGenerator
(
const
cmCustomCommandGenerator
&
)
=
delete
;
cmCustomCommandGenerator
(
cmCustomCommandGenerator
&&
)
=
default
;
cmCustomCommandGenerator
&
operator
=
(
const
cmCustomCommandGenerator
&
)
=
...
...
Source/cmGlobalXCodeGenerator.cxx
View file @
d67cc488
...
...
@@ -17,6 +17,7 @@
#include
"cmsys/RegularExpression.hxx"
#include
"cmCMakePath.h"
#include
"cmComputeLinkInformation.h"
#include
"cmCryptoHash.h"
#include
"cmCustomCommand.h"
...
...
@@ -1864,9 +1865,20 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateRunScriptBuildPhase(
std
::
set
<
std
::
string
>
allConfigInputs
;
std
::
set
<
std
::
string
>
allConfigOutputs
;
cmXCodeObject
*
buildPhase
=
this
->
CreateObject
(
cmXCodeObject
::
PBXShellScriptBuildPhase
,
cmStrCat
(
gt
->
GetName
(),
':'
,
sf
->
GetFullPath
()));
auto
depfilesDirectory
=
cmStrCat
(
gt
->
GetLocalGenerator
()
->
GetCurrentBinaryDirectory
(),
"/CMakeFiles/d/"
);
auto
depfilesPrefix
=
cmStrCat
(
depfilesDirectory
,
buildPhase
->
GetId
(),
"."
);
std
::
string
shellScript
=
"set -e
\n
"
;
for
(
std
::
string
const
&
configName
:
this
->
CurrentConfigurationTypes
)
{
cmCustomCommandGenerator
ccg
(
cc
,
configName
,
this
->
CurrentLocalGenerator
);
cmCustomCommandGenerator
ccg
(
cc
,
configName
,
this
->
CurrentLocalGenerator
,
true
,
{},
[
&
depfilesPrefix
](
const
std
::
string
&
config
,
const
std
::
string
&
)
->
std
::
string
{
return
cmStrCat
(
depfilesPrefix
,
config
,
".d"
);
});
std
::
vector
<
std
::
string
>
realDepends
;
realDepends
.
reserve
(
ccg
.
GetDepends
().
size
());
for
(
auto
const
&
d
:
ccg
.
GetDepends
())
{
...
...
@@ -1886,9 +1898,22 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateRunScriptBuildPhase(
"
\"
; then :
\n
"
,
this
->
ConstructScript
(
ccg
),
"fi
\n
"
);
}
cmXCodeObject
*
buildPhase
=
this
->
CreateObject
(
cmXCodeObject
::
PBXShellScriptBuildPhase
,
cmStrCat
(
gt
->
GetName
(),
':'
,
sf
->
GetFullPath
()));
if
(
!
cc
.
GetDepfile
().
empty
())
{
buildPhase
->
AddAttribute
(
"dependencyFile"
,
this
->
CreateString
(
cmStrCat
(
depfilesDirectory
,
buildPhase
->
GetId
(),
".$(CONFIGURATION).d"
)));
// to avoid spurious errors during first build, create empty dependency
// files
cmSystemTools
::
MakeDirectory
(
depfilesDirectory
);
for
(
std
::
string
const
&
configName
:
this
->
CurrentConfigurationTypes
)
{
auto
file
=
cmStrCat
(
depfilesPrefix
,
configName
,
".d"
);
if
(
!
cmSystemTools
::
FileExists
(
file
))
{
cmSystemTools
::
Touch
(
file
,
true
);
}
}
}
buildPhase
->
AddAttribute
(
"buildActionMask"
,
this
->
CreateString
(
"2147483647"
));
cmXCodeObject
*
buildFiles
=
this
->
CreateObject
(
cmXCodeObject
::
OBJECT_LIST
);
...
...
Source/cmGlobalXCodeGenerator.h
View file @
d67cc488
...
...
@@ -14,6 +14,7 @@
#include
<cm/string_view>
#include
"cmGlobalGenerator.h"
#include
"cmTransformDepfile.h"
#include
"cmXCodeObject.h"
class
cmCustomCommand
;
...
...
@@ -111,6 +112,18 @@ public:
bool
ShouldStripResourcePath
(
cmMakefile
*
)
const
override
;
/**
* Used to determine if this generator supports DEPFILE option.
*/
bool
SupportsCustomCommandDepfile
()
const
override
{
return
this
->
XcodeBuildSystem
>=
BuildSystem
::
Twelve
;
}
virtual
cm
::
optional
<
cmDepfileFormat
>
DepfileFormat
()
const
override
{
return
cmDepfileFormat
::
GccDepfile
;
}
bool
SetSystemName
(
std
::
string
const
&
s
,
cmMakefile
*
mf
)
override
;
bool
SetGeneratorToolset
(
std
::
string
const
&
ts
,
bool
build
,
cmMakefile
*
mf
)
override
;
...
...
Source/cmTransformDepfile.cxx
View file @
d67cc488
...
...
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include
"cmTransformDepfile.h"
#include
<functional>
#include
<string>
#include
<type_traits>
#include
<utility>
...
...
@@ -13,6 +14,7 @@
#include
"cmGccDepfileReader.h"
#include
"cmGccDepfileReaderTypes.h"
#include
"cmGlobalGenerator.h"
#include
"cmLocalGenerator.h"
#include
"cmSystemTools.h"
...
...
@@ -38,6 +40,14 @@ void WriteGccDepfile(cmsys::ofstream& fout, const cmLocalGenerator& lg,
const
cmGccDepfileContent
&
content
)
{
const
auto
&
binDir
=
lg
.
GetBinaryDirectory
();
std
::
function
<
std
::
string
(
const
std
::
string
&
)
>
formatPath
=
[
&
lg
,
&
binDir
](
const
std
::
string
&
path
)
->
std
::
string
{
return
lg
.
MaybeConvertToRelativePath
(
binDir
,
path
);
};
if
(
lg
.
GetGlobalGenerator
()
->
GetName
()
==
"Xcode"
)
{
// full paths must be preserved for Xcode compliance
formatPath
=
[](
const
std
::
string
&
path
)
->
std
::
string
{
return
path
;
};
}
for
(
auto
const
&
dep
:
content
)
{
bool
first
=
true
;
...
...
@@ -46,12 +56,12 @@ void WriteGccDepfile(cmsys::ofstream& fout, const cmLocalGenerator& lg,
fout
<<
"
\\\n
"
;
}
first
=
false
;
WriteFilenameGcc
(
fout
,
lg
.
MaybeConvertToRelativePath
(
binDir
,
rule
));
WriteFilenameGcc
(
fout
,
formatPath
(
rule
));
}
fout
<<
':'
;
for
(
auto
const
&
path
:
dep
.
paths
)
{
fout
<<
"
\\\n
"
;
WriteFilenameGcc
(
fout
,
lg
.
MaybeConvertToRelativePath
(
binDir
,
path
));
WriteFilenameGcc
(
fout
,
formatPath
(
path
));
}
fout
<<
'\n'
;
}
...
...
Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
View file @
d67cc488
...
...
@@ -155,7 +155,8 @@ if (RunCMake_GENERATOR MATCHES "Makefiles")
run_cmake
(
CustomCommandDependencies-BadArgs
)
endif
()
if
(
RunCMake_GENERATOR MATCHES
"Make|Ninja"
)
if
(
RunCMake_GENERATOR MATCHES
"Make|Ninja"
OR
(
RunCMake_GENERATOR STREQUAL
"Xcode"
AND CMAKE_XCODE_BUILD_SYSTEM GREATER_EQUAL
"12"
))
unset
(
run_BuildDepends_skip_step_3
)
run_BuildDepends
(
CustomCommandDepfile
)
set
(
run_BuildDepends_skip_step_3 1
)
...
...
Tests/RunCMake/CMakeLists.txt
View file @
d67cc488
...
...
@@ -222,6 +222,7 @@ endif()
add_RunCMake_test
(
BuildDepends
-DMSVC_VERSION=
${
MSVC_VERSION
}
-DCMAKE_XCODE_BUILD_SYSTEM=
${
CMAKE_XCODE_BUILD_SYSTEM
}
-DCMAKE_C_COMPILER_ID=
${
CMAKE_C_COMPILER_ID
}
-DCMake_TEST_BuildDepends_GNU_AS=
${
CMake_TEST_BuildDepends_GNU_AS
}
)
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment