CMake fix_bundle how to ignore embedded dll - dll

My system has some dlls that are linked in other embedded executables, like commands from MSYS.
Directories structure:
MySystem/
|_ mysystem.exe
|_ CMakeLists.txt
|_ embedded system/
|_ msys_command1.exe
|_ msys_command2.exe
|_ msys-1.0.dll
When it is running fixup_bundle from CMake, this warning is showed:
EXEC : warning : cannot resolve item 'msys-1.0.dll'
possible problems:
need more directories?
need to use InstallRequiredSystemLibraries?
run in install tree instead of build tree?
EXEC : -- warning : gp_resolved_file_type non-absolute file 'msys-1.0.dll' returning type 'other' -- possibly incorrect
--
EXEC : warning : cannot resolve item 'msys-1.0.dll'
possible problems:
need more directories?
need to use InstallRequiredSystemLibraries?
run in install tree instead of build tree?
The MSYS commands are within the software embedded directory.
If I put the embedded directory on fixup_bundle paths, the dlls are copied to my executable directory, but I don't want that behavior.
Is there a way to ignore that dlls?
I've tried with fixup_bundle macro IGNORE_ITEM, but it didn't work.
Besides that, the problem propagates to CPack:
CPack: Create package using NSIS
CPack: Install projects
CPack: - Install project: MySystem
Error copying file "msys-1.0.dll" to "D:/mysystem/solution/build/_CPack_Packages/win64/NSIS/MySystem/msys-1.0.dll".
Error copying file "msys-intl-8.dll" to "D:/mysystem/solution/build/_CPack_Packages/win64/NSIS/MySystem/msys-intl-8.dll".
Error copying file "Qt5Core.dll" to "D:/mysystem/solution/build/_CPack_Packages/win64/NSIS/MySystem/Qt5Core.dll".
Error copying file "Qt5Gui.dll" to "D:/mysystem/solution/build/_CPack_Packages/win64/NSIS/MySystem/Qt5Gui.dll".
Error copying file "Qt5Network.dll" to "D:/mysystem/solution/build/_CPack_Packages/win64/NSIS/MySystem/Qt5Network.dll".
Error copying file "Qt5Widgets.dll" to "D:/mysystem/solution/build/_CPack_Packages/win64/NSIS/MySystem/Qt5Widgets.dll".
Error copying file "libprotobuf.dll" to "D:/mysystem/solution/build/_CPack_Packages/win64/NSIS/MySystem/libprotobuf.dll".
Error copying file "lua.dll" to "D:/mysystem/solution/build/_CPack_Packages/win64/NSIS/MySystem/lua.dll".
Error copying file "qwt.dll" to "D:/mysystem/solution/build/_CPack_Packages/win64/NSIS/MySystem/qwt.dll".
CPack: Create package

