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:
Robert Goulet 2015-08-11 15:19:03 -04:00 committed by Brad King
parent e36a05fd7f
commit d25819bc26
14 changed files with 98 additions and 7 deletions

View File

@ -11,3 +11,6 @@ per-configuration subdirectory to the specified directory. This
property is initialized by the value of the
:variable:`CMAKE_ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>` variable if
it is set when a target is created.
Contents of ``ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>`` may use
:manual:`generator expressions <cmake-generator-expressions(7)>`.

View File

@ -11,3 +11,6 @@ per-configuration subdirectory to the specified directory. This
property is initialized by the value of the
:variable:`CMAKE_LIBRARY_OUTPUT_DIRECTORY_<CONFIG>` variable if
it is set when a target is created.
Contents of ``LIBRARY_OUTPUT_DIRECTORY_<CONFIG>`` may use
:manual:`generator expressions <cmake-generator-expressions(7)>`.

View File

@ -11,3 +11,6 @@ per-configuration subdirectory to the specified directory. This
property is initialized by the value of the
:variable:`CMAKE_RUNTIME_OUTPUT_DIRECTORY_<CONFIG>` variable if
it is set when a target is created.
Contents of ``RUNTIME_OUTPUT_DIRECTORY_<CONFIG>`` may use
:manual:`generator expressions <cmake-generator-expressions(7)>`.

View File

@ -1,8 +1,11 @@
Output directory in which to build |XXX| target files.
This property specifies the directory into which |xxx| target files
should be built. Multi-configuration generators (VS, Xcode) append a
per-configuration subdirectory to the specified directory.
should be built. The property value may use
: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
|CMAKE_XXX_OUTPUT_DIRECTORY| if it is set when a target is created.

View File

@ -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)>`.

View File

@ -3520,7 +3520,10 @@ bool cmTarget::ComputeOutputDir(const std::string& config,
if(const char* config_outdir = this->GetProperty(configProp))
{
// 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.
conf = "";
@ -3528,7 +3531,17 @@ bool cmTarget::ComputeOutputDir(const std::string& config,
else if(const char* outdir = this->GetProperty(propertyName))
{
// 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)
{

View File

@ -105,6 +105,19 @@ target_link_libraries(testLib4
add_executable(testExe3 testExe3.c)
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.
add_library(testLibCycleA STATIC
testLibCycleA1.c testLibCycleA2.c testLibCycleA3.c)
@ -450,7 +463,7 @@ install(FILES
# Install and export from install tree.
install(
TARGETS
testExe1 testLib1 testLib2 testExe2 testLib3 testLib4 testExe3
testExe1 testLib1 testLib2 testExe2 testLib3 testLib4 testExe3 testExe4
testExe2lib testLib4lib testLib4libdbg testLib4libopt
testLib6 testLib7
testLibCycleA testLibCycleB
@ -511,7 +524,7 @@ export(TARGETS testExe1 testLib1 testLib2 testLib3
NAMESPACE bld_
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
testLibCycleA testLibCycleB
testLibPerConfigDest

View File

@ -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;
}

View File

@ -19,11 +19,17 @@ add_custom_command(
COMMAND exp_testExe3 ${Import_BINARY_DIR}/exp_generated3.c
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
imp_testExe1.c
${Import_BINARY_DIR}/exp_generated.c
${Import_BINARY_DIR}/exp_generated3.c
${Import_BINARY_DIR}/exp_generated4.c
)
# 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
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
imp_testExe1.c
${Import_BINARY_DIR}/bld_generated.c
${Import_BINARY_DIR}/bld_generated3.c
${Import_BINARY_DIR}/bld_generated4.c
)
# Try linking to a library imported from the build tree.

View File

@ -1,5 +1,6 @@
extern int generated_by_testExe1();
extern int generated_by_testExe3();
extern int generated_by_testExe4();
extern int testLib2();
extern int testLib3();
extern int testLib4();
@ -24,5 +25,5 @@ int main()
return (testLib2() + generated_by_testExe1() + testLib3() + testLib4()
+ testLib5() + testLib6() + testLib7() + testLibCycleA1()
+ testLibPerConfigDest()
+ generated_by_testExe3() + testLib4lib() + testLib4libcfg());
+ generated_by_testExe3() + generated_by_testExe4() + testLib4lib() + testLib4libcfg());
}

View File

@ -25,6 +25,7 @@ run_cmake(COMPILE_LANGUAGE-add_executable)
run_cmake(COMPILE_LANGUAGE-add_library)
run_cmake(COMPILE_LANGUAGE-add_test)
run_cmake(COMPILE_LANGUAGE-unknown-lang)
run_cmake(TARGET_FILE-recursion)
run_cmake(ImportedTarget-TARGET_PDB_FILE)
if(LINKER_SUPPORTS_PDB)

View File

@ -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\)

View File

@ -0,0 +1,3 @@
enable_language(C)
add_executable(empty1 empty.c)
set_property(TARGET empty1 PROPERTY RUNTIME_OUTPUT_DIRECTORY $<TARGET_FILE_DIR:empty1>)