FreeCAD

Форк
0
/
FreeCadMacros.cmake 
325 строк · 14.7 Кб
1
include (CheckCXXSourceRuns)
2

3
# ================================================================================
4
# == Macros, mostly for special targets ==========================================
5

6
MACRO (fc_copy_sources target_name outpath)
7
	if(BUILD_VERBOSE_GENERATION)
8
		set(fc_details " (fc_copy_sources called from ${CMAKE_CURRENT_SOURCE_DIR})")
9
	else()
10
		set(fc_details "")
11
	endif()
12
	foreach(it ${ARGN})
13
		get_filename_component(infile ${it} ABSOLUTE)
14
		get_filename_component(outfile "${outpath}/${it}" ABSOLUTE)
15
		add_file_dependencies("${infile}" "${outfile}")
16
		ADD_CUSTOM_COMMAND(
17
			COMMAND   "${CMAKE_COMMAND}" -E copy "${infile}" "${outfile}"
18
			OUTPUT   "${outfile}"
19
			COMMENT "Copying ${infile} to ${outfile}${fc_details}"
20
			MAIN_DEPENDENCY "${infile}"
21
		)
22
	endforeach(it)
23
	ADD_CUSTOM_COMMAND(
24
		TARGET    ${target_name}
25
		DEPENDS   ${ARGN}
26
	)
27
ENDMACRO(fc_copy_sources)
28

29
MACRO (fc_copy_file_if_different inputfile outputfile)
30
    if (EXISTS ${inputfile})
31
        if (EXISTS ${outputfile})
32
            execute_process(
33
                COMMAND ${CMAKE_COMMAND} -E compare_files ${inputfile}
34
                                                          ${outputfile}
35
                RESULT_VARIABLE DIFFERENT_FILES
36
                OUTPUT_QUIET
37
                ERROR_QUIET
38
            )
39

40
            if (DIFFERENT_FILES)
41
                execute_process(COMMAND "${CMAKE_COMMAND}" -E copy "${inputfile}"
42
                                                                   "${outputfile}")
43
            endif()
44
        else()
45
            execute_process(COMMAND "${CMAKE_COMMAND}" -E copy "${inputfile}"
46
                                                               "${outputfile}")
47
        endif()
48
    endif()
49
ENDMACRO(fc_copy_file_if_different)
50

51
MACRO (fc_target_copy_resource target_name inpath outpath)
52
# Macro to copy a list of files into a nested directory structure
53
# Arguments -
54
#   target_name - name of the target the files will be added to
55
#   inpath      - name of the source directory
56
#   outpath     - name of the destination directory
57
#   ARGN        - a list of relative file names that will be copied
58
#
59
#   If a relative file name is foo/bar.txt then the foo directory
60
#   part will be kept so that the destination file name will be
61
#   ${outpath}/foo/bar.txt
62
#
63
	if(BUILD_VERBOSE_GENERATION)
64
		set(fc_details " (fc_target_copy_resource called from ${CMAKE_CURRENT_SOURCE_DIR})")
65
	else()
66
		set(fc_details "")
67
	endif()
68
	foreach(it ${ARGN})
69
		get_filename_component(infile "${inpath}/${it}" ABSOLUTE)
70
		get_filename_component(outfile "${outpath}/${it}" ABSOLUTE)
71
		add_file_dependencies("${infile}" "${outfile}")
72
		ADD_CUSTOM_COMMAND(
73
			COMMAND   "${CMAKE_COMMAND}" -E copy "${infile}" "${outfile}"
74
			OUTPUT   "${outfile}"
75
			COMMENT "Copying ${infile} to ${outfile}${fc_details}"
76
			MAIN_DEPENDENCY "${infile}"
77
		)
78
	endforeach(it)
79
	ADD_CUSTOM_COMMAND(
80
		TARGET    ${target_name}
81
		DEPENDS   ${ARGN}
82
	)
83
ENDMACRO(fc_target_copy_resource)
84

