0

I am learning CMake by CMake Tutorial. When I learn Step 9: Packaging an Installer, I meet some question. When use cpack -G WIX -C Debug command in the Windows, the error as title descripted will appear. This is some part of my CMakeLists.txt file:

cmake_minimum_required(VERSION 3.2)
project(Tutorial)

set(Tutorial_VERSION_MAJOR 1)
set(Tutorial_VERSION_MINOR 0)

option(USE_MYMATH
        "Use tutorial provide math implementation" ON)       

configure_file(${PROJECT_SOURCE_DIR}/TutorialConfig.h.in
                ${PROJECT_BINARY_DIR}/TutorialConfig.h)
                
include_directories(${PROJECT_BINARY_DIR})

if(USE_MYMATH)
    include_directories(${PROJECT_SOURCE_DIR}/MathFunctions)
    add_subdirectory(MathFunctions)
    set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif()



add_executable(Tutorial tutorial.cpp)
target_link_libraries(Tutorial ${EXTRA_LIBS})

install (TARGETS Tutorial DESTINATION ${PROJECT_SOURCE_DIR}/install/bin)
install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
         DESTINATION ${PROJECT_SOURCE_DIR}/install/include)

include(CTest)
add_test (TutorialRuns Tutorial 25)

# does it sqrt of 25
add_test (TutorialComp25 Tutorial 25)
set_tests_properties (TutorialComp25 PROPERTIES PASS_REGULAR_EXPRESSION "25 is 5")

# does it handle negative numbers
add_test (TutorialNegative Tutorial -25)
set_tests_properties (TutorialNegative PROPERTIES PASS_REGULAR_EXPRESSION "-25 is 0")

# does it handle small numbers
add_test (TutorialSmall Tutorial 0.0001)
set_tests_properties (TutorialSmall PROPERTIES PASS_REGULAR_EXPRESSION "0.0001 is 0.01")

# does the usage message work?
add_test (TutorialUsage Tutorial)
set_tests_properties (TutorialUsage PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number")


# macro (do_test arg result)
#   add_test (TutorialComp${arg} Tutorial ${arg})
#   set_tests_properties (TutorialComp${arg}
#     PROPERTIES PASS_REGULAR_EXPRESSION ${result})
# endmacro (do_test)

# # do a bunch of result based tests
# do_test (25 "25 is 5")
# do_test (-25 "-25 is 0")


# function(do_test target arg result)
#   add_test(NAME Comp${arg} COMMAND ${target} ${arg})
#   set_tests_properties(Comp${arg}
#     PROPERTIES PASS_REGULAR_EXPRESSION ${result}
#     )
# endfunction()

# # do a bunch of result based tests
# do_test(Tutorial 4 "4 is 2")
# do_test(Tutorial 9 "9 is 3")
# do_test(Tutorial 5 "5 is 2.236")
# do_test(Tutorial 7 "7 is 2.645")
# do_test(Tutorial 25 "25 is 5")
# do_test(Tutorial -25 "-25 is (-nan|nan|0)")
# do_test(Tutorial 0.0001 "0.0001 is 0.01")

include (InstallRequiredSystemLibraries)
set (CPACK_RESOURCE_FILE_LICENSE
     "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set (CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
set (CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
include (CPack)

How should I modify my CMakeLists.txt?

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
TimeGo
  • 36
  • 3
  • [CPack NSIS, generate installer for Windows](https://stackoverflow.com/questions/23613624/cpack-nsis-generate-installer-for-windows),it does not work. – TimeGo Aug 11 '23 at 08:07
  • "it does not work" is a bad description of the attempt. Which answer from the related question have you tried? How exactly have you tried it? The [other answer](https://stackoverflow.com/a/26697362/3440745) tells to not use absolute paths at all, have you tried it? – Tsyvarev Aug 13 '23 at 13:44

1 Answers1

0

You should specify relative paths for every install destination instead of absolute paths and use the following variables to specify appropriate defaults, for different scenarios:

Note that in the scenario you described you most likely want to use the first variant instead of generating a installer; at least you almost certainly don't want to hardcode the project source directory as the install location.

Using relative paths has the added benefit of making cmake --install ... --prefix ... work properly.

...

# my preference is to specify locations files end up in
# by setting the following variables in the toplevel CMakeLists.txt

# these should be the default values, but we'll set it nonetheless
set(CMAKE_INSTALL_BINDIR bin)
set(CMAKE_INSTALL_LIBDIR lib)
set(CMAKE_INSTALL_INCLUDEDIR include)
...

# these values influence the default install behaviour and should
# be set in the toplevel CMakeLists.txt

if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
    set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/install CACHE PATH "The directory to install to locally by default" FORCE)
endif()
...
# this should be set before include(CPack)
set(CPACK_PACKAGING_INSTALL_PREFIX "C:/Program Files/MyOrg/MyPackage") # needs to be changed for non-windows platforms

...

install (TARGETS Tutorial) # we don't need to specify a destination here, if we're using the default one
# install(TARGETS Tutorial RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
         TYPE INCLUDE) # we can also just specify the type to install to CMAKE_INSTALL_INCLUDEDIR instead of using `DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}`

Note: The way you usually do a local installation (assuming you don't need registry entries, ect.) is using

cmake --install build_dir --config Debug

to install the files to the directory specified via CMAKE_INSTALL_PREFIX, or

cmake --install build_dir --config Debug --prefix alternative_destination

to override the install prefix and install below the alternative_destination directory; this path can be relative to the current working directory.

fabian
  • 80,457
  • 12
  • 86
  • 114