Skip to content
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

support for pure C programs? #2954

Closed
rtsai opened this issue May 5, 2017 · 12 comments
Closed

support for pure C programs? #2954

rtsai opened this issue May 5, 2017 · 12 comments
Labels
P3 We're not considering working on this, but happy to review a PR. (No assignee) team-Rules-CPP Issues for C++ rules type: bug

Comments

@rtsai
Copy link

rtsai commented May 5, 2017

Please provide the following information. The more we know about your system and use case, the more easily and likely we can help.

Description of the problem / feature request / question:

We would like to have better support for building pure C programs (not C++). Specifically, we are cross-compiling to a target platform where the boot-time file system does not have libstdc++, but the cc_binary output for that C program has a dynamic link dependency on -lstdc++. The CROSSTOOL linker_flag points to -lstdc++, which is what we want for all the other C++ programs that run after the root file system has been mounted. We can work around this by using "-static" for that particular program, but then we also lose dynamic linking for other things we do have (e.g., libc.so).

If possible, provide a minimal example to reproduce the problem:

Write and build a pure C program. "ldd" on the resulting output will show a dependency on libstdc++

Environment info

  • Operating System: Ubuntu-16.04.2 LTS
  • Bazel version (output of bazel info release): 0.4.5

Have you found anything relevant by searching the web?

#2548

Anything else, information or logs or outputs that would be helpful?

https://groups.google.com/d/msg/bazel-discuss/iYzl5XfMDWE/HGV9MUx3AAAJ

One thing we think might work is to create a new CROSSTOOL that is basically a copy of the regular one, but with "linker_flag -lstdc++" removed. This seems to work, but is undesirable, since we do in fact predominantly use C++. Using a different crosstool_top for different packages is undesirable because package-type rules ("create a tarball") don't seem to support depending on outputs of a different build configuration ("create a package of mostly C++ programs, except for this C program").

So the next step might be to introduce a new cc_{binary,library} attribute "lang"

cc_binary(..., lang="c | c++", ...) which defaults to "c++".

The implementation for "c" would then forbid depending on "c++" providers

The CROSSTOOL configuration would have to add a "cxx_linker_flag" field to be used only when linking C++ programs. The existing "linker_flag" can continue to be used for both C and C++ programs.

@kchodorow
Copy link
Contributor

kchodorow commented May 8, 2017

@katre, could you comment on this from a configurations perspective? Right now, Bazel can only use one toolchain for a build, although we are working on fixing that.

One thing you might be able to work around this is to go ahead and create a custom C toolchain without the -lstdc++ flag and then create a macro like:

def cpp_library(name, srcs, hdrs, deps):
  native.cc_library(
    name = name,
    srcs = srcs,
    hdrs = hdrs,
    deps = deps,
    linkopts = ['-lstdc++'],
  )

Then use cpp_library whenever you use C++ and cc_library for pure C.

@kchodorow kchodorow added category: extensibility > configurability P2 We'll consider working on this in future. (Assignee optional) type: bug labels May 8, 2017
@katre
Copy link
Member

katre commented May 8, 2017

I'm working on #2219, which leads to exposing specific toolchains for different rule types. For the cc rules, this will basically allow wrapping the existing CROSSTOOL functionality in a way that is easier to switch, but it will still be a single choice of toolchain for an invocation, not allowing using different toolchains in the same build.

We have had discussions about allowing specifying the toolchain on a target-by-target basis, which would allow what you want here, but that's unlikely to land in the next half year or so.

@rtsai
Copy link
Author

rtsai commented May 9, 2017

We will have to pursue the custom macro.

My feedback as a user is that C/C++ are similar enough to warrant something built-in and less-heavyweight than having to switch crosstools (e.g., something similar to the macro described above) - they are more similar than, say, cc_library and python_library. That will have impact on whatever syntax is used for including those artifacts in dependencies ("tarball of C/C++ programs"), etc. We are pulling in a decent number of third_party open-source projects that happen to be pure C programs, but through accident of bazel are actually being built as C++ programs.

Thank you!

