| function(append_if condition value) |
| if (${condition}) |
| foreach(variable ${ARGN}) |
| set(${variable} "${${variable}} ${value}" PARENT_SCOPE) |
| endforeach(variable) |
| endif() |
| endfunction() |
| |
| # Set each output directory according to ${CMAKE_CONFIGURATION_TYPES}. |
| # Note: Don't set variables CMAKE_*_OUTPUT_DIRECTORY any more, |
| # or a certain builder, for eaxample, msbuild.exe, would be confused. |
| function(set_output_directory target bindir libdir) |
| # Do nothing if *_OUTPUT_INTDIR is empty. |
| if("${bindir}" STREQUAL "") |
| return() |
| endif() |
| |
| # moddir -- corresponding to LIBRARY_OUTPUT_DIRECTORY. |
| # It affects output of add_library(MODULE). |
| if(WIN32 OR CYGWIN) |
| # DLL platform |
| set(moddir ${bindir}) |
| else() |
| set(moddir ${libdir}) |
| endif() |
| if(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") |
| foreach(build_mode ${CMAKE_CONFIGURATION_TYPES}) |
| string(TOUPPER "${build_mode}" CONFIG_SUFFIX) |
| string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} bi ${bindir}) |
| string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} li ${libdir}) |
| string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} mi ${moddir}) |
| set_target_properties(${target} PROPERTIES "RUNTIME_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${bi}) |
| set_target_properties(${target} PROPERTIES "ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${li}) |
| set_target_properties(${target} PROPERTIES "LIBRARY_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${mi}) |
| endforeach() |
| else() |
| set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${bindir}) |
| set_target_properties(${target} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${libdir}) |
| set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${moddir}) |
| endif() |
| endfunction() |
| |
| macro(add_llbuild_executable name) |
| add_executable(${name} ${ARGN}) |
| |
| set_output_directory(${name} ${LLBUILD_EXECUTABLE_OUTPUT_INTDIR} ${LLBUILD_LIBRARY_OUTPUT_INTDIR}) |
| endmacro() |
| |
| macro(add_llbuild_library name) |
| cmake_parse_arguments(ARG |
| "SHARED" "OUTPUT_NAME" "" |
| ${ARGN}) |
| set(ALL_FILES ${ARG_UNPARSED_ARGUMENTS}) |
| |
| # Add headers to generated project files. |
| if(MSVC_IDE OR XCODE) |
| # Add internal headers. |
| |
| file(GLOB internal_headers *.h) |
| if(internal_headers) |
| set_source_files_properties(${internal_headers} PROPERTIES HEADER_FILE_ONLY ON) |
| list(APPEND ALL_FILES ${internal_headers}) |
| endif() |
| |
| # Add public headers. |
| |
| # Find the library name by finding its relative path. |
| file(RELATIVE_PATH lib_path |
| ${LLBUILD_SRC_DIR}/lib/ |
| ${CMAKE_CURRENT_SOURCE_DIR} |
| ) |
| |
| if(NOT lib_path MATCHES "^[.][.]") |
| file( GLOB_RECURSE headers |
| ${LLBUILD_SRC_DIR}/include/llbuild/${lib_path}/*.h |
| ) |
| set_source_files_properties(${headers} PROPERTIES HEADER_FILE_ONLY ON) |
| |
| list(APPEND ALL_FILES ${headers}) |
| endif() |
| endif(MSVC_IDE OR XCODE) |
| |
| if (ARG_SHARED) |
| add_library(${name} SHARED ${ALL_FILES}) |
| else() |
| add_library(${name} ${ALL_FILES}) |
| endif() |
| |
| set_output_directory(${name} ${LLBUILD_EXECUTABLE_OUTPUT_INTDIR} ${LLBUILD_LIBRARY_OUTPUT_INTDIR}) |
| |
| if(ARG_OUTPUT_NAME) |
| set_target_properties(${name} |
| PROPERTIES |
| OUTPUT_NAME ${ARG_OUTPUT_NAME}) |
| endif() |
| endmacro() |
| |
| # Generic support for adding a unittest. |
| function(add_unittest test_suite test_name) |
| include_directories(${LLBUILD_SRC_DIR}/utils/unittest/googletest/include) |
| |
| add_llbuild_executable(${test_name} ${ARGN}) |
| set_output_directory(${test_name} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} "unused") |
| target_link_libraries(${test_name} gtest gtest_main) |
| |
| add_dependencies(${test_suite} ${test_name}) |
| get_target_property(test_suite_folder ${test_suite} FOLDER) |
| if (NOT ${test_suite_folder} STREQUAL "NOTFOUND") |
| set_property(TARGET ${test_name} PROPERTY FOLDER "${test_suite_folder}") |
| endif () |
| |
| set_property(TARGET ${test_name} APPEND PROPERTY COMPILE_DEFINITIONS GTEST_HAS_RTTI=0) |
| endfunction() |
| |
| # Compile swift sources to a dynamic framework. |
| # Usage: |
| # target # Target name |
| # name # Swift Module name |
| # deps # Target dependencies |
| # sources # List of sources |
| # additional_args # List of additional args to pass |
| function(add_swift_module target name deps sources additional_args) |
| |
| set(BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}) |
| |
| list(APPEND ARGS -module-name ${name}) |
| list(APPEND ARGS -incremental -emit-dependencies -emit-module) |
| list(APPEND ARGS -emit-module-path ${name}.swiftmodule) |
| |
| set(FILEMAP ${BUILD_DIR}/output-file-map.json) |
| set(OUTPUT_FILE_MAP ${FILEMAP}) |
| |
| # Remove old file and start writing new one. |
| file(REMOVE ${FILEMAP}) |
| file(APPEND ${FILEMAP} "{\n") |
| foreach(source ${sources}) |
| file(APPEND ${FILEMAP} "\"${CMAKE_CURRENT_SOURCE_DIR}/${source}\": {\n") |
| file(APPEND ${FILEMAP} "\"dependencies\": \"${BUILD_DIR}/${source}.d\",\n") |
| set(OBJECT ${BUILD_DIR}/${source}.o) |
| list(APPEND OUTPUTS ${OBJECT}) |
| file(APPEND ${FILEMAP} "\"object\": \"${OBJECT}\",\n") |
| file(APPEND ${FILEMAP} "\"swiftmodule\": \"${BUILD_DIR}/${source}~partial.swiftmodule\",\n") |
| file(APPEND ${FILEMAP} "\"swift-dependencies\": \"${BUILD_DIR}/${source}.swiftdeps\"\n},\n") |
| endforeach() |
| file(APPEND ${FILEMAP} "\"\": {\n") |
| file(APPEND ${FILEMAP} "\"swift-dependencies\": \"${BUILD_DIR}/master.swiftdeps\"\n") |
| file(APPEND ${FILEMAP} "}\n") |
| file(APPEND ${FILEMAP} "}") |
| |
| list(APPEND ARGS -output-file-map ${OUTPUT_FILE_MAP}) |
| list(APPEND ARGS -parse-as-library) |
| list(APPEND ARGS -c) |
| |
| foreach(source ${sources}) |
| list(APPEND ARGS ${CMAKE_CURRENT_SOURCE_DIR}/${source}) |
| endforeach() |
| |
| # FIXME: Find a better way to handle build types. |
| if (CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") |
| list(APPEND ARGS -g) |
| endif() |
| if (CMAKE_BUILD_TYPE STREQUAL "Debug") |
| list(APPEND ARGS -Onone -g) |
| else() |
| list(APPEND ARGS -O -whole-module-optimization) |
| endif() |
| |
| foreach(arg ${additional_args}) |
| list(APPEND ARGS ${arg}) |
| endforeach() |
| |
| if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") |
| list(APPEND ARGS -sdk ${CMAKE_OSX_SYSROOT}) |
| endif() |
| |
| # Compile swiftmodule. |
| add_custom_command( |
| OUTPUT ${OUTPUTS} |
| COMMAND swiftc |
| ARGS ${ARGS} |
| DEPENDS ${sources} |
| ) |
| |
| # Link and create dynamic framework. |
| set(DYLIB_OUTPUT ${LLBUILD_LIBRARY_OUTPUT_INTDIR}/${target}.dylib) |
| |
| if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") |
| list(APPEND DYLYB_ARGS -sdk ${CMAKE_OSX_SYSROOT}) |
| endif() |
| |
| list(APPEND DYLYB_ARGS -module-name ${name}) |
| list(APPEND DYLYB_ARGS -o ${DYLIB_OUTPUT}) |
| list(APPEND DYLYB_ARGS -emit-library ${OUTPUTS}) |
| foreach(arg ${additional_args}) |
| list(APPEND DYLYB_ARGS ${arg}) |
| endforeach() |
| list(APPEND DYLYB_ARGS -L ${LLBUILD_LIBRARY_OUTPUT_INTDIR}) |
| |
| add_custom_command( |
| OUTPUT ${DYLIB_OUTPUT} |
| COMMAND swiftc |
| ARGS ${DYLYB_ARGS} |
| DEPENDS ${OUTPUTS} |
| ) |
| |
| # Add the target. |
| add_custom_target(${target} ALL DEPENDS ${deps} ${DYLIB_OUTPUT} ${sources}) |
| endfunction() |