empty default component name is displayed as 'Unspecified' - cmake

I'm trying to make two packages using cmake 2.8.12: the first one contains a shared library, the second one contains headers files. Apparently, I want two packages with names libname and libname-dev respectively, so I used command install with no specified component for the shared library and the same command with COMPONENT dev for the headers files. Before this I had defined an empty default component name. So I have a code as follows:
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "")
install(TARGETS libname DESTINATION /usr/local/lib)
install(FILES ${header_files} DESTINATION /usr/local/include COMPONENT dev)
But as a result, despite the empty default component name libname-Unspecified and libname-dev are generated. I find this behavior quite weird, because it seems I have no way to define two packages with previously described names. Are there any ideas how to do this in any other way?

In case of debian:
Give your main component some temporary name, e.g. "runtime".
install(TARGETS my-target
COMPONENT runtime
DESTINATION ${INSTALLDIR}
)
Then remove the postfixed component name as follows:
set(CPACK_DEBIAN_RUNTIME_PACKAGE_NAME "${CPACK_PACKAGE_NAME}")
Might work with other generators, too if they provide something equivalent to "CPACK_DEBIAN_RUNTIME_PACKAGE_NAME".

Related

Define CMake target that acts as intermediate abstraction layer for another

I have two projects sharing some code. Both have their own tools for generating almost the same boilerplate code, which are defined as a CMake target that runs everything when imported (or used as dependency). Let's assume that it is called generator_A in project A and generator_B in project B.
There are components that are shared "cloned" in both projects that use this boilerplate code, so for component_1 the CMakeLists.txt on each project would have something like:
# In project A
find_package(generator_A)
add_library(component_1 ...)
target_link_libraries(component_1 generator_A)
# In project B
find_package(generator_B)
add_library(component_1 ...)
target_link_libraries(component_1 generator_B)
Apart from this and other small differences regarding the generated code, component_1 would work in both projects.
I would like to define some intermediate layer for the generators on each project, so that its usage is independent of the project and look like:
find_package(generator_unified)
add_library(component_1 ...)
target_link_libraries(component_1 generator_unified)
For reasons not under my control, I cannot change anything about the generators (e.g. names, how they work, generated code/products).
I have no idea what is the best way to do this. Some ideas that I've found searching docs and the internet:
Create a Findgenerator_unified.cmake file that defines a generator_unified::generator_unified from the products of generator_X in project_X (library, headers, other properties?). I am not really how this can be achieved, though.
Does generator_unified needs its own CMakeLists.txt file, or is it enough with the Find<>.cmake.
How can I make sure that the Find<>.cmake file is available for others?
Create some kind of alias that can be used project-wide. This doesn't look possible according to docs .
Is this a better way to achieve this? If 1st alternative is the correct,
Something like this ought to work (your first alternative):
# Findgenerator_unified.cmake
cmake_minimum_required(VERSION 3.23)
if (${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY)
set(quiet QUIET)
else ()
set(quiet "")
endif ()
if (${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED)
set(required REQUIRED)
else ()
set(required "")
endif ()
set(known_backends generator_A generator_B)
set(GENERATOR_UNIFIED_BACKEND "generator_A"
CACHE STRING "Which generator backend package to use.")
set_property(CACHE GENERATOR_UNIFIED_BACKEND
PROPERTY STRINGS "${known_backends}")
foreach (backend IN LISTS known_backends)
if (backend IN_LIST ${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS)
set(GENERATOR_UNIFIED_BACKEND "${backend}")
endif ()
endforeach ()
if (GENERATOR_UNIFIED_BACKEND IN_LIST known_backends)
find_package("${GENERATOR_UNIFIED_BACKEND}" ${quiet} ${required})
set("${CMAKE_FIND_PACKAGE_NAME}_${GENERATOR_UNIFIED_BACKEND}_FOUND"
"${${GENERATOR_UNIFIED_BACKEND}_FOUND}")
endif ()
unset(known_backends)
unset(quiet)
unset(required)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
generator_unified
HANDLE_COMPONENTS
REQUIRED_VARS "${GENERATOR_UNIFIED_BACKEND}_FOUND"
VERSION_VAR "${GENERATOR_UNIFIED_BACKEND}_VERSION"
)
if (generator_unified_FOUND AND NOT TARGET generator::unified)
add_library(generator::unified ALIAS "${GENERATOR_UNIFIED_BACKEND}")
endif ()
This is mostly boilerplate, but the key is in the last few lines... the generator::unified target is set up as an alias to whichever backend was selected.
When a consuming project goes to install a target using this, they will need to generate code that forces the backend to be the same. The HANDLE_COMPONENTS flag naturally handles this because the component name matches the sub-package name. Users will write the following snippet in their project config files:
# proj-config.cmake.in
# ...
include(FindDependencyMacro)
find_dependency(generator_unified COMPONENTS #GENERATOR_UNIFIED_BACKEND#)
# ...

How to add a custom Module-Description Variable in Android.mk?

I want to access a module description variable (a custom variable) while building an android module i.e. an executable or shared-library or prebuilt and based on its value do some extra processing on the executable or shared-lib or prebuilt.
Is there a way to do it?
Add the variable to the list of variables in clear_vars.mk , so that they get cleared when an Android.mk does include $(CLEAR_VARS)

Can CPACK_INSTALL_CMAKE_PROJECTS be used for selective install?

For my application, I created 4 components, and want to 'install' only the applications and their docs. According to https://cmake.org/Wiki/CMake:CPackConfiguration, if in my config file I have the line
set(CPACK_INSTALL_CMAKE_PROJECTS "${CMAKE_CURRENT_BINARY_DIR};${CMAKE_PROJECT_NAME};ALL;/")
then all the four components are installed. If I use the component names instead like
set(CPACK_INSTALL_CMAKE_PROJECTS "${CMAKE_CURRENT_BINARY_DIR};${CMAKE_PROJECT_NAME};apps docs;/")
I receive a package with no component name appended, and it contains the top level requested directory but no files at all. If I provide only one component like
set(CPACK_INSTALL_CMAKE_PROJECTS "${CMAKE_CURRENT_BINARY_DIR};${CMAKE_PROJECT_NAME};apps;/")
the package name does not contain the name of the component, but the files are generated in their right position.
What do I wrong?
EDIT: Just to add more strange things:
For the ALL case 4 files with names install_manifest_+comp name are created. For the second case I have install_manifest_apps docs.txt of zero length, and for the third case I have install_manifest_apps.txt, with the right content.
It seems to me that the macro can only accept one argument which can be either ALL or a component name; this means it cannot be used to install a 2-component system.
Moreover: if I use a component name, make package only produces that one package, without appending the component name, but with the right content. Till now I guessed that make install and make package are independent.
Set multiple values to CPACK_INSTALL_CMAKE_PROJECTS, one for each component you want to include:
set( CPACK_INSTALL_CMAKE_PROJECTS
"${CMAKE_CURRENT_BINARY_DIR};${CMAKE_PROJECT_NAME};apps;/"
"${CMAKE_CURRENT_BINARY_DIR};${CMAKE_PROJECT_NAME};docs;/"
)

2 merge modules have same file name in wix

I have several existing merge modules and one created by me. Lets call my module as 'A'. My merge modules and one existing merge module(say B) contains a file with the same name(customUI.resources) but with different content.
I am making an installer which uses both modules A & B. I want to use the customUI.resources file from module 'A'. When i compile the installer.wix file, it gives me the error as:
light.exe : error LGHT0204 : ICE30: The target file 'va2q4hvb.res|CustomUI.resources' is installed in '[ProgramFilesFolder]\abc\' by two different components on an LFN system: '_5AD14D2401C1408A8B1117B8B85F53E3.7C263653_7A00_4D9C_B52A_39AF1892BC49' and 'Adapter_Config_ja.BABCE01A_0CB9_4A62_B877_5E520A53D609'.
This breaks component reference counting. How can i resolve this error?
Are you in control of authoring module a and b?
If so, author the files as 2 different filenames and use the CopyFile element ( DuplicateFile table ) to duplicate the specific name to the common desired name. Also put mutually exclusive conditions on the components to make sure only one or the other gets installed.
Then in your main installer set a property to decide which one gets installed. The result will pass all ICE validation tests and give you the desired behavior.
You could use Dark to decompile the merge modules and then either combine them to a single module or re-create merge module B without the conflicting file.

Name the root directory of project generated with Maven Archetype

How can I control the name of the top directory of the maven module created by my maven archetype? Currently it creates a new folder named$artifactId. Or even more directly, is there a way that my archetype can create a folder named after the module's artifactId, but with dashes replaced by underscores?
The naming convention for artifactId's is to use dashes (hyphens). I don't think there is any way to make the module's directory named something other than the artifactId. That being said, it is onlvy convention, not a requirement, that your module be named the same as your artifactId. This means that after your project is generated, you could simply change either the artifactId or module folder name or both to whatever you want.
You can rename root folder by making an archetype-post-generate groovy script like :
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
Path projectPath = Paths.get(request.outputDirectory, request.artifactId)
// RENAME ROOT FOLDER INCLUDING A PREFIX FOR EXAMPLE
Files.move(projectPath, projectPath.resolveSibling("prefix-" + projectPath.toFile().getName()))
I got round this by adding a second required property to the archetype, and then using that in place of artifactId within the generated pom etc.
In archtype-metadata.xml:
<requiredProperties>
...
<requiredProperty key="projectCode"/>
</requiredProperties>
In pom.xml (and other substitutions):
<artifactId>${projectCode}</artifactId>
So the folder gets the name supplied for artifactId, but in the pom it is given the name supplied for projectCode.
Unfortunately you don't seem to be able to supply a default value for artifactId within archtype-metadata.xml (I always want the folder name to be the same).