xref: /reactos/sdk/cmake/host-tools.cmake (revision 144e984b)
1
2include(ExternalProject)
3
4function(setup_host_tools)
5    list(APPEND HOST_TOOLS asmpp bin2c widl gendib cabman fatten hpp isohybrid mkhive mkisofs obj2bin spec2def geninc mkshelllink txt2nls utf16le xml2sdb)
6    if(NOT MSVC)
7        list(APPEND HOST_TOOLS rsym pefixup)
8    endif()
9    if ((ARCH STREQUAL "amd64") AND (CMAKE_C_COMPILER_ID STREQUAL "GNU"))
10        execute_process(
11            COMMAND ${CMAKE_C_COMPILER} --print-file-name=plugin
12            OUTPUT_VARIABLE GCC_PLUGIN_DIR)
13        string(STRIP ${GCC_PLUGIN_DIR} GCC_PLUGIN_DIR)
14        list(APPEND CMAKE_HOST_TOOLS_EXTRA_ARGS -DGCC_PLUGIN_DIR=${GCC_PLUGIN_DIR})
15        list(APPEND HOST_MODULES gcc_plugin_seh)
16        if (CMAKE_HOST_WIN32)
17            list(APPEND HOST_MODULES g++_plugin_seh)
18        endif()
19    endif()
20    list(TRANSFORM HOST_TOOLS PREPEND "${REACTOS_BINARY_DIR}/host-tools/bin/" OUTPUT_VARIABLE HOST_TOOLS_OUTPUT)
21    if (CMAKE_HOST_WIN32)
22        list(TRANSFORM HOST_TOOLS_OUTPUT APPEND ".exe")
23        if(MSVC_IDE)
24            set(HOST_EXTRA_DIR "$(ConfigurationName)/")
25        endif()
26        set(HOST_EXE_SUFFIX ".exe")
27        set(HOST_MODULE_SUFFIX ".dll")
28    else()
29        set(HOST_MODULE_SUFFIX ".so")
30    endif()
31
32    # Normalize to the same format as our own ARCH, and add one for the VC shell
33    string(TOLOWER "${CMAKE_HOST_SYSTEM_PROCESSOR}" lowercase_CMAKE_HOST_SYSTEM_PROCESSOR)
34    if(lowercase_CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL x86 OR lowercase_CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "^i[3456]86$")
35        set(HOST_ARCH i386)
36        set(VCVARSALL_ARCH x86)
37    elseif(lowercase_CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL x86_64 OR lowercase_CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL amd64)
38        set(HOST_ARCH amd64)
39        set(VCVARSALL_ARCH amd64_x86) # x64 host-tools are not happy compiling for x86...
40    elseif(lowercase_CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL arm)
41        set(HOST_ARCH arm)
42        set(VCVARSALL_ARCH arm)
43    # 'aarch64' is used in GNU tools instead of 'arm64'
44    elseif(lowercase_CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL arm64 OR lowercase_CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL aarch64)
45        set(HOST_ARCH arm64)
46        set(VCVARSALL_ARCH arm64)
47    else()
48        message(FATAL_ERROR "Unknown host architecture: ${lowercase_CMAKE_HOST_SYSTEM_PROCESSOR}")
49    endif()
50
51    if(ARCH STREQUAL HOST_ARCH)
52        set(HOST_TOOLS_CMAKE_COMMAND "${CMAKE_COMMAND}")
53        message("Not cross-compiling, no special host-tools cmake command")
54    elseif(MSVC)
55        message("Compiling on ${HOST_ARCH} for ${ARCH} (MSVC)")
56        set(HOST_TOOLS_CMAKE_COMMAND "${REACTOS_BINARY_DIR}/host-tools/cmake_shim.cmd")
57        if(MSVC_VERSION EQUAL 1900)
58            file(WRITE ${HOST_TOOLS_CMAKE_COMMAND}
59                "set VSCMD_SKIP_SENDTELEMETRY=1\n"
60                "@call \"$ENV{VCINSTALLDIR}\\vcvarsall.bat\" ${VCVARSALL_ARCH}\n"
61                "\"${CMAKE_COMMAND}\" %*"
62            )
63        elseif(MSVC_VERSION GREATER_EQUAL 1910)
64            # 2017 and 2019 use the same folder structure
65            file(WRITE ${HOST_TOOLS_CMAKE_COMMAND}
66                "@set VSCMD_ARG_no_logo=1\n"
67                "@call \"$ENV{VCINSTALLDIR}\\Auxiliary\\Build\\vcvarsall.bat\" /clean_env\n"
68                "@call \"$ENV{VCINSTALLDIR}\\Auxiliary\\Build\\vcvarsall.bat\" ${VCVARSALL_ARCH}\n"
69                "\"${CMAKE_COMMAND}\" %*"
70            )
71        else()
72            message(FATAL "Unable to figure out vcvarsall path")
73        endif()
74    else()
75        set(HOST_TOOLS_CMAKE_COMMAND "${CMAKE_COMMAND}")
76        message("Cross-compiling on non-msvc, no special host-tools cmake command")
77    endif()
78
79    # CMake might choose clang if it finds it in the PATH. Always prefer cl for host tools
80    if (MSVC)
81        list(APPEND CMAKE_HOST_TOOLS_EXTRA_ARGS
82            -DCMAKE_C_COMPILER=cl
83            -DCMAKE_CXX_COMPILER=cl)
84    endif()
85
86    if (MSVC_IDE)
87        # Required for Bison/Flex wrappers created by /CMakeLists.txt.
88        list(APPEND CMAKE_HOST_TOOLS_EXTRA_ARGS
89            -DROS_SAVED_BISON_PKGDATADIR=${ROS_SAVED_BISON_PKGDATADIR}
90            -DROS_SAVED_M4=${ROS_SAVED_M4}
91            )
92    endif()
93
94    ExternalProject_Add(host-tools
95        SOURCE_DIR ${REACTOS_SOURCE_DIR}
96        PREFIX ${REACTOS_BINARY_DIR}/host-tools
97        BINARY_DIR ${REACTOS_BINARY_DIR}/host-tools/bin
98        CMAKE_COMMAND ${HOST_TOOLS_CMAKE_COMMAND}
99        CMAKE_ARGS
100            -UCMAKE_TOOLCHAIN_FILE
101            -DARCH:STRING=${ARCH}
102            -DCMAKE_INSTALL_PREFIX=${REACTOS_BINARY_DIR}/host-tools
103            -DTOOLS_FOLDER=${REACTOS_BINARY_DIR}/host-tools/bin
104            -DTARGET_COMPILER_ID=${CMAKE_C_COMPILER_ID}
105            ${CMAKE_HOST_TOOLS_EXTRA_ARGS}
106        BUILD_ALWAYS TRUE
107        INSTALL_COMMAND ${CMAKE_COMMAND} -E true
108        BUILD_BYPRODUCTS ${HOST_TOOLS_OUTPUT}
109    )
110
111    ExternalProject_Get_Property(host-tools INSTALL_DIR)
112
113    foreach(_tool ${HOST_TOOLS})
114        add_executable(native-${_tool} IMPORTED)
115        set_target_properties(native-${_tool} PROPERTIES IMPORTED_LOCATION ${INSTALL_DIR}/bin/${HOST_EXTRA_DIR}${_tool}${HOST_EXE_SUFFIX})
116        add_dependencies(native-${_tool} host-tools ${INSTALL_DIR}/bin/${HOST_EXTRA_DIR}${_tool}${HOST_EXE_SUFFIX})
117    endforeach()
118
119    foreach(_module ${HOST_MODULES})
120        add_library(native-${_module} MODULE IMPORTED)
121        set_target_properties(native-${_module} PROPERTIES IMPORTED_LOCATION ${INSTALL_DIR}/bin/${HOST_EXTRA_DIR}${_module}${HOST_MODULE_SUFFIX})
122        add_dependencies(native-${_module} host-tools ${INSTALL_DIR}/bin/${HOST_EXTRA_DIR}${_module}${HOST_MODULE_SUFFIX})
123    endforeach()
124endfunction()
125