85
MACRO (fc_target_copy_resource_flat target_name inpath outpath)
86
# Macro to copy a list of files into a flat directory structure
87
# Arguments -
88
#   target_name - name of the target the files will be added to
89
#   inpath      - name of the source directory
90
#   outpath     - name of the destination directory
91
#   ARGN        - a list of relative file names that will be copied
92
#
93
#   If a relative file name is foo/bar.txt then the foo directory
94
#   part will be removed so that the destination file name will be
95
#   ${outpath}/bar.txt
96
#
97
	if(BUILD_VERBOSE_GENERATION)
98
		set(fc_details " (fc_target_copy_resource_flat called from ${CMAKE_CURRENT_SOURCE_DIR})")
99
	else()
100
		set(fc_details "")
101
	endif()
102
	foreach(it ${ARGN})
103
		get_filename_component(infile "${inpath}/${it}" ABSOLUTE)
104
		get_filename_component(outfile "${it}" NAME)
105
		get_filename_component(outfile "${outpath}/${outfile}" ABSOLUTE)
106
		add_file_dependencies("${infile}" "${outfile}")
107
		ADD_CUSTOM_COMMAND(
108
			COMMAND   "${CMAKE_COMMAND}" -E copy "${infile}" "${outfile}"
109
			OUTPUT    "${outfile}"
110
			COMMENT "Copying ${infile} to ${outfile}${fc_details}"
111
			MAIN_DEPENDENCY "${infile}"
112
		)
113
	endforeach(it)
114
	ADD_CUSTOM_COMMAND(
115
		TARGET    ${target_name}
116
		DEPENDS   ${ARGN}
117
	)
118
ENDMACRO(fc_target_copy_resource_flat)
119

120
# It would be a bit cleaner to generate these files in ${CMAKE_CURRENT_BINARY_DIR}
121

122
macro(generate_from_xml BASE_NAME)
123
    set(TOOL_PATH "${CMAKE_SOURCE_DIR}/src/Tools/generate.py")
124
    file(TO_NATIVE_PATH "${TOOL_PATH}" TOOL_NATIVE_PATH)
125
    file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${BASE_NAME}.xml" SOURCE_NATIVE_PATH)
126

127
    set(SOURCE_CPP_PATH "${CMAKE_CURRENT_BINARY_DIR}/${BASE_NAME}.cpp" )
128
    
129
    # BASE_NAME may include also a path name
130
    GET_FILENAME_COMPONENT(OUTPUT_PATH "${SOURCE_CPP_PATH}" PATH)
131
    file(TO_NATIVE_PATH "${OUTPUT_PATH}" OUTPUT_NATIVE_PATH)
132
    if(NOT EXISTS "${SOURCE_CPP_PATH}")
133
        # assures the source files are generated at least once
134
        message(STATUS "${SOURCE_CPP_PATH}")
135
        execute_process(COMMAND "${PYTHON_EXECUTABLE}" "${TOOL_NATIVE_PATH}" --outputPath "${OUTPUT_NATIVE_PATH}" "${SOURCE_NATIVE_PATH}"
136
                        WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
137
        )
138
    endif()
139
    add_custom_command(
140
        OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${BASE_NAME}.h" "${CMAKE_CURRENT_BINARY_DIR}/${BASE_NAME}.cpp"
141
        COMMAND ${PYTHON_EXECUTABLE} "${TOOL_NATIVE_PATH}" --outputPath "${OUTPUT_NATIVE_PATH}" ${BASE_NAME}.xml
142
        MAIN_DEPENDENCY "${BASE_NAME}.xml"
143
        DEPENDS
144
        "${CMAKE_SOURCE_DIR}/src/Tools/generateTemplates/templateClassPyExport.py"
145
        "${TOOL_PATH}"
146
        WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
147
        COMMENT "Building ${BASE_NAME}.h/.cpp out of ${BASE_NAME}.xml"
148
    )
149
endmacro(generate_from_xml)
150

151
macro(generate_from_py BASE_NAME OUTPUT_FILE)
152
		set(TOOL_PATH "${CMAKE_SOURCE_DIR}/src/Tools/PythonToCPP.py")
153
		file(TO_NATIVE_PATH "${TOOL_PATH}" TOOL_NATIVE_PATH)
