CMake WRAP_EXCLUDE Property for Selective Code Wrapping
Purpose
The WRAP_EXCLUDE
property in CMake is used to specifically prevent a source file from being included in any code wrapping techniques employed during the build process.
Code Wrapping
Code wrapping refers to the process of translating source code written in one language (like C++) into a different language (like Python or Java) to enable easier integration with other systems or languages. Tools like SWIG (Simplified Wrapper and Interface Generator) are commonly used for this purpose.
How WRAP_EXCLUDE
Works
By setting the WRAP_EXCLUDE
property to TRUE
on a source file, you instruct CMake to explicitly exclude that file from being considered for code wrapping. This is useful in scenarios where:
- You already have a separate mechanism for exposing the functionality of the file (e.g., manual creation of bindings).
- The file interacts with system-specific functionalities that wouldn't translate well to another language.
- The source file contains implementation details that aren't meant to be exposed through the wrapped interface.
Setting WRAP_EXCLUDE
You can set the WRAP_EXCLUDE
property on a source file using the set_source_files_properties
command within your CMakeLists.txt file:
set_source_files_properties(
my_source_file.cpp # Replace with the actual file path
PROPERTIES WRAP_EXCLUDE TRUE
)
Example
Imagine you have a C++ project with a source file named internal_functions.cpp
containing helper functions that aren't intended for external use. You wouldn't want these functions to be wrapped, so you can set the WRAP_EXCLUDE
property on this file:
set_source_files_properties(
internal_functions.cpp
PROPERTIES WRAP_EXCLUDE TRUE
)
Scenario 1: Excluding a File with Internal Functions
# CMakeLists.txt
# Source files
set(SOURCE_FILES main.cpp helper_functions.cpp)
# Excluding helper_functions.cpp from code wrapping
set_source_files_properties(
helper_functions.cpp
PROPERTIES WRAP_EXCLUDE TRUE
)
# Target creation (assuming you're building an executable)
add_executable(my_program ${SOURCE_FILES})
In this example:
- We create an executable named
my_program
using both source files. - We set the
WRAP_EXCLUDE
property toTRUE
onhelper_functions.cpp
, ensuring it's not wrapped. - We have two source files:
main.cpp
(likely containing the main logic) andhelper_functions.cpp
(containing internal helper functions).
# CMakeLists.txt
# Source files
set(SOURCE_FILES main.cpp my_library.cpp)
# Header for wrapping (assuming it exposes the desired functionality)
set(WRAP_HEADER my_library.h)
# Excluding my_library.cpp (implementation details)
set_source_files_properties(
my_library.cpp
PROPERTIES WRAP_EXCLUDE TRUE
)
# Target creation (assuming you're building a library)
add_library(my_library SHARED ${SOURCE_FILES} ${WRAP_HEADER})
- We create a shared library named
my_library
using all three files. - We exclude
my_library.cpp
from wrapping. - We define a separate header
my_library.h
that exposes the public interface for wrapping. - We have
main.cpp
(likely using the library) andmy_library.cpp
(containing the library implementation).
- Instead of excluding files, you can create separate targets for wrapping and non-wrapping parts. This can be useful for complex projects with various wrapping needs.
# CMakeLists.txt set(SOURCE_FILES main.cpp helper_functions.cpp) # Target for non-wrapped code (assuming executable) add_executable(my_program ${SOURCE_FILES}) # Target for wrapped code (assuming you have SWIG setup) # This would likely involve additional steps for SWIG configuration add_custom_command( OUTPUT wrapped_library.py COMMAND swig -python helper_functions.cpp -o wrapped_library.py DEPENDS helper_functions.cpp ) # You can then link the wrapped library with your main program if needed
Manual Source File Inclusion
- If you're using a custom code wrapping tool, you might have more control over the specific files included. You can directly specify the source files to the wrapping tool, bypassing CMake's automatic inclusion.
Header-Only Libraries
- For certain scenarios, consider creating a header-only library. This eliminates the need for separate implementation files and simplifies the wrapping process since only the header is involved.
The best approach depends on your specific project structure, wrapping tool, and desired level of granularity.
Choosing the Right Method
- Header-only libraries are ideal when the functionality can be entirely encapsulated in headers.
- If you have a custom wrapping tool, manual source file inclusion might be suitable.
- For more complex projects with multiple wrapping needs, target-specific source files offer more flexibility.
- If you have a clear separation between public and private code,
WRAP_EXCLUDE
is a straightforward solution.