CMake cannot follow symbolic links - cmake

Update: turns out the problem is not related to the Jenkins agent but to CMake. It is easily reproducible from the command line.
It was reported here once before:
CMake cannot follow symlinks on Windows 10
However, the problem is not OS-related. We encounter it on Linux also.
I'm debugging the following error:
CMake Error at C:/jenkins/trial/workspace/WWB6-6.13.0/wwb-Pilot_Build_BB/wwb6/build/cmake_install.cmake:48 (file):
file INSTALL cannot read symlink
"C:/jenkins/trial/workspace/WWB6-6.13.0/wwb6-Build-Pilot-Windows/wwb6/wwb6/HelpFiles"
to duplicate at
"C:/jenkins/trial/workspace/WWB6-6.13.0/wwb6-Build-Pilot-Windows/wwb6/build/_CPack_Packages/win64/NSIS/WWB6 Setup/./Help".
The relevant line in the make file is:
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/./Help" TYPE DIRECTORY FILES "C:/jenkins/trial/workspace/WWB6-6.13.0/wwb-Pilot_Build_BB/wwb6/wwb6/HelpFiles/")
The intent is to copy the contents of the HelpFiles directory into a new directory "Help" in the workspace. The HelpFiles directory in this scenario is a symbolic link to another directory in the source repository:
Directory of C:\jenkins\trial\workspace\WWB6-6.13.0\wwb6-Build-Pilot-Windows\wwb6\wwb6
05/17/2019 03:09 PM <SYMLINKD> HelpFiles [..\helpwwb6]
Traversing this symlink from the command line works fine:
C:\jenkins\trial\workspace\WWB6-6.13.0\wwb6-Build-Pilot-Windows\wwb6\wwb6>cd HelpFiles
C:\jenkins\trial\workspace\WWB6-6.13.0\wwb6-Build-Pilot-Windows\wwb6\wwb6\HelpFiles>
Anyone know of a workaround for this problem? The version of CMake we're running is 3.12.0.

Fortunately, there's an easy (although not elegant) workaround for this: replace the symlink with the real path in the CMakeLists file:
install ( DIRECTORY ${CMAKE_SOURCE_DIR}/../helpwwb6/
DESTINATION ${BINARY_INSTALL_LOCATION}/Help
COMPONENT Runtime
PATTERN ".svn" EXCLUDE
PATTERN ".git" EXCLUDE
)
Would rather see CMake work with symlinks though.

Related

CMake Error: include could not find load file: targets

