1# This program source code file is part of KICAD, a free EDA CAD application. 2# 3# Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> 4# Copyright (C) 2010-2020 Kicad Developers, see AUTHORS.txt for contributors. 5# 6# This program is free software; you can redistribute it and/or 7# modify it under the terms of the GNU General Public License 8# as published by the Free Software Foundation; either version 2 9# of the License, or (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program; if not, you may find one here: 18# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 19# or you may search the http://www.gnu.org website for the version 2 license, 20# or you may write to the Free Software Foundation, Inc., 21# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 22# 23 24 25# Function make_lexer 26# is a standard way to invoke TokenList2DsnLexer.cmake. 27# Extra arguments are treated as source files which depend on the generated 28# files. Some detail here on the indirection: 29# - Parallel builds all depend on the same files, and CMake will generate the same file multiple times in the same location. 30# This can be problematic if the files are generated at the same time and overwrite each other. 31# - To fix this, we create a custom target (outputTarget) that the parallel builds depend on. 32# AND build dependencies. This creates the needed rebuild for appropriate source object changes. 33function( make_lexer outputTarget inputFile outHeaderFile outCppFile enum ) 34 35 add_custom_command( 36 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${outHeaderFile} 37 ${CMAKE_CURRENT_BINARY_DIR}/${outCppFile} 38 COMMAND ${CMAKE_COMMAND} 39 -Denum=${enum} 40 -DinputFile=${CMAKE_CURRENT_SOURCE_DIR}/${inputFile} 41 -DoutHeaderFile=${CMAKE_CURRENT_BINARY_DIR}/${outHeaderFile} 42 -DoutCppFile=${CMAKE_CURRENT_BINARY_DIR}/${outCppFile} 43 -P ${CMAKE_MODULE_PATH}/BuildSteps/TokenList2DsnLexer.cmake 44 COMMENT "TokenList2DsnLexer.cmake creating: 45 ${outHeaderFile} and 46 ${outCppFile} from 47 ${inputFile}" 48 DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${inputFile} 49 ${CMAKE_MODULE_PATH}/BuildSteps/TokenList2DsnLexer.cmake 50 ) 51 52 target_sources( ${outputTarget} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/${outCppFile} ) 53 target_include_directories( ${outputTarget} PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ) 54endfunction() 55 56 57# Function generate_lemon_grammar 58# 59# This is a function to create a custom command to generate a parser grammar using lemon. 60# 61# Arguments: 62# - TGT is the target to add the consuming file to 63# - GRAMMAR_DIR is the path relative to CMAKE_CURRENT_BINARY_DIR for the directory where the files will be generated into 64# - CONSUMING_FILE is the file relative to CMAKE_CURRENT_SOURCE_DIR that will include the grammar.c/h file 65# - GRAMMAR_FILE is the file relative to CMAKE_CURRENT_SOURCE_DIR of the grammar file to use. 66function( generate_lemon_grammar TGT GRAMMAR_DIR CONSUMING_FILE GRAMMAR_FILE ) 67 # Get the name without extension 68 get_filename_component( GRAMMAR_BASE ${GRAMMAR_FILE} NAME_WE ) 69 70 file( MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${GRAMMAR_DIR} ) 71 72 set( LEMON_EXE $<TARGET_FILE:lemon>) 73 74 get_property( LEMON_TEMPLATE 75 TARGET lemon 76 PROPERTY lemon_template 77 ) 78 79 add_custom_command( 80 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${GRAMMAR_DIR}/${GRAMMAR_BASE}.c 81 ${CMAKE_CURRENT_BINARY_DIR}/${GRAMMAR_DIR}/${GRAMMAR_BASE}.h 82 COMMAND ${CMAKE_COMMAND} 83 -DLEMON_EXE=${LEMON_EXE} 84 -DLEMON_TEMPLATE=${LEMON_TEMPLATE} 85 -DGRAMMAR_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${GRAMMAR_FILE} 86 -DGRAMMAR_DIR=${CMAKE_CURRENT_BINARY_DIR}/${GRAMMAR_DIR} 87 -P ${CMAKE_MODULE_PATH}/BuildSteps/LemonParserGenerator.cmake 88 COMMENT "Running Lemon on ${GRAMMAR_FILE} to generate ${GRAMMAR_DIR}/${GRAMMAR_BASE}.c" 89 DEPENDS lemon 90 ${CMAKE_CURRENT_SOURCE_DIR}/${GRAMMAR_FILE} 91 ${CMAKE_MODULE_PATH}/BuildSteps/LemonParserGenerator.cmake 92 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${GRAMMAR_DIR} 93 ) 94 95 # Mark the consuming file with a direct dependency on the generated grammar so that 96 # it isn't compiled until the grammar is generated 97 set_source_files_properties( 98 ${CMAKE_CURRENT_SOURCE_DIR}/${CONSUMING_FILE} 99 PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${GRAMMAR_DIR}/${GRAMMAR_BASE}.c 100 ) 101 102 target_sources( ${TGT} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/${CONSUMING_FILE} ) 103 target_include_directories( ${TGT} PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ) 104endfunction() 105 106 107# Is a macro instead of function so there's a higher probability that the 108# scope of CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA is global 109macro( add_conffiles ) 110 if( ${ARGC} STREQUAL "0" ) 111 # remove the file when user passes no arguments, which he should do exactly once at top 112 file( REMOVE ${CMAKE_CURRENT_BINARY_DIR}/conffiles ) 113 else() 114 foreach( filename ${ARGV} ) 115 file( APPEND ${CMAKE_CURRENT_BINARY_DIR}/conffiles "${filename}\n" ) 116 endforeach() 117 set( CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA ${CMAKE_CURRENT_BINARY_DIR}/conffiles ) 118 endif() 119endmacro( add_conffiles ) 120 121 122# Function translate_language 123# 124# This is a function to add the targets and install step for translating a language 125# 126# Arguments: 127# - LANG is the code for the language (which must be the same as the directory name) 128# - OUT_FILE is the file (including directory) to save the translations to 129function( translate_language LANG OUT_FILE) 130 # Make the output directory (if it doesn't already exist) 131 get_filename_component( OUT_DIR ${OUT_FILE} DIRECTORY ) 132 133 file( MAKE_DIRECTORY ${OUT_DIR} ) 134 135 add_custom_command( 136 OUTPUT ${OUT_FILE} 137 DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/pofiles/${LANG}.po 138 COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} 139 ${CMAKE_CURRENT_SOURCE_DIR}/pofiles/${LANG}.po 140 -o ${OUT_FILE} 141 COMMENT "Building translation library for ${LANG}" 142 ) 143 144 if( UNIX AND KICAD_I18N_UNIX_STRICT_PATH ) 145 install( FILES ${OUT_FILE} 146 DESTINATION ${KICAD_I18N_PATH}/${LANG}/LC_MESSAGES 147 COMPONENT resources ) 148 else() 149 install( FILES ${OUT_FILE} 150 DESTINATION ${KICAD_I18N_PATH}/${LANG} 151 COMPONENT resources ) 152 endif() 153endfunction() 154 155 156# Function linux_metadata_translation 157# 158# This is a macro to handle the translation of the linux metadata files using 159# the existing .po files. 160# 161# Arguments: 162# - SRC_FILE is the file to use as the translation source 163# - OUT_FILE is the file (including directory) to save the translations to 164# - PO_DIR is the directory containing the raw po files 165macro( linux_metadata_translation SRC_FILE OUT_FILE PO_DIR ) 166 get_filename_component( OUT_DIR ${OUT_FILE} DIRECTORY ) 167 get_filename_component( OUT_FNAME ${OUT_FILE} NAME ) 168 169 file( MAKE_DIRECTORY ${OUT_DIR} ) 170 171 172 # Find all the po files to setup the dependency chain 173 file( STRINGS ${PO_DIR}/LINGUAS LANG_ARRAY REGEX "^[^#].*" ) 174 175 set( LANG_FILES "" ) 176 177 foreach( LANG ${LANG_ARRAY} ) 178 # Keep a list of the language files that are created to add to the target 179 list( APPEND LANG_FILES "${PO_DIR}/${LANG}.po" ) 180 endforeach() 181 182 183 # Add the command to translate the file 184 if( KICAD_BUILD_I18N ) 185 add_custom_command( 186 OUTPUT ${OUT_FILE} 187 DEPENDS ${SRC_FILE} 188 ${LANG_FILES} 189 ${CMAKE_MODULE_PATH}/BuildSteps/TranslatePlatformMetadata_linux.cmake 190 COMMAND ${CMAKE_COMMAND} 191 -DMSGFMT_EXE="${GETTEXT_MSGFMT_EXECUTABLE}" 192 -DPO_DIR="${PO_DIR}" 193 -DSRC_FILE="${SRC_FILE}" 194 -DDEST_FILE="${OUT_FILE}" 195 -P ${CMAKE_MODULE_PATH}/BuildSteps/TranslatePlatformMetadata_linux.cmake 196 COMMENT "Translating file ${OUT_FNAME}" 197 ) 198 else() 199 add_custom_command( 200 OUTPUT ${OUT_FILE} 201 DEPENDS ${SRC_FILE} 202 COMMAND ${CMAKE_COMMAND} -E copy_if_different "${SRC_FILE}" "${OUT_FILE}" 203 COMMENT "Copying file ${OUT_FNAME}" 204 ) 205 endif() 206endmacro() 207