Not sure if this is what you need but I made a custom fixup_bundle function which also uses the IGNORE_ITEM key to skip libraries.
I call fixup_bundle2 as follows:
install(CODE "
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/dist/cmake)
include(InstallRequiredSystemLibraries)
include(BundleUtilities)
include(FixUp)
fixup_bundle2(\"\${CMAKE_INSTALL_PREFIX}/${APPS}\" \"${LIBS}\" \"${DIRS}\" IGNORE_ITEM \"exe_with_z64;exe_with_zip;libopenvr_api_so\")"
)
Note the set(CMAKE_MODULE_PATH... line which is there to include my own provided fixup_bundle2 from my FixUp.cmake file. Also note that I need to specify libopenvr_api_so while in reality it is libopenvr_api.so.
fixup_bundle2 is a copy of fixup_bundle with the following added in the foreach(key ${keys}) loop:
# also ignore libs in INGORE_ITEM
if(key IN_LIST CFG_IGNORE_ITEM)
message(STATUS "skipping ${key}")
continue()
endif()
You'll also need to set
cmake_policy(SET CMP0057 NEW)
in the FixUp.cmake file apparently.

Related

Install a target defined in an included directory [duplicate]

Consider the following CMakeLists.txt file:
add_subdirectory(execA)
add_subdirectory(libB)
install(TARGETS execA libB
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
I get the following error:
install TARGETS given target "execA" which does not exist in this
directory
execA and libB have their own CMakeList.txt files and are located under project directory, as well as the build directory I'm running cmake (cmake ..):
project
|------ CMakeList.txt (the one with the code)
|----execA
| \- .cpp, .hpp and CMakelist.txt
|----libB
| \- .cpp, .hpp and CMakelist.txt
|---- lib
|---- bin
\---- build (where I´m commanding: $ cmake ..
How do I fix this error?
According to this bugreport, install(TARGETS) command flow accepts only targets created within the same directory.
So you need either move the add_library() call into the top-level directory, or split install(TARGETS) call into per-target ones, and move each of them into the corresponding subdirectory.
Since CMake 3.13 install(TARGETS) can work even with targets created in other directories.
install(TARGETS) can install targets that were created in other directories. When using such cross-directory install rules, running make install (or similar) from a subdirectory will not guarantee that targets from other directories are up-to-date.
Even though it would help seeing the CMakeLists.txt files contained in the subdirectories, I guess they contain add_executable and/or add_library statements to create your stuff.
Also, because of your example, I guess you are using the same name of your directories for your targets.
That said, you should know that symbols defined in a CMakeLists.txt file in a subdirectory are not visible by default within the context of the CMakeLists.txt file in the parent directory. Because of that, you should rather move your install statements within the CMakeLists.txt files within your subdirectories.
This should solve the problem, if my thoughts were right. Otherwise, I strongly suggest you to post in your question also the content of the other files above mentioned.
Anyway, the error is quite clear.
The file that contains the install statement for the target named X does not contain a target creation statement (add_executable and the others) that gives birth to that target, so it goes on saying that that target does not exist in that directory.
This still seems to be a pain point in CMake 3.11.
In our codebase, we have many targets defined in subdirectories and need to create an assortment of installers with different configurations and (potentially overlapping) combinations of targets.
Here's my solution:
Before calling add_subdirectory in your root CMakeLists.txt file, create a GLOBAL property with the names of the target(s) you want to include in your installer.
Wrap target creation functions (add_executable, etc.) in your own custom functions. Within those functions check if the target is present in the global property, and invoke install accordingly.
That approach allows you to centralize installer configuration.
Also: To support creation of multiple installers, we populate our global list along with other installer properties in separate .cmake files. When we invoke cmake, we pass the name of the installer configuration CMake file as a command-line argument. Our root CMakeLists.txt file simply calls include with that file.

CMake does not compíle Qt5 generate from buildroot

I generate a tarball with Qt5 using Buildroot 2014.05.
When I uncompressed this files to compile my project using CMake I receive the following error message:
CMake Error at <project> /sysroot/usr/lib/cmake/Qt5Core/Qt5CoreConfig.cmake:27 (message):
The imported target "Qt5::Core" references the file
"<project>/host/usr/bin/qmake"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
"/<project>/sysroot/usr/lib/cmake/Qt5Core/Qt5CoreConfigExtras.cmake"
but not all the files it references.
I'm using the cmake configs under
<project>/sysroot/usr/lib/cmake/
and my CMakeLists.txt
set(CMAKE_PREFIX_PATH <project>/sysroot/usr/lib/cmake/QtWidgets/ )
find_package(Qt5Widgets REQUIRED)
Any suggestion?
Buildroot 2014.05 does not have qmake to install
This part: I generate a tarball with Qt5 using Buildroot does make much sense. What do you mean exactly by this ?
If by this you mean that you tarball'ed the contents of output/host/ (which is the toolchain and all the libraries that you need to build applications for your target), then beware that it is not relocatable. So it has to be installed in the same location as the one it was generated in. So for now, if you want to do this, you should set the BR2_HOST_DIR configuration option to something like /opt/<something>/, and then tarball that up and uncompress it on the other machines where you want to use the toolchain.
It's in our TODO-list to make this relocatable.

Install a custom file generated during compilation in CMake

I'd like to install a custom file which is generated during compilation of a CMake project:
In my project the file SampleDictionary_rdict.pcm is generated by a command from an external module during compilation, and I would like to have it copied to $CMAKE_INSTALL_PREFIX/lib with make install
The issue I'm running into is all the variants of install(...) I've tried require the file to exist before compilation.
The command from an external module that generates the file is:
ROOT_GENERATE_DICTIONARY(
SampleDictionary
...
)
This generates SampleDictionary_rdict.pcm in my build directory.
For example, if I try to add:
install(TARGETS SampleDictionary DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
to the end of my CMakeLists.txt I have the issue of the file not existing.
install(TARGETS ... is used to install targets built within the project. You want to install the file SampleDictionary_rdict.pcm so you need a variant for files: install(FILES ...

Running fixup_bundle for a specific target (PACKAGE)

I would like to incorporate external dlls when running CPACK without enumerating all of them (by explicitly calling INSTALL(FILE ...) )
Employing fixup_bundle it is possible to fixup all the executables in the install folder (CMAKE_INSTALL_PREFIX) by copying the required libraries.
INSTALL(CODE "
include(BundleUtilities)
fixup_bundle(\"${APPS}\" \"\" \"${DIRS}\")
" DESTINATION bin COMPONENT Runtime)
This code is executed when building the INSTALL target and will handle only elements present inside the folder CMAKE_INSTALL_PREFIX.
What I would like to do instead is to run fixup_bundle during the building of the PACKAGE target which is added by CPACK. in this way the install script generated will also include externa libraries.
Did anyone managed to do this?
The best solution I found so far do not rely on fixup_bundle but on listing all files that have to be installed for the runtime configuration (e.g. all dlls).
Given a target you can recover the associated runtime file and add it to the INSTALL project:
#get dll location
get_target_property(BIN_F ${target} LOCATION_${Configuration})
#copy to the bin folder
install(FILES ${BIN_F} DESTINATION ${destinationFolder}
CONFIGURATIONS ${Configuration}
COMPONENT Runtime)
You then can recurse over the target dependenices to perform the same two operations using
get_target_property(link_libs ${target} INTERFACE_LINK_LIBRARIES)

CMake cannot find custom module

I have found in library Poco under contrib a PocoConfig.cmake which I've copied under /cmake/Modules
I also added in my CMakeLists.txt:
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
Now I run under /Build/cmake ..
And I keep getting:
CMake Error at CMakeLists.txt:41 (find_package):
By not providing "FindPoco.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "Poco", but
CMake did not find one.
Could not find a package configuration file provided by "Poco" with any of
the following names:
PocoConfig.cmake
poco-config.cmake
Add the installation prefix of "Poco" to CMAKE_PREFIX_PATH or set
"Poco_DIR" to a directory containing one of the above files. If "Poco"
provides a separate development package or SDK, be sure it has been
installed.
Obviously CMake is not finding the module file. What am I doing wrong, how to explicitly point CMake to that module file?
The PocoConfig.cmake doesn't works with find_package (otherwise, it would be named FindPoco.cmake), that's why you're getting this error.
Just include the PocoConfig.cmake in your CMakeLists.txt with:
include(${CMAKE_SOURCE_DIR}/cmake/Modules/PocoConfig.cmake)
I've had similar issues. In my case I was recompiling with an old build folder in place - deleting the folder and recompiling worked.