简体   繁体   English

与链接静态库相比,为什么从源构建时gcc会产生不同的结果?

[英]Why does gcc produce a different result when bulding from source compared to linking a static library?

I have a single C++14 file, my.cpp , and from within it I'm trying to use a C99 library called open62541 . 我有一个C ++ 14文件my.cpp ,并且在其中尝试使用一个名为open62541的C99库。 For the latter, both full source open62541.c/.h and a library libopen62541.a exist. 对于后者,完整源代码open62541.c/.h和库libopen62541.a存在。 In my.cpp , where I include the open62541.h , I'm using C++ specific code (eg iostream), so technically I'm mixing C and C++. my.cpp ,其中包括open62541.h ,我使用的是C ++特定代码(例如iostream),因此从技术上讲,我正在混合C和C ++。

I can get my.cpp to compile successfully by referencing the libopen62541.a : 我可以my.cpp通过引用成功编译libopen62541.a

gcc -x c++ -std=c++14 -Wall my.cpp -l:libopen62541.a -lstdc++ -o out

This outputs no warnings, and creates an executable out . 这不会输出任何警告,并创建一个可执行文件out

However, if I try to compile using source code only: 但是,如果我尝试仅使用源代码进行编译:

gcc -x c++ -std=c++14 -Wall my.cpp open62541.c -lstdc++ -o out

I get a lot of ISO C++ warnings (eg " ISO C++ forbids converting a string constant to 'char '*") and some " jump to label " errors originating from within open62541.c , resulting in compilation failure. 我收到很多ISO C ++警告(例如,“ ISO C ++禁止将字符串常量转换为'char '*”)和源自open62541.c一些“ 跳转到标签 ”错误,导致编译失败。

I can get compilation to succeed by using the -fpermissive switch: 我可以使用-fpermissive开关使编译成功:

gcc -x c++ -std=c++14 -Wall my.cpp open62541.c -lstdc++ -fpermissive -o out

which still outputs a lot of warnings, but creates the executable successfully. 仍然会输出很多警告,但会成功创建可执行文件。 However, I'm unsure if doing this is a good idea. 但是,我不确定这样做是否是个好主意。

Perhaps worth mentioning is that open62541.h considers C++ at the beginning: 也许值得一提的是open62541.h在一开始就考虑使用C ++:

#ifdef __cplusplus
extern "C" {
#endif
  1. Given that .a library, which comes bundled with the open62541 library code, is supposedly built from the same source, why are the first two approaches not consistent in terms of warnings and errors generated? 假设与open62541库代码捆绑在一起的.a库是从同一源构建的,为什么前两种方法在生成警告和错误方面不一致? Why does one work and the other doesn't? 为什么一个起作用而另一个不起作用?

  2. Should one method - linking .a vs referring to .c - be preferred to another? 链接.a与引用.c的一种方法是否应该优先于另一种方法? I was under impression that they should be equivalent, but apparently they aren't. 我的印象是它们应该等效,但显然不是。

  3. Is using -fpermissive in this case more of a hack that could mask potential problems, and should thus be avoided? 在这种情况下,使用-fpermissive是否更多是可以掩盖潜在问题的技巧,因此应避免使用?

The error (and warning) you see are compilation errors (and warning) output by a C++ compiler when compiling C code. 您看到的错误(和警告)是C ++编译器在编译C代码时输出的编译错误(和警告)。

For instance, in C "literal" has type char[] while in C++ it has type const char[] . 例如,在C中, "literal"类型为char[]而在C ++中,其类型为const char[]

Would you get a C++ compiler build libopen62541.a from open62541.c , you would see the same errors (warnings). 您会从open62541.c得到一个C ++编译器libopen62541.a open62541.c ,您将看到相同的错误(警告)。 But a C compiler might be OK with it (depending on the state of that C source file). 但是C编译器可能会满意(取决于该C源文件的状态)。

On the other hand, when you compile my.cpp and links it against libopen62541.a , the compiler doesn't see that offending C code, so no errors (warnings). 另一方面,当编译my.cpp并将其链接到libopen62541.a ,编译器不会看到该冒犯的C代码,因此不会出现错误(警告)。


From here, you basically have two options: 从这里开始,您基本上有两个选择:

  1. Use the procompiled library if it suits you as is 如果适合您,请使用预编译的库

     g++ -std=c++14 -Wall -Wextra -Werror my.cpp -lopen62541.a -o out 
  2. Compile the library's code as a first step if you need to modify it 如果需要修改,请先编译库的代码

     gcc -Wall -Wextra -Werror -c open62541.c g++ -std=c++14 -Wall -Wextra -Werror -c my.cpp g++ open62541.o my.o -o out 
gcc -x c++ -std=c++14 -Wall my.cpp open62541.c -lstdc++ -o out

This command forces the C code in open62541.c to be compiled as C++. 此命令强制将open62541.c的C代码编译为C ++。 That file apparently contains constructs that are valid in C but not C++. 该文件显然包含在C中有效的构造,但在C ++中无效。

What you should be doing is compiling each file as its own language and then linking them together: 您应该做的是将每个文件编译为自己的语言,然后将它们链接在一起:

gcc -std=gnu11 -Wall -c open62541.c
g++ -std=gnu++14 -Wall -c my.cpp
g++ -o out my.o open62541.o

Wrapping up those commands in an easily repeatable package is what Makefiles are for. 将这些命令包装在易于重复的软件包中是Makefile的作用。

If you're wondering why I changed from the strict -std=c++14 to the loose -std=gnu++14 mode, it's because the strict mode is so strict that it may break the system headers! 如果您想知道为什么我从严格的-std=c++14更改为宽松的-std=gnu++14模式,那是因为严格的模式是如此严格,以至于可能破坏系统头文件! You don't need to deal with that on top of everything else. 您无需在所有其他事情上都进行处理。 If you want a more practical additional amount of strictness, try adding -Wextra and -Wpedantic instead ... but be prepared for that to throw lots of warnings that don't actually indicate bugs, on the third-party code. 如果您希望获得更多实用性的严格性,请尝试添加-Wextra和-Wpedantic ...,但是为此准备好在第三方代码上抛出很多实际上并不指示错误的警告。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 GCC链接静态库 - GCC linking a static library 链接静态库两次会导致重复吗? - Does linking a static library twice result in duplication? 当使用具有共享库到可执行文件的静态链接的静态成员时,我在UNIX和WIN上收到不同的结果。请解释原因? - I receive different results on UNIX and WIN when use static members with static linking of shared library to executable. Please explain why? 为什么当调用成员 function 时,ofstream &lt;&lt; 重载会产生不同的结果? - Why does the ofstream << overload produce a different result when called as member function? 为什么GCC中的-Wunused-variable即使在静态const上也会产生错误? - Why does -Wunused-variable in GCC produce an error even on static const? 将静态库链接到共享库时,__attribute __((used))不起作用(android gcc 4.8) - __attribute__((used)) has no effect when linking static library into shared object (android gcc 4.8) 从静态库中剥离所有符号是否会阻止链接? - Does stripping all symbols from a static library prevent linking? 将Rust编译的动态库与gcc链接 - Linking a dynamic library compiled from Rust with gcc 与静态库链接时,为什么要强制执行命令(例如source.cxx -lstatic)? - Why order(e.g. source.cxx -lstatic) is enforced while linking with static library? 使用gcc在C中链接C ++静态库 - Linking C++ static Library in C using gcc
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM