Skip to content

Commit f7adba4

Browse files
SibiSiddharthangitster
authored andcommitted
cmake: support for building git on windows with mingw
This patch facilitates building git on Windows with CMake using MinGW NOTE: The funtions unsetenv and hstrerror are not checked in Windows builds. Reasons NO_UNSETENV is not compatible with Windows builds. lines 262-264 compat/mingw.h compat/mingw.h(line 25) provides a definition of hstrerror which conflicts with the definition provided in git-compat-util.h(lines 733-736). To use CMake on Windows with MinGW do this: cmake `relative-path-to-srcdir` -G "MinGW Makefiles" Signed-off-by: Sibi Siddharthan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7f5397a commit f7adba4

File tree

1 file changed

+94
-23
lines changed

1 file changed

+94
-23
lines changed

contrib/buildsystems/CMakeLists.txt

Lines changed: 94 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ cmake_minimum_required(VERSION 3.14)
4242
set(CMAKE_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
4343

4444
find_program(SH_EXE sh)
45+
if(NOT SH_EXE)
46+
message(FATAL_ERROR "sh: shell interpreter was not found in your path, please install one."
47+
"On Windows, you can get it as part of 'Git for Windows' install at https://gitforwindows.org/")
48+
endif()
4549

4650
#Create GIT-VERSION-FILE using GIT-VERSION-GEN
4751
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/GIT-VERSION-FILE)
@@ -65,7 +69,9 @@ project(git
6569
VERSION ${git_version}
6670
LANGUAGES C)
6771

72+
6873
#TODO gitk git-gui gitweb
74+
#TODO Enable NLS on windows natively
6975
#TODO Add pcre support
7076

7177
#macros for parsing the Makefile for sources and scripts
@@ -104,6 +110,7 @@ find_package(EXPAT)
104110
find_package(Iconv)
105111
find_package(Intl)
106112

113+
107114
if(NOT Intl_FOUND)
108115
add_compile_definitions(NO_GETTEXT)
109116
if(NOT Iconv_FOUND)
@@ -125,6 +132,14 @@ if(Intl_FOUND)
125132
include_directories(SYSTEM ${Intl_INCLUDE_DIRS})
126133
endif()
127134

135+
136+
if(WIN32)
137+
find_program(WINDRES_EXE windres)
138+
if(NOT WINDRES_EXE)
139+
message(FATAL_ERROR "Install windres on Windows for resource files")
140+
endif()
141+
endif()
142+
128143
find_program(MSGFMT_EXE msgfmt)
129144
if(NOT MSGFMT_EXE)
130145
message(WARNING "Text Translations won't be build")
@@ -156,11 +171,35 @@ add_compile_definitions(PAGER_ENV="LESS=FRX LV=-c"
156171
BINDIR="bin"
157172
GIT_BUILT_FROM_COMMIT="")
158173

159-
set(FALLBACK_RUNTIME_PREFIX /home/$ENV{USER})
160-
add_compile_definitions(FALLBACK_RUNTIME_PREFIX="${FALLBACK_RUNTIME_PREFIX}")
174+
if(WIN32)
175+
set(FALLBACK_RUNTIME_PREFIX /mingw64)
176+
add_compile_definitions(FALLBACK_RUNTIME_PREFIX="${FALLBACK_RUNTIME_PREFIX}")
177+
else()
178+
set(FALLBACK_RUNTIME_PREFIX /home/$ENV{USER})
179+
add_compile_definitions(FALLBACK_RUNTIME_PREFIX="${FALLBACK_RUNTIME_PREFIX}")
180+
endif()
181+
182+
183+
#Platform Specific
184+
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
185+
include_directories(${CMAKE_SOURCE_DIR}/compat/win32)
186+
add_compile_definitions(HAVE_ALLOCA_H NO_POSIX_GOODIES NATIVE_CRLF NO_UNIX_SOCKETS WIN32
187+
_CONSOLE DETECT_MSYS_TTY STRIP_EXTENSION=".exe" NO_SYMLINK_HEAD UNRELIABLE_FSTAT
188+
NOGDI OBJECT_CREATION_MODE=1 __USE_MINGW_ANSI_STDIO=0
189+
USE_NED_ALLOCATOR OVERRIDE_STRDUP MMAP_PREVENTS_DELETE USE_WIN32_MMAP
190+
UNICODE _UNICODE HAVE_WPGMPTR ENSURE_MSYSTEM_IS_SET)
191+
list(APPEND compat_SOURCES compat/mingw.c compat/winansi.c compat/win32/path-utils.c
192+
compat/win32/pthread.c compat/win32mmap.c compat/win32/syslog.c
193+
compat/win32/trace2_win32_process_info.c compat/win32/dirent.c
194+
compat/nedmalloc/nedmalloc.c compat/strdup.c)
195+
set(NO_UNIX_SOCKETS 1)
196+
197+
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
198+
add_compile_definitions(PROCFS_EXECUTABLE_PATH="/proc/self/exe" HAVE_DEV_TTY )
199+
list(APPEND compat_SOURCES unix-socket.c)
200+
endif()
161201

