Link both iOS and tvOS libraries with react-native link (fix #13783)
Summary: Fix issues with the react-native CLI when linking iOS and tvOS libraries to a project created with `react-native init`. (#13783) Verified the changes against test project at https://github.com/dlowder-salesforce/react-native-link-test. Both `react-native link react-native-svg` and `react-native unlink react-native-svg` work correctly on this project. Added new unit test for the new file added to `local-cli/link/ios`. [CLI] [BUGFIX] `react-native link` has been fixed to correctly link iOS and tvOS targets. [IOS] [BUGFIX] `react-native link` has been fixed to correctly link iOS and tvOS targets. Closes https://github.com/facebook/react-native/pull/17231 Differential Revision: D6837567 Pulled By: hramos fbshipit-source-id: 234d3d3966ae1b89cd16a37c95d303553f7ba5f5
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 90 KiB |
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 165 KiB |
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 127 KiB |
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 96 KiB |
@ -46,9 +46,8 @@
|
|||||||
self.keyLabel.numberOfLines = 0;
|
self.keyLabel.numberOfLines = 0;
|
||||||
#if !TARGET_OS_TV
|
#if !TARGET_OS_TV
|
||||||
self.keyLabel.lineBreakMode = UILineBreakModeWordWrap;
|
self.keyLabel.lineBreakMode = UILineBreakModeWordWrap;
|
||||||
#endif
|
|
||||||
self.keyLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:12.0f];
|
self.keyLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:12.0f];
|
||||||
|
#endif
|
||||||
self.valueLabel = [UILabel new];
|
self.valueLabel = [UILabel new];
|
||||||
[self.contentView addSubview:self.valueLabel];
|
[self.contentView addSubview:self.valueLabel];
|
||||||
|
|
||||||
@ -67,8 +66,8 @@
|
|||||||
self.valueLabel.numberOfLines = 0;
|
self.valueLabel.numberOfLines = 0;
|
||||||
#if !TARGET_OS_TV
|
#if !TARGET_OS_TV
|
||||||
self.valueLabel.lineBreakMode = UILineBreakModeWordWrap;
|
self.valueLabel.lineBreakMode = UILineBreakModeWordWrap;
|
||||||
#endif
|
|
||||||
self.valueLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:12.0f];
|
self.valueLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:12.0f];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -256,6 +256,7 @@
|
|||||||
27595AD61E575C7800CCE2B1 /* Platform.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D21E03699D0018521A /* Platform.h */; };
|
27595AD61E575C7800CCE2B1 /* Platform.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D21E03699D0018521A /* Platform.h */; };
|
||||||
27595AD71E575C7800CCE2B1 /* SampleCxxModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D41E03699D0018521A /* SampleCxxModule.h */; };
|
27595AD71E575C7800CCE2B1 /* SampleCxxModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D41E03699D0018521A /* SampleCxxModule.h */; };
|
||||||
27595AD81E575C7800CCE2B1 /* SystraceSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D51E03699D0018521A /* SystraceSection.h */; };
|
27595AD81E575C7800CCE2B1 /* SystraceSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D51E03699D0018521A /* SystraceSection.h */; };
|
||||||
|
2D0EB9F32021067800CAF88A /* RCTUIUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = F1EFDA4E201F660F00EE6E4C /* RCTUIUtils.m */; };
|
||||||
2D16E68E1FA4FD3900B85C8A /* RCTTVNavigationEventEmitter.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D0B842D1EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.h */; };
|
2D16E68E1FA4FD3900B85C8A /* RCTTVNavigationEventEmitter.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D0B842D1EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.h */; };
|
||||||
2D1D83CD1F74E2CE00615550 /* libprivatedata-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9936F32F1F5F2E5B0010BF04 /* libprivatedata-tvOS.a */; };
|
2D1D83CD1F74E2CE00615550 /* libprivatedata-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9936F32F1F5F2E5B0010BF04 /* libprivatedata-tvOS.a */; };
|
||||||
2D1D83CE1F74E2DA00615550 /* libdouble-conversion.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D383D621EBD27B9005632C8 /* libdouble-conversion.a */; };
|
2D1D83CE1F74E2DA00615550 /* libdouble-conversion.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D383D621EBD27B9005632C8 /* libdouble-conversion.a */; };
|
||||||
@ -328,6 +329,7 @@
|
|||||||
2D3B5EF11D9B09E700451313 /* UIView+React.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E067541A70F44B002CDEE1 /* UIView+React.m */; };
|
2D3B5EF11D9B09E700451313 /* UIView+React.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E067541A70F44B002CDEE1 /* UIView+React.m */; };
|
||||||
2D74EAFA1DAE9590003B751B /* RCTMultipartDataTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 006FC4131D9B20820057AAAD /* RCTMultipartDataTask.m */; };
|
2D74EAFA1DAE9590003B751B /* RCTMultipartDataTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 006FC4131D9B20820057AAAD /* RCTMultipartDataTask.m */; };
|
||||||
2D8C2E331DA40441000EE098 /* RCTMultipartStreamReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 001BFCCF1D8381DE008E587E /* RCTMultipartStreamReader.m */; };
|
2D8C2E331DA40441000EE098 /* RCTMultipartStreamReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 001BFCCF1D8381DE008E587E /* RCTMultipartStreamReader.m */; };
|
||||||
|
2DCCC3151FE48142007C5315 /* RCTRedBoxExtraDataViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FEFAAC9C1FDB89B40057BBE0 /* RCTRedBoxExtraDataViewController.m */; };
|
||||||
2DD0EFE11DA84F2800B0C975 /* RCTStatusBarManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13723B4F1A82FD3C00F88898 /* RCTStatusBarManager.m */; };
|
2DD0EFE11DA84F2800B0C975 /* RCTStatusBarManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13723B4F1A82FD3C00F88898 /* RCTStatusBarManager.m */; };
|
||||||
352DCFF01D19F4C20056D623 /* RCTI18nUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 352DCFEF1D19F4C20056D623 /* RCTI18nUtil.m */; };
|
352DCFF01D19F4C20056D623 /* RCTI18nUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 352DCFEF1D19F4C20056D623 /* RCTI18nUtil.m */; };
|
||||||
369123E11DDC75850095B341 /* RCTJSCSamplingProfiler.m in Sources */ = {isa = PBXBuildFile; fileRef = 369123E01DDC75850095B341 /* RCTJSCSamplingProfiler.m */; };
|
369123E11DDC75850095B341 /* RCTJSCSamplingProfiler.m in Sources */ = {isa = PBXBuildFile; fileRef = 369123E01DDC75850095B341 /* RCTJSCSamplingProfiler.m */; };
|
||||||
@ -4108,6 +4110,7 @@
|
|||||||
598FD1931F817284006C54CB /* PrivateDataBase.cpp in Sources */,
|
598FD1931F817284006C54CB /* PrivateDataBase.cpp in Sources */,
|
||||||
3DC159E41E83E1AE007B1282 /* RCTRootContentView.m in Sources */,
|
3DC159E41E83E1AE007B1282 /* RCTRootContentView.m in Sources */,
|
||||||
3D80D91B1DF6F8200028D040 /* RCTPlatform.m in Sources */,
|
3D80D91B1DF6F8200028D040 /* RCTPlatform.m in Sources */,
|
||||||
|
2D0EB9F32021067800CAF88A /* RCTUIUtils.m in Sources */,
|
||||||
2DD0EFE11DA84F2800B0C975 /* RCTStatusBarManager.m in Sources */,
|
2DD0EFE11DA84F2800B0C975 /* RCTStatusBarManager.m in Sources */,
|
||||||
2D3B5EC91D9B095C00451313 /* RCTBorderDrawing.m in Sources */,
|
2D3B5EC91D9B095C00451313 /* RCTBorderDrawing.m in Sources */,
|
||||||
66CD94B81F1045E700CB3C7C /* RCTMaskedViewManager.m in Sources */,
|
66CD94B81F1045E700CB3C7C /* RCTMaskedViewManager.m in Sources */,
|
||||||
@ -4166,6 +4169,7 @@
|
|||||||
C606692F1F3CC60500E67165 /* RCTModuleMethod.mm in Sources */,
|
C606692F1F3CC60500E67165 /* RCTModuleMethod.mm in Sources */,
|
||||||
2D3B5E9F1D9B08AF00451313 /* RCTKeyCommands.m in Sources */,
|
2D3B5E9F1D9B08AF00451313 /* RCTKeyCommands.m in Sources */,
|
||||||
2D3B5EA51D9B08C700451313 /* RCTRootView.m in Sources */,
|
2D3B5EA51D9B08C700451313 /* RCTRootView.m in Sources */,
|
||||||
|
2DCCC3151FE48142007C5315 /* RCTRedBoxExtraDataViewController.m in Sources */,
|
||||||
13134C871E296B2A00B9F3CB /* RCTCxxBridge.mm in Sources */,
|
13134C871E296B2A00B9F3CB /* RCTCxxBridge.mm in Sources */,
|
||||||
CF2731C31E7B8DF30044CA4F /* RCTDeviceInfo.m in Sources */,
|
CF2731C31E7B8DF30044CA4F /* RCTDeviceInfo.m in Sources */,
|
||||||
599FAA3F1FB274980058CCF6 /* RCTSurfaceRootShadowView.m in Sources */,
|
599FAA3F1FB274980058CCF6 /* RCTSurfaceRootShadowView.m in Sources */,
|
||||||
|
35
local-cli/link/__tests__/ios/getTargets.spec.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2013-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* @emails oncall+javascript_foundation
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const xcode = require('xcode');
|
||||||
|
const getTargets = require('../../ios/getTargets');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const project = xcode.project(
|
||||||
|
path.join(__dirname, '../../__fixtures__/project.pbxproj')
|
||||||
|
);
|
||||||
|
|
||||||
|
describe('ios::getTargets', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
project.parseSync();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an array of project targets', () => {
|
||||||
|
const targets = getTargets(project);
|
||||||
|
expect(targets.length).toBe(2);
|
||||||
|
expect(targets[0].name).toContain('Basic.app');
|
||||||
|
expect(targets[1].name).toContain('BasicTests.xctest');
|
||||||
|
});
|
||||||
|
});
|
20
local-cli/link/ios/getTargets.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* Given xcodeproj it returns list of targets
|
||||||
|
*/
|
||||||
|
module.exports = function getTargets(project) {
|
||||||
|
let targets = project.getFirstProject().firstProject.targets;
|
||||||
|
let nativeTargetSection = project.pbxNativeTargetSection();
|
||||||
|
return targets.map(function(target) {
|
||||||
|
let key = target.value;
|
||||||
|
let configurationListId = project.pbxNativeTargetSection()[key].buildConfigurationList;
|
||||||
|
let configurationList = project.pbxXCConfigurationList()[configurationListId];
|
||||||
|
let buildConfigurationId = configurationList.buildConfigurations[0].value;
|
||||||
|
let buildConfiguration = project.pbxXCBuildConfigurationSection()[buildConfigurationId];
|
||||||
|
return {
|
||||||
|
uuid: key,
|
||||||
|
target: nativeTargetSection[key],
|
||||||
|
name: nativeTargetSection[key].productReference_comment,
|
||||||
|
isTVOS: (buildConfiguration.buildSettings.SDKROOT && (buildConfiguration.buildSettings.SDKROOT.indexOf('appletv') !== -1)) || false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
@ -7,6 +7,7 @@ const addToHeaderSearchPaths = require('./addToHeaderSearchPaths');
|
|||||||
const getHeadersInFolder = require('./getHeadersInFolder');
|
const getHeadersInFolder = require('./getHeadersInFolder');
|
||||||
const getHeaderSearchPath = require('./getHeaderSearchPath');
|
const getHeaderSearchPath = require('./getHeaderSearchPath');
|
||||||
const getProducts = require('./getProducts');
|
const getProducts = require('./getProducts');
|
||||||
|
const getTargets = require('./getTargets');
|
||||||
const createGroupWithMessage = require('./createGroupWithMessage');
|
const createGroupWithMessage = require('./createGroupWithMessage');
|
||||||
const addFileToProject = require('./addFileToProject');
|
const addFileToProject = require('./addFileToProject');
|
||||||
const addProjectToLibraries = require('./addProjectToLibraries');
|
const addProjectToLibraries = require('./addProjectToLibraries');
|
||||||
@ -31,12 +32,31 @@ module.exports = function registerNativeModuleIOS(dependencyConfig, projectConfi
|
|||||||
path.relative(projectConfig.sourceDir, dependencyConfig.projectPath)
|
path.relative(projectConfig.sourceDir, dependencyConfig.projectPath)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const targets = getTargets(project);
|
||||||
|
|
||||||
addProjectToLibraries(libraries, file);
|
addProjectToLibraries(libraries, file);
|
||||||
|
|
||||||
getProducts(dependencyProject).forEach(product => {
|
getTargets(dependencyProject).forEach(product => {
|
||||||
project.addStaticLibrary(product, {
|
var i;
|
||||||
target: project.getFirstTarget().uuid,
|
if (!product.isTVOS) {
|
||||||
|
for (i=0; i<targets.length; i++) {
|
||||||
|
if(!targets[i].isTVOS) {
|
||||||
|
project.addStaticLibrary(product.name, {
|
||||||
|
target: targets[i].uuid
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (product.isTVOS) {
|
||||||
|
for (i=0; i<targets.length; i++) {
|
||||||
|
if(targets[i].isTVOS) {
|
||||||
|
project.addStaticLibrary(product.name, {
|
||||||
|
target: targets[i].uuid
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
addSharedLibraries(project, dependencyConfig.sharedLibraries);
|
addSharedLibraries(project, dependencyConfig.sharedLibraries);
|
||||||
|
@ -6,6 +6,7 @@ const isEmpty = require('lodash').isEmpty;
|
|||||||
|
|
||||||
const getGroup = require('./getGroup');
|
const getGroup = require('./getGroup');
|
||||||
const getProducts = require('./getProducts');
|
const getProducts = require('./getProducts');
|
||||||
|
const getTargets = require('./getTargets');
|
||||||
const getHeadersInFolder = require('./getHeadersInFolder');
|
const getHeadersInFolder = require('./getHeadersInFolder');
|
||||||
const getHeaderSearchPath = require('./getHeaderSearchPath');
|
const getHeaderSearchPath = require('./getHeaderSearchPath');
|
||||||
const removeProjectFromProject = require('./removeProjectFromProject');
|
const removeProjectFromProject = require('./removeProjectFromProject');
|
||||||
@ -32,8 +33,8 @@ module.exports = function unregisterNativeModule(dependencyConfig, projectConfig
|
|||||||
|
|
||||||
removeProjectFromLibraries(libraries, file);
|
removeProjectFromLibraries(libraries, file);
|
||||||
|
|
||||||
getProducts(dependencyProject).forEach(product => {
|
getTargets(dependencyProject).forEach(target => {
|
||||||
removeFromStaticLibraries(project, product, {
|
removeFromStaticLibraries(project, target.name, {
|
||||||
target: project.getFirstTarget().uuid,
|
target: project.getFirstTarget().uuid,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|