-
Notifications
You must be signed in to change notification settings - Fork 30.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
build: refactor pkg-config for shared libraries #1603
Changes from 8 commits
e7ce51e
38c6195
4365f34
d5990d1
43feb45
82e5af7
524de59
ac3df1b
bb6697f
1f99345
dea139a
0350f14
d8f4f6d
c5fed67
1e1b008
389a667
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -343,17 +343,28 @@ def b(value): | |
|
||
|
||
def pkg_config(pkg): | ||
cmd = os.popen('pkg-config --libs %s' % pkg, 'r') | ||
libs = cmd.readline().strip() | ||
ret = cmd.close() | ||
if (ret): return None | ||
|
||
cmd = os.popen('pkg-config --cflags %s' % pkg, 'r') | ||
cflags = cmd.readline().strip() | ||
ret = cmd.close() | ||
if (ret): return None | ||
|
||
return (libs, cflags) | ||
pkg_config = 'pkg-config' | ||
pkg_config = os.environ.get('PKG_CONFIG', pkg_config) | ||
pkg_config = os.environ.get('PKG_CONFIG_PATH', pkg_config) | ||
args = '--silence-errors' | ||
retval = () | ||
for flag in ['--libs-only-l', '--cflags-only-I', '--libs-only-L']: | ||
try: | ||
val = subprocess.check_output([pkg_config, args, flag, pkg]).rstrip('\n') | ||
except subprocess.CalledProcessError: | ||
# most likely missing a .pc-file | ||
val = None | ||
except OSError: | ||
# no pkg-config/pkgconf installed | ||
return (None, None, None) | ||
retval += (val,) | ||
return retval | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Style: two newlines after functions. |
||
|
||
|
||
def format_libraries(list): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Style: two newlines between functions. |
||
"""Returns string of space separated libraries""" | ||
set = list.split(',') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good point. |
||
return ' '.join('-l{0}'.format(i) for i in set) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, was mixed for readability (based on feedback by bnoordhuis). I previously had format everywhere. |
||
|
||
|
||
def try_check_compiler(cc, lang): | ||
|
@@ -672,41 +683,27 @@ def configure_node(o): | |
o['variables']['node_target_type'] = 'static_library' | ||
|
||
|
||
def configure_libz(o): | ||
o['variables']['node_shared_zlib'] = b(options.shared_zlib) | ||
|
||
if options.shared_zlib: | ||
o['libraries'] += ['-l%s' % options.shared_zlib_libname] | ||
if options.shared_zlib_libpath: | ||
o['libraries'] += ['-L%s' % options.shared_zlib_libpath] | ||
if options.shared_zlib_includes: | ||
o['include_dirs'] += [options.shared_zlib_includes] | ||
|
||
|
||
def configure_http_parser(o): | ||
o['variables']['node_shared_http_parser'] = b(options.shared_http_parser) | ||
|
||
if options.shared_http_parser: | ||
o['libraries'] += ['-l%s' % options.shared_http_parser_libname] | ||
if options.shared_http_parser_libpath: | ||
o['libraries'] += ['-L%s' % options.shared_http_parser_libpath] | ||
if options.shared_http_parser_includes: | ||
o['include_dirs'] += [options.shared_http_parser_includes] | ||
|
||
|
||
def configure_libuv(o): | ||
o['variables']['node_shared_libuv'] = b(options.shared_libuv) | ||
|
||
if options.shared_libuv: | ||
o['libraries'] += ['-l%s' % options.shared_libuv_libname] | ||
if options.shared_libuv_libpath: | ||
o['libraries'] += ['-L%s' % options.shared_libuv_libpath] | ||
else: | ||
o['variables']['uv_library'] = 'static_library' | ||
|
||
if options.shared_libuv_includes: | ||
o['include_dirs'] += [options.shared_libuv_includes] | ||
|
||
def configure_library(lib, output): | ||
shared_lib = 'shared_' + lib | ||
output['variables']['node_' + shared_lib] = b(getattr(options, shared_lib)) | ||
|
||
if getattr(options, shared_lib): | ||
default_cflags = getattr(options, shared_lib + '_includes') | ||
default_lib = format_libraries(getattr(options, shared_lib + '_libname')) | ||
default_libpath = getattr(options, shared_lib + '_libpath') | ||
if default_libpath: | ||
default_libpath = "-L" + default_libpath | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Femto-style nit: can you use single quotes for consistency here and below? |
||
(pkg_libs, pkg_cflags, pkg_libpath) = pkg_config(lib) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will throw a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I always return a tuple -- "worst case" being There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My bad, confused |
||
cflags = pkg_cflags.split("-I") if pkg_cflags else default_cflags | ||
libs = pkg_libs if pkg_libs else default_lib | ||
libpath = pkg_libpath if pkg_libpath else default_libpath | ||
|
||
if libs: | ||
output['libraries'] += libs.split() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok. |
||
if cflags: | ||
output['include_dirs'] += [cflags] | ||
if libpath: | ||
output['libraries'] += [libpath] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Style nit: two newlines. |
||
|
||
def configure_v8(o): | ||
o['variables']['v8_enable_gdbjit'] = 1 if options.gdb else 0 | ||
|
@@ -718,26 +715,11 @@ def configure_v8(o): | |
def configure_openssl(o): | ||
o['variables']['node_use_openssl'] = b(not options.without_ssl) | ||
o['variables']['node_shared_openssl'] = b(options.shared_openssl) | ||
o['variables']['openssl_no_asm'] = ( | ||
1 if options.openssl_no_asm else 0) | ||
o['variables']['openssl_no_asm'] = 1 if options.openssl_no_asm else 0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason not to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not a boolean, its string true or false but the openssl build system requires 1 or 0. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, my bad. |
||
|
||
if options.without_ssl: | ||
return | ||
|
||
if options.shared_openssl: | ||
(libs, cflags) = pkg_config('openssl') or ('-lssl -lcrypto', '') | ||
|
||
libnames = options.shared_openssl_libname.split(',') | ||
o['libraries'] += ['-l%s' % s for s in libnames] | ||
|
||
if options.shared_openssl_libpath: | ||
o['libraries'] += ['-L%s' % options.shared_openssl_libpath] | ||
|
||
if options.shared_openssl_includes: | ||
o['include_dirs'] += [options.shared_openssl_includes] | ||
else: | ||
o['cflags'] += cflags.split() | ||
|
||
configure_library('openssl', o) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Style: two newlines. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about a separate pr with a full pep8 on configure? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I personally don't care that much about pep8. As long as changes are not too incongruent with existing code, they're fine by me. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok; was just looking through the eslint PR and thought we could improve configure as well. |
||
|
||
def configure_fullystatic(o): | ||
if options.fully_static: | ||
|
@@ -857,12 +839,13 @@ def configure_intl(o): | |
# ICU from pkg-config. | ||
o['variables']['v8_enable_i18n_support'] = 1 | ||
pkgicu = pkg_config('icu-i18n') | ||
if not pkgicu: | ||
if pkgicu[1] == None: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, we probably want to check for libs here. I'll update. |
||
print 'Error: could not load pkg-config data for "icu-i18n".' | ||
print 'See above errors or the README.md.' | ||
sys.exit(1) | ||
(libs, cflags) = pkgicu | ||
(libs, cflags, libpath) = pkgicu | ||
o['libraries'] += libs.split() | ||
o['libraries'] += libpath.split() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add a similar comment about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do, this is wrong though -- libpath needs to be treated as a string similar to pkg-config. I might look at refactoring this to using |
||
o['cflags'] += cflags.split() | ||
# use the "system" .gyp | ||
o['variables']['icu_gyp_path'] = 'tools/icu/icu-system.gyp' | ||
|
@@ -1020,15 +1003,18 @@ if (options.dest_os): | |
flavor = GetFlavor(flavor_params) | ||
|
||
configure_node(output) | ||
configure_libz(output) | ||
configure_http_parser(output) | ||
configure_libuv(output) | ||
configure_library('zlib', output) | ||
configure_library('http_parser', output) | ||
configure_library('libuv', output) | ||
configure_v8(output) | ||
configure_openssl(output) | ||
configure_winsdk(output) | ||
configure_intl(output) | ||
configure_fullystatic(output) | ||
|
||
# remove duplicates from libraries | ||
output['libraries'] = list(set(output['libraries'])) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dangerous. You reorder libraries, you ask for symbol resolution failures. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, you're right. Ignore duplicates? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. Just pass whatever you get. Don't do magic, duplicates don't hurt. |
||
|
||
# variables should be a root level element, | ||
# move everything else to target_defaults | ||
variables = output['variables'] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're clobbering the executable with .pc file search paths :P.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PKG_CONFIG is in there for backwards compatibility from the floating pkg-config patch and PKG_CONFIG_PATH is suggested by pkg-config upstream.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whaaat?
PKG_CONFIG
is used by some build systems to point to pkg-config executable.PKG_CONFIG_PATH
contains search path for .pc files.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll re-read the docs. A python library also added it to path which is why I considered it in the first place.