162-
add_compile_definitions(PROCFS_EXECUTABLE_PATH="/proc/self/exe" HAVE_DEV_TTY )
163-
list(APPEND compat_SOURCES unix-socket.c)
202+
set(EXE_EXTENSION ${CMAKE_EXECUTABLE_SUFFIX})
164203

165204
#header checks
166205
check_include_file(libgen.h HAVE_LIBGEN_H)
@@ -223,7 +262,12 @@ endif()
223262
#function checks
224263
set(function_checks
225264
strcasestr memmem strlcpy strtoimax strtoumax strtoull
226-
setenv mkdtemp poll pread memmem unsetenv hstrerror)
265+
setenv mkdtemp poll pread memmem)
266+
267+
#unsetenv,hstrerror are incompatible with windows build
268+
if(NOT WIN32)
269+
list(APPEND function_checks unsetenv hstrerror)
270+
endif()
227271

228272
foreach(f ${function_checks})
229273
string(TOUPPER ${f} uf)
@@ -444,7 +488,13 @@ unset(CMAKE_REQUIRED_INCLUDES)
444488
#programs
445489
set(PROGRAMS_BUILT
446490
git git-bugreport git-credential-store git-daemon git-fast-import git-http-backend git-sh-i18n--envsubst
447-
git-shell git-remote-testsvn git-credential-cache git-credential-cache--daemon)
491+
git-shell git-remote-testsvn)
492+
493+
if(NO_UNIX_SOCKETS)
494+
list(APPEND excluded_progs git-credential-cache git-credential-cache--daemon)
495+
else()
496+
list(APPEND PROGRAMS_BUILT git-credential-cache git-credential-cache--daemon)
497+
endif()
448498

449499
if(NOT CURL_FOUND)
450500
list(APPEND excluded_progs git-http-fetch git-http-push)
@@ -516,15 +566,34 @@ parse_makefile_for_sources(libvcs-svn_SOURCES "VCSSVN_OBJS")
516566
list(TRANSFORM libvcs-svn_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/")
517567
add_library(vcs-svn STATIC ${libvcs-svn_SOURCES})
518568

569+
#add git.rc for gcc
570+
if(WIN32)
571+
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/git.res
572+
COMMAND ${WINDRES_EXE} -O coff -DMAJOR=${PROJECT_VERSION_MAJOR} -DMINOR=${PROJECT_VERSION_MINOR}
573+
-DMICRO=${PROJECT_VERSION_PATCH} -DPATCHLEVEL=0 -DGIT_VERSION="\\\"${PROJECT_VERSION}.GIT\\\""
574+
-i ${CMAKE_SOURCE_DIR}/git.rc -o ${CMAKE_BINARY_DIR}/git.res
575+
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
576+
VERBATIM)
577+
add_custom_target(git-rc DEPENDS ${CMAKE_BINARY_DIR}/git.res)
578+
endif()
579+
519580
#link all required libraries to common-main
520581
add_library(common-main OBJECT ${CMAKE_SOURCE_DIR}/common-main.c)
521-
target_link_libraries(common-main libgit xdiff ${ZLIB_LIBRARIES} pthread rt)
582+
583+
target_link_libraries(common-main libgit xdiff ${ZLIB_LIBRARIES})
522584
if(Intl_FOUND)
523585
target_link_libraries(common-main ${Intl_LIBRARIES})
524586
endif()
525587
if(Iconv_FOUND)
526588
target_link_libraries(common-main ${Iconv_LIBRARIES})
527589
endif()
590+
if(WIN32)
591+
target_link_libraries(common-main ws2_32 ntdll ${CMAKE_BINARY_DIR}/git.res)
592+
add_dependencies(common-main git-rc)
593+
target_link_options(common-main PUBLIC -municode -Wl,--nxcompat -Wl,--dynamicbase -Wl,--pic-executable,-e,mainCRTStartup)
594+
elseif(UNIX)
595+
target_link_libraries(common-main pthread rt)
596+
endif()
528597