154
		file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${BASE_NAME}.py" SOURCE_NATIVE_PATH)
155
		add_custom_command(
156
		 		OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_FILE}"
157
		 		COMMAND "${PYTHON_EXECUTABLE}" "${TOOL_NATIVE_PATH}" "${SOURCE_NATIVE_PATH}" "${OUTPUT_FILE}"
158
				MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/${BASE_NAME}.py"
159
				DEPENDS "${TOOL_PATH}"
160
				WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
161
				COMMENT "Building files out of ${BASE_NAME}.py")
162
endmacro(generate_from_py)
163

164
macro(generate_from_any INPUT_FILE OUTPUT_FILE VARIABLE)
165
		set(TOOL_PATH "${CMAKE_SOURCE_DIR}/src/Tools/PythonToCPP.py")
166
		file(TO_NATIVE_PATH "${TOOL_PATH}" TOOL_NATIVE_PATH)
167
		file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_FILE}" SOURCE_NATIVE_PATH)
168
		add_custom_command(
169
		 		OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_FILE}"
170
		 		COMMAND "${PYTHON_EXECUTABLE}" "${TOOL_NATIVE_PATH}" "${SOURCE_NATIVE_PATH}" "${OUTPUT_FILE}" "${VARIABLE}"
171
				MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_FILE}"
172
				DEPENDS "${TOOL_PATH}"
173
				WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
174
				COMMENT "Building files out of ${INPUT_FILE}")
175
endmacro(generate_from_any)
176

177

178

179
MACRO(ADD_MSVC_PRECOMPILED_HEADER TargetName PrecompiledHeader PrecompiledSource SourcesVar)
180
  IF(MSVC)
181
    GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
182
    IF(MSVC_IDE)
183
      SET(PrecompiledBinary "$(IntDir)\\$(TargetName).pch")
184
    ELSE(MSVC_IDE)
185
      SET(PrecompiledBinary ${CMAKE_CURRENT_BINARY_DIR}/${TargetName}.pch)
186
    ENDIF(MSVC_IDE)
187
    SET(Sources ${${SourcesVar}})
188

189
    SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource}
190
                                PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
191
                                           OBJECT_OUTPUTS "${PrecompiledBinary}")
192
    SET_SOURCE_FILES_PROPERTIES(${Sources}
193
                                PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledHeader}\" /FI\"${PrecompiledBinary}\" /Fp\"${PrecompiledBinary}\""
194
                                           OBJECT_DEPENDS "${PrecompiledBinary}")  
195
    # Add precompiled header to SourcesVar
196
    LIST(APPEND ${SourcesVar} ${PrecompiledSource})
197
  ENDIF(MSVC)
198
ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)
199

200
MACRO(GET_MSVC_PRECOMPILED_SOURCE PrecompiledSource SourcesVar)
201
  IF(MSVC)
202
    FOREACH (it ${ARGN})
203
      GET_FILENAME_COMPONENT(file_ext ${it} EXT)
204
      GET_FILENAME_COMPONENT(file_name ${it} NAME)
205
	  STRING(COMPARE EQUAL ${it} ${PrecompiledSource} pch)
206
	  IF (NOT pch)
207
	    # get c++ source files
208
		STRING(REGEX MATCH "^(.cpp|.cc|.cxx)$" cpp_file ${file_ext})
209
		# ignore any generated source files from Qt
210
		STRING(REGEX MATCH "^(moc_|qrc_|ui_)" gen_file ${file_name})
211
		IF(cpp_file AND NOT gen_file)
212
			LIST(APPEND ${SourcesVar} ${it})
213
		ENDIF(cpp_file AND NOT gen_file)
214
	  ENDIF(NOT pch)
215
    ENDFOREACH (it)
216
  ENDIF(MSVC)
217
ENDMACRO(GET_MSVC_PRECOMPILED_SOURCE)
218

