blob: 3f82b72006dd309b67fb94f1030fcf51c3597f74 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
# Copyright (c) 2009 Tobias Gunkel <tobigun@at@users.sourceforge.net>
#
# Copying and distribution of this file, with or without
# modification, are permitted in any medium without royalty provided
# the copyright notice and this notice are preserved.
# - Find Pascal compiler
#
# This module defines
# PPC_FOUND, If false, do not try to use PPC.
##
# Find FreePascal executable
##
set(PPC_BIN_PATH
"$ENV{SystemDrive}/fpc/*/bin/*"
"$ENV{ProgramFiles}/fpc/*/bin/*"
"$ENV{SystemDrive}/lazarus/fpc/*/bin/*"
"$ENV{ProgramFiles}/lazarus/fpc/*/bin/*"
)
find_program(PPC fpc PATHS ${PPC_BIN_PATH})
##
# Get FPC compiler info
##
set(PPC_CHECK_DIR ${CMAKE_BINARY_DIR}/ppc_check)
# - creates file with code in PPC_CHECK_DIR and compiles it with
# the given flags. The result will be stored in result_var.
# If NO_CLEAN is given, the PPC_CHECK_DIR will not be removed
# after the check.
#
# PPC_CHECK(file code flags result_var NO_CLEAN)
#
function(PPC_CHECK file code flags result_var)
# create compiler check directory
file(MAKE_DIRECTORY ${PPC_CHECK_DIR})
file(WRITE ${PPC_CHECK_DIR}/${file} "${code}")
execute_process(
COMMAND ${PPC} ${flags} ${file}
WORKING_DIRECTORY ${PPC_CHECK_DIR}
RESULT_VARIABLE check_result
ERROR_QUIET
OUTPUT_QUIET)
# remove compiler check directory
list(FIND ARGN "NO_CLEAN" no_clean)
if(no_clean EQUAL -1)
file(REMOVE_RECURSE ${PPC_CHECK_DIR})
endif(no_clean EQUAL -1)
set(${result_var} ${check_result} PARENT_SCOPE)
endfunction(PPC_CHECK)
# use a foreach statement so we can leave this section with break()
# if an error occurs.
foreach(once 1)
set(PPC_WORKS)
set(PPC_ERROR)
if(NOT PPC)
set(PPC_ERROR "Executable not found")
break()
endif(NOT PPC)
# retrieve FPC version
execute_process(COMMAND ${PPC} -iV
OUTPUT_VARIABLE FPC_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
# check version
if(PPC_FIND_VERSION_EXACT)
if(NOT FPC_VERSION VERSION_EQUAL PPC_FIND_VERSION)
set(PPC_ERROR "Required =${PPC_FIND_VERSION} but found ${FPC_VERSION}")
break()
endif(NOT FPC_VERSION VERSION_EQUAL PPC_FIND_VERSION)
endif(PPC_FIND_VERSION_EXACT)
if(PPC_FIND_VERSION)
if(FPC_VERSION VERSION_LESS PPC_FIND_VERSION)
set(PPC_ERROR "Required >=${PPC_FIND_VERSION} but found ${FPC_VERSION}")
break()
endif(FPC_VERSION VERSION_LESS PPC_FIND_VERSION)
endif(PPC_FIND_VERSION)
# retrieve FPC platform info
execute_process(COMMAND ${PPC} -iTO
OUTPUT_VARIABLE FPC_PLATFORM
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${PPC} -iTP
OUTPUT_VARIABLE FPC_PROCESSOR
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${PPC} -iSO
OUTPUT_VARIABLE FPC_CPLATFORM
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${PPC} -iSP
OUTPUT_VARIABLE FPC_CPROCESSOR
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(FPC_TARGET "${FPC_PROCESSOR}-${FPC_PLATFORM}")
#-v -l verbose/banner
#-n ignore fpc.cfg
#-Fi -I include-dir
#-k
#-Fl linker-dir
#-Fo -Fu object-/unit-dir
#-Xt -Xc
#-Ciort range checks
#-Cs -Ch stack/heap size
#-Cg -fPIC PIC code
#-E
#-g -gv -gw(2/3) -gh -gl -pg
#-O
#-T -Xd -XP cross-compiling
#-d -u define/undefine
#-Xs strip
#-B build all modules
#-Dd -Dv description + DLL-version
#PFLAGS_BASE_DEFAULT := -Si -Sg- -Sc- -v0Binwe
#PFLAGS_DEBUG_DEFAULT := -Xs- -g -gl -dDEBUG_MODE
#PFLAGS_RELEASE_DEFAULT := -Xs- -O2
##
# Compiler checks
##
set(default_flags "")
# check whether FPC works and can compile a program
ppc_check(simple.pas "program simple;\nbegin\nend."
"${default_flags}" check_result)
if(check_result)
set(PPC_ERROR "Cannot compile simple test-program")
break()
endif(check_result)
# check if FPC can link with standard libraries
ppc_check(link.pas "program link;\nuses SysUtils;\nbegin\nWriteLn('Test');\nend."
"${default_flags}" check_result)
if(check_result)
set(PPC_ERROR "Cannot link with standard libraries")
break()
endif(check_result)
# check whether FPC's linker knows (or at least doesn't crash with)
# "-z noexecstack"
# FPC does not set the NX-flag on stack memory. Binaries generated with FPC
# might crash on platforms that require the stack to be non-executable.
# So we will try to find a workaround here.
# See http://bugs.freepascal.org/view.php?id=11563
set(noexecstack_flags -k"-z noexecstack")
ppc_check(noexecstack.pas "program noexecstack;\nbegin\nend."
"${default_flags} ${noexecstack_flags}" check_result)
if(check_result)
set(noexecstack_flags)
endif(check_result)
# check prefixes and suffixes
ppc_check(testlib.pas "library link;\nbegin\nend."
"${default_flags}" check_result
NO_CLEAN)
# find generated library
find_library(PPC_TEST_LIBPATH testlib
PATHS ${PPC_CHECK_DIR}
NO_DEFAULT_PATH)
# do not show library name in GUI
mark_as_advanced(PPC_TEST_LIBPATH)
# extract prefix and suffix from library name
if(PPC_TEST_LIBPATH)
get_filename_component(PPC_LIBRARY_SUFFIX ${PPC_TEST_LIBPATH} EXT CACHE)
get_filename_component(libfilename ${PPC_TEST_LIBPATH} NAME_WE)
string(REGEX REPLACE "^(.*)testlib.*" "\\1" PPC_LIBRARY_PREFIX ${libfilename})
endif(PPC_TEST_LIBPATH)
# remove library test directory
file(REMOVE_RECURSE ${PPC_CHECK_DIR})
if(check_result)
set(PPC_ERROR "Cannot link with standard libraries")
break()
endif(check_result)
##
# Check results
##
#set(PFLAGS ${noexecstack_flags} "-B" "-FE../bin" "-Cs2000000" "-vwi" "-O2" "-Fl/opt/local/lib" ${hwengine_project})
set(PPC_WORKS TRUE)
endforeach(once)
# handle the QUIETLY and REQUIRED arguments and set PPC_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PPC "Could NOT find PPC: ${PPC_ERROR}!" PPC PPC_WORKS)
mark_as_advanced(PPC)
|