My main development platform is Gentoo on Linux. However, recently I tried to build my program on the fresh VM install on Debian.
My program contains of main binary and couple of dll/so/dylib libraries. One of the libraries depends on the presence of unixODBC/iODBC.
I was told by unixODBC maintainers to use odbc_config script to identify the build parameters.
When I build on Gentoo - everything works fine. There is no problems.
However, when I build on Debian - the build fails because apparently Debian does not produce odbc_config script and instead in this case rely on pkg-config.
So, I need to add a test in configure.ac to check for odbc_config script presence and pass it along to one of the so files generation (lets call it libodbc_lib project).
Could someone please help me with this?
EDIT:
Is this correct to be put in configure.ac:
AC_CHECK_PROG(ODBC,odbc_config,yes)
if test x"${ODBC}" == x"yes" ; then
ODBC_CFLAGS = `odbc_config --cflags`
ODBC_LIBS = `odbc_config --libs` -lodbcinst
else
ODBC_CFLAGS = `pkg-config odbc --cflags`
ODBC_LIBS = `pkg-config odbc --libs` -lodbcinst
fi
AC_SUBST(ODBC_CFLAGS)
AC_SUBST(ODBC_LIBS)
If it is - how do I use ODBC_FLAGS/ODBC_LIBS in my subproject?
EDIT2:
Based on this answer I used the following code:
In the main configure.ac:
AC_CHECK_PROG(ODBC,odbc_config,yes)
if test x"${ODBC}" == x"yes" ; then
ODBC_CFLAGS = `odbc_config --cflags`
ODBC_LIBS = `odbc_config --libs` -lodbcinst
else
ODBC_CFLAGS = `pkg-config odbc --cflags`
ODBC_LIBS = `pkg-config odbc --libs` -lodbcinst
fi
AC_SUBST(ODBC_CFLAGS)
AC_SUBST(ODBC_LIBS)
In the libodbc_lib/Makefile.am:
libodbc_lib_la_CXXFLAGS = -I../../dbinterface \
-DUNICODE \
-DUNIXODBC \
-I#ODBC_CFLAGS#
libodbc_lib_la_LDFLAGS = -L../dbinterface \
-ldbinterface \
#ODBC_LIB#
I regenerated configure, run it successfully and then tried running make.
I got following error:
CXXLD libodbc_lib.la
/usr/lib/gcc/x86_64-pc-linux-gnu/11.3.0/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find #ODBC_LIB#: No such file or directory
What I did wrong?
EDIT3:
After fixing the missing S, I got following compile commands:
make[2]: Entering directory '/home/igor/dbhandler/Debug/libodbc'
/bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I/home/igor/dbhandler/libodbc -I.. -I../../dbinterface -DUNICODE -DUNIXODBC -I#IODBC_CFLAGS# -g -O0 -MT libodbc_lib_la-database_odbc.lo -MD -MP -MF .deps/libodbc_lib_la-database_odbc.Tpo -c -o libodbc_lib_la-database_odbc.lo `test -f 'database_odbc.cpp' || echo '/home/igor/dbhandler/libodbc/'`database_odbc.cpp
libtool: compile: g++ -DHAVE_CONFIG_H -I. -I/home/igor/dbhandler/libodbc -I.. -I../../dbinterface -DUNICODE -DUNIXODBC -I#IODBC_CFLAGS# -g -O0 -MT libodbc_lib_la-database_odbc.lo -MD -MP -MF .deps/libodbc_lib_la-database_odbc.Tpo -c /home/igor/dbhandler/libodbc/database_odbc.cpp -fPIC -DPIC -o .libs/libodbc_lib_la-database_odbc.o
libtool: compile: g++ -DHAVE_CONFIG_H -I. -I/home/igor/dbhandler/libodbc -I.. -I../../dbinterface -DUNICODE -DUNIXODBC -I#IODBC_CFLAGS# -g -O0 -MT libodbc_lib_la-database_odbc.lo -MD -MP -MF .deps/libodbc_lib_la-database_odbc.Tpo -c /home/igor/dbhandler/libodbc/database_odbc.cpp -o libodbc_lib_la-database_odbc.o >/dev/null 2>&1
mv -f .deps/libodbc_lib_la-database_odbc.Tpo .deps/libodbc_lib_la-database_odbc.Plo
/bin/sh ../libtool --tag=CXX --mode=link g++ -I../../dbinterface -DUNICODE -DUNIXODBC -I#IODBC_CFLAGS# -g -O0 -L../dbinterface -ldbinterface -o libodbc_lib.la -rpath /usr/local/lib libodbc_lib_la-database_odbc.lo
libtool: link: g++ -fPIC -DPIC -shared -nostdlib /usr/lib/gcc/x86_64-pc-linux-gnu/11.3.0/../../../../lib64/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/11.3.0/crtbeginS.o .libs/libodbc_lib_la-database_odbc.o -L../dbinterface -ldbinterface -L/usr/lib/gcc/x86_64-pc-linux-gnu/11.3.0 -L/usr/lib/gcc/x86_64-pc-linux-gnu/11.3.0/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-pc-linux-gnu/11.3.0/../../../../x86_64-pc-linux-gnu/lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/11.3.0/../../.. -lstdc++ -lm -lc -lgcc_s /usr/lib/gcc/x86_64-pc-linux-gnu/11.3.0/crtendS.o /usr/lib/gcc/x86_64-pc-linux-gnu/11.3.0/../../../../lib64/crtn.o -g -O0 -Wl,-soname -Wl,libodbc_lib.so.0 -o .libs/libodbc_lib.so.0.0.0
libtool: link: (cd ".libs" && rm -f "libodbc_lib.so.0" && ln -s "libodbc_lib.so.0.0.0" "libodbc_lib.so.0")
libtool: link: (cd ".libs" && rm -f "libodbc_lib.so" && ln -s "libodbc_lib.so.0.0.0" "libodbc_lib.so")
libtool: link: ar cru .libs/libodbc_lib.a libodbc_lib_la-database_odbc.o
libtool: link: ranlib .libs/libodbc_lib.a
libtool: link: ( cd ".libs" && rm -f "libodbc_lib.la" && ln -s "../libodbc_lib.la" "libodbc_lib.la" )
make[2]: Leaving directory '/home/igor/dbhandler/Debug/libodbc'
I still the variable name there and not their values.
Is it normal?
As UnixODBC upstream does ship and install *.pc files, I would expect that file to be both present and correct and therefore I would ignore any *-config scripts. The pkg-config system is quite well thought out and works even for quite weird cross compilation environments. The *.pc mechanism works well on Linux, on FreeBSD, on OSX, cross-compiling for Windows on Linux, to name a few.
A well-written _config program written in portable shell could do the same by basically reproducing much of the pkg-config logic in portable shell for each and every _config script, hopefully correctly.
However, odbc_config is not a portable shell script. It is a binary executable, i.e. it will regularly break for cross-compiling, as the system you build on will usually not be able to run programs like odbc_config which are built to run on the system you are building for.
And even if the flags from the *.pc files were unsuitable for a very unusual build environment: Using PKG_CHECK_MODULES defines appropriate _CFLAGS and _LIBS variables for the configure script, so even in a very unusual build environments one can always override whatever the *.pc file might contain by calling configure like
../configure ODBC_CFLAGS='-I/weird/stuff -DWEIRD_STRING="moo"' ODBC_LIBS='-L/very/weird/libxyz -lodbc'
So... using odbc_config has no advantages, upstream already provides a odbc.pc file so it is always present, so why not just always use odbc.pc?
So, in configure.ac (if builds without odbc.pc present should fail, otherwise you will have to do some AC_DEFINE and/or AM_CONDITIONAL to conditionally build with or without ODBC support) do
m4_pattern_forbid([PKG_CHECK_MODULES])dnl
PKG_CHECK_MODULES([ODBC], [odbc])
and in any subdirectory (what you call "subproject") Makefile.am or Makefile-files where you need to link somehting against libodbc, put, depending on whether you are building an executable
bin_PROGRAMS += foobar
[…]
foobar_CPPFLAGS += $(ODBC_CFLAGS)
foobar_LDADD += $(ODBC_LIBS)
or a (libtool) library
lib_LTLIBRARIES += libfoo.la
[…]
libfoo_la_CPPFLAGS += $(ODBC_CFLAGS)
libfoo_la_LIBADD += $(ODBC_LIBS)
That should work for all native and cross-compile builds in properly set up build environments, and people can still override odbc_CFLAGS and odbc_LIBS in case of problems.
Of course, you can always AC_CHECK_PROG or AC_PATH_PROG or AC_CHECK_TOOL or AC_PATH_TOOL together with an AC_ARG_VAR for the odbc_config program and then define and AC_SUBST an _CFLAGS and _LIBS variable set to the output of $ODBC_CONFIG --cflags and $ODBC_CONFIG --libs, respectively, and then then use the _CFLAGS and _LIBS vars in Makefile.am/Makefile-files as above.
However, that is a lot of code to write, and with a lot of special cases to consider, and if you have to ask about how to do this you will probably get a lot more wrong than if you just just use PKG_CHECK_MODULES.
You can always add something later if the PKG_CHECK_MODULES route actually does not work for a use case and which cannot be fixed within the pkg-config framework. Until that time (if it ever happens), I would recommend to just use the simple PKG_CHECK_MODULES method and probably be done.
So, I need to add a test in configure.ac to check for odbc_config script presence and pass it along to one of the so files generation
Autoconf has AC_PATH_PROG() for checking for a program in the executable search path. You would of course use AC_SUBST() to define one or more output variables by which to convey the results to the generated makefiles.
But no, coming back around to my comment on the answer to one of your previous questions, what you ought to do is not have configure forward information about the executable, but rather for it to determine the needed flags itself and forward them, via one or more output variables. If you continue to use odbc_config, at least conditionally, then that means having configure run it and capture the output. You should not inject shell command substitutions into your compilation commands.
And if you substitute a different mechanism, whether conditionally or exclusively, then similarly for that. (That's what your other answer describes with respect to pkg-config.)
How to create a makefile for Linux for the next command?
gcc -shared -home/ time.c /libperi.a -o time.so
First, pick a name. This command appears to build time.so, so that's a good name.
The makefile is just a text file. Write it like this:
time.so:
gcc -shared -home/ time.c /libperi.a -o time.so
That whitespace before the gcc is a TAB, not spaces.
Once you have that working, you can read the manual and learn more about Make, which will allow you to write more powerful rules.
Here's my makefile:
assemblera: main.o parsingA.o parsingC.o symbolTable.o
gcc -o assemblera main.o parsingA.o parsingC.o symbolTable.o
main.o: main.c parsingA.h parsingC.h symbolTable.h
gcc -c main.c
parsingA.o: parsingA.c parsingA.h
gcc -c parsingA.c
parsingC.o: parsingC.c parsingC.h
gcc -c parsingC.c
symbolTable.o: symbolTable.c symbolTable.h
gcc -c symbolTable.c
clean:
rm *.o assemblera
Now for the problem: with Windows command prompt I can easily generate all the .o files and .exe file, and if I run the latter it works as intended. Now, if I use the cygwin terminal, I can give the instructions to generate the object files / the exe, but those do not appear nowhere in the folder and no error is returned. Also, if I use the make command, it returns this error:
gcc -c main.c
make: *** [Makefile:5: main.o] Error 1
(I did put tabs in front of every "gcc" and "rm"). I know next to nothing about makefiles and cygwin.
i'm newbie use MinGW64 and msys2.
i have write simple program, just output "hello,world", but it links a dll for test.
#include <stdio.h>
int main() {
printf("hello, world\n");
return 0;
}
i run command in terminal like this:
$ gcc -g -Wall -I/usr/local/include -L/usr/local/bin -llua53 --shared -o test.dll main.c
it's works well.
but i write a Makefile use same command like this:
all: main.c
gcc -g -Wall -I/usr/local/include -L/usr/local/bin -llua53 --shared -o test.dll main.c
the error was output:
$ mingw32-make.exe
gcc -g -Wall -I/usr/local/include -L/usr/local/bin -llua53 --shared -o test.dll main.c
E:/mingw/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/5.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -llua53
this problem confused me, what the difference of command process from terminal input and from Makefile?
mingw32-make.exe is for use with the windows command shell and doesn't understand POSIX paths, you need to use make.exe.
I need help it is bug or I don't understand how compilation options are working ?
I have sample main.c file and try to compile it as:
$ g++ -nostdlib -g -fno-rtti -fno-exceptions -ffreestanding -nostdinc -nostdinc++ -Wl,--build-id=none,-g,-nostdlib,-nostartfiles,-zmax-page-size=0x1000 main.c -o main
and as output I have this:
$ ls
main.c startfiles
I am trying to understand why g++ created file named "startfiles" not "main" ?
If you read the GNU ld official documentation you will see that there is no option named -nostartfiles. What you do pass for arguments to the linker with that is the options -n and -ostartfiles.
If I were you, I would check those other options you try to pass to the linker as well.
-nostartfiles is a compiler flag as far as I know, not a linker flag.
For the linker, it's the same as -n -o startfiles, which is why you're getting that output file name.