219
# Macro to replace all the binary output locations.  Takes 2 optional parameters.
220
# ${ARGVN} is zero based so the 3rd element is ${ARGV2}.  When the 3rd element is missing,
221
# Runtime and Lib directories default to /bin and /lib.  When present, the 3rd element
222
# specifies both Runtime and Lib directories.  4th specifies linux install path.
223
MACRO(SET_BIN_DIR ProjectName OutputName)
224
    set_target_properties(${ProjectName} PROPERTIES OUTPUT_NAME ${OutputName})
225
    if(${ARGC} GREATER 2)
226
        # VS_IDE (and perhaps others) make Release and Debug subfolders.  This removes them.
227
        set_target_properties(${ProjectName} PROPERTIES RUNTIME_OUTPUT_DIRECTORY         ${CMAKE_BINARY_DIR}${ARGV2})
228
        set_target_properties(${ProjectName} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}${ARGV2})
229
        set_target_properties(${ProjectName} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG   ${CMAKE_BINARY_DIR}${ARGV2})
230
        set_target_properties(${ProjectName} PROPERTIES LIBRARY_OUTPUT_DIRECTORY         ${CMAKE_BINARY_DIR}${ARGV2})
231
        set_target_properties(${ProjectName} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}${ARGV2})
232
        set_target_properties(${ProjectName} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_DEBUG   ${CMAKE_BINARY_DIR}${ARGV2})
233
    else(${ARGC} GREATER 2)
234
        set_target_properties(${ProjectName} PROPERTIES RUNTIME_OUTPUT_DIRECTORY         ${CMAKE_BINARY_DIR}/bin)
235
        set_target_properties(${ProjectName} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/bin)
236
        set_target_properties(${ProjectName} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG   ${CMAKE_BINARY_DIR}/bin)
237
        set_target_properties(${ProjectName} PROPERTIES LIBRARY_OUTPUT_DIRECTORY         ${CMAKE_BINARY_DIR}/lib)
238
        set_target_properties(${ProjectName} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/lib)
239
        set_target_properties(${ProjectName} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_DEBUG   ${CMAKE_BINARY_DIR}/lib)
240
    endif(${ARGC} GREATER 2)
241

242
    if(WIN32)
243
        set_target_properties(${ProjectName} PROPERTIES DEBUG_OUTPUT_NAME ${OutputName}_d)
244
    else(WIN32)
245
        # FreeCADBase, SMDS, Driver and MEFISTO2 libs don't depend on parts from CMAKE_INSTALL_LIBDIR
246
        if(NOT ${ProjectName} MATCHES "^(FreeCADBase|SMDS|Driver|MEFISTO2)$")
247
            if(${ARGC} STREQUAL 4)
248
                set_property(TARGET ${ProjectName} APPEND PROPERTY INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/${ARGV3})
249
            elseif(NOT IS_ABSOLUTE ${CMAKE_INSTALL_LIBDIR})