@kchodorow
Copy link
Contributor

Agreed that C and C++ rules should be close cousins! Sorry for the inconvenience.

@kchodorow kchodorow added P3 We're not considering working on this, but happy to review a PR. (No assignee) and removed P2 We'll consider working on this in future. (Assignee optional) labels May 9, 2017
@ulfjack
Copy link
Contributor

ulfjack commented May 10, 2017

I think we should make it so the cc_* rules automatically detect if there are only .c files in srcs, and then not add -lstdc++ to the final link. That should be straightforward to do and doesn't require any configuration shenanigans.

@hlopko
Copy link
Member

hlopko commented May 10, 2017

One possible approach that works already is to define a crosstool feature adding "-lstdc++" (let's call it cxxstdlib), but instead of implying it from the action_configs you'd enable it from .bazelrc (--features=cxxstdlib) so it's enabled by default, and then disable it for individual packages (package(..., features = ["-cxxstdlib"])) or rules (cc_library(..., features = ["-cxxstdlib"]...).

@rtsai
Copy link
Author

rtsai commented Jul 26, 2017

Thank you very much for the suggestion. Things seem to be working.

Can you please confirm this is correct? My CROSSTOOL diff (basically the same as that in @local_config_cc/CROSSTOOL):

@@ -39,7 +40,6 @@ toolchain {
   target_system_name: "local"
   cxx_flag: "-std=c++0x"
-  linker_flag: "-lstdc++"
   linker_flag: "-lm"
   linker_flag: "-fuse-ld=gold"
   linker_flag: "-Wl,-no-as-needed"
@@ -84,6 +84,19 @@ toolchain {
   tool_path {name: "gcc" path: "/usr/bin/gcc" }
   tool_path {name: "ar" path: "/usr/bin/ar" }
 
+  feature {
+    # See https://github.com/bazelbuild/bazel/issues/2954
+    name: 'cxxstdlib'
+    flag_set {
+      action: 'c++-link-executable'
+      flag_group {
+        flag: '-lstdc++'
+      }
+    }
+  }
+

My BUILD file:

diff --git a/BUILD b/BUILD
index 0589bbd..de81b7e 100644
--- a/BUILD
+++ b/BUILD
@@ -1,4 +1,7 @@
-package(default_visibility = ["//visibility:private"])
+package(
+    default_visibility = ["//visibility:private"],
+    features = ["-cxxstdlib"],
+)

Are there any "reserved words" for feature names that I should avoid using? :)

Thank you so much!

@hlopko
Copy link
Member

hlopko commented Jul 27, 2017

You might want to add the feature to c++-link-dynamic-library action too. Otherwise looks good, hope it will work :)

jayconrod pushed a commit to jayconrod/rules_go that referenced this issue Aug 24, 2018
This avoids an unnecessary run-time dependency on libstdc++.so, which
may not be present in container environments.

go build only adds this dependency if C++ code is included in the
build. We now filter out this dependency from the cc toolchain flags
unless we have C++/ObjC source or we have a dependency on a cc_library
or objc_library.

Fixes bazelbuild#1681
Related bazelbuild/bazel#2954
jayconrod pushed a commit to jayconrod/rules_go that referenced this issue Aug 24, 2018
This avoids an unnecessary run-time dependency on libstdc++.so, which
may not be present in container environments.

go build only adds this dependency if C++ code is included in the
build. We now filter out this dependency from the cc toolchain flags
unless we have C++/ObjC source or we have a dependency on a cc_library
or objc_library.

Fixes bazelbuild#1681
Related bazelbuild/bazel#2954
jayconrod pushed a commit to jayconrod/rules_go that referenced this issue Aug 24, 2018
This avoids an unnecessary run-time dependency on libstdc++.so, which
may not be present in container environments.

go build only adds this dependency if C++ code is included in the
build. We now filter out this dependency from the cc toolchain flags
unless we have C++/ObjC source or we have a dependency on a cc_library
or objc_library.

Fixes bazelbuild#1681
Related bazelbuild/bazel#2954
jayconrod added a commit to bazelbuild/rules_go that referenced this issue Aug 24, 2018
This avoids an unnecessary run-time dependency on libstdc++.so, which
may not be present in container environments.

go build only adds this dependency if C++ code is included in the
build. We now filter out this dependency from the cc toolchain flags
unless we have C++/ObjC source or we have a dependency on a cc_library
or objc_library.

Fixes #1681
Related bazelbuild/bazel#2954
jayconrod added a commit to bazelbuild/rules_go that referenced this issue Sep 5, 2018
This avoids an unnecessary run-time dependency on libstdc++.so, which
may not be present in container environments.

go build only adds this dependency if C++ code is included in the
build. We now filter out this dependency from the cc toolchain flags
unless we have C++/ObjC source or we have a dependency on a cc_library
or objc_library.

Fixes #1681
Related bazelbuild/bazel#2954
@hlopko hlopko added team-Rules-CPP Issues for C++ rules and removed category: rules > C++ labels Oct 11, 2018
@hlopko hlopko added Bazel 1.0 and removed P3 We're not considering working on this, but happy to review a PR. (No assignee) labels Nov 28, 2018
@lberki lberki removed the bazel 1.0 label Jul 25, 2019
@scentini scentini added P2 We'll consider working on this in future. (Assignee optional) and removed untriaged labels Jul 29, 2019
@c-mita c-mita added P3 We're not considering working on this, but happy to review a PR. (No assignee) and removed P2 We'll consider working on this in future. (Assignee optional) labels Nov 24, 2020
@jheaff1
Copy link
Contributor

jheaff1 commented Sep 29, 2021

I too would like to be able to compile a pure C application without linking to libstdc++. Any progress on this issue?

jheaff1 added a commit to jheaff1/bazel that referenced this issue Feb 6, 2022
This commit splits the user_link_flags_feature so that the default link
libs (i.e libstdc++ and libm) can be removed from the linker command
line by specifying "-default_link_libs" as a cc "feature".
jheaff1 added a commit to jheaff1/bazel that referenced this issue Feb 6, 2022
This commit splits the user_link_flags_feature so that the default link
libs (i.e libstdc++ and libm) can be removed from the linker command
line by specifying "-default_link_libs" as a cc "feature".
copybara-service bot pushed a commit that referenced this issue Jul 20, 2022
This commit splits the user_link_flags_feature so that the default link
libs (i.e libstdc++ and libm) can be removed from the linker command
line by specifying "-default_link_libs" as a cc "feature".

Closes #14736.

PiperOrigin-RevId: 462123947
Change-Id: I03a6cfc552d6aab0fd603eb42616d0cd0e085aea
@jheaff1
Copy link
Contributor

jheaff1 commented Jul 20, 2022

Resolved by #14736

aranguyen pushed a commit to aranguyen/bazel that referenced this issue Jul 20, 2022
This commit splits the user_link_flags_feature so that the default link
libs (i.e libstdc++ and libm) can be removed from the linker command
line by specifying "-default_link_libs" as a cc "feature".

Closes bazelbuild#14736.

PiperOrigin-RevId: 462123947
Change-Id: I03a6cfc552d6aab0fd603eb42616d0cd0e085aea
aranguyen pushed a commit to aranguyen/bazel that referenced this issue Jul 20, 2022
This commit splits the user_link_flags_feature so that the default link
libs (i.e libstdc++ and libm) can be removed from the linker command
line by specifying "-default_link_libs" as a cc "feature".

Closes bazelbuild#14736.

PiperOrigin-RevId: 462123947
Change-Id: I03a6cfc552d6aab0fd603eb42616d0cd0e085aea
@fmeum
Copy link
Collaborator

fmeum commented Dec 12, 2022

@sgowroji Can be closed based on #2954 (comment)

@sgowroji
Copy link
Member

We are closing this issue w.r.t the above comment. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P3 We're not considering working on this, but happy to review a PR. (No assignee) team-Rules-CPP Issues for C++ rules type: bug
Projects
None yet
Development

No branches or pull requests