Moving Beyond LOCATION: Reliable Techniques for Determining Build Target Paths in CMake
CMP0026: Disallow Use of the LOCATION Target Property
This policy controls how you access the location (file path) of build targets within CMake projects. It was introduced in CMake version 3.0 to promote a more modern and reliable approach for determining target locations.
Understanding the LOCATION Property
In CMake versions 2.8.12 and earlier, the LOCATION
target property (and its configuration-specific variants) could be used to retrieve the final location of a build target after the build process. However, this approach had limitations:
- Deprecated Syntax
This property was considered outdated and discouraged by CMake developers. - Unreliable During Configuration
The property might not reflect the actual location until after the build was complete, making it unsuitable for configuration-time operations. - Inconsistency
TheLOCATION
property's behavior could vary depending on the build system generator (e.g., Makefiles, Ninja).
The New Approach
CMP0026 addresses these issues by disallowing the use of the LOCATION
property. Instead, CMake recommends the following preferred methods to determine the location of build targets:
Direct Target Name
Use the target name directly with commands likeadd_custom_command
orconfigure_file
. For example:add_custom_command( OUTPUT ${TARGET_NAME}.processed COMMAND process ${TARGET_NAME} )
Setting and Handling the Policy
- Enabling/Disabling (Not Recommended)
While you can usecmake_policy
orcmake_minimum_required
to explicitly set this policy toOLD
(allowingLOCATION
), it's generally discouraged due to potential issues and its deprecated nature. - CMake Version Check
If you're using CMake 3.0 or later, CMP0026 is enabled by default, and you'll likely encounter warnings if you attempt to use theLOCATION
property.
Benefits of Using Alternative Methods
By adopting the recommended approaches, you gain the following advantages:
- Modern CMake Practices
Aligning your code with current CMake best practices. - Enhanced Reliability
You can access target locations during configuration, leading to more robust CMakeLists.txt files. - Improved Portability
Generator expressions work seamlessly across different build system generators.
In Summary
Using Direct Target Name
This example shows a custom command that processes the output of a target named MY_TARGET
:
add_executable(MY_TARGET source1.cpp source2.cpp)
add_custom_command(
OUTPUT ${MY_TARGET}.processed # Use target name directly
COMMAND process ${MY_TARGET} # Pass target name to the command
)
Employing Generator Expressions
This example demonstrates configuring a file based on the location of the target MY_TARGET
:
add_executable(MY_TARGET source1.cpp source2.cpp)
configure_file(my_config.txt.in OUTPUT $<TARGET_FILE:MY_TARGET>.config)
$<TARGET_FILE:MY_TARGET>
: This generator expression dynamically retrieves the final location of theMY_TARGET
executable based on the build system generator (e.g., Makefile, Ninja).
Handling Potential CMP0026 Warnings (Not Recommended)
If you're working with an older project that still uses the LOCATION
property and you encounter CMP0026 warnings, you could temporarily disable the policy (not recommended for long-term use):
cmake_policy(SET CMP0026 OLD) # Disabling (discouraged)
# Code using LOCATION (may cause issues)
cmake_policy(SET CMP0026 NEW) # Re-enabling (recommended)
Direct Target Name
Example:
add_executable(MY_TARGET source1.cpp source2.cpp) add_custom_command( OUTPUT ${MY_TARGET}.processed COMMAND process ${MY_TARGET} # Pass target name directly )
Use the target name directly with commands like
add_custom_command
,configure_file
, or any other command that needs to interact with the target's location.
Generator Expressions
add_executable(MY_TARGET source1.cpp source2.cpp) configure_file(my_config.txt.in OUTPUT $<TARGET_FILE:MY_TARGET>.config)
Leverage generator expressions like
<TARGET_FILE>
to obtain the location dynamically based on the build system generator. This ensures compatibility across different build systems (e.g., Makefiles, Ninja).
Remember that these are the recommended methods in modern CMake practices. Using the LOCATION
property (which CMP0026 discourages) can lead to:
- Deprecated Syntax
This property is considered outdated by CMake developers. - Unreliable During Configuration
The location might not be available until after the build, making it unsuitable for configuration-time operations. - Inconsistency
The behavior might vary depending on the build system generator.
By adopting these alternatives, you gain:
- Modern CMake Practices
Aligning your code with current CMake best practices. - Enhanced Reliability
You can access target locations during configuration, leading to more robust CMakeLists.txt files. - Improved Portability
Generator expressions work seamlessly across different build system generators.