I'm trying to run AmazonFreeRTOS on my ESP32 (at Windows). After creating build folder in my amazon-freertos main folder I've tried to build it from main folder with
cmake --build .\build
The Error I've got is
include could not find load file: targets
However, there is a idf_functions.cmake file that contains include(targets) command, and the targets.cmake file is in the same folder so I don't know why the error occured.
If you pay close attention to the error, you'd notice the full error says something like:
CMake Error at
your-amazon-freertos-directory/vendors/espressif/esp-idf/tools/cmake/idf_functions.cmake: 26 (include)
include could not find load file:
targets
This is because idf_functions.cmake sets the variable IDF_PATH to $ENV{IDF_PATH} which was configured in ~/.profile when the line export IDF_PATH=~/esp/esp-idf was added, as seen here.
If you navigate to ~/esp/esp-idf/tools/cmake/ you'd notice that files like target.cmake and ldgen.cmake, which are being included <your-amazon-freertos-directory>/vendors/espressif/esp-idf/tools/cmake/idf_functions.cmake, do not exist.
Solution 1 (somewhat hacky):
Copy the contents of <your-amazon-freertos-directory>/vendors/espressif/esp-idf/tools/cmake/ to ~/esp/esp-idf/tools/cmake/
Solution 2:
Modify the ~/.profile file to add the following lines instead of that suggested in the guide:
export IDF_PATH=~/<your-amazon-freertos-directory>/vendors/espressif/esp-idf/
export PATH="$PATH:$IDF_PATH/tools"
This should circumvent any CMake include errors during generation of build files and during build.
Since Amazon FreeRTOS supports many different platforms in addition to ESP32, you might need to supply additional commands to tell CMake that ESP32 is the target you want to build.
Try using
cmake -DVENDOR=espressif -DBOARD=esp32_wrover_kit -DCOMPILER=xtensa-esp32 -S . -B your-build-directory
from your top level folder to generate your makefiles into the build folder, and then switching to your build folder and calling
make all
(From the "Build, Flash, and Run the Amazon FreeRTOS Demo Project" section of
https://docs.aws.amazon.com/freertos/latest/userguide/getting_started_espressif.html)

CMake does not find the source directory (installing Eigen)

I was installing the library Eigen on Ubuntu. I followed the instructions by creating a "build directory" alongside the downloaded source directory. That is, I have two directories: eigen-eigen-1306d75b4a21 for source, and an empty eigen-build for build.
Then I did:
cd eigen-build
cmake ../eigen-eigen-1306d75b4a21/
sudo make install
An error occurred immediately after make install and it stops the installation:
CMake Error: The source directory "/home/username/something/eigen-eigen-1306d75b4a21" does not exist.
Obviously the directory exists. What is wrong with my CMake? (I don't know much about CMake. I observed some warnings during the second step, saying lots of things such as Qt4 are missing, but I don't think this is the cause, because of what the error message suggests.)
Probably your directory does not include the CMakeLists.txt file.

Installed library cannot be found by CMake

I have the following problem when running CMake.
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
DIRECTFB_INCLUDE_DIR (ADVANCED)
used as include directory in directory /u/menie482/workspace/AtariTEXPLORE
used as include directory in directory /u/menie482/workspace/AtariTEXPLORE/rl_common
used as include directory in directory /u/menie482/workspace/AtariTEXPLORE/rl_agent
used as include directory in directory /u/menie482/workspace/AtariTEXPLORE/rl_env
DIRECTFB_LIBRARY (ADVANCED)
linked by target "experiment" in directory /u/menie482/workspace/AtariTEXPLORE
Actually, I have checked that the DirectFB is already installed when running
locate libdirectfb
So, what shall I do to let CMake know where DIrectFB is? An inconvenient constraint is that I cannot do sudo on this machine..
Thanks!
I guess, you are trying to use something like find_package(directfb) in your CMakeLists.txt file. That can only run if you have /usr/share/cmake/Modules/directfb.cmake (Ubuntu 12.04).
My second guess is you are using something like pkg_module(directfb) in your CMakeLists.txt file. That can only run if you have directfb.pc somewhere.
Otherwise
Where are you setting the variables DIRECTFB_INCLUDE_DIR and DIRECTFB_LIBRARY.
As an alternate step, try using find_library(). You will have to give exact path of libdirectfb.so and do something like
find_library(DIRECT_FB NAMES directfb PATHS path/directfb.so )
target_link_libraries( MyLibraryOrMyExecutable ${DIRECT_FB} )

CMake follow symbolic links during install

Short question:
Is it possible to set CMake to follow symlinks when copying files during an install, and if so how is this done?
Details: I am using CMake to build and install LLVM. In my LLVM source tree in the include directory I have a symbolic link to another subproject that is being developed against LLVM. Everything seems to work, except that I noticed that when I ran "cmake install" that it copied the include directory without following the symlinks. The problem that I have is that my symlinks have a relative path (because it is inside a git repo). So when the symlinks are copied (instead of followed and copying the contents) they no longer point to the correct files. For example I have dsa -> ../../llvm-poolalloc/include/dsa/ I would like to copy the contents of this link when I do the install rather than just copying the link. But I did not find a cmake flag for doing this yet.
I realize that this is probably not the idea way to structure my project, but I am working with something that's already in place and it would be preferable to not have to change too much of the directory structures because other people I am working with expect it to be this way. So I think that being able to follow symlinks might solve my problem without having to restructure the whole build system. But I am open to other suggestions for better ways to accomplish what I am trying to do.
Note that I am working in Linux (Ubuntu 10.04) and using LLVM 2.6 (that I am compiling from source along with llvm-gcc). Also I am using CMake version 2.8.
Edit:
Here is the source code from the CMakeLists.txt file that is associated with the install instruction:
install(DIRECTORY include
DESTINATION .
PATTERN ".svn" EXCLUDE
PATTERN "*.cmake" EXCLUDE
PATTERN "*.in" EXCLUDE
PATTERN "*.tmp" EXCLUDE
)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include
DESTINATION .
)
the directory listing for the include directory is:
dsa -> ../../llvm-poolalloc/include/dsa/
llvm
llvm-c
poolalloc -> ../../llvm-poolalloc/include/poolalloc
What I want is for the dsa and poolalloc directories to be copied rather than just copying the symbolic links. The reason that I don't use absolute paths in the symbolic links is that I have them checked into a git repo. So my absolute path would differ from someone else working on the project when they do a checkout from the repo.
Hmm, let's try this:
get_filename_component(ABS_DIR include REALPATH)
install(DIRECTORY ${ABS_DIR}
DESTINATION .
PATTERN ".svn" EXCLUDE
PATTERN "*.cmake" EXCLUDE
PATTERN "*.in" EXCLUDE
PATTERN "*.tmp" EXCLUDE
)
If it wouldn't help, you can try to install not the include dir itself (which is symlink), but it's contents. But in your case you would need to came up with smart regex:
file(GLOB INCLUDES include/*) # filter there .svn and others
install(FILES ${INCLUDES}
DESTINATION include
)
Finally, make the symlink absolute.

CMake rpm installing a file in /etc/init.d

I want to install a file in
/etc/init.d directory
I have written code
INSTALL(FILES ${CMAKE_SOURCE_DIR}/app/script/appd DESTINATION /etc/init.d/appd)
but when I run packing code using cmake I get error
CMake Error at /home/vivek/workspace/app/build/standalone/cmake_install.cmake:54 (FILE):
file cannot create directory: /etc/init.d/appd. Maybe need
administrative privileges.
How can I set cmake to install a file inside /etc/init.d directory ?
You can do this, but you may need to explicitly set:
set(CPACK_SET_DESTDIR ON)
prior to:
include(CPack)
in your CMakeLists.txt file. (You will need to do this only for older versions on CMake/CPack, prior to 2.8.3)
The reason you need to do this is that you are specifying a full path name as the DESTINATION of one of your installed files. In order to do that properly in the packing phase, CPack needs to use a DESTDIR environment variable in its "make install" call.
We didn't do this automatically by default for backwards compatibility reasons.
But then, this bug was fixed in version 2.8.3 so that it could be done transparently and automatically with install rules that use full path names:
http://public.kitware.com/Bug/view.php?id=7000
Hopefully, you can use either CPACK_SET_DESTDIR to ON for your rpm packages, OR use a more recent version of CMake/CPack that includes the automatic fix.
You can't. Only thing you can do is to ask user to run make install for your app with administrative priveleges.
Also, you can try detecting presense of sudo command and add_custom_command() which would install your files with sudo.