I am compiling courier-authlib-0.66.1 which utilizes libtool for compilation. I modified all Makefiles to remove CFLAGS and CXXFLAGS in --mode=link lines because I use some specially compiler flags for clang that will confuse the linker.
During compilation, I got the following error:
libtool: link: /usr/bin/nm -B .libs/authsasl.o .libs/authsaslcram.o .libs/authsasllogin.o .libs/authsaslplain.o .libs/authsaslfrombase64.o .libs/authsasltobase64.o | | /bin/sed 's/.* //' | sort | uniq > .libs/libcourierauthsasl.exp
./libtool: eval: line 1085: syntax error near unexpected token `|'
Apparently there are two bars in the command and I should remove one of them. However, when I opened the libtool file and jumped to line 1085, I only find the following code
eval "$my_cmd"
Could you please tell me how to find the root cause of this error and address it? Or which documents might help me? Thank you!
The problem is solved. I asked a question in Courier's mail list and got a very good answer:
http://sourceforge.net/p/courier/mailman/message/32327466/
I just copied the key part here.
$ fgrep 'sort | uniq' libtool
export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe |
\$SED 's/.* //' | sort | uniq > \$export_symbols"
Actually, the \$global_symbol_pipe variable is somehow missing, so I just removed it. Of course, it is just a dirty solution...
Related
So my organization is upgrading our Oracle database from 11g to 19c.
Previously, in my makefile, I had been setting ORACLE_HOME like this:
ORACLE_HOME=/opt/app/oracle/product/11.2.0.4/db_1
However, Oracle 19c has a fun feature that whenever they run a patch on it, the db_1 changes incrementally, becoming db_2, then db_3, with each patch, etc.
So obviously I can't hardcode the ORACLE_HOME path anymore.
In a bunch of my scripts, I'm pulling the current value from the ortab file, like this:
setenv ORACLE_SID DATABASE1
setenv ORACLE_HOME `cat /var/opt/oracle/oratab | sed 's/#.*//g' | grep -w $ORACLE_SID | awk -F: '{print $2;}'`
And this is working just fine, pulling the correct ORACLE_HOME path from the ortab file.
However, when I tried to do this in a makefile, like so:
ORACLE_SID=DATABASE1
ORACLE_HOME=`cat /var/opt/oracle/oratab | sed 's/#.*//g' | grep -w $ORACLE_SID | awk -F: '{print $2;}'`
I get this error when I try to run make:
$ make
`cat /var/opt/oracle/oratab | sed 's//bin/proc sys_include=/usr/include lines=yes iname=file1.pc oname=file1.c include=/path/to/include
First RE may not be null
*** Error code 2
make: Fatal error: Command failed for target `file1.o'
So obviously the command isn't working the way I'm expecting, but I am unsure how to fix it.
How do I fix the command to work inside makefile? I'm running Solaris 11.
This is not GNU make, this is just the default make that comes with Solaris 11.
Adding more information:
My ortab file looks like this:
$cat /var/opt/oracle/oratab
DATABASE_TEST:/opt/app/oracle/product/11.2.0.4/db_7:Y
DATABASE1:/opt/app/oracle/product/19.0.0.0/db_3:N
DATABASE2:/opt/app/oracle/product/11.2.0.4/db_13:Y
DATABASE3:/opt/app/oracle/product/11.2.0.4/db_1:Y
DATABASE_PROD:/opt/app/oracle/product/11.2.0.4/db_2:Y
So, what I need to do, is using the ORACLE_SID of DATABASE1, pull out the /opt/app/oracle/product/19.0.0.0/db_3 part, to use as my ORACLE_HOME directory in the makefile.
Update:
Based on an answer below from MadScientist , this is now my makefile:
ORACLE_SID=DATABASE1
#ORACLE_HOME = /opt/app/oracle/product/19.0.0/db_3
ORACLE_HOME = `cat /var/opt/oracle/oratab | sed 's/\#.*//g' | grep -w ${ORACLE_SID} | awk -F: '{print $$2;}'`
PROC=${ORACLE_HOME}/bin/proc
E_INCLUDE=/path/to/include
print-% : ; #echo $* = $($*)
file1.o: file1.pc
${PROC} sys_include=/usr/include lines=yes iname=$*.pc oname=$*.c include=${E_INCLUDE}
When I hardcode ORACLE_HOME, everything works correctly.
When I try to use the dynamically created ORACLE_HOME, I get this error:
$ make
`cat /var/opt/oracle/oratab | sed 's/\#.*//g' | grep -w DATABASE1 | awk -F: '{print $2;}'`/bin/proc sys_include=/usr/include lines=yes iname=file1.pc oname=file1.c include=/path/to/include
make: Fatal error: Command failed for target `file1.o'
So it looks like it's setting ORACLE_HOME as the command itself, rather than as the result of the command.
Weirdly, when I run make print-ORACLE_HOME, I get the expected result /opt/app/oracle/product/19.0.0/db_3
Well, certainly this:
setenv ORACLE_HOME /opt/app/oracle/product/11.2.0.4/db_1
could not have been in your makefile before because this is not valid makefile syntax. Also, it surprises me that anyone is still using csh for anything, and especially scripting, in 2020. But anyway.
The problem you're having is that makefiles are not shell scripts and the rules of syntax are different. Of course a makefile contains shell scripts inside of it, but only in recipes: here you're setting a makefile variable. So just plopping a shell statement down into a variable assignment very well might not work.
Here you have three problems: first, variable reference in makefiles are of the form $(FOO) or ${FOO} but not $FOO. Second, a # is considered a comment character in a makefile and must be escaped. And finally, if you do want an actual $ not a variable reference you have to escape it, as: $$. Fixing those, this should work but note that there are likely simpler ways to do this:
ORACLE_SID = DATABASE1
ORACLE_HOME = `cat /var/opt/oracle/oratab | sed 's/\#.*//g' | grep -w $(ORACLE_SID) | awk -F: '{print $$2;}'`
You say that after this, this rule:
PROC=${ORACLE_HOME}/bin/proc
file1.o: file1.pc
${PROC} sys_include=/usr/include lines=yes iname=$*.pc oname=$*.c include=${E_INCLUDE}
Gives this output:
$ make
`cat /var/opt/oracle/oratab | sed 's/\#.*//g' | grep -w DATABASE1 | awk -F: '{print $2;}'`/bin/proc sys_include=/usr/include lines=yes iname=file1.pc oname=file1.c include=/path/to/include
make: Fatal error: Command failed for target `file1.o'
That error message is not very helpful and means nothing. It's a shame this doesn't give a better message.
I recommend you change the rule to this:
file1.o: file1.pc
echo PROC=\'${PROC}\'; ${PROC} sys_include=/usr/include lines=yes iname=$*.pc oname=$*.c include=${E_INCLUDE}
then, you should see something like this in the output:
$ make
echo PROC=\'`cat /var/opt/oracle/oratab...lots of stuff...
PROC='/...'
make: Fatal error: Command failed for target `file1.o'
What you want to look at is the second line of the output, PROC='/...' and examine that path /..., whatever it is, to make sure it looks right. Also it should not contain any whitespace or other special characters, etc.
If that value that is printed looks wrong, you'll have to fix your script to make it right. If it looks right, then I have no idea what's going on and it must be something particular about the version of make you're using.
Here's a simplified example to start. This initial version uses awk to search, drops the sed absent any # comments
ORACLE_SID := DATABASE1
ORACLE_HOME := $(shell awk -F: "/^$(ORACLE_SID)/ { print \$$2; }" /var/opt/oracle/oratab)
(Update) possible Solaris version from documents, unverified:
ORACLE_HOME:sh = awk -F: '/^DATABASE1/ { print $$2; }' /var/opt/oracle/oratab
I finally got it to work.
Using #Milag 's answer regarding the :sh command substitution, I was able to find the documentation regarding that for Solaris (not GNU) make: link to documentation
THIS was the answer:
ORACLE_HOME :sh =cat /var/opt/oracle/oratab | sed 's/\#.*//g' | grep -w DATABASE1 | awk -F: '{print $2;}'
The key? NOT putting a double dollar sign, as the documentation said:
"In contrast to commands in rules, the command is not subject for macro substitution; therefore, a dollar sign ($) need not be replaced with a double dollar sign ($$)."
Because of this I also had to hardcode DATABASE1 instead of using the ${ORACLE_SID} variable, but since that value will never change, I can live with that.
I have recently moved from bash to zsh and one of the little scripts I found a long time ago stopped working.
The script shows what packages depend on the package specified.
comm -12 <(pactree -ru $1 | sort) <(pacman -Qqe | sort) | grep -v ^$1$ | sed 's/^/ /'
After some time messing with it around I found out it breaks at grep -v ^$1$. Back then, when I found the script I tried googling to learn what does it mean but unsuccessfully. Now that it broke itself I'm even more interested in what it does and how exactly does it work.
So, the question is, what does ^$1$ mean and how to get it to work in zsh? Thanks!
Edit:
Okay, ^ and $ are regular expressions, I see. RE is the topic I always laid aside as it requires a lot of free time and willingness to study. The question is, why doesn't it work in zsh as it is a grep feature and the shell shouldn't interact with it.
I fixed it by adding a pair of double quotes around the ^$1$. For some reason bash worked perfectly without the quotes yet zsh didn't like it at all. The fix is actually a lot easier than I expected but that's just because I didn't know that that was a regular expression(thanks, #DevSolar).
If one wants the final script for pacman to check what packages depend on a specific package, here it is
comm -12 <(pactree -ru $1 | sort) <(pacman -Qqe | sort) | grep -v "^$1$" | sed 's/^/ /'
}
Use it in a function or in a shell script.
Edit: I figured what was the problem by myself before #DevSolar suggested it but I'm still very grateful for the help :)
I have bunch of Make files though directory hierarchy, some of them define C (CPP) and H files to use in compilations, some of them not, that are not adds to CPFLAFS -I../../SomeDir1 -I../SomeDir2/SomeDir2/Inc. etc.
Some of the Make files are called via make -C PATH Target .
The thing is hierarchy of sources grew for years and covers different projects and target platforms.
Now there are no people left in the company who remember "why that" and there is not enough documentation left.
The question: is there way to know particular sources and header files used to build the final target "all" ?
Thank you
There are ways, I know of two. Both require that you run make all, and before that remove all generated files so every file in question would actually be rebuilt (usually make clean).
Using strace
If strace is available, you can find the files by tracing and analyzing the system calls.
You can do it like this:
$ strace -f -o trace make all
$ grep 'open.*\.[ch]"' trace | grep -v 'open("/\(tmp\|usr\)' | sed -e 's/.*open("//' -e 's/".*//' | sort -u
Using Dependency Files (doesn't work with all compilers)
If your compiler can generate dependency files (i.e. gcc, armcc), you can analyze the dependency files. Make sure that dependency files are generated by putting the corresponding option in your CFLAGS or CPPFLAGS. For gcc, this would be -MMD. If Makefiles are written nicely, you can set CPPFLAGS on the command line, I will use this example here.
$ make all CPPFLAGS+=-MMD
$ find -name "*.d" -exec cat {} \; | sed -e 's/[:\\]//' -e 's/ /\n/g' | grep '\.[ch]$' | sort -u
I'm currently trying to set up my build system in Sublime Text to compile C++11 Code and additionally use libpqxx library for some Postgres database stuff.
Right now, without C++11, my g++ command looks like this:
"cmd": ["g++", "${file}", "-o", "${file_path}/${file_base_name}", "-I/usr/include/pqxx", "-lpqxx", "-lpq"]
Which works fine.
Now I add "-std=c++0x" to the line, and it doesn't work. However, I wrote a simple testprogram that has #include <regex> in it, startet out with a default build file and added the C++11 flag to look like this:
"cmd": ["g++", "-std=c++0x", "${file}", "-o", "${file_path}/${file_base_name}"]
It works fine.
I also tried running the build from terminal, using this line:
g++ Connect.cpp -o Connect -std=c++0x -I/usr/include/pqxx -lpqxx, -lpq
But with no luck either.
Further I tried different places for the -std=c++0x. Right after g++, after the input and output file names, after the include, after the libary linking. And I trief to alter the std flag to -std+gnu++11, -std=c++11, -std=gnu++0x. Nothing helped.
What am I doing wrong?
(by the way my GCC/G++ has version 4.9, so there shouldn't be any problems with C++11 itself. The testfile.cpp without lipqxx include and linking works as mentioned before)
The solution: -I/usr/include/pqxx needed to be taken out.
Indeed, the solution is to remove the -I/usr/include/pqxx. But why?
The file he wants to include is /usr/include/pqxx/pqxx.
He is including it with #include <pqxx/pqxx> (He didnt provide that information on stackoverflow). With this include statement he doesn't need the additional include path since /usr/include is in the standard path.
But why is the build failing?
% ~ cpp -Wall -std=c++11 -M test.cpp > test2
% ~ cpp -Wall -std=c++11 -I/usr/include/pqxx -M test.cpp > test
% ~ cat test2 | sed "s/ \\\\//g" | sed "s/ /\n/g" | sort > test2
% ~ cat test | sed "s/ \\\\//g" | sed "s/ /\n/g" | sort > test
% ~ diff test test2
235d234
<
270a270
> /usr/include/c++/4.9.0/array
404a405
> /usr/include/c++/4.9.0/tuple
496d496
< /usr/include/pqxx/tuple
The -M option outputs a makefile.compatible list of headerfiles. The rest is just reformating to have a nicer diff.
Result: with -I/usr/include/pqxx the pqxx/tuple is included instead of the standard c++ tuple. That causes the compilation errors he didnt provide here.
I have been struggling like for two hours to figure out the issue regarding this script of mine. When I used it statically without any variable it fetches the grep results, but when I put them with those variables, i keep receiving error and no results. I believe there is something wrong with the special character escape which I can not handle.
I have the file FLAGS_IN with this structure :
automotive_susan_s dataset1 -funsafe-math-optimizations -fno-guess-branch-probability -fno-ivopts -fno-inline-functions -fno-omit-frame-pointer -fselective-scheduling -fno-inline-small-functions -fno-tree-pre -ftracer -fno-move-loop-invariants
that have the flags for i in AppName and the dataset$j as structured above. Could anyone help me figure out what is wrong with this part of my sh script?
GCC_OPT="-O3"
OPT_FLAGS=$("grep $i\ dataset$j\ $FLAGS_IN|sed\ s/$i\ dataset$j//g")
echo $GCC_OPT
echo $OPT_FLAGS
echo "found the validated flags, they are \n $GCC_OPT $OPT_FLAGS"
make -f Makefile.gcc -j4 CCC_OPTS="$GCC_OPT\ $OPT_FLAG"
You're a little overzealous with your quoting. Also, it's a little easier to use cut here than sed.
OPT_FLAGS=$(grep "$i dataset$j" FLAGS_IN | cut -d " " -f3-)
and
make -f Makefile.gcc -j4 CCC_OPTS="$GCC_OPT $OPT_FLAG"
Is this what you're trying to do:
$ cat file
foo
automotive_susan_s dataset1 -funsafe-math-optimizations ...
bar
$ i=automotive_susan_s
$ j=1
$ sed -n "s/$i dataset$j//p" file
-funsafe-math-optimizations ...