529598
#git
530599
parse_makefile_for_sources(git_SOURCES "BUILTIN_OBJS")
@@ -575,11 +644,13 @@ endif()
575644
add_executable(git-remote-testsvn ${CMAKE_SOURCE_DIR}/remote-testsvn.c)
576645
target_link_libraries(git-remote-testsvn common-main vcs-svn)
577646

578-
add_executable(git-credential-cache ${CMAKE_SOURCE_DIR}/credential-cache.c)
579-
target_link_libraries(git-credential-cache common-main)
647+
if(NOT NO_UNIX_SOCKETS)
648+
add_executable(git-credential-cache ${CMAKE_SOURCE_DIR}/credential-cache.c)
649+
target_link_libraries(git-credential-cache common-main)
580650

581-
add_executable(git-credential-cache--daemon ${CMAKE_SOURCE_DIR}/credential-cache--daemon.c)
582-
target_link_libraries(git-credential-cache--daemon common-main)
651+
add_executable(git-credential-cache--daemon ${CMAKE_SOURCE_DIR}/credential-cache--daemon.c)
652+
target_link_libraries(git-credential-cache--daemon common-main)
653+
endif()
583654

584655

585656
set(git_builtin_extra
@@ -591,16 +662,16 @@ set(git_builtin_extra
591662
foreach(s ${git_SOURCES} ${git_builtin_extra})
592663
string(REPLACE "${CMAKE_SOURCE_DIR}/builtin/" "" s ${s})
593664
string(REPLACE ".c" "" s ${s})
594-
file(APPEND ${CMAKE_BINARY_DIR}/CreateLinks.cmake "file(CREATE_LINK git git-${s})\n")
595-
list(APPEND git_links ${CMAKE_BINARY_DIR}/git-${s})
665+
file(APPEND ${CMAKE_BINARY_DIR}/CreateLinks.cmake "file(CREATE_LINK git${EXE_EXTENSION} git-${s}${EXE_EXTENSION})\n")
666+
list(APPEND git_links ${CMAKE_BINARY_DIR}/git-${s}${EXE_EXTENSION})
596667
endforeach()
597668

598669
if(CURL_FOUND)
599670
set(remote_exes
600671
git-remote-https git-remote-ftp git-remote-ftps)
601672
foreach(s ${remote_exes})
602-
file(APPEND ${CMAKE_BINARY_DIR}/CreateLinks.cmake "file(CREATE_LINK git-remote-http ${s})\n")
603-
list(APPEND git_http_links ${CMAKE_BINARY_DIR}/${s})
673+
file(APPEND ${CMAKE_BINARY_DIR}/CreateLinks.cmake "file(CREATE_LINK git-remote-http${EXE_EXTENSION} ${s}${EXE_EXTENSION})\n")
674+
list(APPEND git_http_links ${CMAKE_BINARY_DIR}/${s}${EXE_EXTENSION})
604675
endforeach()
605676
endif()
606677

@@ -722,20 +793,20 @@ set(bin_links
722793
git-receive-pack git-upload-archive git-upload-pack)
723794

724795
foreach(b ${bin_links})
725-
install(CODE "file(CREATE_LINK ${CMAKE_INSTALL_PREFIX}/bin/git ${CMAKE_INSTALL_PREFIX}/bin/${b})")
796+
install(CODE "file(CREATE_LINK ${CMAKE_INSTALL_PREFIX}/bin/git${EXE_EXTENSION} ${CMAKE_INSTALL_PREFIX}/bin/${b}${EXE_EXTENSION})")
726797
endforeach()
727798

728-
install(CODE "file(CREATE_LINK ${CMAKE_INSTALL_PREFIX}/bin/git ${CMAKE_INSTALL_PREFIX}/libexec/git-core/git)")
729-
install(CODE "file(CREATE_LINK ${CMAKE_INSTALL_PREFIX}/bin/git-shell ${CMAKE_INSTALL_PREFIX}/libexec/git-core/git-shell)")
799+
install(CODE "file(CREATE_LINK ${CMAKE_INSTALL_PREFIX}/bin/git${EXE_EXTENSION} ${CMAKE_INSTALL_PREFIX}/libexec/git-core/git${EXE_EXTENSION})")
800+
install(CODE "file(CREATE_LINK ${CMAKE_INSTALL_PREFIX}/bin/git-shell${EXE_EXTENSION} ${CMAKE_INSTALL_PREFIX}/libexec/git-core/git-shell${EXE_EXTENSION})")
730801

731802
foreach(b ${git_links})
732803
string(REPLACE "${CMAKE_BINARY_DIR}" "" b ${b})
733-
install(CODE "file(CREATE_LINK ${CMAKE_INSTALL_PREFIX}/bin/git ${CMAKE_INSTALL_PREFIX}/libexec/git-core/${b})")
804+
install(CODE "file(CREATE_LINK ${CMAKE_INSTALL_PREFIX}/bin/git${EXE_EXTENSION} ${CMAKE_INSTALL_PREFIX}/libexec/git-core/${b}${EXE_EXTENSION})")
734805
endforeach()
735806

736807
foreach(b ${git_http_links})
737808
string(REPLACE "${CMAKE_BINARY_DIR}" "" b ${b})
738-
install(CODE "file(CREATE_LINK ${CMAKE_INSTALL_PREFIX}/libexec/git-core/git-remote-http ${CMAKE_INSTALL_PREFIX}/libexec/git-core/${b})")
809+
install(CODE "file(CREATE_LINK ${CMAKE_INSTALL_PREFIX}/libexec/git-core/git-remote-http${EXE_EXTENSION} ${CMAKE_INSTALL_PREFIX}/libexec/git-core/${b}${EXE_EXTENSION})")
739810
endforeach()
740811

741812
install(PROGRAMS ${git_shell_scripts} ${git_perl_scripts} ${CMAKE_BINARY_DIR}/git-p4
@@ -784,14 +855,14 @@ set(wrapper_test_scripts
784855
foreach(script ${wrapper_scripts})
785856
file(STRINGS ${CMAKE_SOURCE_DIR}/wrap-for-bin.sh content NEWLINE_CONSUME)
786857
string(REPLACE "@@BUILD_DIR@@" "${CMAKE_BINARY_DIR}" content "${content}")
787-
string(REPLACE "@@PROG@@" "${script}" content "${content}")
858+
string(REPLACE "@@PROG@@" "${script}${EXE_EXTENSION}" content "${content}")
788859
file(WRITE ${CMAKE_BINARY_DIR}/bin-wrappers/${script} ${content})
789860
endforeach()
790861

791862
foreach(script ${wrapper_test_scripts})
792863
file(STRINGS ${CMAKE_SOURCE_DIR}/wrap-for-bin.sh content NEWLINE_CONSUME)
793864
string(REPLACE "@@BUILD_DIR@@" "${CMAKE_BINARY_DIR}" content "${content}")
794-
string(REPLACE "@@PROG@@" "t/helper/${script}" content "${content}")
865+
string(REPLACE "@@PROG@@" "t/helper/${script}${EXE_EXTENSION}" content "${content}")
795866
file(WRITE ${CMAKE_BINARY_DIR}/bin-wrappers/${script} ${content})
796867
endforeach()
797868

@@ -857,7 +928,7 @@ file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_PTHREADS='${NO_PTHREADS}'\
857928
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_UNIX_SOCKETS='${NO_UNIX_SOCKETS}'\n")
858929
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "PAGER_ENV='${PAGER_ENV}'\n")
859930
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "DC_SHA1='${DC_SHA1}'\n")
860-
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "X=''\n")
931+
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "X='${EXE_EXTENSION}'\n")
861932
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_GETTEXT='${NO_GETTEXT}'\n")
862933
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "RUNTIME_PREFIX='${RUNTIME_PREFIX}'\n")
863934
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_PYTHON='${NO_PYTHON}'\n")

0 commit comments

Comments
 (0)