blob: 8631e6c7a15108077898ccda67febae9e245019a [file] [log] [blame]
Mate Toth-Pal76867262018-03-09 13:15:36 +01001#-------------------------------------------------------------------------------
2# Copyright (c) 2018, Arm Limited. All rights reserved.
3#
4# SPDX-License-Identifier: BSD-3-Clause
5#
6#-------------------------------------------------------------------------------
7
8#A cmake script to merge two archives using GNU AR.
9#
10# The script will first run AR to get the list of files in the source archive.
11# Then each file is:
12# -extracted
13# -added to the target archive
14# -deleted
15#
16# The loop is needed to avoid losing files with matching name in the source
17# archive.
18# The destination archive is updated in a way not to overwrite existing files
19# with matching names.
20#
21#Examples:
22# cmake -DCMAKE_AR=arm-none-eabi-ar -DDESTINATION=new_lib.a -DSOURCE=/foo/bar/old_lib.a -P ./GNUArMerge.cmake
23#
24#Parameters:
25# SOURCE - archive file to copy all members from
26# DESTINATION - archive file to copy members to. If file exists, then new
27# members are added without overwriting existing ones.
28# CMAKE_AR - GNU AR executable
29#
30
31#Execute AR and capture its output
32#
33# Script execution will stop with a fatal error if AR execution fails.
34#
35#Examples:
36# List content of archive:
37# run_ar(RESULT t /foo/bar/my_lib.a)
38# Add object file to archive
39# run_ar(RESULT q /foo/bar/my_lib.a new_obj.o)
40#
41#INPUTS:
42# RESULT - (mandatory) - name of variable to put result in
43# All remaining parameters will be command line options to AR
44#
45#OUTPUTS
46# RESULT - text output of AR command
47#
48function(run_ar OUTPUT )
49 execute_process(COMMAND ${CMAKE_AR} ${ARGN}
50 TIMEOUT 120
51 OUTPUT_VARIABLE _RES
52 RESULT_VARIABLE _STATUS_CODE
53 OUTPUT_STRIP_TRAILING_WHITESPACE)
54
55 if (STATUS_CODE GREATER 0)
56 message(FATAL_ERROR "ERROR: Failed to execute \"${CMAKE_AR} ${ARGN}\".")
57 endif()
58 set(${OUTPUT} ${_RES} PARENT_SCOPE)
59endfunction()
60
61#Delete a file
62#
63# Function to delete a file. No error will be reported if file is missing.
64# Script execution will stop with a fatal error if AR execution fails.
65#
66#Examples:
67# rm(/foo/bar/my_lib.a)
68#
69#INPUTS:
70# FILE - path to file to delete
71#
72#OUTPUTS
73# N/A
74#
75function(rm FILE)
76 execute_process(COMMAND ${CMAKE_COMMAND} -E remove ${FILE}
77 RESULT_VARIABLE _STATUS_CODE
78 TIMEOUT 120)
79 if (STATUS_CODE GREATER 0)
80 message(FATAL_ERROR "ERROR: Failed to execute \"${CMAKE_COMMAND} -E remove ${FILE}\".")
81 endif()
82endfunction()
83
84
85#############################################################################
86# Entry point
87#############################################################################
88#Verify input variables.
89
90if(NOT DEFINED SOURCE)
91 message(FATAL_ERROR "GNUArMerge.cmake: Variable SOURCE is not defined.")
92endif()
93
94if(NOT DEFINED DESTINATION)
95 message(FATAL_ERROR "GNUArMerge.cmake: Variable DESTINATION is not defined.")
96endif()
97
98if(NOT DEFINED CMAKE_AR)
99 message(FATAL_ERROR "GNUArMerge.cmake: Variable CMAKE_AR is not defined.")
100endif()
101
102
103#Get list of archive members
104run_ar("OBJ_LIST" t ${SOURCE})
105
106#Convert AR output to cmake list
107string(REPLACE "\n" ";" OBJ_LIST ${OBJ_LIST})
108
109#Iterate over member list.
110foreach(OBJ ${OBJ_LIST})
111 #Extract member
112 run_ar("_DUMMY" x ${SOURCE} ${OBJ})
113 #Add member to destination archive
114 run_ar("_DUMMY" q ${DESTINATION} ${OBJ})
115 #Remove extracted member
116 rm("${OBJ}")
117endforeach()
118
119#Update the symbol table
120run_ar("_DUMMY" s ${DESTINATION})