function addOpenMPSupport(tcInfo, buildInfo, isCpp)
%ADDOPENMPSUPPORT extracts compiler and linker flags for OpenMP from the toolchain definition
%and adds them to buildInfo. It should be called at the compile stage when the compiler has
%been selected.

% Copyright 2018-2020 The MathWorks, Inc.
    if isempty(tcInfo)
        DAStudio.error('RTW:buildProcess:InvalidAddOpenMPSupportFirstArgument');
    end
    
    if tcInfo.hasCustomBuildConfiguration('OpenMP')
        [libs, libPaths, linkFlags] = locParseLinkFlags(tcInfo, isCpp);
        if isCpp
            compileFlags = tcInfo.getCustomBuildConfigurationOption('OpenMP','C++ Compiler');
        else
            compileFlags = tcInfo.getCustomBuildConfigurationOption('OpenMP','C Compiler');
        end
    else
        % error out because the toolchain does not have OpenMP support.
        DAStudio.error('coder_compile:toolchain:NotSupportOpenMP', tcInfo.Name);
    end

    % Expand MATLAB_ROOT and ARCH. TMF-based targets (e.g. raccel) passes
    % OPTS directly to the make command, which causes shell error in Mac.
    compileFlags = strrep(compileFlags, '$(MATLAB_ROOT)', matlabroot);
    compileFlags = strrep(compileFlags, '$(ARCH)', computer('arch'));

    buildInfo.addCompileFlags(compileFlags, 'OPTS');
    buildInfo.addLinkFlags(linkFlags);
    buildInfo.addSysLibs(libs, libPaths, 'Standard');
    
end

function [libs, libPaths, linkFlags] = locParseLinkFlags(tcInfo, isCpp)
%Some toolchains (ms_vc and gnu_gcc) store the openmp library inside link flags. This
%function parses the link flags for openmp obtained from toolchain, and outputs the
%library, the library path and the link flags.
    if isCpp
        btName = 'C++ Linker';
    else
        btName = 'Linker';
    end
    opts = tcInfo.getCustomBuildConfigurationOption('OpenMP',btName);

    % ----------------------------------------------------
    % libPaths
    % ----------------------------------------------------
    if ispc
        % TO DO: The if statement is need because ms_vc.m defines the LibrarySearchPath 
        % Directive as "-LIBPATH:". Changing it to "/LIBPATH:" causes issues with 
        % ERT S-function. Once the issue is fixed, the if statement can be removed.
        libPathDirective = '/LIBPATH:';
    else
        libPathDirective = tcInfo.getBuildTool(btName).getDirective('LibrarySearchPath'); %'-L'
    end 
    exp = [libPathDirective, '\S+']; % non-space characters start with libPathDirective
    libPaths = regexp(opts, exp, 'match');
    % remove libPathDirective
    libPaths = regexprep(libPaths, ['^', libPathDirective], '');
    % replace $(ARCH) with computer('arch')
    libPaths = regexprep(libPaths, '\$\(ARCH\)', computer('arch'));
    
    % remove lib paths from link flags obtained from toolchain
    opts = regexprep(opts, exp, '');

    % ----------------------------------------------------
    % libs
    % ----------------------------------------------------
    if ispc
        libExt = tcInfo.getBuildTool( 'Archiver' ).getFileExtension( 'Static Library' ); %'.lib'
        exp = ['\S+\', libExt]; % '\S+\.lib' non-space characters end with .lib
        libs = regexp(opts, exp, 'match');
        % On Windows, system library is in the format of lib<library_name>.lib. Extract
        % only the <library_name>.
        libs = regexprep( regexprep( libs, ['\', libExt], '' ), '^lib', '' );
    else
        libDirective= tcInfo.getBuildTool( 'Linker' ).getDirective( 'Library' ); %'-l'
        exp = [libDirective, '\S+']; %'-l\S+' non-space characters start with -l
        libs = regexp(opts, exp, 'match');
        % On Linux, library is in the format of -l<library_name>. Extract only the
        % <library_name>.
        libs = regexprep( libs, ['^', libDirective], '' );
    end

    % ----------------------------------------------------
    % linkFlags
    % ----------------------------------------------------
    % remove libs. Now what is left is the link flags.
    linkFlags = regexprep(opts, exp, '');
    if isempty(regexp(linkFlags, '\S+', 'once'))
        % if linkFlags only has white-spaces, set it to empty.
        linkFlags = '';
    end
end
