Conflicting PACKAGE_NAME and other macros when using autotools - gcc

When using autotools (with a config.h file) for both a library, and a software built on that library, the compiler complains about a redefinition of some macros (PACKAGE_NAME, PACKAGE_TARNAME and so on).
How can I prevent this?
The config.h file is needed in the library to propagate it's setting to the software that use it.
Right now I have a wrapper script library_config.h that includes the original config.h and provides defaults when the user is not using autotools, but even undefining the macros in that package I get the redefinition warning from gcc.
#ifndef LIB_CONFIG_H
#define LIB_CONFIG_H
#ifdef HAVE_CONFIG_H
# include "config.h"
# undef PACKAGE
# undef PACKAGE_BUGREPORT
# undef PACKAGE_NAME
# undef PACKAGE_STRING
# undef PACKAGE_TARNAME
# undef PACKAGE_VERSION
# undef VERSION
#else
# if defined (WIN32)
# define HAVE_UNORDERED_MAP 1
# define TR1_MIXED_NAMESPACE 1
# elif defined (__GXX_EXPERIMENTAL_CXX0X__)
# define HAVE_UNORDERED_MAP 1
# else
# define HAVE_TR1_UNORDERED_MAP 1
# endif
#endif
#endif
I believe the best option would be to have a library without that macros: How can I avoid the definition of PACKAGE, PACKAGE_NAME and so on in the library when using autotools?
EDIT: attemp to explain better.
When using the AC_CONFIG_HEADER macro in the configure.ac of the library I produce a config.h file with a lot of useful defines. This defines are useful for the library itself (both for it's compiled part and for its header files) AND for the client software. It's a pity however that the AC_CONFIG_HEADER mixes the useful macros that I need with other generic defines with fixed names (PACKAGE, PACKAGE_NAME) that clash when autotools are used also for the client software configuration.

If your application might dynamically link to the library, it makes no sense to have the static strings from the library statically built into the application.
Otherwise, you might want to look for ax_prefix_config_h.m4.
I would still just try to avoid installing a config.h file and define the library's API without resorting to config.h:
/* library.h */
const char library_version[];
/* library.c */
#include "library.h"
#include "config.h" /* the library's config.h */
const char library_version[] = PACKAGE_VERSION;
/* application.c */
#include "library.h"
#include "config.h" /* the application's config.h */
int main()
{
print("This is app version %s.\n", PACKAGE_VERSION);
print("The library is version %s\n", library_version);
return 0;
}
Make sure that the public library header files do not #include "config.h", and that the library does not install its config.h.

You should be able to designate the library as a "subpackage" of the software by calling AC_CONFIG_SUBDIRS([library]) in the software's configure.ac. That should eliminate the conflicts, and the settings from the top-level configure will still propagate down to the subpackage.
Here is the link to the page of the Autoconf manual describing this feature: http://www.gnu.org/software/hello/manual/automake/Subpackages.html

Related

Using a particular version for golang dependency module

I'm trying to build postfix-exporter code from the github link.
It has a dependency on the go-systemd package as mentioned in go.mod file github.com/coreos/go-systemd/v22 v22.0.0.
I see in the go.mod file , the mentioned version for the package is v22.0.0.
But when I run go get -u for this path, it starts downloading the latest version ( v22.2.0) of go-systemd which has an issue in the latest commit and causing failure to compile .
The error coming in that is
github.com/coreos/go-systemd/v22#v22.2.0/sdjournal/journal.go:313:60: error: '_SD_ARRAY_STATIC' undeclared here (not in a function) // my_sd_id128_to_string(void *f, sd_id128_t boot_id, char s[_SD_ARRAY_STATIC SD_ID128_STRING_MAX]) ^ In file included from /usr/include/systemd/sd-journal.h:31:0, from pkg/mod/github.com/coreos/go-systemd/v22#v22.2.0/sdjournal/journal.go:27: pkg/mod/github.com/coreos/go-systemd/v22#v22.2.0/sdjournal/journal.go:313:77: error: expected ']' before numeric constant // my_sd_id128_to_string(void *f, sd_id128_t boot_id, char s[_SD_ARRAY_STATIC SD_ID128_STRING_MAX])
I want to know , how to compile for a specific version of any dependency module if this is not the way or I'm missing some option required to honor the version of dependency packages mentioned in go.mod
Thanks very much in advance and please pardon my golang knowledge.
Don't use -u. The purpose of -u is to allow Go to try to upgrade you to the latest minor or patch version:
The -u flag instructs get to update modules providing dependencies
of packages named on the command line to use newer minor or patch
releases when available.
If you're just trying to install dependencies, use go get.
I was trying to build podman for Centos7 and found this error, noticed that _SD_ARRAY_STATIC was not defined, so I just did a search in google and found this header file: https://code.woboq.org/qt5/include/systemd/_sd-common.h.html.
Also, by doing a search of this file in my docker I found this very old one: /usr/include/systemd/_sd-common.h, so I just decided to modify it and add that definition:
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#ifndef foosdcommonhfoo
#define foosdcommonhfoo
/***
This file is part of systemd.
Copyright 2013 Lennart Poettering
...
...
#ifndef _SD_END_DECLARATIONS
# ifdef __cplusplus
# define _SD_END_DECLARATIONS \
} \
struct __useless_struct_to_allow_trailing_semicolon__
# else
# define _SD_END_DECLARATIONS \
struct __useless_struct_to_allow_trailing_semicolon__
# endif
#endif
#ifndef _SD_ARRAY_STATIC
# if __STDC_VERSION__ >= 199901L
# define _SD_ARRAY_STATIC static
# else
# define _SD_ARRAY_STATIC
# endif
#endif
#endif
And voila, got it working.
TL;DR, probably you have to update systemd package or at least the systemd C library.

clion disable code insight in certain files

Is there any way to disable code insight in Clion for only one file in the project?
I have a swig file with just a few lines. But every time when I go into the file clion complains about header and freeze for long time. I have to open this file in phpstorm or other editor which can't parse c++.
complain messages from Clion
//anal.swig
%module anal
%{
#include "anal.cpp"
%}
void anal(char *str, int size);
The are several ways to do it:
1. Change the file extension from ".h/.cpp" to ".templ" (non C++ related)
2. Clion has special IDE macros, so you can add guard
#ifndef __CLION_IDE__
//anal.swig
%module anal
%{
#include "anal.cpp"
%}
#endif
void anal(char *str, int size);
CLion has #pragma ide diagnostic ignored for selective switch off.

CMAKE for windows DLL with OpenCV project

Behold: My Cmakelists.txt file
project(facedetectlib)
cmake_minimum_required(VERSION 2.8)
include (GenerateExportHeader)
SET(CMAKE_VERBOSE_MAKEFILE TRUE)
file(GLOB HEADER_LIST ./include/*.h)
include_directories(./include)
aux_source_directory(. SRC_LIST)
find_package(OpenCV REQUIRED )
# Allow the developer to select if Dynamic or Static libraries are built
OPTION (BUILD_SHARED_LIBS "Build Shared Libraries" OFF)
# Set the LIB_TYPE variable to STATIC
SET (LIB_TYPE STATIC)
IF (BUILD_SHARED_LIBS)
# User wants to build Dynamic Libraries, so change the LIB_TYPE variable to CMake keyword 'SHARED'
SET (LIB_TYPE SHARED)
ENDIF (BUILD_SHARED_LIBS)
add_library(ocvfacedetectlib ${LIB_TYPE} ${SRC_LIST} ${HEADER_LIST})
target_link_libraries(ocvfacedetectlib ${OpenCV_LIBS})
GENERATE_EXPORT_HEADER( ocvfacedetectlib
BASE_NAME ocvfacedetectlib
EXPORT_MACRO_NAME ocvfacedetectlib_EXPORT
EXPORT_FILE_NAME ocvfacedetectlib_Export.h
STATIC_DEFINE ocvfacedetectlib_BUILT_AS_STATIC
)
Using this cmake file and piecing together some instructions from here:
http://www.cmake.org/Wiki/BuildingWinDLL
I am trying to figure out if the DLL is getting built correctly. My header file for my little library has the following in it:
#include "ocvfacedetectlib_Export.h"
typedef unsigned char uint8_t;
extern "C" {
ocvfacedetectlib_EXPORT uint8_t * facedetect( uint8_t *imageData, long buffsize, unsigned char *retbuffer );
}
And then I have in my .cpp file this:
ocvfacedetectlib_EXPORT uint8_t * facedetect( uint8_t *imageData, long buffsize, unsigned char *retbuffer )
{ ..do stuff using OpenCV
...}
This seems to be enough to generate a DLL but I am not sure if it is being built correctly - I am unable to load it use js.ctypes() which is what I am trying to do as my end goal.
For what it's worth—my .cpp has a main() method as well and when I build the code to an .exe it runs.
What is the proper way to generate a windows DLL from a CMake project for later versions of CMake than 2.8, and what has to be changed in the source code to make it work?

How to instrument gcc?

I have to instrument gcc for some purposes. The goal is to be able to track what GCC functions are called during a particularly compile. Unfortunately I'm not really familiar with the architecture of GCC so I need a little help. I tried the following steps:
1) Hacking gcc/Makefile.in and adding "-finstrument-functions" flag to T_CFLAGS.
2) I have an already implemented and tested version of start_test and end_test functions. They are called from gcc/main.c, before and after toplev_main() call. The containing file is linked to gcc (the object is added to OBJS-common and the dependency is defined later in gcc/Makefile.in)
3) Downloading prerequisites with contrib/download_prerequisites.
4) Executing the configuration from a clean build directory (on the same level with the source dir): ./../gcc-4.6.2/configure --prefix="/opt/gcc-4.6.2/" --enable-languages="c,c++"
5) Starting the build with "make all"
This way I runned out of memory, although I had 28G.
Next I tried to remove the T_CFLAGS settings from the Makefile and give -finstrument-functions to the make command: make CFLAGS="-finstrument-functions". The build was successful this way but when I tried to compile something it resulted empty output files. (Theoretically end_test should have written its result to a given file.)
What do I make wrong?
Thanks in advance!
Unless you specifically exclude it from being instrumented, main itself is subject to instrumentation, so placing calls to your start_test and end_test inside main is not how you want to do it. The 'correct' way to ensure that the file is opened and closed at the right times is to define a 'constructor' and 'destructor', and GCC automatically generates calls to them before and after main:
void start_test (void)
__attribute__ ( (no_instrument_function, constructor));
void end_test (void)
__attribute__ ( (no_instrument_function, destructor));
/* FILE to write profiling information. */
static FILE *profiler_out;
void start_test (void)
{
profiler_out = fopen ("profiler.out", "w");
if (profiler_out == NULL)
exit (-1);
}
void end_test (void)
{
fclose (profiler_out);
}
Footnotes:
Read more about constructor, destructor and no_instrument_function attributes here. They are function attributes that GCC understands.
Read this excellent guide to instrumentation, on the IBM website.

A warning with building 64bit dll

dll export header
extern "C"
void _declspec(dllexport) __stdcall foo();
.def file
EXPORTS
foo #1
When I build the dll by 64bit build config, I meet this warning.
warning LNK4197: export 'foo' specified multiple times; using first specification
But If I build the dll by 32bit build config, the warning never occurs.
What is the problem? What is the difference.
In dll header for interface, we usually use this technic,
#ifdef EXPORT_DLL
#define BASICAPI _declspec(dllexport)
#else
#define BASICAPI _declspec(dllimport)
#endif //_EXPORT_DLL
But if def file also exists, we always will be meet the warning when we are building 64bit dll.
So, should we write the codes like this?
#ifdef EXPORT_DLL
#define BASICAPI
#else
#define BASICAPI _declspec(dllimport)
#endif //_EXPORT_DLL
It works well. But it's not familiar to me.
Give me any your opinions.
It's generally not good practise to specify exports twice for the same function. If you already have __declspec(dllexport) then you do not need to specify the export in a .def file as well. Conversely, if you have the export listed in a .def file, then there's no need for a __declspec(dllexport).
I believe the reason for the warning is that in x86 builds, the __declspec(dllexport) is exporting the decorated name with a leading underscore, but the 64-bit compiler does not decorate names with a leading underscore, leading to the duplicate. To verify this, you could look at the 32-bit DLL in Dependency Walker and you should see two exported functions, "foo" and "_foo".
__declspec(dllexport) and .def files are two different ways to export symbols from a dll. You don't need both and should omit ono of them. The __declspec method is far more versatile for c++ programs as it exports names with c++ mangling, allowing overloaded functions to be exported, but conversely that does make the names harder to import via GetProcAddress.
Also, using a generic macro like EXPORT_DLL is dangerous as it means that you can't build a dll, that uses another dll, without the one one dll trying to export all the symbols of both dlls.
DevStudio automatically creates a symbol on dll projects: <PROJECT>_EXPORTS making it easy and safe to create a EXPORT macro:
#ifdef EXPORT
#undef EXPORT
#endif
#ifdef PROJECTNAMEHERE_EXPORTS
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif
EXTERN_C EXPORT void __stdcall Function1(void);
EXTERN_C EXPORT void __cdecl Function2(...);
EXPORT void Function3(void);
Functions 1 & 2 can be gotten with GetProcAddress as _Function1#0 and Function2 respectively. Function3 is going to be exported via a compiler specific mangled name that will look something like: #Function3##UAG_DB#Z. This name is different for each overload of the function, which is how it allows overloading to work.
Its important to know the name mangling of __declspec as .def files don't care and would just export Function1, Function2 and Function3.

Resources