]> gerrit.simantics Code Review - simantics/fmil.git/blob - org.simantics.fmil.core/native/FMILibrary/CMakeLists.txt
Merge "Added getters and setters for all FMI data types."
[simantics/fmil.git] / org.simantics.fmil.core / native / FMILibrary / CMakeLists.txt
1 #    Copyright (C) 2012 Modelon AB
2
3 #    This program is free software: you can redistribute it and/or modify
4 #    it under the terms of the BSD style license.
5
6 #    This program is distributed in the hope that it will be useful,
7 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
8 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9 #    FMILIB_License.txt file for more details.
10
11 #    You should have received a copy of the FMILIB_License.txt file
12 #    along with this program. If not, contact Modelon AB <http://www.modelon.com>.
13         
14 # NOTE: CMake 2.8.6 is required since this is the version used in development.
15 # The script is KNOWN NOT TO WORK WITH 2.8.3 and below (ExternalProject 
16 # interface changes). CMake 2.8.4 and 2.8.5 are not tested.
17 cmake_minimum_required (VERSION 2.8.6 FATAL_ERROR)
18
19 # Prohibit in-source build
20 IF("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
21   message(FATAL_ERROR "In-source build is not supported. Please, use an empty directory for building the project.")
22 ENDIF()
23 project (FMILibrary)
24 set_property(GLOBAL PROPERTY PROPERTYPREDEFINED_TARGETS_FOLDER Global)
25 set(FMILIBRARYHOME ${FMILibrary_SOURCE_DIR})
26 set(FMILIBRARYBUILD ${FMILibrary_BINARY_DIR})
27
28 # User configuration options and parameters
29 SET(FMILIB_INSTALL_PREFIX ${FMILibrary_BINARY_DIR}/../install CACHE PATH "Prefix prepended to install directories")
30 set(FMILIB_THIRDPARTYLIBS  ${FMILibrary_SOURCE_DIR}/ThirdParty CACHE PATH "Path to the ThirdParty library dir" )
31 set(FMILIB_FMI_STANDARD_HEADERS  ${FMILIB_THIRDPARTYLIBS}/FMI/default CACHE PATH "Path to the FMI standard headers dir" )
32
33 option (FMILIB_DEFAULT_BUILD_TYPE_RELEASE "Default build-type used for Makefile generation is 'Release'. Can be overwritten by CMAKE_BUILD_TYPE command line switch." ON)
34
35 if(MSVC)
36         option (FMILIB_BUILD_WITH_STATIC_RTLIB "Use static run-time libraries (/MT or /MTd linker flags)" OFF)
37 endif()
38
39 option(FMILIB_BUILD_STATIC_LIB   "Build the library as static." ON)
40 option(FMILIB_BUILD_SHARED_LIB   "Build the library as shared (dll/so/dylib)." ON)
41 option(FMILIB_INSTALL_SUBLIBS    "Install sub-libraries (fmicapi. fmixml, jmutil, fmiimport, fmizip)" OFF)
42
43
44 IF(NOT (WIN32 OR CYGWIN OR APPLE))
45 # On LINUX position independent code (-fPIC) must be used on all files to be linked into .so
46 # On other systems this is not needed (either is default or relocation is done)
47         if(NOT FMILIB_BUILD_SHARED_LIB)
48                 option(FMILIB_BUILD_FOR_SHARED_LIBS  "The static library 'fmilib' can be linked into shared libraries. Mostly needed on Linux." ON)
49         else()
50                 set(FMILIB_BUILD_FOR_SHARED_LIBS ON CACHE INTERNAL "The static library 'fmilib' can be linked into shared libraries. Mostly needed on Linux." FORCE)
51         endif()
52 else()
53         set(FMILIB_BUILD_FOR_SHARED_LIBS OFF CACHE INTERNAL "The static library 'fmilib' can be linked into shared libraries. Mostly needed on Linux." FORCE)
54 endif()
55
56 option (FMILIB_GENERATE_DOXYGEN_DOC "Generate doxygen doc target" ON)
57
58 option (FMILIB_BUILD_TESTS "Build tests" ON)
59 option (FMILIB_BUILD_BEFORE_TESTS "Force build before testing" ON)
60 option(FMILIB_LINK_TEST_TO_SHAREDLIB "Link the tests to fmilib_shared (if built) instead of fmilib" ON)
61
62 option(FMILIB_GENERATE_BUILD_STAMP "Generate a build time stamp and include in into the library" OFF)
63 option(FMILIB_ENABLE_LOG_LEVEL_DEBUG "Enable log level 'debug'. If the option is of then the debug level is not compiled in." OFF)
64 option(FMILIB_PRINT_DEBUG_MESSAGES "Enable printing of status messages from the build script. Intended for debugging." OFF)
65 mark_as_advanced(FMILIB_PRINT_DEBUG_MESSAGES FMILIB_DEBUG_TRACE)
66
67 if(NOT FMILIB_BUILD_SHARED_LIB AND NOT FMILIB_BUILD_STATIC_LIB)
68         message(FATAL_ERROR "Either shared or static library build must be chosen")
69 endif()
70
71 if(FMILIB_BUILD_STATIC_LIB AND NOT FMILIB_BUILD_SHARED_LIB)
72         set(FMILIB_STATIC_LIB_ONLY ON)
73 else()
74         set(FMILIB_STATIC_LIB_ONLY OFF)
75 endif()
76
77 if(FMILIB_DEFAULT_BUILD_TYPE_RELEASE)
78         set (FMILIB_DEFAULT_BUILD_TYPE "Release")
79 else()
80         set (FMILIB_DEFAULT_BUILD_TYPE "Debug")
81 endif()
82
83 IF(NOT CMAKE_BUILD_TYPE)
84         SET(CMAKE_BUILD_TYPE ${FMILIB_DEFAULT_BUILD_TYPE})
85 ENDIF(NOT CMAKE_BUILD_TYPE)
86
87 SET(CMAKE_INSTALL_PREFIX ${FMILIB_INSTALL_PREFIX} CACHE INTERNAL "Prefix prepended to install directories" FORCE)
88
89 # debug_message is used to trace the build script
90 function(debug_message)
91         if(FMILIB_PRINT_DEBUG_MESSAGES)
92                 message(STATUS "${ARGV}")
93         endif()
94 endfunction()
95
96 IF(NOT CMAKE_CFG_INTDIR)
97  SET(CMAKE_CFG_INTDIR ${FMILIB_DEFAULT_BUILD_TYPE})
98 ENDIF(NOT CMAKE_CFG_INTDIR)
99
100 if(MSVC)
101         # With C89 we're forced to use non-secure functions
102         ADD_DEFINITIONS (/D _CRT_SECURE_NO_WARNINGS)
103         
104         # Set the run-time library flag as controlled by the FMILIB_BUILD_WITH_STATIC_RTLIB option
105         if(FMILIB_BUILD_WITH_STATIC_RTLIB)
106                 set(BUILD_WITH_STATIC_CRT YES)
107                 set(replace_from "/MD")
108                 set(replace_to "/MT")
109         else()
110                 set(BUILD_WITH_STATIC_CRT NO)
111                 set(replace_from "/MT")
112                 set(replace_to "/MD")
113         endif(FMILIB_BUILD_WITH_STATIC_RTLIB)
114
115         foreach(flag_var
116                 CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
117                 CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO
118                 CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
119                 CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
120                 if(${${flag_var}} MATCHES "${replace_from}")
121                         string(REPLACE "${replace_from}" "${replace_to}" tmp "${${flag_var}}")
122                         set(${flag_var} ${tmp} CACHE STRING "compiler flags" FORCE)
123                 endif()
124         endforeach(flag_var)    
125 endif(MSVC)
126
127 IF(CMAKE_COMPILER_IS_GNUCC)
128    SET(SAVED_C_DEFAULT_FLAGS "${CMAKE_C_FLAGS}")
129    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c89 -pedantic -Wall -Wno-unused-function")
130    if(NOT MSYS)
131         include(CheckCCompilerFlag)
132         CHECK_C_COMPILER_FLAG("-fvisibility=hidden" SUPPORT_VISIBILITY)
133         if(SUPPORT_VISIBILITY)
134                 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
135         endif()
136   endif()
137 ENDIF(CMAKE_COMPILER_IS_GNUCC)
138
139 # The config files will end up in the binary dir
140 include_directories("${FMILibrary_BINARY_DIR}")
141
142 if(FMILIB_BUILD_FOR_SHARED_LIBS) 
143         SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_SHARED_LIBRARY_C_FLAGS}")
144         SET(WITH_PIC ON) # this is used in MERGE_LIBRARIES below
145 endif()
146
147 # prefix each element of list by ${prefix}element
148 macro(PREFIXLIST list_name prefix)
149 # create empty list - necessary?
150         SET(${list_name}_TMP)
151
152     # prefix and suffix elements
153     foreach(l IN LISTS ${list_name})
154       list(APPEND ${list_name}_TMP ${prefix}${l}${suffix} )
155     endforeach()
156         
157     # replace list by tmp list
158     SET(${list_name} ${${list_name}_TMP})
159     UNSET(${list_name}_TMP)
160 endmacro(PREFIXLIST)
161
162 # For MSVC define source groups. Does not work for MSVC 8. MSVC 9 not tested.
163 if(MSVC AND (${CMAKE_GENERATOR} MATCHES "Visual Studio 10"))
164         source_group("Source files\\FMI1" REGULAR_EXPRESSION "fmi1_.*.c") 
165         source_group("Source files\\FMI2" REGULAR_EXPRESSION "fmi2_.*.c") 
166         source_group("Header files\\FMI1" REGULAR_EXPRESSION "fmi1_.*.h") 
167         source_group("Header files\\FMI2" REGULAR_EXPRESSION "fmi2_.*.h") 
168         source_group("Private headers" REGULAR_EXPRESSION "fmi_.*impl.h") 
169         source_group("Private headers\\FMI1" REGULAR_EXPRESSION "fmi1_.*impl.h") 
170         source_group("Private headers\\FMI2" REGULAR_EXPRESSION "fmi2_.*impl.h") 
171 endif()
172
173 set(FMILIBKIND STATIC)
174 if(NOT FMILIB_STATIC_LIB_ONLY)
175         add_definitions(-DFMILIB_BUILDING_LIBRARY)
176 endif()
177
178 include(CheckSymbolExists)
179 include(CheckFunctionExists)
180 CHECK_SYMBOL_EXISTS(va_copy stdarg.h HAVE_VA_COPY)
181 CHECK_SYMBOL_EXISTS(__va_copy stdarg.h HAVE___VA_COPY)
182
183 CHECK_SYMBOL_EXISTS(vsnprintf stdio.h HAVE_VSNPRINTF_SYM)
184 CHECK_FUNCTION_EXISTS(vsnprintf HAVE_VSNPRINTF_FCN)
185
186 MACRO(FMIL_EVAL_CONDITION var_to_store_cond_eval)
187    IF(${ARGN})
188      SET(${var_to_store_cond_eval} 1)
189    ELSE(${ARGN})
190      SET(${var_to_store_cond_eval} 0)
191    ENDIF(${ARGN})
192 ENDMACRO(FMIL_EVAL_CONDITION)
193
194 FMIL_EVAL_CONDITION(HAVE_VSNPRINTF HAVE_VSNPRINTF_SYM OR HAVE_VSNPRINTF_FCN)
195
196 # MSVC < 19.0 (Visual Studio 2015) have a non-standard vsnprintf
197 # implementation. Use the one provided by c99snprintf instead
198 if (MSVC AND (MSVC_VERSION LESS 1900))
199     set(HAVE_VSNPRINTF FALSE)
200 endif()
201
202 add_subdirectory(ThirdParty/c99_snprintf)
203
204 SET(CMAKE_MODULE_PATH ${FMILIBRARYHOME}/Config.cmake)
205
206 include(jmutil)
207 include(fmixml)
208 include(fmicapi)
209 include(fmizip)
210 include(fmiimport)
211
212 #Cmake variables set in config files.
213 if(WIN32)
214         set(FMI_FILE_SEP "\\\\")
215 else(WIN32)
216         set(FMI_FILE_SEP "/")
217 endif(WIN32)
218
219 set(FMILIB_FMI_PLATFORM_DOC "FMI platform defines the subdirectory within FMU where binary is located")
220 set(FMILIB_FMI_PLATFORM ”unknown” CACHE STRING ${FMILIB_FMI_PLATFORM_DOC})
221 if(FMILIB_FMI_PLATFORM MATCHES ”unknown”)
222     include(fmiplatform)
223     fmi_platform(FMI_PLATFORM)
224         set(FMILIB_FMI_PLATFORM ${FMI_PLATFORM} CACHE STRING ${FMILIB_FMI_PLATFORM_DOC} FORCE)
225 else()
226         set(FMI_PLATFORM ${FMILIB_FMI_PLATFORM})
227 endif()
228
229 configure_file (
230   "${FMILibrary_SOURCE_DIR}/Config.cmake/config_fmilib.h.cmake"
231   "${FMILibrary_BINARY_DIR}/fmilib_config.h"
232   ) 
233
234 set(FMILIB_SHARED_SUBLIBS ${FMIXML_LIBRARIES} ${FMIZIP_LIBRARIES} ${FMICAPI_LIBRARIES} expat minizip zlib c99snprintf)
235 set(FMILIB_SUBLIBS ${FMIIMPORT_LIBRARIES} ${JMUTIL_LIBRARIES} ${FMILIB_SHARED_SUBLIBS})
236 set(FMILIB_SHARED_SRC ${FMIIMPORTSOURCE} ${JMUTILSOURCE} ${FMIIMPORTHEADERS})
237
238 if(FMILIB_GENERATE_BUILD_STAMP)
239         debug_message("FMILIB_SUBLIBS= ${FMILIB_SUBLIBS}")
240     add_custom_command(
241                 OUTPUT ${FMILibrary_BINARY_DIR}/config_fmilib.c
242                 COMMAND "${CMAKE_COMMAND}" 
243                         -D FMILIBRARYHOME="${FMILIBRARYHOME}" -D FMILIBRARYBUILD="${FMILIBRARYBUILD}"
244                         -P ${FMILIBRARYHOME}/Config.cmake/config_stamp.cmake
245                 COMMAND ${CMAKE_COMMAND}  -E touch ${FMILibrary_BINARY_DIR}/config_fmilib.c
246                 DEPENDS ${FMILIB_SUBLIBS}
247         )
248         add_library(fmilib_timestamp STATIC ${FMILibrary_BINARY_DIR}/config_fmilib.c "${FMILibrary_BINARY_DIR}/fmilib_config.h")
249 #       add_dependencies(fmilib_timestamp ${FMILIB_SUBLIBS} expat minizip zlib ${FMILIBRARYHOME}/Config.cmake/config_stamp.cmake)
250         
251         set(FMILIB_SUBLIBS ${FMILIB_SUBLIBS} fmilib_timestamp)
252         set(FMILIB_SHARED_SRC ${FMILIB_SHARED_SRC} ${FMILibrary_BINARY_DIR}/config_fmilib.c)
253 endif()
254
255 set_target_properties(
256         ${FMILIB_SUBLIBS}
257     PROPERTIES FOLDER "Sublibs")
258         
259 if(FMILIB_INSTALL_SUBLIBS)
260         set(FMILIB_TARGETS fmiimport jmutils fmizip fmixml fmicapi)
261 endif()
262         
263 if(FMILIB_BUILD_STATIC_LIB)
264         include(mergestaticlibs)
265         if(WIN32)
266                 merge_static_libs(fmilib ${FMILIB_SUBLIBS})
267         target_link_libraries(fmilib Shlwapi)
268         foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES})
269                         set(flags "")
270                         string(TOUPPER "STATIC_LIBRARY_FLAGS_${CONFIG_TYPE}" PROPNAME)
271                         get_target_property(flags fmilib ${PROPNAME})
272                         set_target_properties(fmilib PROPERTIES ${PROPNAME} "${flags} Shlwapi.lib")
273                 endforeach()
274         else()
275                 merge_static_libs(fmilib ${FMILIB_SUBLIBS} )
276         endif(WIN32)
277         if(UNIX) 
278                 target_link_libraries(fmilib dl)
279         endif(UNIX)
280         set(FMILIB_TARGETS ${FMILIB_TARGETS} fmilib)
281 endif()
282
283 if(FMILIB_BUILD_SHARED_LIB)
284         add_library(fmilib_shared SHARED ${FMILIB_SHARED_SRC})
285
286     if (UNIX)
287         target_compile_definitions(fmilib_shared PRIVATE -D_GNU_SOURCE)
288     endif()
289
290         target_link_libraries(fmilib_shared ${FMILIB_SHARED_SUBLIBS})
291         set(FMILIB_TARGETS ${FMILIB_TARGETS} fmilib_shared)
292 endif()
293
294 if(FMILIB_BUILD_TESTS)
295         include(runtime_test)
296         configure_file (
297                 "${FMILibrary_SOURCE_DIR}/Config.cmake/config_test.h.cmake"
298                 "${FMILibrary_BINARY_DIR}/config_test.h"
299         )
300 endif()
301
302 file(COPY "${FMILIBRARYHOME}/Config.cmake/fmilib.h" DESTINATION "${FMILibrary_BINARY_DIR}")
303
304 install(TARGETS ${FMILIB_TARGETS}
305         ARCHIVE DESTINATION lib
306         LIBRARY DESTINATION lib
307         RUNTIME DESTINATION lib
308 )
309 install(FILES 
310                         "${FMILIBRARYHOME}/FMILIB_Readme.txt"
311                         "${FMILIBRARYHOME}/FMILIB_License.txt"
312                         "${FMILIBRARYHOME}/FMILIB_Acknowledgements.txt"
313                 DESTINATION doc)
314                 
315 install(FILES 
316                         "${FMILibrary_BINARY_DIR}/fmilib_config.h" 
317                         "${FMILibrary_BINARY_DIR}/fmilib.h" 
318                 DESTINATION include)
319
320 install(DIRECTORY 
321         ${FMIIMPORTDIR}/include 
322         ${JMUTILDIR}/include
323         DESTINATION .
324     FILES_MATCHING PATTERN "*.h")
325
326 if(FMILIB_INSTALL_SUBLIBS)
327         install(DIRECTORY 
328                 ${FMICAPIDIR}/include   
329                 ${FMIXMLDIR}/include 
330                 ${FMIZIPDIR}/include
331                 DESTINATION .
332         FILES_MATCHING PATTERN "*.h")
333 endif()
334         
335 install(DIRECTORY 
336         ${FMILIB_FMI_STANDARD_HEADERS}/FMI1
337         ${FMILIB_FMI_STANDARD_HEADERS}/FMI2
338         DESTINATION include
339     FILES_MATCHING PATTERN "*.h")
340
341 function(append_file_context file_out file_in)
342         #file(APPEND filename "message to write"... )
343         #file(READ filename variable [LIMIT numBytes] [OFFSET offset] [HEX])
344         file(READ "${file_in}" text)
345         string(REGEX REPLACE "%.*%" " " text "${text}") 
346         file(APPEND ${file_out} "${text}")
347         set(text "")
348 endfunction()
349         
350
351 if(FMILIB_GENERATE_DOXYGEN_DOC)
352
353         file(MAKE_DIRECTORY "${FMILIB_INSTALL_PREFIX}/doc")
354
355         set(DOXYFILE_IN ${FMILIBRARYHOME}/Config.cmake/fmilib_doxydoc.conf CACHE INTERNAL "Doxygen config file")
356         set(DOXYFILE_IMAGE_DIR "${FMILIBRARYHOME}/images" CACHE INTERNAL "Doxygen images" FORCE)
357
358         file(MAKE_DIRECTORY ${FMILIBRARYBUILD}/doc)
359         
360         file(COPY 
361                 "${FMILIBRARYHOME}/Config.cmake/fmilib.h"
362                 "${FMILibrary_BINARY_DIR}/fmilib_config.h"
363                 DESTINATION ${FMILIBRARYBUILD}/doc)
364
365         set(fmilib_mainpage_h "${FMILIBRARYBUILD}/doc/fmilib_mainpage.h")
366         file(WRITE ${fmilib_mainpage_h} "/** @file fmilib_mainpage.h \n @brief Autogenerated file with documentation. \n ")
367         append_file_context(${fmilib_mainpage_h} "${FMILIBRARYHOME}/FMILIB_Readme.txt" )
368         append_file_context(${fmilib_mainpage_h} "${FMILIBRARYHOME}/FMILIB_License.txt" )
369         append_file_context(${fmilib_mainpage_h} "${FMILIBRARYHOME}/FMILIB_Acknowledgements.txt" )
370         file(APPEND ${fmilib_mainpage_h} "*/")
371
372         set(DOXYFILE_SOURCE_DIR "${FMILIBRARYBUILD}/doc" CACHE INTERNAL "Doxygen default source dir" FORCE)
373         set(DOXYFILE_EXTRA_SOURCES "${DOXYFILE_EXTRA_SOURCES} \"${FMILIBRARYHOME}/Test\"")
374
375         set(DOXYFILE_OUTPUT_DIR "${FMILIB_INSTALL_PREFIX}/doc")
376
377         set(DOXYFILE_STRIP_FROM_PATH "${FMILIBRARYHOME}")
378
379         SET(CMAKE_MODULE_PATH ${FMILIB_THIRDPARTYLIBS}/CMakeModules)
380  
381         include(UseDoxygen/UseDoxygen)
382 endif(FMILIB_GENERATE_DOXYGEN_DOC)