Add generator expression support to OUTPUT_DIRECTORY target properties
If {ARCHIVE,LIBRARY,RUNTIME}_OUTPUT_DIRECTORY is set with a genex then do not add the per-config subdirectory on multi-config generators. This will allow projects to use $<CONFIG> to place the per-config part of the directory path somewhere other than the end.
This commit is contained in:
parent
e36a05fd7f
commit
d25819bc26
|
@ -11,3 +11,6 @@ per-configuration subdirectory to the specified directory. This
|
||||||
property is initialized by the value of the
|
property is initialized by the value of the
|
||||||
:variable:`CMAKE_ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>` variable if
|
:variable:`CMAKE_ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>` variable if
|
||||||
it is set when a target is created.
|
it is set when a target is created.
|
||||||
|
|
||||||
|
Contents of ``ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>`` may use
|
||||||
|
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
||||||
|
|
|
@ -11,3 +11,6 @@ per-configuration subdirectory to the specified directory. This
|
||||||
property is initialized by the value of the
|
property is initialized by the value of the
|
||||||
:variable:`CMAKE_LIBRARY_OUTPUT_DIRECTORY_<CONFIG>` variable if
|
:variable:`CMAKE_LIBRARY_OUTPUT_DIRECTORY_<CONFIG>` variable if
|
||||||
it is set when a target is created.
|
it is set when a target is created.
|
||||||
|
|
||||||
|
Contents of ``LIBRARY_OUTPUT_DIRECTORY_<CONFIG>`` may use
|
||||||
|
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
||||||
|
|
|
@ -11,3 +11,6 @@ per-configuration subdirectory to the specified directory. This
|
||||||
property is initialized by the value of the
|
property is initialized by the value of the
|
||||||
:variable:`CMAKE_RUNTIME_OUTPUT_DIRECTORY_<CONFIG>` variable if
|
:variable:`CMAKE_RUNTIME_OUTPUT_DIRECTORY_<CONFIG>` variable if
|
||||||
it is set when a target is created.
|
it is set when a target is created.
|
||||||
|
|
||||||
|
Contents of ``RUNTIME_OUTPUT_DIRECTORY_<CONFIG>`` may use
|
||||||
|
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
Output directory in which to build |XXX| target files.
|
Output directory in which to build |XXX| target files.
|
||||||
|
|
||||||
This property specifies the directory into which |xxx| target files
|
This property specifies the directory into which |xxx| target files
|
||||||
should be built. Multi-configuration generators (VS, Xcode) append a
|
should be built. The property value may use
|
||||||
per-configuration subdirectory to the specified directory.
|
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
||||||
|
Multi-configuration generators (VS, Xcode) append a per-configuration
|
||||||
|
subdirectory to the specified directory unless a generator expression
|
||||||
|
is used.
|
||||||
|
|
||||||
This property is initialized by the value of the variable
|
This property is initialized by the value of the variable
|
||||||
|CMAKE_XXX_OUTPUT_DIRECTORY| if it is set when a target is created.
|
|CMAKE_XXX_OUTPUT_DIRECTORY| if it is set when a target is created.
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
OUTPUT_DIRECTORY-genex
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
* The :prop_tgt:`ARCHIVE_OUTPUT_DIRECTORY`,
|
||||||
|
:prop_tgt:`LIBRARY_OUTPUT_DIRECTORY`, and
|
||||||
|
:prop_tgt:`RUNTIME_OUTPUT_DIRECTORY` target properties learned to
|
||||||
|
support :manual:`generator expressions <cmake-generator-expressions(7)>`.
|
|
@ -3520,7 +3520,10 @@ bool cmTarget::ComputeOutputDir(const std::string& config,
|
||||||
if(const char* config_outdir = this->GetProperty(configProp))
|
if(const char* config_outdir = this->GetProperty(configProp))
|
||||||
{
|
{
|
||||||
// Use the user-specified per-configuration output directory.
|
// Use the user-specified per-configuration output directory.
|
||||||
out = config_outdir;
|
cmGeneratorExpression ge;
|
||||||
|
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
|
||||||
|
ge.Parse(config_outdir);
|
||||||
|
out = cge->Evaluate(this->Makefile, config);
|
||||||
|
|
||||||
// Skip per-configuration subdirectory.
|
// Skip per-configuration subdirectory.
|
||||||
conf = "";
|
conf = "";
|
||||||
|
@ -3528,7 +3531,17 @@ bool cmTarget::ComputeOutputDir(const std::string& config,
|
||||||
else if(const char* outdir = this->GetProperty(propertyName))
|
else if(const char* outdir = this->GetProperty(propertyName))
|
||||||
{
|
{
|
||||||
// Use the user-specified output directory.
|
// Use the user-specified output directory.
|
||||||
out = outdir;
|
cmGeneratorExpression ge;
|
||||||
|
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
|
||||||
|
ge.Parse(outdir);
|
||||||
|
out = cge->Evaluate(this->Makefile, config);
|
||||||
|
|
||||||
|
// Skip per-configuration subdirectory if the value contained a
|
||||||
|
// generator expression.
|
||||||
|
if (out != outdir)
|
||||||
|
{
|
||||||
|
conf = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(this->GetType() == cmTarget::EXECUTABLE)
|
else if(this->GetType() == cmTarget::EXECUTABLE)
|
||||||
{
|
{
|
||||||
|
|
|
@ -105,6 +105,19 @@ target_link_libraries(testLib4
|
||||||
add_executable(testExe3 testExe3.c)
|
add_executable(testExe3 testExe3.c)
|
||||||
set_property(TARGET testExe3 PROPERTY MACOSX_BUNDLE 1)
|
set_property(TARGET testExe3 PROPERTY MACOSX_BUNDLE 1)
|
||||||
|
|
||||||
|
# Test <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_DIRECTORY[_<CONFIG>] properties with generator expressions
|
||||||
|
add_executable(testExe4 testExe4.c)
|
||||||
|
target_link_libraries(testExe4 testExe1lib)
|
||||||
|
set_property(TARGET testLib7 PROPERTY ARCHIVE_OUTPUT_DIRECTORY_DEBUG testLib7D-$<CONFIG>)
|
||||||
|
set_property(TARGET testLib7 PROPERTY ARCHIVE_OUTPUT_DIRECTORY_RELEASE testLib7R-$<CONFIG>)
|
||||||
|
set_property(TARGET testLib7 PROPERTY ARCHIVE_OUTPUT_DIRECTORY testLib7-$<CONFIG>)
|
||||||
|
set_property(TARGET testLib5 PROPERTY LIBRARY_OUTPUT_DIRECTORY_DEBUG testLib5D-$<CONFIG>)
|
||||||
|
set_property(TARGET testLib5 PROPERTY LIBRARY_OUTPUT_DIRECTORY_RELEASE testLib5R-$<CONFIG>)
|
||||||
|
set_property(TARGET testLib5 PROPERTY LIBRARY_OUTPUT_DIRECTORY testLib5-$<CONFIG>)
|
||||||
|
set_property(TARGET testExe4 PROPERTY RUNTIME_OUTPUT_DIRECTORY_DEBUG testExe4D-$<CONFIG>)
|
||||||
|
set_property(TARGET testExe4 PROPERTY RUNTIME_OUTPUT_DIRECTORY_RELEASE testExe4R-$<CONFIG>)
|
||||||
|
set_property(TARGET testExe4 PROPERTY RUNTIME_OUTPUT_DIRECTORY testExe4-$<CONFIG>)
|
||||||
|
|
||||||
# Test cyclic dependencies.
|
# Test cyclic dependencies.
|
||||||
add_library(testLibCycleA STATIC
|
add_library(testLibCycleA STATIC
|
||||||
testLibCycleA1.c testLibCycleA2.c testLibCycleA3.c)
|
testLibCycleA1.c testLibCycleA2.c testLibCycleA3.c)
|
||||||
|
@ -450,7 +463,7 @@ install(FILES
|
||||||
# Install and export from install tree.
|
# Install and export from install tree.
|
||||||
install(
|
install(
|
||||||
TARGETS
|
TARGETS
|
||||||
testExe1 testLib1 testLib2 testExe2 testLib3 testLib4 testExe3
|
testExe1 testLib1 testLib2 testExe2 testLib3 testLib4 testExe3 testExe4
|
||||||
testExe2lib testLib4lib testLib4libdbg testLib4libopt
|
testExe2lib testLib4lib testLib4libdbg testLib4libopt
|
||||||
testLib6 testLib7
|
testLib6 testLib7
|
||||||
testLibCycleA testLibCycleB
|
testLibCycleA testLibCycleB
|
||||||
|
@ -511,7 +524,7 @@ export(TARGETS testExe1 testLib1 testLib2 testLib3
|
||||||
NAMESPACE bld_
|
NAMESPACE bld_
|
||||||
FILE ExportBuildTree.cmake
|
FILE ExportBuildTree.cmake
|
||||||
)
|
)
|
||||||
export(TARGETS testExe2 testLib4 testLib5 testLib6 testLib7 testExe3 testExe2lib
|
export(TARGETS testExe2 testLib4 testLib5 testLib6 testLib7 testExe3 testExe4 testExe2lib
|
||||||
testLib4lib testLib4libdbg testLib4libopt
|
testLib4lib testLib4libdbg testLib4libopt
|
||||||
testLibCycleA testLibCycleB
|
testLibCycleA testLibCycleB
|
||||||
testLibPerConfigDest
|
testLibPerConfigDest
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(int argc, const char* argv[])
|
||||||
|
{
|
||||||
|
if(argc < 2)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Must specify output file.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
FILE* f = fopen(argv[1], "w");
|
||||||
|
if(f)
|
||||||
|
{
|
||||||
|
fprintf(f, "int generated_by_testExe4() { return 0; }\n");
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error writing to %s\n", argv[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -19,11 +19,17 @@ add_custom_command(
|
||||||
COMMAND exp_testExe3 ${Import_BINARY_DIR}/exp_generated3.c
|
COMMAND exp_testExe3 ${Import_BINARY_DIR}/exp_generated3.c
|
||||||
DEPENDS exp_testExe3
|
DEPENDS exp_testExe3
|
||||||
)
|
)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${Import_BINARY_DIR}/exp_generated4.c
|
||||||
|
COMMAND exp_testExe4 ${Import_BINARY_DIR}/exp_generated4.c
|
||||||
|
DEPENDS exp_testExe4
|
||||||
|
)
|
||||||
|
|
||||||
add_executable(imp_testExe1
|
add_executable(imp_testExe1
|
||||||
imp_testExe1.c
|
imp_testExe1.c
|
||||||
${Import_BINARY_DIR}/exp_generated.c
|
${Import_BINARY_DIR}/exp_generated.c
|
||||||
${Import_BINARY_DIR}/exp_generated3.c
|
${Import_BINARY_DIR}/exp_generated3.c
|
||||||
|
${Import_BINARY_DIR}/exp_generated4.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# Try linking to a library imported from the install tree.
|
# Try linking to a library imported from the install tree.
|
||||||
|
@ -53,11 +59,17 @@ add_custom_command(
|
||||||
COMMAND bld_testExe3 ${Import_BINARY_DIR}/bld_generated3.c
|
COMMAND bld_testExe3 ${Import_BINARY_DIR}/bld_generated3.c
|
||||||
DEPENDS bld_testExe3
|
DEPENDS bld_testExe3
|
||||||
)
|
)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${Import_BINARY_DIR}/bld_generated4.c
|
||||||
|
COMMAND bld_testExe4 ${Import_BINARY_DIR}/bld_generated4.c
|
||||||
|
DEPENDS bld_testExe4
|
||||||
|
)
|
||||||
|
|
||||||
add_executable(imp_testExe1b
|
add_executable(imp_testExe1b
|
||||||
imp_testExe1.c
|
imp_testExe1.c
|
||||||
${Import_BINARY_DIR}/bld_generated.c
|
${Import_BINARY_DIR}/bld_generated.c
|
||||||
${Import_BINARY_DIR}/bld_generated3.c
|
${Import_BINARY_DIR}/bld_generated3.c
|
||||||
|
${Import_BINARY_DIR}/bld_generated4.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# Try linking to a library imported from the build tree.
|
# Try linking to a library imported from the build tree.
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
extern int generated_by_testExe1();
|
extern int generated_by_testExe1();
|
||||||
extern int generated_by_testExe3();
|
extern int generated_by_testExe3();
|
||||||
|
extern int generated_by_testExe4();
|
||||||
extern int testLib2();
|
extern int testLib2();
|
||||||
extern int testLib3();
|
extern int testLib3();
|
||||||
extern int testLib4();
|
extern int testLib4();
|
||||||
|
@ -24,5 +25,5 @@ int main()
|
||||||
return (testLib2() + generated_by_testExe1() + testLib3() + testLib4()
|
return (testLib2() + generated_by_testExe1() + testLib3() + testLib4()
|
||||||
+ testLib5() + testLib6() + testLib7() + testLibCycleA1()
|
+ testLib5() + testLib6() + testLib7() + testLibCycleA1()
|
||||||
+ testLibPerConfigDest()
|
+ testLibPerConfigDest()
|
||||||
+ generated_by_testExe3() + testLib4lib() + testLib4libcfg());
|
+ generated_by_testExe3() + generated_by_testExe4() + testLib4lib() + testLib4libcfg());
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ run_cmake(COMPILE_LANGUAGE-add_executable)
|
||||||
run_cmake(COMPILE_LANGUAGE-add_library)
|
run_cmake(COMPILE_LANGUAGE-add_library)
|
||||||
run_cmake(COMPILE_LANGUAGE-add_test)
|
run_cmake(COMPILE_LANGUAGE-add_test)
|
||||||
run_cmake(COMPILE_LANGUAGE-unknown-lang)
|
run_cmake(COMPILE_LANGUAGE-unknown-lang)
|
||||||
|
run_cmake(TARGET_FILE-recursion)
|
||||||
|
|
||||||
run_cmake(ImportedTarget-TARGET_PDB_FILE)
|
run_cmake(ImportedTarget-TARGET_PDB_FILE)
|
||||||
if(LINKER_SUPPORTS_PDB)
|
if(LINKER_SUPPORTS_PDB)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,4 @@
|
||||||
|
CMake Error at TARGET_FILE-recursion.cmake:[0-9]+ \(add_executable\):
|
||||||
|
Target 'empty1' OUTPUT_DIRECTORY depends on itself.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,3 @@
|
||||||
|
enable_language(C)
|
||||||
|
add_executable(empty1 empty.c)
|
||||||
|
set_property(TARGET empty1 PROPERTY RUNTIME_OUTPUT_DIRECTORY $<TARGET_FILE_DIR:empty1>)
|
Loading…
Reference in New Issue