4 Build a msvc makefile project.
9 SOURCE_PATH <${SOURCE_PATH}>
12 [PROJECT_SUBPATH <${SUBPATH}>]
13 [PROJECT_NAME <${MAKEFILE_NAME}>]
14 [PRERUN_SHELL <${SHELL_PATH}>]
15 [PRERUN_SHELL_DEBUG <${SHELL_PATH}>]
16 [PRERUN_SHELL_RELEASE <${SHELL_PATH}>]
17 [OPTIONS <-DUSE_THIS_IN_ALL_BUILDS=1>...]
18 [OPTIONS_RELEASE <-DOPTIMIZE=1>...]
19 [OPTIONS_DEBUG <-DDEBUGGABLE=1>...]
25 Specifies the directory containing the source files.
26 By convention, this is usually set in the portfile as the variable `SOURCE_PATH`.
29 Specifies the sub directory containing the `makefile.vc`/`makefile.mak`/`makefile.msvc` or other msvc makefile.
32 Specifies the name of msvc makefile name.
33 Default is `makefile.vc`
36 This port doesn't support debug mode.
39 Install binaries after build.
42 Script that needs to be called before build
44 ### PRERUN_SHELL_DEBUG
45 Script that needs to be called before debug build
47 ### PRERUN_SHELL_RELEASE
48 Script that needs to be called before release build
51 Additional options passed to generate during the generation.
54 Additional options passed to generate during the Release generation. These are in addition to `OPTIONS`.
57 Additional options passed to generate during the Debug generation. These are in addition to `OPTIONS`.
60 The target passed to the nmake build command (`nmake/nmake install`). If not specified, no target will
64 Adds the appropriate Release and Debug `bin\` directories to the path during the build such that executables can run against the in-tree DLLs.
67 This command should be preceded by a call to [`vcpkg_configure_nmake()`](vcpkg_configure_nmake.md).
68 You can use the alias [`vcpkg_install_nmake()`](vcpkg_install_nmake.md) function if your makefile supports the
73 * [tcl](https://github.com/Microsoft/vcpkg/blob/master/ports/tcl/portfile.cmake)
74 * [freexl](https://github.com/Microsoft/vcpkg/blob/master/ports/freexl/portfile.cmake)
77 function(vcpkg_build_nmake)
78 # parse parameters such that semicolons in options arguments to COMMAND don't get erased
79 cmake_parse_arguments(PARSE_ARGV 0 _bn
80 "ADD_BIN_TO_PATH;ENABLE_INSTALL;NO_DEBUG"
81 "SOURCE_PATH;PROJECT_SUBPATH;PROJECT_NAME;LOGFILE_ROOT"
82 "OPTIONS;OPTIONS_RELEASE;OPTIONS_DEBUG;PRERUN_SHELL;PRERUN_SHELL_DEBUG;PRERUN_SHELL_RELEASE;TARGET"
85 if (NOT CMAKE_HOST_WIN32)
86 message(FATAL_ERROR "vcpkg_build_nmake only support windows.")
89 if (_bn_OPTIONS_DEBUG STREQUAL _bn_OPTIONS_RELEASE)
90 message(FATAL_ERROR "Detected debug configuration is equal to release configuration, please use NO_DEBUG for vcpkg_build_nmake/vcpkg_install_nmake")
93 if(NOT _bn_LOGFILE_ROOT)
94 set(_bn_LOGFILE_ROOT "build")
97 if (NOT _bn_PROJECT_NAME)
98 set(MAKEFILE_NAME makefile.vc)
100 set(MAKEFILE_NAME ${_bn_PROJECT_NAME})
106 find_program(NMAKE nmake REQUIRED)
107 get_filename_component(NMAKE_EXE_PATH ${NMAKE} DIRECTORY)
109 if(NOT VCPKG_CHAINLOAD_TOOLCHAIN_FILE)
110 set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE "${SCRIPTS}/toolchains/windows.cmake")
112 include("${VCPKG_CHAINLOAD_TOOLCHAIN_FILE}")
114 set(ENV{PATH} "$ENV{PATH};${NMAKE_EXE_PATH}")
115 set(ENV{INCLUDE} "${CURRENT_INSTALLED_DIR}/include;$ENV{INCLUDE}")
116 # Set make command and install command
117 set(MAKE ${NMAKE} /NOLOGO /G /U)
118 set(MAKE_OPTS_BASE -f ${MAKEFILE_NAME})
119 if (_bn_ENABLE_INSTALL)
120 set(INSTALL_COMMAND install)
123 set(MAKE_OPTS_BASE ${MAKE_OPTS_BASE} ${_bn_TARGET} ${INSTALL_COMMAND})
125 set(MAKE_OPTS_BASE ${MAKE_OPTS_BASE} all ${INSTALL_COMMAND})
127 # Add subpath to work directory
128 if (_bn_PROJECT_SUBPATH)
129 set(_bn_PROJECT_SUBPATH /${_bn_PROJECT_SUBPATH})
131 set(_bn_PROJECT_SUBPATH )
134 foreach(BUILDTYPE "debug" "release")
135 if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL BUILDTYPE)
136 if(BUILDTYPE STREQUAL "debug")
137 # Skip debug generate
141 # Generate obj dir suffix
142 set(SHORT_BUILDTYPE "-dbg")
144 # Add install command and arguments
145 set(MAKE_OPTS ${MAKE_OPTS_BASE})
146 if (_bn_ENABLE_INSTALL)
147 set(INSTALL_OPTS INSTALLDIR=${CURRENT_PACKAGES_DIR}/debug)
148 set(MAKE_OPTS ${MAKE_OPTS} ${INSTALL_OPTS})
150 set(MAKE_OPTS ${MAKE_OPTS} ${_bn_OPTIONS} ${_bn_OPTIONS_DEBUG})
153 set(TMP_CL_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG}")
154 string(REPLACE "/" "-" TMP_CL_FLAGS "${TMP_CL_FLAGS}")
155 set(ENV{CL} "$ENV{CL} ${TMP_CL_FLAGS}")
157 # In NO_DEBUG mode, we only use ${TARGET_TRIPLET} directory.
159 set(SHORT_BUILDTYPE "")
161 set(SHORT_BUILDTYPE "-rel")
163 set(CONFIG "Release")
164 # Add install command and arguments
165 set(MAKE_OPTS ${MAKE_OPTS_BASE})
166 if (_bn_ENABLE_INSTALL)
167 set(INSTALL_OPTS INSTALLDIR=${CURRENT_PACKAGES_DIR})
168 set(MAKE_OPTS ${MAKE_OPTS} ${INSTALL_OPTS})
170 set(MAKE_OPTS ${MAKE_OPTS} ${_bn_OPTIONS} ${_bn_OPTIONS_RELEASE})
173 set(TMP_CL_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}")
174 string(REPLACE "/" "-" TMP_CL_FLAGS "${TMP_CL_FLAGS}")
175 set(ENV{CL} "$ENV{CL} ${TMP_CL_FLAGS}")
178 set(CURRENT_TRIPLET_NAME ${TARGET_TRIPLET}${SHORT_BUILDTYPE})
179 set(OBJ_DIR ${CURRENT_BUILDTREES_DIR}/${CURRENT_TRIPLET_NAME})
181 file(REMOVE_RECURSE ${OBJ_DIR})
182 file(MAKE_DIRECTORY ${OBJ_DIR})
183 file(GLOB_RECURSE SOURCE_FILES ${_bn_SOURCE_PATH}/*)
184 foreach(ONE_SOUCRCE_FILE ${SOURCE_FILES})
185 get_filename_component(DST_DIR ${ONE_SOUCRCE_FILE} PATH)
186 string(REPLACE "${_bn_SOURCE_PATH}" "${OBJ_DIR}" DST_DIR "${DST_DIR}")
187 file(COPY ${ONE_SOUCRCE_FILE} DESTINATION ${DST_DIR})
190 if (_bn_PRERUN_SHELL)
191 message(STATUS "Prerunning ${CURRENT_TRIPLET_NAME}")
192 vcpkg_execute_required_process(
193 COMMAND ${_bn_PRERUN_SHELL}
194 WORKING_DIRECTORY ${OBJ_DIR}${_bn_PROJECT_SUBPATH}
195 LOGNAME "$prerun-${CURRENT_TRIPLET_NAME}"
198 if (BUILDTYPE STREQUAL "debug" AND _bn_PRERUN_SHELL_DEBUG)
199 message(STATUS "Prerunning ${CURRENT_TRIPLET_NAME}")
200 vcpkg_execute_required_process(
201 COMMAND ${_bn_PRERUN_SHELL_DEBUG}
202 WORKING_DIRECTORY ${OBJ_DIR}${_bn_PROJECT_SUBPATH}
203 LOGNAME "prerun-${CURRENT_TRIPLET_NAME}-dbg"
206 if (BUILDTYPE STREQUAL "release" AND _bn_PRERUN_SHELL_RELEASE)
207 message(STATUS "Prerunning ${CURRENT_TRIPLET_NAME}")
208 vcpkg_execute_required_process(
209 COMMAND ${_bn_PRERUN_SHELL_RELEASE}
210 WORKING_DIRECTORY ${OBJ_DIR}${_bn_PROJECT_SUBPATH}
211 LOGNAME "prerun-${CURRENT_TRIPLET_NAME}-rel"
215 if (NOT _bn_ENABLE_INSTALL)
216 message(STATUS "Building ${CURRENT_TRIPLET_NAME}")
218 message(STATUS "Building and installing ${CURRENT_TRIPLET_NAME}")
221 vcpkg_execute_build_process(
222 COMMAND ${MAKE} ${MAKE_OPTS}
223 WORKING_DIRECTORY ${OBJ_DIR}${_bn_PROJECT_SUBPATH}
224 LOGNAME "${_bn_LOGFILE_ROOT}-${CURRENT_TRIPLET_NAME}"
227 if(_bn_ADD_BIN_TO_PATH)
228 set(ENV{PATH} "${_BACKUP_ENV_PATH}")