'Symbolic links CMake
I want to rename certain executables in CMakeLists.txt but also want symbolic links from the older names to new files for backward compatibility. How can this be accomplished on systems that support symbolic links?
Also what are the alternatives for system that does not support symbolic links?
Solution 1:[1]
Another way to do it:
INSTALL(CODE "execute_process( \
COMMAND ${CMAKE_COMMAND} -E create_symlink \
${target} \
${link} \
)"
)
This way the symlinking will be done during make install only.
Solution 2:[2]
Another method that is a bit more verbose and only runs on install:
macro(install_symlink filepath sympath)
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${filepath} ${sympath})")
install(CODE "message(\"-- Created symlink: ${sympath} -> ${filepath}\")")
endmacro(install_symlink)
Use it like this (similar to ln -s):
install_symlink(filepath sympath)
Solution 3:[3]
Lets say you need to create a link in binary dir to a target located in source directory.
You can try file CREATE_LINK since version 3.14
${CMAKE_COMMAND} -E create_symlink is accessible at Windows since 3.17
You can use execute_process since early cmake versions:
if(WIN32)
get_filename_component(real_path "${dirname}" REALPATH)
string(REPLACE "/" "\\" target_path "${real_path}")
execute_process(
COMMAND cmd /C mklink /J ${dirname} "${target_path}"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
)
else()
execute_process(COMMAND "ln -s ${CMAKE_CURRENT_SOURCE_DIR}/${dirname} ${CMAKE_CURRENT_BINARY_DIR}/${dirname}")
endif()
Solution 4:[4]
I've added the check to @ulidtko's approach, so symlink doesn't overridden on every rebuild unconditionally:
install(CODE "if (NOT EXISTS ${link})
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink \
${target} \
${link})
endif()" )
Solution 5:[5]
When I build, I create a symlink to the compile_commands.json. This helps clangd and vscode's intellisense.
Here's a full working example of what worked for me.
add_custom_command is what creates the symlink.
cmake_minimum_required(VERSION "3.1.0")
# project name
project("a-s-i-o")
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -std=c++17 -pthread -Wall -Wextra -Werror -pedantic -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-unused-private-field"
)
# Create `compile_commands.json` file.
#
# This is required by `clangd` to find the header files. For this to work, this
# file must be in the root of the project. Therefore, we create a symbolic link in the root that
# points to the `compile_commands.json` file created by CMake in the `build` directory.
#
# This specific commands creates the file in the build directory. The command `add_custom_command`
# creates the symbolic link in the root directory.
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_executable(x main.cpp)
target_include_directories(x PUBLIC "/usr/local/include/asio-1.20.0/include")
# When target `x` is built, a symlink will be created to
# `build/compile_commands.json`. This is required for clangd to be able to find
# the header files included in the project.
add_custom_command(TARGET x
COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json" "../compile_commands.json"
DEPENDS compile_commands.json
VERBATIM ON
)
# Print success message to the console
add_custom_command(TARGET x POST_BUILD
COMMAND echo "Created symlink pointing to `compile_commands.json`"
DEPENDS compile_commands.json
VERBATIM ON
)
Solution 6:[6]
I've struggled with this a few different ways with the above responses in order to install '.so.#' files that refer to other '.so.#.#' files. I've had success by not introducing a link to the file, but by installing the '.so.#.#' file as the '.so.#' file.
I.e. instead of
install(
FILES
.../libmpi.so.12.0
DESTINATION lib
)
install(CODE
"EXECUTE_PROCESS( ${CMAKE_COMMAND} -E create_symlink lib/libmpi.so.12.0 lib/libmpi.so.12)")
Which didn't quite work for me even. I have instead had success by doing this.
install(FILES
.../libmpi.so.12.0
RENAME libmpi.so.12
DESTINATION lib
)
Not 'exactly' the same, but sufficient. Don't defeat the problem, solve the problem.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Rian Quinn |
| Solution 3 | |
| Solution 4 | bam |
| Solution 5 | lenz |
| Solution 6 |
