Including a .tag file for a library which itself includes a .tag file can provoke duplicate anchor warnings - doxygen

I have three libraries - libA, libB and libC.
libA has a .dox file, which contains the following anchors:
\section First_Section First Section
\subsection First_Subsection First Subsection
libB includes the tag file for libA as follows:
#TAGFILES = $(DOXY_OUTPUT)/../libA/libA.tag=../libA
libC includes the tag files for libA and libB, as follows:
#TAGFILES = $(DOXY_OUTPUT)/../libA/libA.tag=../libA \
$(DOXY_OUTPUT)/../libB/libB.tag=../libB
However, when I run doxygen on libC in order to generate the documentation for libC, I see the following warning messages:
libB.tag: warning: Duplicate anchor First_Section found
libB.tag: warning: Duplicate anchor First_Subsection found
It seems that, because libB uses the tagfile for libA, that when libC tries to use the tagfile for libB, it has in fact already obtained the anchors from libA and so it considers those it finds in libB relating to libA to be duplicates.
I am using Doxygen 1.8.10.

With the example provided by OP. at https://bugzilla.gnome.org/show_bug.cgi?id=793088 OP. had no problem with version 1.8.13. My tests also revealed that with 1.8.14 there was no warning anymore.
Solution: upgrade to a newer version.

Related

How do I get CMake to dynamically link a merged static library with system libraries?

I have to merge one of my app's libs with the NVIDIA CUDA static lib using this horrific awful CMake code:
GET_TARGET_PROPERTY(OUTPUT_LIB ${LIBNAME} LOCATION)
add_custom_command (TARGET ${LIBNAME}
POST_BUILD
COMMAND mv ${OUTPUT_LIB} ${OUTPUT_LIB}.old
COMMAND echo "create ${OUTPUT_LIB}" > combineLibs.mri
COMMAND echo "addlib ${OUTPUT_LIB}.old" >> combineLibs.mri
COMMAND echo "addlib ${CUDA_LOCATION}" >> combineLibs.mri
COMMAND echo "save" >> combineLibs.mri
COMMAND echo "end" >> combineLibs.mri
COMMAND ar -M <combineLibs.mri
COMMAND rm ${OUTPUT_LIB}.old
COMMENT "Building merged library for ${LIBNAME} at ${OUTPUT_LIB}, including ${CUDA_LOCATION}"
)
target_link_libraries(${LIBNAME} -pthread -c)
This successfully produces a merged static library that has all the symbols in it. However, the NVIDIA CUDA static lib brought with it dependencies on libpthread and libc in the form of unresolved symbols. Now the merged library also has those unresolved symbols, and the target_link_libraries line doesn't seem to do what I seem to think it does, because the symbols don't get resolved at link-time. How do I get the merged static library to dynamically link against libpthread and libc?
The the target_link_libraries line does indeed not do what you think.
target_link_libraries(target,options) can have the desired effect of
adding the linker options options to the linkage of target only if target
is something that is produced by the linker. If no linkage happens in the
production of target then this directive will have no effect.
Your target is a static library. A static library - unlike a program, and unlike
a dynamic/shared library - is not produced by the linker. As your custom_command
in fact illustrates, a static library is produced by the GNU general purpose archiver,
ar. It is nothing but an archive of files which happen to be object files,
but as far as ar is concerned they might as well be the contents of your
Documents, Pictures and Music folders. Since no linkage is involved in the
production of a static library, nothing can be linked with a static library.
An ar archive can be used as a linker input in the linkage of something that
is produced by the linker - a program or a shared library. In that case the
linker will look into the archive to see if contains any object files it needs
to carry on the linkage. If it finds any, it will extract them from the archive
and link them into the program. The linkage will be exactly the same as if
you had listed the required object files in the linker commandline and not
mentioned the archive at all.
But if any of the object files that the linker extracts from an archive bring
with them undefined references, then to get them resolved you must link some
library or libraries that define those references in the linkage of the
program or shared library that you want the linker to produce - just as you
must do to resolve undefined references in any other object files you
input to the linkage.
So,
How do I get the merged static library to dynamically link against libpthread and libc?
You can't. It doesn't make sense. Any library dependencies of object files
in a static library can be satisfied only in the linkage of a program or shared library
that has acquired those dependencies by linking those object files.
Finally, -c is not a GCC linkage option that will have the effect of requesting
linkage of libc. It is not a linkage option at all. It is an option that
directs the GCC frontend not to invoke the linker. It is passed to GCC to
request compilation without linkage, and the perverse effect of including it in a
CMake target_link_libraries directive will be to stop any linkage of the
target from happening.
If you want to explicitly request linkage of libc, use -lc, following
the linker usage protocol that -lname requests linkage of libname.
Perhaps you inferred that -c requests linkage of libc from the assumption
that -pthread requests linkage of libpthread. In fact, -lpthread would
request linkage of libpthread. The option -pthread is a more abstract GCC
option, for both compilation and linkage, that means do the right things, for this platform, to link with the Posix Threads
library - which might entail passing -lpthead to the linker, and possibly not.
Thus -pthread is OK as an argument of target_link_libraries that will
have the effect of requesting Posix Threads linkage, but see
answers to cmake and libpthread
for CMake-proper ways of doing this.

