• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1cmake_minimum_required(VERSION 3.15)
2
3include(CheckSymbolExists)
4include(CheckIPOSupported)
5
6project(ninja)
7
8# --- optional link-time optimization
9check_ipo_supported(RESULT lto_supported OUTPUT error)
10
11if(lto_supported)
12	message(STATUS "IPO / LTO enabled")
13	set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE)
14else()
15	message(STATUS "IPO / LTO not supported: <${error}>")
16endif()
17
18# --- compiler flags
19if(MSVC)
20	set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
21	string(REPLACE "/GR" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
22	add_compile_options(/W4 /wd4100 /wd4267 /wd4706 /wd4702 /wd4244 /GR- /Zc:__cplusplus)
23	add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
24else()
25	include(CheckCXXCompilerFlag)
26	check_cxx_compiler_flag(-Wno-deprecated flag_no_deprecated)
27	if(flag_no_deprecated)
28		add_compile_options(-Wno-deprecated)
29	endif()
30	check_cxx_compiler_flag(-fdiagnostics-color flag_color_diag)
31	if(flag_color_diag)
32		add_compile_options(-fdiagnostics-color)
33	endif()
34endif()
35
36# --- optional re2c
37find_program(RE2C re2c)
38if(RE2C)
39	# the depfile parser and ninja lexers are generated using re2c.
40	function(re2c IN OUT)
41		add_custom_command(DEPENDS ${IN} OUTPUT ${OUT}
42			COMMAND ${RE2C} -b -i --no-generation-date --no-version -o ${OUT} ${IN}
43		)
44	endfunction()
45	re2c(${PROJECT_SOURCE_DIR}/src/depfile_parser.in.cc ${PROJECT_BINARY_DIR}/depfile_parser.cc)
46	re2c(${PROJECT_SOURCE_DIR}/src/lexer.in.cc ${PROJECT_BINARY_DIR}/lexer.cc)
47	add_library(libninja-re2c OBJECT ${PROJECT_BINARY_DIR}/depfile_parser.cc ${PROJECT_BINARY_DIR}/lexer.cc)
48else()
49	message(WARNING "re2c was not found; changes to src/*.in.cc will not affect your build.")
50	add_library(libninja-re2c OBJECT src/depfile_parser.cc src/lexer.cc)
51endif()
52target_include_directories(libninja-re2c PRIVATE src)
53
54# --- Check for 'browse' mode support
55function(check_platform_supports_browse_mode RESULT)
56	# Make sure the inline.sh script works on this platform.
57	# It uses the shell commands such as 'od', which may not be available.
58
59	execute_process(
60		COMMAND sh -c "echo 'TEST' | src/inline.sh var"
61		WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
62		RESULT_VARIABLE inline_result
63		OUTPUT_QUIET
64		ERROR_QUIET
65	)
66	if(NOT inline_result EQUAL "0")
67		# The inline script failed, so browse mode is not supported.
68		set(${RESULT} "0" PARENT_SCOPE)
69		if(NOT WIN32)
70			message(WARNING "browse feature omitted due to inline script failure")
71		endif()
72		return()
73	endif()
74
75	# Now check availability of the unistd header
76	check_symbol_exists(fork "unistd.h" HAVE_FORK)
77	check_symbol_exists(pipe "unistd.h" HAVE_PIPE)
78	set(browse_supported 0)
79	if (HAVE_FORK AND HAVE_PIPE)
80		set(browse_supported 1)
81	endif ()
82	set(${RESULT} "${browse_supported}" PARENT_SCOPE)
83	if(NOT browse_supported)
84		message(WARNING "browse feature omitted due to missing `fork` and `pipe` functions")
85	endif()
86
87endfunction()
88
89check_platform_supports_browse_mode(platform_supports_ninja_browse)
90
91# Core source files all build into ninja library.
92add_library(libninja OBJECT
93	src/build_log.cc
94	src/build.cc
95	src/clean.cc
96	src/clparser.cc
97	src/dyndep.cc
98	src/dyndep_parser.cc
99	src/debug_flags.cc
100	src/deps_log.cc
101	src/disk_interface.cc
102	src/edit_distance.cc
103	src/eval_env.cc
104	src/graph.cc
105	src/graphviz.cc
106	src/json.cc
107	src/line_printer.cc
108	src/manifest_parser.cc
109	src/metrics.cc
110	src/missing_deps.cc
111	src/parser.cc
112	src/state.cc
113	src/status.cc
114	src/string_piece_util.cc
115	src/util.cc
116	src/version.cc
117)
118if(WIN32)
119	target_sources(libninja PRIVATE
120		src/subprocess-win32.cc
121		src/includes_normalize-win32.cc
122		src/msvc_helper-win32.cc
123		src/msvc_helper_main-win32.cc
124		src/getopt.c
125		src/minidump-win32.cc
126	)
127else()
128	target_sources(libninja PRIVATE src/subprocess-posix.cc)
129	if(CMAKE_SYSTEM_NAME STREQUAL "OS400" OR CMAKE_SYSTEM_NAME STREQUAL "AIX")
130		target_sources(libninja PRIVATE src/getopt.c)
131	endif()
132
133	# Needed for perfstat_cpu_total
134	if(CMAKE_SYSTEM_NAME STREQUAL "AIX")
135		target_link_libraries(libninja PUBLIC "-lperfstat")
136	endif()
137endif()
138
139#Fixes GetActiveProcessorCount on MinGW
140if(MINGW)
141target_compile_definitions(libninja PRIVATE _WIN32_WINNT=0x0601 __USE_MINGW_ANSI_STDIO=1)
142endif()
143
144# On IBM i (identified as "OS400" for compatibility reasons) and AIX, this fixes missing
145# PRId64 (and others) at compile time in C++ sources
146if(CMAKE_SYSTEM_NAME STREQUAL "OS400" OR CMAKE_SYSTEM_NAME STREQUAL "AIX")
147	add_compile_definitions(__STDC_FORMAT_MACROS)
148endif()
149
150# Main executable is library plus main() function.
151add_executable(ninja src/ninja.cc)
152target_link_libraries(ninja PRIVATE libninja libninja-re2c)
153
154if(WIN32)
155  target_sources(ninja PRIVATE windows/ninja.manifest)
156endif()
157
158# Adds browse mode into the ninja binary if it's supported by the host platform.
159if(platform_supports_ninja_browse)
160	# Inlines src/browse.py into the browse_py.h header, so that it can be included
161	# by src/browse.cc
162	add_custom_command(
163		OUTPUT build/browse_py.h
164		MAIN_DEPENDENCY src/browse.py
165		DEPENDS src/inline.sh
166		COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/build
167		COMMAND src/inline.sh kBrowsePy
168						< src/browse.py
169						> ${PROJECT_BINARY_DIR}/build/browse_py.h
170		WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
171		VERBATIM
172	)
173
174	target_compile_definitions(ninja PRIVATE NINJA_HAVE_BROWSE)
175	target_sources(ninja PRIVATE src/browse.cc)
176	set_source_files_properties(src/browse.cc
177		PROPERTIES
178			OBJECT_DEPENDS "${PROJECT_BINARY_DIR}/build/browse_py.h"
179			INCLUDE_DIRECTORIES "${PROJECT_BINARY_DIR}"
180			COMPILE_DEFINITIONS NINJA_PYTHON="python"
181	)
182endif()
183
184include(CTest)
185if(BUILD_TESTING)
186  # Tests all build into ninja_test executable.
187  add_executable(ninja_test
188    src/build_log_test.cc
189    src/build_test.cc
190    src/clean_test.cc
191    src/clparser_test.cc
192    src/depfile_parser_test.cc
193    src/deps_log_test.cc
194    src/disk_interface_test.cc
195    src/dyndep_parser_test.cc
196    src/edit_distance_test.cc
197    src/graph_test.cc
198    src/json_test.cc
199    src/lexer_test.cc
200    src/manifest_parser_test.cc
201    src/missing_deps_test.cc
202    src/ninja_test.cc
203    src/state_test.cc
204    src/string_piece_util_test.cc
205    src/subprocess_test.cc
206    src/test.cc
207    src/util_test.cc
208  )
209  if(WIN32)
210    target_sources(ninja_test PRIVATE src/includes_normalize_test.cc src/msvc_helper_test.cc)
211  endif()
212  target_link_libraries(ninja_test PRIVATE libninja libninja-re2c)
213
214  foreach(perftest
215    build_log_perftest
216    canon_perftest
217    clparser_perftest
218    depfile_parser_perftest
219    hash_collision_bench
220    manifest_parser_perftest
221  )
222    add_executable(${perftest} src/${perftest}.cc)
223    target_link_libraries(${perftest} PRIVATE libninja libninja-re2c)
224  endforeach()
225
226  if(CMAKE_SYSTEM_NAME STREQUAL "AIX" AND CMAKE_SIZEOF_VOID_P EQUAL 4)
227    # These tests require more memory than will fit in the standard AIX shared stack/heap (256M)
228    target_link_options(hash_collision_bench PRIVATE "-Wl,-bmaxdata:0x80000000")
229    target_link_options(manifest_parser_perftest PRIVATE "-Wl,-bmaxdata:0x80000000")
230  endif()
231
232  add_test(NAME NinjaTest COMMAND ninja_test)
233endif()
234
235install(TARGETS ninja)
236