1cmake_minimum_required(VERSION 2.8.12)
2if(POLICY CMP0042)
3	cmake_policy(SET CMP0042 NEW)
4endif()
5if(POLICY CMP0063)
6	cmake_policy(SET CMP0063 OLD)
7endif()
8
9project(libfirm C)
10set(libfirm_VERSION "1.22.1")
11set(PROJECT_DESCRIPTION "library implementing the intermediate representation Firm")
12
13set(CMAKE_C_VISIBILITY_PRESET hidden)
14
15set(SOURCES
16	ir/adt/array.c
17	ir/adt/bipartite.c
18	ir/adt/bitset.c
19	ir/adt/cpset.c
20	ir/adt/deq.c
21	ir/adt/gaussjordan.c
22	ir/adt/gaussseidel.c
23	ir/adt/hungarian.c
24	ir/adt/pmap.c
25	ir/adt/pqueue.c
26	ir/adt/pset.c
27	ir/adt/pset_new.c
28	ir/adt/set.c
29	ir/adt/xmalloc.c
30	ir/ana/analyze_irg_args.c
31	ir/ana/callgraph.c
32	ir/ana/cdep.c
33	ir/ana/cgana.c
34	ir/ana/constbits.c
35	ir/ana/dca.c
36	ir/ana/dfs.c
37	ir/ana/domfront.c
38	ir/ana/execfreq.c
39	ir/ana/heights.c
40	ir/ana/irbackedge.c
41	ir/ana/ircfscc.c
42	ir/ana/irconsconfirm.c
43	ir/ana/irdom.c
44	ir/ana/irlivechk.c
45	ir/ana/irloop.c
46	ir/ana/irmemory.c
47	ir/ana/irouts.c
48	ir/ana/vrp.c
49	ir/be/be2addr.c
50	ir/be/bearch.c
51	ir/be/beasm.c
52	ir/be/beblocksched.c
53	ir/be/bechordal.c
54	ir/be/bechordal_common.c
55	ir/be/bechordal_main.c
56	ir/be/becopyheur4.c
57	ir/be/becopyilp.c
58	ir/be/becopyilp2.c
59	ir/be/becopyopt.c
60	ir/be/bediagnostic.c
61	ir/be/bedump.c
62	ir/be/bedwarf.c
63	ir/be/beemithlp.c
64	ir/be/beemitter.c
65	ir/be/beflags.c
66	ir/be/begnuas.c
67	ir/be/beifg.c
68	ir/be/beinfo.c
69	ir/be/beinsn.c
70	ir/be/beirg.c
71	ir/be/bejit.c
72	ir/be/belistsched.c
73	ir/be/belive.c
74	ir/be/beloopana.c
75	ir/be/belower.c
76	ir/be/bemain.c
77	ir/be/bemodule.c
78	ir/be/benode.c
79	ir/be/bepbqpcoloring.c
80	ir/be/bepeephole.c
81	ir/be/beprefalloc.c
82	ir/be/bera.c
83	ir/be/besched.c
84	ir/be/beschednormal.c
85	ir/be/beschedrand.c
86	ir/be/beschedtrivial.c
87	ir/be/bespill.c
88	ir/be/bespillbelady.c
89	ir/be/bespilldaemel.c
90	ir/be/bespillslots.c
91	ir/be/bespillutil.c
92	ir/be/bessaconstr.c
93	ir/be/bessadestr.c
94	ir/be/bestack.c
95	ir/be/bestat.c
96	ir/be/bestate.c
97	ir/be/betranshlp.c
98	ir/be/beuses.c
99	ir/be/beutil.c
100	ir/be/bevarargs.c
101	ir/be/beverify.c
102	ir/common/debug.c
103	ir/common/debugger.c
104	ir/common/firm.c
105	ir/common/firm_common.c
106	ir/common/panic.c
107	ir/common/timing.c
108	ir/ident/ident.c
109	ir/ir/dbginfo.c
110	ir/ir/irarch.c
111	ir/ir/irargs.c
112	ir/ir/ircons.c
113	ir/ir/irdump.c
114	ir/ir/irdumptxt.c
115	ir/ir/iredges.c
116	ir/ir/irflag.c
117	ir/ir/irgmod.c
118	ir/ir/irgraph.c
119	ir/ir/irgwalk.c
120	ir/ir/irgwalk_blk.c
121	ir/ir/irhooks.c
122	ir/ir/irio.c
123	ir/ir/irmode.c
124	ir/ir/irnode.c
125	ir/ir/irnodehashmap.c
126	ir/ir/irnodeset.c
127	ir/ir/irop.c
128	ir/ir/irprintf.c
129	ir/ir/irprofile.c
130	ir/ir/irprog.c
131	ir/ir/irssacons.c
132	ir/ir/irtools.c
133	ir/ir/irverify.c
134	ir/ir/valueset.c
135	ir/kaps/brute_force.c
136	ir/kaps/bucket.c
137	ir/kaps/heuristical.c
138	ir/kaps/heuristical_co.c
139	ir/kaps/heuristical_co_ld.c
140	ir/kaps/html_dumper.c
141	ir/kaps/kaps.c
142	ir/kaps/matrix.c
143	ir/kaps/optimal.c
144	ir/kaps/pbqp_edge.c
145	ir/kaps/pbqp_node.c
146	ir/kaps/vector.c
147	ir/libcore/lc_appendable.c
148	ir/libcore/lc_opts.c
149	ir/libcore/lc_opts_enum.c
150	ir/libcore/lc_printf.c
151	ir/lower/lower_alloc.c
152	ir/lower/lower_builtins.c
153	ir/lower/lower_calls.c
154	ir/lower/lower_copyb.c
155	ir/lower/lower_dw.c
156	ir/lower/lower_hl.c
157	ir/lower/lower_intrinsics.c
158	ir/lower/lower_mode_b.c
159	ir/lower/lower_mux.c
160	ir/lower/lower_softfloat.c
161	ir/lower/lower_switch.c
162	ir/lpp/lpp.c
163	ir/lpp/lpp_cplex.c
164	ir/lpp/lpp_gurobi.c
165	ir/lpp/lpp_solvers.c
166	ir/lpp/mps.c
167	ir/lpp/sp_matrix.c
168	ir/obstack/obstack.c
169	ir/obstack/obstack_printf.c
170	ir/opt/boolopt.c
171	ir/opt/cfopt.c
172	ir/opt/code_placement.c
173	ir/opt/combo.c
174	ir/opt/convopt.c
175	ir/opt/critical_edges.c
176	ir/opt/dead_code_elimination.c
177	ir/opt/funccall.c
178	ir/opt/garbage_collect.c
179	ir/opt/gvn_pre.c
180	ir/opt/ifconv.c
181	ir/opt/instrument.c
182	ir/opt/ircgopt.c
183	ir/opt/ircomplib.c
184	ir/opt/irgopt.c
185	ir/opt/iropt.c
186	ir/opt/jumpthreading.c
187	ir/opt/ldstopt.c
188	ir/opt/loop.c
189	ir/opt/occult_const.c
190	ir/opt/opt_blocks.c
191	ir/opt/opt_confirms.c
192	ir/opt/opt_frame.c
193	ir/opt/opt_inline.c
194	ir/opt/opt_ldst.c
195	ir/opt/opt_osr.c
196	ir/opt/parallelize_mem.c
197	ir/opt/proc_cloning.c
198	ir/opt/reassoc.c
199	ir/opt/return.c
200	ir/opt/rm_bads.c
201	ir/opt/rm_tuples.c
202	ir/opt/scalar_replace.c
203	ir/opt/tailrec.c
204	ir/opt/unreachable.c
205	ir/stat/stat_timing.c
206	ir/stat/statev.c
207	ir/tr/entity.c
208	ir/tr/tr_inheritance.c
209	ir/tr/trverify.c
210	ir/tr/type.c
211	ir/tr/typewalk.c
212	ir/tv/fltcalc.c
213	ir/tv/strcalc.c
214	ir/tv/tv.c
215)
216include_directories(
217	include
218	include/libfirm
219	include/libfirm/adt
220	ir/adt
221	ir/ana
222	ir/be
223	ir/common
224	ir/debug
225	ir/ident
226	ir/ir
227	ir/kaps
228	ir/libcore
229	ir/lower
230	ir/lpp
231	ir/lower
232	ir/obstack
233	ir/opt
234	ir/stat
235	ir/tr
236	ir/tv
237)
238
239set(TESTS
240	unittests/deq
241	unittests/globalmap
242	unittests/nan_payload
243	unittests/rbitset
244	unittests/sc_val_from_bits
245	unittests/snprintf
246	unittests/strcalc
247	unittests/tarval_calc
248	unittests/tarval_float
249	unittests/tarval_floatops
250	unittests/tarval_from_to
251	unittests/tarval_is_long
252)
253
254# Codegenerators
255set(GEN_DIR "${CMAKE_CURRENT_BINARY_DIR}/gen")
256set(GEN_IR_DIR "${PROJECT_SOURCE_DIR}/scripts")
257set(IR_SPEC "${PROJECT_SOURCE_DIR}/scripts/ir_spec.py")
258set(GEN_TEMPLATEDIR "${PROJECT_SOURCE_DIR}/scripts/templates")
259
260set(Python_ADDITIONAL_VERSIONS 2.7 3.0 3.1 3.2 3.3 3.4)
261include(FindPythonInterp)
262if(NOT PYTHONINTERP_FOUND)
263	message(FATAL_ERROR "Unable to find python interpreter")
264endif()
265include(FindPerl)
266if(NOT PERL_FOUND)
267	message(FATAL_ERROR "Unable to find perl interpreter")
268endif()
269
270function(gen_ir target)
271	get_filename_component(basename ${target} NAME)
272	get_filename_component(target_dir ${target} DIRECTORY)
273	add_custom_command (
274		OUTPUT ${target}
275		COMMAND ${CMAKE_COMMAND} -E make_directory ${target_dir}
276		COMMAND ${PYTHON_EXECUTABLE} ${GEN_IR_DIR}/gen_ir.py ${IR_SPEC} ${GEN_TEMPLATEDIR}/${basename} > ${target}
277		DEPENDS ${GEN_IR_DIR}/gen_ir.py ${GEN_IR_DIR}/jinjautil.py ${GEN_IR_DIR}/irops.py ${IR_SPEC}
278	)
279	list(APPEND SOURCES ${target})
280	set(SOURCES ${SOURCES} PARENT_SCOPE)
281endfunction()
282
283function(begen generator target spec)
284	get_filename_component(target_dir ${target} DIRECTORY)
285	set(GENERATOR ${PROJECT_SOURCE_DIR}/ir/be/scripts/${generator})
286	add_custom_command(
287		OUTPUT ${target}
288		COMMAND ${CMAKE_COMMAND} -E make_directory ${target_dir}
289		COMMAND ${PERL_EXECUTABLE} ${GENERATOR} ${spec} ${target_dir}
290		DEPENDS ${GENERATOR} ${spec}
291	)
292	list(APPEND SOURCES ${target})
293	set(SOURCES ${SOURCES} PARENT_SCOPE)
294endfunction()
295
296function(add_backend name)
297	list(APPEND SOURCES ${ARGN})
298	set(SPEC ${PROJECT_SOURCE_DIR}/ir/be/${name}/${name}_spec.pl)
299	begen(generate_emitter.pl
300		${GEN_DIR}/ir/be/${name}/gen_${name}_emitter.c
301		${SPEC})
302	begen(generate_regalloc_if.pl
303		${GEN_DIR}/ir/be/${name}/gen_${name}_regalloc_if.c
304		${SPEC})
305	begen(generate_new_opcodes.pl
306		${GEN_DIR}/ir/be/${name}/gen_${name}_new_nodes.c
307		${SPEC})
308	set(SOURCES ${SOURCES} PARENT_SCOPE)
309	include_directories(
310		${PROJECT_SOURCE_DIR}/ir/be/${name}
311		${GEN_DIR}/ir/be/${name}
312	)
313endfunction()
314
315foreach(file
316	include/libfirm/nodes.h
317	ir/ir/gen_irnode.h
318	ir/ir/gen_proj_names.h
319	ir/ir/gen_irio.c
320	ir/ir/gen_irnode.c)
321	gen_ir(${GEN_DIR}/${file})
322endforeach(file)
323include_directories(
324	${GEN_DIR}/include/libfirm
325	${GEN_DIR}/ir/ir
326)
327
328add_backend(ia32
329	ir/be/ia32/ia32_architecture.c
330	ir/be/ia32/ia32_bearch.c
331	ir/be/ia32/ia32_cconv.c
332	ir/be/ia32/ia32_emitter.c
333	ir/be/ia32/ia32_encode.c
334	ir/be/ia32/ia32_finish.c
335	ir/be/ia32/ia32_fpu.c
336	ir/be/ia32/ia32_intrinsics.c
337	ir/be/ia32/ia32_new_nodes.c
338	ir/be/ia32/ia32_optimize.c
339	ir/be/ia32/ia32_pic.c
340	ir/be/ia32/ia32_transform.c
341	ir/be/ia32/x86_address_mode.c
342	ir/be/ia32/x86_asm.c
343	ir/be/ia32/x86_cconv.c
344	ir/be/ia32/x86_node.c
345	ir/be/ia32/x86_x87.c
346)
347add_backend(arm
348	ir/be/arm/arm_bearch.c
349	ir/be/arm/arm_cconv.c
350	ir/be/arm/arm_emitter.c
351	ir/be/arm/arm_finish.c
352	ir/be/arm/arm_lower64.c
353	ir/be/arm/arm_new_nodes.c
354	ir/be/arm/arm_optimize.c
355	ir/be/arm/arm_transform.c
356)
357add_backend(sparc
358	ir/be/sparc/sparc_bearch.c
359	ir/be/sparc/sparc_cconv.c
360	ir/be/sparc/sparc_emitter.c
361	ir/be/sparc/sparc_finish.c
362	ir/be/sparc/sparc_lower64.c
363	ir/be/sparc/sparc_new_nodes.c
364	ir/be/sparc/sparc_stackframe.c
365	ir/be/sparc/sparc_transform.c
366)
367add_backend(amd64
368	ir/be/amd64/amd64_bearch.c
369	ir/be/amd64/amd64_cconv.c
370	ir/be/amd64/amd64_emitter.c
371	ir/be/amd64/amd64_finish.c
372	ir/be/amd64/amd64_new_nodes.c
373	ir/be/amd64/amd64_optimize.c
374	ir/be/amd64/amd64_pic.c
375	ir/be/amd64/amd64_transform.c
376	ir/be/amd64/amd64_varargs.c
377	ir/be/amd64/amd64_x87.c
378)
379add_backend(TEMPLATE
380	ir/be/TEMPLATE/TEMPLATE_bearch.c
381	ir/be/TEMPLATE/TEMPLATE_emitter.c
382	ir/be/TEMPLATE/TEMPLATE_new_nodes.c
383	ir/be/TEMPLATE/TEMPLATE_transform.c
384)
385
386# Produce revision.h
387include_directories(${CMAKE_CURRENT_BINARY_DIR})
388if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git/HEAD)
389	set(REVISIONH "${CMAKE_CURRENT_BINARY_DIR}/firm_revision.h")
390	set(REVGEN echo '\#define libfirm_VERSION_REVISION \"'`git describe --abbrev=40 --always --dirty --match ''`'\"')
391	add_custom_command(
392		OUTPUT ${REVISIONH}
393		DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/.git/HEAD
394		COMMAND ${REVGEN} | cmp -s - "${REVISIONH}" 2> /dev/null || ${REVGEN} > "${REVISIONH}"
395		WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
396	)
397	SET_SOURCE_FILES_PROPERTIES(ir/common/firm.c PROPERTIES OBJECT_DEPENDS ${REVISIONH})
398	add_definitions(-DHAVE_FIRM_REVISION_H)
399endif()
400
401# Enable C99
402if(CMAKE_VERSION VERSION_LESS "3.1")
403	if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
404		set(CMAKE_C_FLAGS "-std=c99 ${CMAKE_C_FLAGS}")
405	endif()
406else()
407	set(CMAKE_C_STANDARD 99)
408endif()
409# Indicate that we build a shared library
410add_definitions(-DFIRM_BUILD -DFIRM_DLL)
411
412# Build library
413set(BUILD_SHARED_LIBS Off CACHE BOOL "whether to build shared libraries")
414add_library(firm ${SOURCES})
415if(UNIX)
416	target_link_libraries(firm LINK_PUBLIC m)
417elseif(WIN32)
418	target_link_libraries(firm LINK_PUBLIC gnurx winmm)
419endif()
420
421enable_testing()
422add_custom_target(
423		check
424		${CMAKE_CTEST_COMMAND} -C $<CONFIG>
425		WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
426)
427foreach(test ${TESTS})
428	# Replace `/` with a `.` so cmake accepts the target name
429	string(REPLACE "/" "." test-id ${test})
430	add_executable(${test-id} ${test}.c)
431	target_link_libraries(${test-id} LINK_PRIVATE firm)
432	add_test(test-${test-id} ${test-id})
433	add_dependencies(check ${test-id})
434endforeach(test)
435
436# Create install target
437set(INSTALL_HEADERS
438	include/libfirm/adt/array.h
439	include/libfirm/adt/bipartite.h
440	include/libfirm/adt/funcattr.h
441	include/libfirm/adt/gaussjordan.h
442	include/libfirm/adt/gaussseidel.h
443	include/libfirm/adt/hashptr.h
444	include/libfirm/adt/hungarian.h
445	include/libfirm/adt/list.h
446	include/libfirm/adt/obst.h
447	include/libfirm/adt/obstack.h
448	include/libfirm/adt/pmap.h
449	include/libfirm/adt/pqueue.h
450	include/libfirm/adt/pset.h
451	include/libfirm/adt/set.h
452	include/libfirm/adt/unionfind.h
453	include/libfirm/adt/xmalloc.h
454	include/libfirm/analyze_irg_args.h
455	include/libfirm/be.h
456	include/libfirm/begin.h
457	include/libfirm/callgraph.h
458	include/libfirm/cdep.h
459	include/libfirm/cgana.h
460	include/libfirm/dbginfo.h
461	include/libfirm/end.h
462	include/libfirm/execfreq.h
463	include/libfirm/firm.h
464	include/libfirm/firm_common.h
465	include/libfirm/firm_types.h
466	include/libfirm/heights.h
467	include/libfirm/ident.h
468	include/libfirm/irarch.h
469	include/libfirm/ircgopt.h
470	include/libfirm/ircons.h
471	include/libfirm/irconsconfirm.h
472	include/libfirm/irdom.h
473	include/libfirm/irdump.h
474	include/libfirm/iredgekinds.h
475	include/libfirm/iredges.h
476	include/libfirm/irflag.h
477	include/libfirm/irgmod.h
478	include/libfirm/irgopt.h
479	include/libfirm/irgraph.h
480	include/libfirm/irgwalk.h
481	include/libfirm/irio.h
482	include/libfirm/irloop.h
483	include/libfirm/irmemory.h
484	include/libfirm/irmode.h
485	include/libfirm/irnode.h
486	include/libfirm/irop.h
487	include/libfirm/iropt.h
488	include/libfirm/iroptimize.h
489	include/libfirm/irouts.h
490	include/libfirm/irprintf.h
491	include/libfirm/irprog.h
492	include/libfirm/irverify.h
493	include/libfirm/lowering.h
494	include/libfirm/statev.h
495	include/libfirm/timing.h
496	include/libfirm/tv.h
497	include/libfirm/typerep.h
498	include/libfirm/vrp.h
499)
500
501install(TARGETS firm
502	EXPORT libfirmTargets
503	DESTINATION lib
504)
505foreach(header ${INSTALL_HEADERS})
506	get_filename_component(DIR ${header} DIRECTORY)
507	install(FILES ${header} DESTINATION ${DIR})
508endforeach(header)
509install(FILES ${CMAKE_CURRENT_BINARY_DIR}/gen/include/libfirm/nodes.h DESTINATION include/libfirm)
510
511# Generate cmake Config file
512include(CMakePackageConfigHelpers)
513set(libfirm_INCLUDE_DIRS include)
514set(ConfigPackageLocation lib/cmake/libfirm)
515configure_package_config_file(support/libfirmConfig.cmake.in
516	${CMAKE_CURRENT_BINARY_DIR}/libfirmConfig.cmake
517	INSTALL_DESTINATION ${ConfigPackageLocation}
518	PATH_VARS libfirm_INCLUDE_DIRS
519)
520write_basic_package_version_file(
521	${CMAKE_CURRENT_BINARY_DIR}/libfirmConfigVersion.cmake
522	VERSION ${libfirm_VERSION}
523	COMPATIBILITY ExactVersion
524)
525install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libfirmConfig.cmake
526              ${CMAKE_CURRENT_BINARY_DIR}/libfirmConfigVersion.cmake
527        DESTINATION ${ConfigPackageLocation}
528)
529install(EXPORT libfirmTargets
530	FILE libfirmTargets.cmake
531	NAMESPACE libfirm::
532	DESTINATION ${ConfigPackageLocation}
533)
534
535# Generate pkg-config for external projects
536configure_file(${CMAKE_CURRENT_SOURCE_DIR}/support/libfirm.pc.in
537	${CMAKE_CURRENT_BINARY_DIR}/libfirm.pc
538	@ONLY
539)
540install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libfirm.pc"
541	DESTINATION lib/pkgconfig
542)
543