SwiftPM: How to setup Swift module.map referring to two connected C libraries

I'm trying to build a Swift Package Manager system package (a module.modulemap)
making available two system C libraries where one includes the other.
That is, one (say libcurl) is a base module and the other C library is including
that (like so: #include "libcurl.h"). On the regular C side this works, because
the makefiles pass in proper -I flags and all is good (and I could presumably
do the same in SPM, but I'd like to avoid extra flags to SPM).
So what I came up with is this module map:
module CBase [system] {
header "/usr/include/curl.h"
link "curl"
export *
}
module CMyLib [system] {
use CBase
header "/usr/include/mylib.h"
link "mylib"
export *
}
I got importing CBase in a Swift package working fine.
But when I try to import CMyLib, the compiler complains:
error: 'curl.h' file not found
Which is kinda understandable because the compiler doesn't know where to look
(though I assumed that use CBase would help).
Is there a way to get this to work w/o having to add -Xcc -I flags to the
build process?
Update 1: To a degree this is covered in
Swift SR-145
and
SE-0063: SwiftPM System Module Search Paths.
The recommendation is to use the Package.swift pkgConfig setting. This seems to work OK for my specific setup. However, it is a chicken and egg if there is no .pc file. I tried embedding an own .pc file in the package, but the system package directory isn't added to the PKG_CONFIG_PATH (and hence won't be considered during the compilation of a dependent module). So the question stands: how to accomplish that in an environment where there libs are installed, but w/o a .pc file (just header and lib).

STM32 Eclipse + ARM GNU toolchain error linker

I use Eclipse + ARM plugin to build my projects. When I needed to use in my project the StemWin library, I configured my IDE to use external library.
I set
Preferences -> C/C++ General -> Paths and Symbols
I added in "Library Paths" the link to my folder includes library.
I also added the name of my library in tab "Library".
I checked the settings in the compiler tab and I ascertained all should be good.
When I tried to build my project I got an error from linker:
cannot find -lMyLib.a Hello C/C++ Problem
I double checked the name of my library and link, all are correct. This is the output of my linker:
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -L"C:\lib"
-T"C:\arm_toolchain\stm32_workspace\Hello\LinkerScript.ld" -Wl,
-Map=output.map -Wl,--gc-sections -o "Hello.elf" #"objects.list" -lMyLib.a
What should I do from here?
I faced the same problem before.
-l:STemWin526_CM4_GCC.a
-L"C:\Edu_Workspace\STM32F4\stm32f4_bsp_template\Drivers\Middlewares\ST\STemWin\Lib"
Above are my working settings.
With -l:<archive file name> the colon : is important for archive file linking.
And -L will contain library path.
Also for stemwin make sure to compile with hardware floating point
-mfloat-abi=hard -mfpu=fpv4-sp-d16
the convention for the -l option of the linker (say you give -lMyLib.a as a linker option) is to search for a library file with "lib" prepended to the given name and .a (or .so) appended, i.e. your command line searches for a file libMyLib.a.{a,so} which is probably not how it's named.
Either you rename your library according to this convention or give it to the linker command line omitting -l (provided your IDE allows you to do so).
Looks like the problem is in -lMyLib.a which means you're trying to link a static library as a dynamic one.
To link a static lib you have to use its path as with ordinary .o files: ... /path/to/MyLib.a
and the resulting command line should look something like
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -L"C:\lib" -T"C:\arm_toolchain\stm32_workspace\Hello\LinkerScript.ld" -Wl,-Map=output.map -Wl,--gc-sections -o "Hello.elf" #"objects.list" /path/to/MyLib.a
UPDATE:
Although it might fix the issue, turns out it's not true:
-llibrary
-l library
...
Normally the files found this way are library files—archive files whose members are object files. The linker handles an archive file by scanning through it for members which define symbols that have so far been referenced but not defined. But if the file that is found is an ordinary object file, it is linked in the usual fashion. The only difference between using an -l option and specifying a file name is that -l surrounds library with ‘lib’ and ‘.a’ and searches several directories.
(https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html)

Error running Simulator: duplicate symbol for architecture i386

I added ShareKit framework to try and here is the error running it in Simulator:
duplicate symbol _LFHRReadStreamClientCallBack in
.../Xcode/DerivedData/....build/Objects-normal/i386/LFHTTPRequest-8C6F35228BA446B9.o
and
.../Xcode/DerivedData/....build/Objects-normal/i386/LFHTTPRequest-8ACF920D803FDCA6.o
for architecture i386
I looked at previous posts Build Error - missing required architecture i386 in file and tried to edit project.pbxproj commenting FRAMEWORK_SEARCH_PATHS lines out as well as looking for .framework files accidently added to my project but with no luck.
What else can I try?
You've included LFHTTPRequest in your project twice. It's possible that another library (such as sharekit) included it for you, doublecheck the files sharekit includes and remove one copy of LFHTTPRequest and things should compile.
This can also happen if you move coredata-generated classes into a group, like "Models" and then regenerate the NSManagedObjectModel subclasses. The generated files will be placed in the project root and added into the build twice.
I got the same error when working with TessBaseAPI. I had two c++ files and both had the following declaration:
namespace tesseract {
class TessBaseAPI;
};
tesseract::TessBaseAPI *tesseract1;
uint32_t *pixels;
The I read the full error message. I got a line there:
duplicate symbol _tesseract1 in
And later, which files contains the duplicate also included (the file name).
So, I changed the instance name as follows:
namespace tesseract {
class TessBaseAPI;
};
tesseract::TessBaseAPI *tesseractNew;
uint32_t *pixelsNew;
That solved my problem.

What is the difference between building C++ Builder project from IDE and command line?

I have different behaviour of compiler, when building project from IDE and from command-line, which I can not explain.
The detailed issue's description is rather big, but it's really simple.
I have a C++ Builder project, which has a PAS-file included (IncludeUnits.pas). This pas-file has several units and inc-files listed. These files are located in separate folders and these folders are listed in library&include paths in project's options.
Folders layout:
C:\Demo\Bin
C:\Demo\Project
C:\Demo\Project\CBuilder5
C:\Demo\Project\Common
C:\Demo\Source
C:\Demo\Source\Common
Bin is output folder, Project/CBuilder5 holds project (bpr-file), Project/Common holds included pas-file (IncludeUnits.pas), Source and Source/Common hold other files (pas&inc). I think that it's pretty usual layout.
C:\Demo\Project\Common\ IncludeUnits.pas :
unit IncludeUnits;
interface
uses
Test;
implementation
end.
C:\Demo\Source\ Test.pas :
unit Test;
interface
{$I Test.inc}
implementation
end.
C:\Demo\Source\Common\ Test.inc :
// this file is empty
If I compile this project from C++ Builder IDE - it will compile fine. C++ Builder IDE doesn't have any additional paths in IDE settings set.
Now, I want to compile it from command-line. First, I issue
bpr2mak.exe MyProject.bpr
command.
This command creates MyProject.mak file, where I can see all paths ("....\Source" and "....\Source\Common" are the paths in question):
...
INCLUDEPATH = $(BCB)\include;$(BCB)\include\vcl;..\Common;..\..\Source;..\..\Source\Common
LIBPATH = $(BCB)\lib\obj;$(BCB)\lib;..\Common;..\..\Source;..\..\Source\Common
...
Now, I run make command:
make.exe -B -f"MyProject.mak"
It gives me the following output:
C:\PROGRA~1\Borland\CBUILD~2\BIN\dcc32 -N2....\Bin -N0....\Bin -$Y+ -$W -$R -v -JPHNE -M -UC:\PROGRA~1\Borland\CBUILD~2\bin..\include;C:\PROGRA~1\Borland\CBUILD~2\bin..\include\vcl;..\Common;..\..\Source;..\..\Source\Common -D_DEBUG;_RTLDLL;NO_STRICT -OC:\PROGRA~1\Borland\CBUILD~2\bin..\include;C:\PROGRA~1\Borland\CBUILD~2\bin..\include\vcl;..\Common;..\..\Source;..\..\Source\Common --BCB ..\Common\IncludeUnits.PAS
Borland Delphi Version 13.0 Copyright (c) 1983,99 Inprise Corporation
C:\Demo\Project\Common\IncludeUnits.pas(1) C:\Demo\Project\Common\IncludeUnits.pas(1) C:\Demo\Project\Common\IncludeUnits.pas(1) C:\Demo\Project\Common\IncludeUnits.pas(6) C:\Demo\Source\Test.pas(1) C:\Demo\Source\Test.pas(5) Fatal: File not found: 'Test.inc'
As you can see - all search path is passed to compiler and the file (Test.inc) is all here - in that Source\Common folder. But still compiler can't find it?
Of course, I run both commands from folder with bpr-file. And changing paths to absolute doesn't help.
Copying Test.inc from Source\Common to Source will help. Changing {$I Test.inc} to {$I Common\Test.inc} will also help.
Why? It seems that I'm missing something. Remember: project have no problems with compiling from IDE, Test.inc is found without copying or changing declaration. Did I miss some switch to make or dcc32?
I found the reason: command line for dcc32 misses -I switch, which specifies paths for include files.
For some reason, bpr2mak doesn't respect this option. Fortunately, it allows you to specify alternate template for conversion bpr -> mak. I edited default template and added "-I" option to it, pass new template to bpr2mak - and it worked.