250
                set_property(TARGET ${ProjectName} APPEND PROPERTY INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
251
            else()
252
                set_property(TARGET ${ProjectName} APPEND PROPERTY INSTALL_RPATH ${CMAKE_INSTALL_LIBDIR})
253
            endif()
254
        endif()
255
    endif(WIN32)
256
ENDMACRO(SET_BIN_DIR)
257

258
# Set python prefix & suffix together
259
MACRO(SET_PYTHON_PREFIX_SUFFIX ProjectName)
260
    if(NOT MSVC)
261
        set_target_properties(${ProjectName} PROPERTIES PREFIX "")
262
    endif(NOT MSVC)
263
    
264
    if(WIN32)
265
        set_target_properties(${ProjectName} PROPERTIES SUFFIX ".pyd")
266
    # 0000661: cmake build on Mac OS: dealing with dylib versus so
267
    elseif(APPLE)
268
        set_target_properties(${ProjectName} PROPERTIES SUFFIX ".so")
269
    endif(WIN32)
270
ENDMACRO(SET_PYTHON_PREFIX_SUFFIX)
271

272
# Locate the include directory for a pip-installed package -- uses pip show to find the base pip
273
# install directory, and then appends the package name and  "/include" to the end
274
macro(find_pip_package PACKAGE)
275
	execute_process(
276
			COMMAND ${PYTHON_EXECUTABLE} -m pip show ${PACKAGE}
277
			RESULT_VARIABLE FAILURE
278
			OUTPUT_VARIABLE PRINT_OUTPUT
279
	)
280
	if(NOT FAILURE)
281
		# Extract Name: and Location: lines and use them to construct the include directory
282
		string(REPLACE "\n" ";" PIP_OUTPUT_LINES ${PRINT_OUTPUT})
283
		foreach(LINE IN LISTS PIP_OUTPUT_LINES)
284
			STRING(FIND "${LINE}" "Name: " NAME_STRING_LOCATION)
285
			STRING(FIND "${LINE}" "Location: " LOCATION_STRING_LOCATION)
286
			if(${NAME_STRING_LOCATION} EQUAL 0)
287
				STRING(SUBSTRING "${LINE}" 6 -1 PIP_PACKAGE_NAME)
288
				STRING(STRIP "${PIP_PACKAGE_NAME}" PIP_PACKAGE_NAME)
289
				STRING(REPLACE "-" "_" PIP_PACKAGE_NAME "${PIP_PACKAGE_NAME}")
290
			elseif(${LOCATION_STRING_LOCATION} EQUAL 0)
291
				STRING(SUBSTRING "${LINE}" 9 -1 PIP_PACKAGE_LOCATION)
292
				STRING(STRIP "${PIP_PACKAGE_LOCATION}" PIP_PACKAGE_LOCATION)
293
			endif()
294
		endforeach()
295
		file(TO_CMAKE_PATH "${PIP_PACKAGE_LOCATION}" PIP_PACKAGE_LOCATION)
296
		if(EXISTS "${PIP_PACKAGE_LOCATION}/${PIP_PACKAGE_NAME}/include")
297
			set(INCLUDE_DIR "${PIP_PACKAGE_LOCATION}/${PIP_PACKAGE_NAME}/include")
298
		endif()
299
		# There are many different library naming schemes, but basically we are looking for things that look like
300
		#  PACKAGE*.lib/so or PACKAGE_d*.lib/so
301
		if(WIN32)
302
			file(GLOB OPT_LIBRARIES "${PIP_PACKAGE_LOCATION}/${PIP_PACKAGE_NAME}/${PIP_PACKAGE_NAME}.*.lib")
303
			file(GLOB DEBUG_LIBRARIES "${PIP_PACKAGE_LOCATION}/${PIP_PACKAGE_NAME}/${PIP_PACKAGE_NAME}_d.*.lib")
304
		else()
305
			string(TOLOWER ${PIP_PACKAGE_NAME} PIP_LIB_NAME)
306
			file(GLOB OPT_LIBRARIES "${PIP_PACKAGE_LOCATION}/${PIP_PACKAGE_NAME}/*${PIP_LIB_NAME}*.so.*")
307
		endif()
308
		if (OPT_LIBRARIES AND DEBUG_LIBRARIES)
309
			set(${PACKAGE}_LIBRARIES optimized ${OPT_LIBRARIES} debug ${DEBUG_LIBRARIES} CACHE PATH "")
310
		elseif(OPT_LIBRARIES)
311
			set(${PACKAGE}_LIBRARIES ${OPT_LIBRARIES} CACHE PATH "")
312
		elseif(DEBUG_LIBRARIES)
313
			set(${PACKAGE}_LIBRARIES ${DEBUG_LIBRARIES} CACHE PATH "")
314
		endif()
315
		set(${PACKAGE}_INCLUDE_DIRS ${INCLUDE_DIR} CACHE PATH "")
316
		set(${PACKAGE}_FOUND ON CACHE BOOL OFF)
317
		message(STATUS "Found pip-installed ${PACKAGE} in ${PIP_PACKAGE_LOCATION}/${PIP_PACKAGE_NAME}")
318
	endif()
319
endmacro()
320

321
function(target_compile_warn_error ProjectName)
322
    if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGXX)
323
        target_compile_options(${ProjectName} PRIVATE -Werror)
324
    endif()
325
endfunction()
326

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.